ARTS  2.0.49
rte.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2008
2  Patrick Eriksson <Patrick.Eriksson@rss.chalmers.se>
3  Stefan Buehler <sbuehler@ltu.se>
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation; either version 2, or (at your option) any
8  later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18  USA. */
19 
20 
21 
22 /*===========================================================================
23  === File description
24  ===========================================================================*/
25 
36 /*===========================================================================
37  === External declarations
38  ===========================================================================*/
39 
40 #include <cmath>
41 #include <stdexcept>
42 #include "auto_md.h"
43 #include "check_input.h"
44 #include "logic.h"
45 #include "math_funcs.h"
46 #include "montecarlo.h"
47 #include "physics_funcs.h"
48 #include "ppath.h"
49 #include "rte.h"
50 #include "special_interp.h"
51 #include "lin_alg.h"
52 
53 extern const Numeric BOLTZMAN_CONST;
54 extern const Numeric PLANCK_CONST;
55 extern const Numeric SPEED_OF_LIGHT;
56 extern const Numeric PI;
57 extern const Numeric DEG2RAD;
58 extern const Numeric RAD2DEG;
59 
60 
61 
62 /*===========================================================================
63  === The functions in alphabetical order
64  ===========================================================================*/
65 
67 
83  MatrixView iy,
84  const String& y_unit,
85  ConstVectorView f_grid,
86  const ArrayOfIndex& i_pol )
87 {
88  // The code is largely identical between the two apply_y_unit functions.
89  // If any change here, remember to update the other function.
90 
91  const Index nf = iy.nrows();
92  const Index ns = iy.ncols();
93 
94  assert( f_grid.nelem() == nf );
95  assert( i_pol.nelem() == ns );
96 
97  if( y_unit == "1" )
98  {}
99 
100  else if( y_unit == "RJBT" )
101  {
102  for( Index iv=0; iv<nf; iv++ )
103  {
104  const Numeric scfac = invrayjean( 1, f_grid[iv] );
105  for( Index is=0; is<ns; is++ )
106  {
107  if( i_pol[is] < 5 ) // Stokes components
108  { iy(iv,is) *= scfac; }
109  else // Measuement single pols
110  { iy(iv,is) *= 2*scfac; }
111  }
112  }
113  }
114 
115  else if( y_unit == "PlanckBT" )
116  {
117  for( Index iv=0; iv<nf; iv++ )
118  {
119  for( Index is=ns-1; is>=0; is-- ) // Order must here be reversed
120  {
121  if( i_pol[is] == 1 )
122  { iy(iv,is) = invplanck( iy(iv,is), f_grid[iv] ); }
123  else if( i_pol[is] < 5 )
124  {
125  assert( i_pol[0] == 1 );
126  iy(iv,is) =
127  invplanck( 0.5*(iy(iv,0)+iy(iv,is)), f_grid[iv] ) -
128  invplanck( 0.5*(iy(iv,0)-iy(iv,is)), f_grid[iv] );
129  }
130  else
131  { iy(iv,is) = invplanck( 2*iy(iv,is), f_grid[iv] ); }
132  }
133  }
134  }
135 
136  else if ( y_unit == "W/(m^2 m sr)" )
137  {
138  for( Index iv=0; iv<nf; iv++ )
139  {
140  const Numeric scfac = f_grid[iv] * ( f_grid[iv] / SPEED_OF_LIGHT );
141  for( Index is=0; is<ns; is++ )
142  { iy(iv,is) *= scfac; }
143  }
144  }
145 
146  else if ( y_unit == "W/(m^2 m-1 sr)" )
147  {
148  iy *= SPEED_OF_LIGHT;
149  }
150 
151  else
152  {
153  ostringstream os;
154  os << "Unknown option: y_unit = \"" << y_unit << "\"\n"
155  << "Recognised choices are: \"1\", \"RJBT\", \"PlanckBT\""
156  << "\"W/(m^2 m sr)\" and \"W/(m^2 m-1 sr)\"";
157 
158  throw runtime_error( os.str() );
159  }
160 }
161 
162 
163 
165 
185  Tensor3View J,
186  ConstMatrixView iy,
187  const String& y_unit,
188  ConstVectorView f_grid,
189  const ArrayOfIndex& i_pol )
190 {
191  // The code is largely identical between the two apply_y_unit functions.
192  // If any change here, remember to update the other function.
193 
194  const Index nf = iy.nrows();
195  const Index ns = iy.ncols();
196  const Index np = J.npages();
197 
198  assert( J.nrows() == nf );
199  assert( J.ncols() == ns );
200  assert( f_grid.nelem() == nf );
201  assert( i_pol.nelem() == ns );
202 
203  if( y_unit == "1" )
204  {}
205 
206  else if( y_unit == "RJBT" )
207  {
208  for( Index iv=0; iv<nf; iv++ )
209  {
210  const Numeric scfac = invrayjean( 1, f_grid[iv] );
211  for( Index is=0; is<ns; is++ )
212  {
213  if( i_pol[is] < 5 ) // Stokes componenets
214  {
215  for( Index ip=0; ip<np; ip++ )
216  { J(ip,iv,is) *= scfac; }
217  }
218  else // Measuement single pols
219  {
220  for( Index ip=0; ip<np; ip++ )
221  { J(ip,iv,is) *= 2*scfac; }
222  }
223  }
224  }
225  }
226 
227  else if( y_unit == "PlanckBT" )
228  {
229  for( Index iv=0; iv<f_grid.nelem(); iv++ )
230  {
231  for( Index is=ns-1; is>=0; is-- )
232  {
233  Numeric scfac = 1;
234  if( i_pol[is] == 1 )
235  { scfac = dinvplanckdI( iy(iv,is), f_grid[iv] ); }
236  else if( i_pol[is] < 5 )
237  {
238  assert( i_pol[0] == 1 );
239  scfac =
240  dinvplanckdI( 0.5*(iy(iv,0)+iy(iv,is)), f_grid[iv] ) +
241  dinvplanckdI( 0.5*(iy(iv,0)-iy(iv,is)), f_grid[iv] );
242  }
243  else
244  { scfac = dinvplanckdI( 2*iy(iv,is), f_grid[iv] ); }
245  //
246  for( Index ip=0; ip<np; ip++ )
247  { J(ip,iv,is) *= scfac; }
248  }
249  }
250  }
251 
252  else if ( y_unit == "W/(m^2 m sr)" )
253  {
254  for( Index iv=0; iv<nf; iv++ )
255  {
256  const Numeric scfac = f_grid[iv] * ( f_grid[iv] / SPEED_OF_LIGHT );
257  for( Index ip=0; ip<np; ip++ )
258  {
259  for( Index is=0; is<ns; is++ )
260  { J(ip,iv,is) *= scfac; }
261  }
262  }
263  }
264 
265  else if ( y_unit == "W/(m^2 m-1 sr)" )
266  {
267  J *= SPEED_OF_LIGHT;
268  }
269 
270  else
271  {
272  ostringstream os;
273  os << "Unknown option: y_unit = \"" << y_unit << "\"\n"
274  << "Recognised choices are: \"1\", \"RJBT\", \"PlanckBT\""
275  << "\"W/(m^2 m sr)\" and \"W/(m^2 m-1 sr)\"";
276 
277  throw runtime_error( os.str() );
278  }
279 
280 }
281 
282 
283 
285 
301 void ext2trans(//Output and Input:
302  MatrixView trans_mat,
303  //Input
304  ConstMatrixView ext_mat_av,
305  const Numeric& l_step )
306 {
307  //Stokes dimension:
308  Index stokes_dim = ext_mat_av.nrows();
309 
310  //Check inputs:
311  assert( is_size(trans_mat, stokes_dim, stokes_dim) );
312  assert( is_size(ext_mat_av, stokes_dim, stokes_dim) );
313  assert( l_step >= 0 );
314  assert( !is_singular( ext_mat_av ) );
315 
316  // Any changes here should also be implemented in rte_step_std.
317 
318  //--- Scalar case: ---------------------------------------------------------
319  if( stokes_dim == 1 )
320  {
321  trans_mat(0,0) = exp(-ext_mat_av(0,0) * l_step);
322  }
323 
324 
325  //--- Vector case: ---------------------------------------------------------
326 
327  //- Unpolarised
328  else if( is_diagonal(ext_mat_av) )
329  {
330  const Numeric tv = exp(-ext_mat_av(0,0) * l_step);
331 
332  trans_mat = 0;
333 
334  for( Index i=0; i<stokes_dim; i++ )
335  {
336  trans_mat(i,i) = tv;
337  }
338  }
339 
340 
341  //- General case
342  else
343  {
344  Matrix ext_mat_ds = ext_mat_av;
345  ext_mat_ds *= -l_step;
346 
347  Index q = 10; // index for the precision of the matrix exp function
348 
349  matrix_exp( trans_mat, ext_mat_ds, q );
350  }
351 }
352 
353 
354 
356 
384  Vector& ppath_p,
385  Vector& ppath_t,
386  Matrix& ppath_vmr,
387  Vector& ppath_wind_u,
388  Vector& ppath_wind_v,
389  Vector& ppath_wind_w,
390  const Ppath& ppath,
391  const Index& atmosphere_dim,
392  ConstVectorView p_grid,
393  ConstTensor3View t_field,
394  ConstTensor4View vmr_field,
395  ConstTensor3View wind_u_field,
396  ConstTensor3View wind_v_field,
397  ConstTensor3View wind_w_field )
398 {
399  const Index np = ppath.np;
400 
401  // Pressure:
402  ppath_p.resize(np);
403  Matrix itw_p(np,2);
404  interpweights( itw_p, ppath.gp_p );
405  itw2p( ppath_p, p_grid, ppath.gp_p, itw_p );
406 
407  // Temperature:
408  ppath_t.resize(np);
409  Matrix itw_field;
410  interp_atmfield_gp2itw( itw_field, atmosphere_dim,
411  ppath.gp_p, ppath.gp_lat, ppath.gp_lon );
412  interp_atmfield_by_itw( ppath_t, atmosphere_dim, t_field,
413  ppath.gp_p, ppath.gp_lat, ppath.gp_lon, itw_field );
414 
415  // VMR fields:
416  const Index ns = vmr_field.nbooks();
417  ppath_vmr.resize(ns,np);
418  for( Index is=0; is<ns; is++ )
419  {
420  interp_atmfield_by_itw( ppath_vmr(is, joker), atmosphere_dim,
421  vmr_field( is, joker, joker, joker ),
422  ppath.gp_p, ppath.gp_lat, ppath.gp_lon,
423  itw_field );
424  }
425 
426  // Winds:
427  //
428  ppath_wind_w.resize(np);
429  if( wind_w_field.npages() > 0 )
430  {
431  interp_atmfield_by_itw( ppath_wind_w, atmosphere_dim, wind_w_field,
432  ppath.gp_p, ppath.gp_lat, ppath.gp_lon, itw_field );
433  }
434  else
435  { ppath_wind_w = 0; }
436  //
437  ppath_wind_v.resize(np);
438  if( wind_v_field.npages() > 0 )
439  {
440  interp_atmfield_by_itw( ppath_wind_v, atmosphere_dim, wind_v_field,
441  ppath.gp_p, ppath.gp_lat, ppath.gp_lon, itw_field );
442  }
443  else
444  { ppath_wind_v = 0; }
445  //
446  ppath_wind_u.resize(np);
447  if( atmosphere_dim > 2 )
448  {
449  if( wind_u_field.npages() > 0 )
450  {
451  interp_atmfield_by_itw( ppath_wind_u, atmosphere_dim, wind_u_field,
452  ppath.gp_p, ppath.gp_lat, ppath.gp_lon, itw_field );
453  }
454  else
455  { ppath_wind_u = 0; }
456  }
457  else
458  { ppath_wind_u = 0; }
459 }
460 
461 
462 
464 
480  Matrix& ppath_pnd,
481  const Ppath& ppath,
482  const Index& atmosphere_dim,
483  const ArrayOfIndex& cloudbox_limits,
484  ConstTensor4View pnd_field )
485 {
486  ppath_pnd.resize( pnd_field.nbooks(), ppath.np );
487 
488  Matrix itw_field;
489  ArrayOfGridPos gpc_p, gpc_lat, gpc_lon;
490  //
491  interp_cloudfield_gp2itw( itw_field, gpc_p, gpc_lat, gpc_lon,
492  ppath.gp_p, ppath.gp_lat, ppath.gp_lon,
493  atmosphere_dim, cloudbox_limits );
494  for( Index ip=0; ip<pnd_field.nbooks(); ip++ )
495  {
496  interp_atmfield_by_itw( ppath_pnd(ip,joker), atmosphere_dim,
497  pnd_field(ip,joker,joker,joker),
498  gpc_p, gpc_lat, gpc_lon, itw_field );
499  }
500 }
501 
502 
504 
532  Workspace& ws,
533  Tensor3& ppath_abs_scalar,
534  Matrix& ppath_tau,
535  Vector& total_tau,
536  Matrix& ppath_emission,
537  const Agenda& abs_scalar_gas_agenda,
538  const Agenda& emission_agenda,
539  const Ppath& ppath,
540  ConstVectorView ppath_p,
541  ConstVectorView ppath_t,
542  ConstMatrixView ppath_vmr,
543  ConstVectorView ppath_wind_u,
544  ConstVectorView ppath_wind_v,
545  ConstVectorView ppath_wind_w,
546  ConstVectorView f_grid,
547  const Index& atmosphere_dim,
548  const Index& emission_do )
549 {
550  // Sizes
551  const Index np = ppath.np;
552  const Index nabs = ppath_vmr.nrows();
553  const Index nf = f_grid.nelem();
554 
555  // Init variables
556  ppath_abs_scalar.resize( nf, nabs, np );
557  ppath_tau.resize( nf, np-1 );
558  total_tau.resize( nf );
559  total_tau = 0;
560  if( emission_do )
561  { ppath_emission.resize( nf, np ); }
562  else
563  { ppath_emission.resize( 0, 0 ); }
564 
565  // Mean of extreme frequencies
566  const Numeric f0 = (f_grid[0]+f_grid[nf-1])/2.0;
567 
568  for( Index ip=0; ip<np; ip++ )
569  {
570  // Doppler shift
571  //
572  Numeric rte_doppler = 0;
573  //
574  if( ppath_wind_v[ip]!=0 || ppath_wind_u[ip]!=0 || ppath_wind_w[ip]!=0 )
575  {
576  // za nd aa of winds and LOS
577  const Numeric v = sqrt( pow(ppath_wind_u[ip],2) +
578  pow(ppath_wind_v[ip],2) + pow(ppath_wind_w[ip],2) );
579  Numeric aa_w = 0, aa_p = 0;
580  if( atmosphere_dim < 3 )
581  {
582  if( ppath_wind_v[ip]<0 )
583  { aa_w = PI; } // Negative v-winds for 1 and 2D
584  if( atmosphere_dim == 2 && ppath.los(ip,0) < 0 )
585  { aa_p = PI; } // Negative sensor za for 2D
586  }
587  else //3D
588  {
589  aa_w = atan2( ppath_wind_u[ip], ppath_wind_v[ip] );
590  aa_p = DEG2RAD * ppath.los(ip,1);
591  }
592  const Numeric za_w = acos( ppath_wind_w[ip] / v );
593  const Numeric za_p = DEG2RAD * fabs( ppath.los(ip,0) );
594  //
595  // Actual shift
596  const Numeric costerm = cos(za_w) * cos(za_p) +
597  sin(za_w) * sin(za_p)*cos(aa_w-aa_p);
598 
599  rte_doppler = -v * f0 * costerm / SPEED_OF_LIGHT;
600  }
601 
602  // We must use temporary variables as the agenda input must be
603  // free to be resized
604  Vector evector;
605  Matrix sgmatrix;
606  //
607  abs_scalar_gas_agendaExecute( ws, sgmatrix, -1, rte_doppler, ppath_p[ip],
608  ppath_t[ip], ppath_vmr(joker,ip),
609  abs_scalar_gas_agenda );
610  ppath_abs_scalar(joker,joker,ip) = sgmatrix;
611  //
612  if( emission_do )
613  {
614  emission_agendaExecute( ws, evector, ppath_t[ip], emission_agenda );
615  ppath_emission(joker,ip) = evector;
616  }
617 
618  // Partial and total tau
619  //
620  if( ip > 0 )
621  {
622  for( Index iv=0; iv<nf; iv++ )
623  {
624  ppath_tau(iv,ip-1) = 0.5 * ppath.l_step[ip-1] * (
625  ppath_abs_scalar(iv,joker,ip-1).sum() +
626  ppath_abs_scalar(iv,joker,ip).sum() );
627  total_tau[iv] += ppath_tau(iv,ip-1);
628  }
629  }
630  }
631 }
632 
633 
634 
636 
673  Workspace& ws,
674  Tensor3& ppath_asp_abs_vec,
675  Tensor4& ppath_asp_ext_mat,
676  Tensor3& ppath_pnd_abs_vec,
677  Tensor4& ppath_pnd_ext_mat,
678  Tensor4& ppath_transmission,
679  Tensor3& total_transmission,
680  Matrix& ppath_emission,
682  const Agenda& abs_scalar_gas_agenda,
683  const Agenda& emission_agenda,
684  const Agenda& opt_prop_gas_agenda,
685  const Ppath& ppath,
686  ConstVectorView ppath_p,
687  ConstVectorView ppath_t,
688  ConstMatrixView ppath_vmr,
689  ConstVectorView ppath_wind_u,
690  ConstVectorView ppath_wind_v,
691  ConstVectorView ppath_wind_w,
692  ConstMatrixView ppath_pnd,
693  const Index& use_mean_scat_data,
694  const ArrayOfSingleScatteringData& scat_data_raw,
695  const Index& stokes_dim,
696  ConstVectorView f_grid,
697  const Index& atmosphere_dim,
698  const Index& emission_do,
699  const Verbosity& verbosity)
700 {
701  // Sizes
702  const Index np = ppath.np;
703  const Index nf = f_grid.nelem();
704 
705  // Init variables
706  ppath_asp_abs_vec.resize( nf, stokes_dim, np );
707  ppath_asp_ext_mat.resize( nf, stokes_dim, stokes_dim, np );
708  ppath_pnd_abs_vec.resize( nf, stokes_dim, np );
709  ppath_pnd_ext_mat.resize( nf, stokes_dim, stokes_dim, np );
710  ppath_transmission.resize( nf, stokes_dim, stokes_dim, np-1 );
711  total_transmission.resize( nf, stokes_dim, stokes_dim );
712  //
713  if( emission_do )
714  { ppath_emission.resize( nf, np ); }
715  else
716  { ppath_emission.resize( 0, 0 ); }
717 
718  // Mean of extreme frequencies
719  const Numeric f0 = (f_grid[0]+f_grid[nf-1])/2.0;
720 
721 
722  // Particle single scattering properties (are independent of position)
723  //
724  if( use_mean_scat_data )
725  {
726  scat_data.resize( 1 );
727  scat_data_monoCalc( scat_data[0], scat_data_raw, Vector(1,f0), 0, verbosity );
728  }
729  else
730  {
731  scat_data.resize( nf );
732  for( Index iv=0; iv<nf; iv++ )
733  { scat_data_monoCalc( scat_data[iv], scat_data_raw, f_grid, iv, verbosity ); }
734  }
735 
736 
737  // Loop ppath points
738  //
739  for( Index ip=0; ip<np; ip++ )
740  {
741  // Doppler shift
742  //
743  assert( ppath_wind_u[ip] == 0 );
744  assert( ppath_wind_v[ip] == 0 );
745  assert( ppath_wind_w[ip] == 0 );
746  //
747  const Numeric rte_doppler = 0;
748 
749  // Emission source term
750  //
751  if( emission_do )
752  {
753  Vector evector; // Agenda must be free to resize
754  emission_agendaExecute( ws, evector, ppath_t[ip], emission_agenda );
755  ppath_emission(joker,ip) = evector;
756  }
757 
758  // Absorption species properties
759  {
760  Matrix asgmatrix; // Agendas must be free to resize
761  Matrix abs_vec( nf, stokes_dim, 0 );
762  Tensor3 ext_mat( nf, stokes_dim, stokes_dim, 0 );
763  //
764  abs_scalar_gas_agendaExecute( ws, asgmatrix, -1, rte_doppler,
765  ppath_p[ip], ppath_t[ip],
766  ppath_vmr(joker,ip),
767  abs_scalar_gas_agenda );
768  opt_prop_gas_agendaExecute( ws, ext_mat, abs_vec, -1, asgmatrix,
769  opt_prop_gas_agenda );
770  ppath_asp_ext_mat(joker,joker,joker,ip) = ext_mat;
771  ppath_asp_abs_vec(joker,joker,ip) = abs_vec;
772  }
773 
774  // Particle properties
775  {
776  // Direction of outgoing scattered radiation (which is reversed to
777  // LOS). Note that rte_los2 is only used for extracting scattering
778  // properties.
779  Vector rte_los2;
780  mirror_los( rte_los2, ppath.los(ip,joker), atmosphere_dim );
781 
782  // Extinction and absorption
783  if( use_mean_scat_data )
784  {
785  Vector abs_vec( stokes_dim, 0 );
786  Matrix ext_mat( stokes_dim, stokes_dim, 0 );
787  opt_propCalc( ext_mat, abs_vec,
788  rte_los2[0], rte_los2[1], scat_data[0],
789  stokes_dim, ppath_pnd(joker,ip), ppath_t[ip],
790  verbosity);
791  for( Index iv=0; iv<nf; iv++ )
792  {
793  ppath_pnd_ext_mat(iv,joker,joker,ip) = ext_mat;
794  ppath_pnd_abs_vec(iv,joker,ip) = abs_vec;
795  }
796  }
797  else
798  {
799  for( Index iv=0; iv<nf; iv++ )
800  {
801  Vector abs_vec( stokes_dim, 0 );
802  Matrix ext_mat( stokes_dim, stokes_dim, 0 );
803  opt_propCalc( ext_mat, abs_vec,
804  rte_los2[0], rte_los2[1], scat_data[iv],
805  stokes_dim, ppath_pnd(joker,ip), ppath_t[ip],
806  verbosity );
807  ppath_pnd_ext_mat(iv,joker,joker,ip) = ext_mat;
808  ppath_pnd_abs_vec(iv,joker,ip) = abs_vec;
809  }
810  }
811  }
812 
813  // Transmission
814  //
815  if( ip == 0 ) // Set total_transmission to identity matrices
816  {
817  for( Index iv=0; iv<nf; iv++ )
818  { id_mat( total_transmission(iv,joker,joker) ); }
819  }
820  else
821  {
822  for( Index iv=0; iv<nf; iv++ )
823  {
824  // Average extinction matrix
825  Matrix ext_mat_av( stokes_dim, stokes_dim,0 );
826  for( Index is1=0; is1<stokes_dim; is1++ )
827  {
828  for( Index is2=0; is2<stokes_dim; is2++ )
829  {
830  ext_mat_av(is1,is2) = 0.5 * (
831  ppath_asp_ext_mat(iv,is1,is2,ip-1) +
832  ppath_asp_ext_mat(iv,is1,is2,ip) +
833  ppath_pnd_ext_mat(iv,is1,is2,ip-1) +
834  ppath_pnd_ext_mat(iv,is1,is2,ip) );
835  }
836  }
837  // Transmission
838  ext2trans( ppath_transmission(iv,joker,joker,ip-1),
839  ext_mat_av, ppath.l_step[ip-1] );
840  const Matrix tmp = total_transmission(iv,joker,joker);
841  mult( total_transmission(iv,joker,joker), tmp,
842  ppath_transmission(iv,joker,joker,ip-1) );
843  }
844  }
845  }
846 }
847 
848 
849 
851 
862  const Sparse& sensor_response,
863  const Index& imblock )
864 {
865  const Index n1y = sensor_response.nrows();
866  return Range( n1y*imblock, n1y );
867 }
868 
869 
870 
872 
886  Tensor3& iy_transmission,
887  const Index& stokes_dim,
888  ConstVectorView tau )
889 {
890  iy_transmission.resize( tau.nelem(), stokes_dim, stokes_dim );
891  iy_transmission = 0;
892  for( Index i=0; i<tau.nelem(); i++ )
893  {
894  const Numeric t = exp( -tau[i] );
895  for( Index is=0; is<stokes_dim; is++ )
896  {
897  iy_transmission(i,is,is) = t;
898  }
899  }
900 }
901 
902 
903 
905 
930  Tensor3& iy_trans_new,
931  ConstTensor3View iy_transmission,
932  ConstTensor3View trans )
933 {
934  const Index nf = iy_transmission.npages();
935  const Index ns = iy_transmission.ncols();
936 
937  assert( ns == iy_transmission.nrows() );
938  assert( nf == trans.npages() );
939  assert( ns == trans.nrows() );
940  assert( ns == trans.ncols() );
941 
942  iy_trans_new.resize( nf, ns, ns );
943 
944  for( Index iv=0; iv<nf; iv++ )
945  {
946  mult( iy_trans_new(iv,joker,joker), iy_transmission(iv,joker,joker),
947  trans(iv,joker,joker) );
948  }
949 }
950 
951 
952 
954 
982  Tensor3& iy_trans_new,
983  ConstTensor3View iy_transmission,
984  ConstVectorView tau )
985 {
986  const Index nf = iy_transmission.npages();
987 
988  assert( iy_transmission.ncols() == iy_transmission.nrows() );
989  assert( nf == tau.nelem() );
990 
991  iy_trans_new = iy_transmission;
992 
993  for( Index iv=0; iv<nf; iv++ )
994  { iy_trans_new(iv,joker,joker) *= exp( -tau[iv] ); }
995 }
996 
997 
998 
1000 
1017  Vector& los_mirrored,
1018  ConstVectorView los,
1019  const Index& atmosphere_dim )
1020 {
1021  los_mirrored.resize(2);
1022  //
1023  if( atmosphere_dim == 1 )
1024  {
1025  los_mirrored[0] = 180 - los[0];
1026  los_mirrored[1] = 180;
1027  }
1028  else if( atmosphere_dim == 2 )
1029  {
1030  los_mirrored[0] = 180 - fabs( los[0] );
1031  if( los[0] >= 0 )
1032  { los_mirrored[1] = 180; }
1033  else
1034  { los_mirrored[1] = 0; }
1035  }
1036  else if( atmosphere_dim == 3 )
1037  {
1038  los_mirrored[0] = 180 - los[0];
1039  los_mirrored[1] = los[1] + 180;
1040  if( los_mirrored[1] > 180 )
1041  { los_mirrored[1] -= 360; }
1042  }
1043 }
1044 
1045 
1046 
1048 
1092 void rte_step_std(//Output and Input:
1093  VectorView stokes_vec,
1094  MatrixView trans_mat,
1095  //Input
1096  ConstMatrixView ext_mat_av,
1097  ConstVectorView abs_vec_av,
1098  ConstVectorView sca_vec_av,
1099  const Numeric& l_step,
1100  const Numeric& rte_planck_value )
1101 {
1102  //Stokes dimension:
1103  Index stokes_dim = stokes_vec.nelem();
1104 
1105  //Check inputs:
1106  assert(is_size(trans_mat, stokes_dim, stokes_dim));
1107  assert(is_size(ext_mat_av, stokes_dim, stokes_dim));
1108  assert(is_size(abs_vec_av, stokes_dim));
1109  assert(is_size(sca_vec_av, stokes_dim));
1110  assert( rte_planck_value >= 0 );
1111  assert( l_step >= 0 );
1112  assert (!is_singular( ext_mat_av ));
1113 
1114  // Any changes here associated with the extinction matrix should also be
1115  // implemented in ext2mat.
1116 
1117  // Check, if only the first component of abs_vec is non-zero:
1118  bool unpol_abs_vec = true;
1119 
1120  for (Index i = 1; i < stokes_dim; i++)
1121  if (abs_vec_av[i] != 0)
1122  unpol_abs_vec = false;
1123 
1124  bool unpol_sca_vec = true;
1125 
1126  for (Index i = 1; i < stokes_dim; i++)
1127  if (sca_vec_av[i] != 0)
1128  unpol_sca_vec = false;
1129 
1130 
1131  //--- Scalar case: ---------------------------------------------------------
1132  if( stokes_dim == 1 )
1133  {
1134  trans_mat(0,0) = exp(-ext_mat_av(0,0) * l_step);
1135  stokes_vec[0] = stokes_vec[0] * trans_mat(0,0) +
1136  (abs_vec_av[0] * rte_planck_value + sca_vec_av[0]) /
1137  ext_mat_av(0,0) * (1 - trans_mat(0,0));
1138  }
1139 
1140 
1141  //--- Vector case: ---------------------------------------------------------
1142 
1143  // We have here two cases, diagonal or non-diagonal ext_mat_gas
1144  // For diagonal ext_mat_gas, we expect abs_vec_gas to only have a
1145  // non-zero value in position 1.
1146 
1147  //- Unpolarised
1148  else if( is_diagonal(ext_mat_av) && unpol_abs_vec && unpol_sca_vec )
1149  {
1150  trans_mat = 0;
1151  trans_mat(0,0) = exp(-ext_mat_av(0,0) * l_step);
1152 
1153  // Stokes dim 1
1154  // assert( ext_mat_av(0,0) == abs_vec_av[0] );
1155  // Numeric transm = exp( -l_step * abs_vec_av[0] );
1156  stokes_vec[0] = stokes_vec[0] * trans_mat(0,0) +
1157  (abs_vec_av[0] * rte_planck_value + sca_vec_av[0]) /
1158  ext_mat_av(0,0) * (1 - trans_mat(0,0));
1159 
1160  // Stokes dims > 1
1161  for( Index i=1; i<stokes_dim; i++ )
1162  {
1163  // assert( abs_vec_av[i] == 0.);
1164  trans_mat(i,i) = trans_mat(0,0);
1165  stokes_vec[i] = stokes_vec[i] * trans_mat(i,i) +
1166  sca_vec_av[i] / ext_mat_av(i,i) * (1 - trans_mat(i,i));
1167  }
1168  }
1169 
1170 
1171  //- General case
1172  else
1173  {
1174  //Initialize internal variables:
1175 
1176  // Matrix LU used for LU decompostion and as dummy variable:
1177  Matrix LU(stokes_dim, stokes_dim);
1178  ArrayOfIndex indx(stokes_dim); // index for pivoting information
1179  Vector b(stokes_dim); // dummy variable
1180  Vector x(stokes_dim); // solution vector for K^(-1)*b
1181  Matrix I(stokes_dim, stokes_dim);
1182 
1183  Vector B_abs_vec(stokes_dim);
1184  B_abs_vec = abs_vec_av;
1185  B_abs_vec *= rte_planck_value;
1186 
1187  for (Index i=0; i<stokes_dim; i++)
1188  b[i] = B_abs_vec[i] + sca_vec_av[i]; // b = abs_vec * B + sca_vec
1189 
1190  // solve K^(-1)*b = x
1191  ludcmp(LU, indx, ext_mat_av);
1192  lubacksub(x, LU, b, indx);
1193 
1194  Matrix ext_mat_ds(stokes_dim, stokes_dim);
1195  ext_mat_ds = ext_mat_av;
1196  ext_mat_ds *= -l_step; // ext_mat_ds = -ext_mat*ds
1197 
1198  Index q = 10; // index for the precision of the matrix exp function
1199  //Matrix exp_ext_mat(stokes_dim, stokes_dim);
1200  //matrix_exp(exp_ext_mat, ext_mat_ds, q);
1201  matrix_exp( trans_mat, ext_mat_ds, q);
1202 
1203  Vector term1(stokes_dim);
1204  Vector term2(stokes_dim);
1205 
1206  id_mat(I);
1207  for(Index i=0; i<stokes_dim; i++)
1208  {
1209  for(Index j=0; j<stokes_dim; j++)
1210  LU(i,j) = I(i,j) - trans_mat(i,j); // take LU as dummy variable
1211  // LU(i,j) = I(i,j) - exp_ext_mat(i,j); // take LU as dummy variable
1212  }
1213  mult(term2, LU, x); // term2: second term of the solution of the RTE with
1214  //fixed scattered field
1215 
1216  // term1: first term of solution of the RTE with fixed scattered field
1217  //mult(term1, exp_ext_mat, stokes_vec);
1218  mult( term1, trans_mat, stokes_vec );
1219 
1220  for (Index i=0; i<stokes_dim; i++)
1221  stokes_vec[i] = term1[i] + term2[i]; // Compute the new Stokes Vector
1222  }
1223 }
1224 
1225 
1226 
1228 
1246  Matrix& iy,
1247  const Tensor3& I,
1248  const Matrix& surface_los,
1249  const Tensor4& surface_rmatrix,
1250  const Matrix& surface_emission )
1251 {
1252  // Some sizes
1253  const Index nf = I.nrows();
1254  const Index stokes_dim = I.ncols();
1255  const Index nlos = surface_los.nrows();
1256 
1257  iy = surface_emission;
1258 
1259  // Loop *surface_los*-es. If no such LOS, we are ready.
1260  if( nlos > 0 )
1261  {
1262  for( Index ilos=0; ilos<nlos; ilos++ )
1263  {
1264  Vector rtmp(stokes_dim); // Reflected Stokes vector for 1 frequency
1265 
1266  for( Index iv=0; iv<nf; iv++ )
1267  {
1268  mult( rtmp, surface_rmatrix(ilos,iv,joker,joker), I(ilos,iv,joker) );
1269  iy(iv,joker) += rtmp;
1270  }
1271  }
1272  }
1273 }
1274 
1275 
1276 
1278 
1300 void trans_step_std(//Output and Input:
1301  VectorView stokes_vec,
1302  MatrixView trans_mat,
1303  //Input
1304  ConstMatrixView ext_mat_av,
1305  const Numeric& l_step )
1306 {
1307  // Checks made in *ext2trans*.
1308  ext2trans( trans_mat, ext_mat_av, l_step );
1309 
1310  Vector tmp = stokes_vec;
1311 
1312  mult( stokes_vec, trans_mat, tmp );
1313 }
1314 
Matrix
The Matrix class.
Definition: matpackI.h:767
SPEED_OF_LIGHT
const Numeric SPEED_OF_LIGHT
apply_y_unit2
void apply_y_unit2(Tensor3View J, ConstMatrixView iy, const String &y_unit, ConstVectorView f_grid, const ArrayOfIndex &i_pol)
apply_y_unit2
Definition: rte.cc:184
Tensor4::resize
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1404
DEG2RAD
const Numeric DEG2RAD
MatrixView
The MatrixView class.
Definition: matpackI.h:668
iy_transmission_mult
void iy_transmission_mult(Tensor3 &iy_trans_new, ConstTensor3View iy_transmission, ConstTensor3View trans)
iy_transmission_mult
Definition: rte.cc:929
auto_md.h
opt_propCalc
void opt_propCalc(MatrixView ext_mat_mono, VectorView abs_vec_mono, const Numeric za, const Numeric aa, const ArrayOfSingleScatteringData &scat_data_mono, const Index stokes_dim, ConstVectorView pnd_vec, const Numeric rte_temperature, const Verbosity &verbosity)
opt_propCalc
Definition: montecarlo.cc:1180
rte_step_std
void rte_step_std(VectorView stokes_vec, MatrixView trans_mat, ConstMatrixView ext_mat_av, ConstVectorView abs_vec_av, ConstVectorView sca_vec_av, const Numeric &l_step, const Numeric &rte_planck_value)
rte_step_std
Definition: rte.cc:1092
abs_scalar_gas_agendaExecute
void abs_scalar_gas_agendaExecute(Workspace &ws, Matrix &abs_scalar_gas, const Index f_index, const Numeric rte_doppler, const Numeric rte_pressure, const Numeric rte_temperature, const Vector &rte_vmr_list, const Agenda &input_agenda)
Definition: auto_md.cc:9032
Tensor3
The Tensor3 class.
Definition: matpackIII.h:340
id_mat
void id_mat(MatrixView I)
Identity Matrix.
Definition: lin_alg.cc:298
itw2p
void itw2p(VectorView p_values, ConstVectorView p_grid, const ArrayOfGridPos &gp, ConstMatrixView itw)
itw2p
Definition: special_interp.cc:763
is_diagonal
bool is_diagonal(ConstMatrixView A)
Checks if a square matrix is diagonal.
Definition: logic.cc:387
joker
const Joker joker
get_ppath_rtvars
void get_ppath_rtvars(Workspace &ws, Tensor3 &ppath_abs_scalar, Matrix &ppath_tau, Vector &total_tau, Matrix &ppath_emission, const Agenda &abs_scalar_gas_agenda, const Agenda &emission_agenda, const Ppath &ppath, ConstVectorView ppath_p, ConstVectorView ppath_t, ConstMatrixView ppath_vmr, ConstVectorView ppath_wind_u, ConstVectorView ppath_wind_v, ConstVectorView ppath_wind_w, ConstVectorView f_grid, const Index &atmosphere_dim, const Index &emission_do)
get_ppath_rtvars
Definition: rte.cc:531
get_ppath_cloudrtvars
void get_ppath_cloudrtvars(Workspace &ws, Tensor3 &ppath_asp_abs_vec, Tensor4 &ppath_asp_ext_mat, Tensor3 &ppath_pnd_abs_vec, Tensor4 &ppath_pnd_ext_mat, Tensor4 &ppath_transmission, Tensor3 &total_transmission, Matrix &ppath_emission, Array< ArrayOfSingleScatteringData > &scat_data, const Agenda &abs_scalar_gas_agenda, const Agenda &emission_agenda, const Agenda &opt_prop_gas_agenda, const Ppath &ppath, ConstVectorView ppath_p, ConstVectorView ppath_t, ConstMatrixView ppath_vmr, ConstVectorView ppath_wind_u, ConstVectorView ppath_wind_v, ConstVectorView ppath_wind_w, ConstMatrixView ppath_pnd, const Index &use_mean_scat_data, const ArrayOfSingleScatteringData &scat_data_raw, const Index &stokes_dim, ConstVectorView f_grid, const Index &atmosphere_dim, const Index &emission_do, const Verbosity &verbosity)
get_ppath_cloudrtvars
Definition: rte.cc:672
opt_prop_gas_agendaExecute
void opt_prop_gas_agendaExecute(Workspace &ws, Tensor3 &ext_mat, Matrix &abs_vec, const Index f_index, const Matrix &abs_scalar_gas, const Agenda &input_agenda)
Definition: auto_md.cc:10073
get_ppath_atmvars
void get_ppath_atmvars(Vector &ppath_p, Vector &ppath_t, Matrix &ppath_vmr, Vector &ppath_wind_u, Vector &ppath_wind_v, Vector &ppath_wind_w, const Ppath &ppath, const Index &atmosphere_dim, ConstVectorView p_grid, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstTensor3View wind_u_field, ConstTensor3View wind_v_field, ConstTensor3View wind_w_field)
get_ppath_atmvars
Definition: rte.cc:383
interp_atmfield_by_itw
void interp_atmfield_by_itw(VectorView x, const Index &atmosphere_dim, ConstTensor3View x_field, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon, ConstMatrixView itw)
interp_atmfield_by_itw
Definition: special_interp.cc:159
interp_cloudfield_gp2itw
void interp_cloudfield_gp2itw(Matrix &itw, ArrayOfGridPos &gp_p_out, ArrayOfGridPos &gp_lat_out, ArrayOfGridPos &gp_lon_out, const ArrayOfGridPos &gp_p_in, const ArrayOfGridPos &gp_lat_in, const ArrayOfGridPos &gp_lon_in, const Index &atmosphere_dim, const ArrayOfIndex &cloudbox_limits)
interp_cloudfield_gp2itw
Definition: special_interp.cc:300
Sparse
The Sparse class.
Definition: matpackII.h:55
emission_agendaExecute
void emission_agendaExecute(Workspace &ws, Vector &emission, const Numeric rte_temperature, const Agenda &input_agenda)
Definition: auto_md.cc:9367
dinvplanckdI
Numeric dinvplanckdI(const Numeric &i, const Numeric &f)
dinvplanckdI
Definition: physics_funcs.cc:71
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:771
is_singular
bool is_singular(ConstMatrixView A)
Checks if a square matrix is singular.
Definition: logic.cc:353
iy_transmission_for_scalar_tau
void iy_transmission_for_scalar_tau(Tensor3 &iy_transmission, const Index &stokes_dim, ConstVectorView tau)
iy_transmission_for_scalar_tau
Definition: rte.cc:885
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
montecarlo.h
Tensor4
The Tensor4 class.
Definition: matpackIV.h:375
matrix_exp
void matrix_exp(MatrixView F, ConstMatrixView A, const Index &q)
Exponential of a Matrix.
Definition: lin_alg.cc:193
q
#define q
Definition: continua.cc:14103
is_size
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
Definition: logic.cc:90
Ppath
The structure to describe a propagation path and releated quantities.
Definition: ppath.h:59
Ppath::gp_p
ArrayOfGridPos gp_p
Definition: ppath.h:66
Tensor3::resize
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:863
Agenda
The Agenda class.
Definition: agenda_class.h:44
apply_y_unit
void apply_y_unit(MatrixView iy, const String &y_unit, ConstVectorView f_grid, const ArrayOfIndex &i_pol)
apply_y_unit
Definition: rte.cc:82
get_rowindex_for_mblock
Range get_rowindex_for_mblock(const Sparse &sensor_response, const Index &imblock)
get_rowindex_for_mblock
Definition: rte.cc:861
ludcmp
void ludcmp(MatrixView LU, ArrayOfIndex &indx, ConstMatrixView A)
LU decomposition.
Definition: lin_alg.cc:53
ConstTensor3View::npages
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:151
ConstTensor4View
A constant view of a Tensor4.
Definition: matpackIV.h:149
invrayjean
Numeric invrayjean(const Numeric &i, const Numeric &f)
invrayjean
Definition: physics_funcs.cc:170
Tensor3View
The Tensor3View class.
Definition: matpackIII.h:234
Array< Index >
PLANCK_CONST
const Numeric PLANCK_CONST
mult
void mult(VectorView y, const ConstMatrixView &M, const ConstVectorView &x)
Matrix Vector multiplication.
Definition: matpackI.cc:1607
Ppath::gp_lat
ArrayOfGridPos gp_lat
Definition: ppath.h:67
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
my_basic_string
The implementation for String, the ARTS string class.
Definition: mystring.h:62
trans_step_std
void trans_step_std(VectorView stokes_vec, MatrixView trans_mat, ConstMatrixView ext_mat_av, const Numeric &l_step)
trans_step_std
Definition: rte.cc:1300
Ppath::los
Matrix los
Definition: ppath.h:69
Ppath::gp_lon
ArrayOfGridPos gp_lon
Definition: ppath.h:68
Ppath::np
Index np
Definition: ppath.h:61
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:175
VectorView
The VectorView class.
Definition: matpackI.h:373
physics_funcs.h
BOLTZMAN_CONST
const Numeric BOLTZMAN_CONST
ns
#define ns
Definition: continua.cc:14564
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
lin_alg.h
Linear algebra functions.
Verbosity
Definition: messages.h:50
RAD2DEG
const Numeric RAD2DEG
Ppath::l_step
Vector l_step
Definition: ppath.h:65
PI
const Numeric PI
ConstTensor4View::nbooks
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:60
math_funcs.h
invplanck
Numeric invplanck(const Numeric &i, const Numeric &f)
invplanck
Definition: physics_funcs.cc:142
Matrix::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1549
scat_data_monoCalc
void scat_data_monoCalc(ArrayOfSingleScatteringData &scat_data_mono, const ArrayOfSingleScatteringData &scat_data_raw, const Vector &f_grid, const Index &f_index, const Verbosity &)
WORKSPACE METHOD: scat_data_monoCalc.
Definition: m_optproperties.cc:1035
ConstTensor3View::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:154
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:591
Range
The range class.
Definition: matpackI.h:148
get_ppath_pnd
void get_ppath_pnd(Matrix &ppath_pnd, const Ppath &ppath, const Index &atmosphere_dim, const ArrayOfIndex &cloudbox_limits, ConstTensor4View pnd_field)
get_ppath_pnd
Definition: rte.cc:479
interp_atmfield_gp2itw
void interp_atmfield_gp2itw(Matrix &itw, const Index &atmosphere_dim, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon)
interp_atmfield_gp2itw
Definition: special_interp.cc:99
ppath.h
Propagation path structure and functions.
ext2trans
void ext2trans(MatrixView trans_mat, ConstMatrixView ext_mat_av, const Numeric &l_step)
ext2trans
Definition: rte.cc:301
surface_calc
void surface_calc(Matrix &iy, const Tensor3 &I, const Matrix &surface_los, const Tensor4 &surface_rmatrix, const Matrix &surface_emission)
surface_calc
Definition: rte.cc:1245
logic.h
Header file for logic.cc.
Sparse::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackII.cc:53
mirror_los
void mirror_los(Vector &los_mirrored, ConstVectorView los, const Index &atmosphere_dim)
mirror_los
Definition: rte.cc:1016
ConstTensor3View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:157
rte.h
Declaration of functions in rte.cc.
Workspace
Workspace class.
Definition: workspace_ng.h:47
ConstTensor3View
A constant view of a Tensor3.
Definition: matpackIII.h:147
special_interp.h
Header file for special_interp.cc.
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
check_input.h
Vector
The Vector class.
Definition: matpackI.h:555
iy_transmission_mult_scalar_tau
void iy_transmission_mult_scalar_tau(Tensor3 &iy_trans_new, ConstTensor3View iy_transmission, ConstVectorView tau)
iy_transmission_mult_scalar_tau
Definition: rte.cc:981
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:300
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
interpweights
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
Definition: interpolation.cc:756
lubacksub
void lubacksub(VectorView x, ConstMatrixView LU, ConstVectorView b, const ArrayOfIndex &indx)
LU backsubstitution.
Definition: lin_alg.cc:144