ARTS  2.0.49
m_disort.cc
Go to the documentation of this file.
1 /* Copyright (C) 2006-2008 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 
32 /*===========================================================================
33  === External declarations
34  ===========================================================================*/
35 
36 #include <stdexcept>
37 #include <iostream>
38 #include <cstdlib>
39 #include <cstring>
40 #include <cmath>
41 #include "arts.h"
42 #include "array.h"
43 #include "auto_md.h"
44 #include "messages.h"
45 #include "xml_io.h"
46 #include "m_general.h"
47 #include "wsv_aux.h"
48 #include "disort.h"
49 //#include "physics_funcs.h"
50 #include "disort_DISORT.h"
51 
52 extern const Numeric PI;
53 extern const Numeric RAD2DEG;
54 extern const Numeric SPEED_OF_LIGHT;
55 extern const Numeric COSMIC_BG_TEMP;
56 
57 
58 
59 /* Workspace method: Doxygen documentation will be auto-generated */
60 void cloudboxSetDisort(//WS Output
61  Index& cloudbox_on,
62  ArrayOfIndex& cloudbox_limits,
63  // WS Input
64  const Vector& p_grid,
65  const Verbosity&)
66 {
67  cloudbox_on = 1;
68  cloudbox_limits.resize(2);
69  cloudbox_limits[0] = 0;
70  cloudbox_limits[1] = p_grid.nelem()-1;
71 }
72 
73 
74 /* Workspace method: Doxygen documentation will be auto-generated */
75 #ifdef ENABLE_DISORT
77  // WS Output:
78  Tensor7& scat_i_p,
79  Tensor7& scat_i_lat,
80  Tensor7& scat_i_lon,
81  Index& f_index,
82  ArrayOfSingleScatteringData& scat_data_mono,
83  Tensor4& doit_i_field1D_spectrum,
84  // WS Input
85  const ArrayOfIndex& cloudbox_limits,
86  const Index& stokes_dim,
87  const Agenda& opt_prop_part_agenda,
88  const Agenda& abs_scalar_gas_agenda,
89  const Agenda& spt_calc_agenda,
90  const Tensor4& pnd_field,
91  const Tensor3& t_field,
92  const Tensor3& z_field,
93  const Vector& p_grid,
94  const Tensor4& vmr_field,
95  const ArrayOfSingleScatteringData& scat_data_raw,
96  const Vector& f_grid,
97  const Vector& scat_za_grid,
98  const Matrix& surface_emissivity_field,
99  const Verbosity& verbosity)
100 {
101 
102  out1<< "Start DISORT calculation...\n";
103 
104  if(pnd_field.ncols() != 1)
105  throw runtime_error(
106  "*pnd_field* is not 1D! \n"
107  "DISORT can only be used for 1D! \n" );
108 
109  if (stokes_dim != 1)
110  throw runtime_error( "DISORT can only be used for unpolarized \n"
111  "calculations (i.e., stokes_dim=1),\n" );
112 
113  // NOTE: It is at the moment not possible to combine particle types
114  // being stored on different scattering angle grids.
115  // Ask whether this is required. Temperature dependance also not yet
116  // implemented.
117 
118  // DISORT calculations are done over the whole atmosphere because it is
119  // only possible to give a constant value, i.e. cosmic background,
120  // as input, not a radiation field at the to of the domain
121  Index nlyr=pnd_field.npages()-1;
122 
123  // Check whether cloudbox expands over the whole atmosphere
124 
125  if(cloudbox_limits.nelem()!=2 || cloudbox_limits[0] != 0 ||
126  cloudbox_limits[1] != pnd_field.npages()-1)
127  throw runtime_error("The cloudbox is not set correctly for DISORT.\n"
128  "Please use *cloudboxSetDisort*. \n");
129 
130  scat_i_p.resize(f_grid.nelem(), 2, 1, 1,
131  scat_za_grid.nelem(), 1, 1);
132 
133  scat_i_p = 0.;
134 
135  doit_i_field1D_spectrum.resize(f_grid.nelem(), pnd_field.npages(),
136  scat_za_grid.nelem(), 1);
137 
138  doit_i_field1D_spectrum= 0;
139  // Scat_i_lat, lon ---> only dummies, not used further
140  scat_i_lat.resize(1,1,1,1,1,1,1);
141  scat_i_lat = 0.;
142  scat_i_lon.resize(1,1,1,1,1,1,1);
143  scat_i_lon = 0.;
144 
145  // Input variables for DISORT
146  // Optical depth of layers
147  Vector dtauc(nlyr, 0.);
148  // Single scattering albedo of layers
149  Vector ssalb(nlyr, 0.);
150 
151  // Phase function
152  Matrix phase_function(nlyr,scat_data_raw[0].za_grid.nelem(), 0.);
153  // Scattering angle grid, assumed here that it is the same for
154  // all particle types
155  Vector scat_angle_grid(scat_data_raw[0].za_grid.nelem(), 0.);
156  scat_angle_grid = scat_data_raw[0].za_grid;
157 
158  // Number of streams, I think in microwave 8 is more that sufficient
159  Index nstr=8 ;
160  Index n_legendre=nstr+1;
161 
162  // Legendre polynomials of phase function
163  Matrix pmom(nlyr, n_legendre, 0.);
164 
165  // Intensities to be computed for user defined polar (zenith angles)
166  Index usrang = TRUE_;
167  Index numu = scat_za_grid.nelem();
168  Vector umu(numu);
169  // Transform to mu, starting with negative values
170  for (Index i = 0; i<numu; i++)
171  umu[i]=cos(scat_za_grid[numu-i-1]*PI/180);
172 
173  // Since we have no solar source there is no angular dependance
174  Index nphi = 1;
175  Vector phi(nphi, 0.);
176 
177  Index ibcnd=0;
178 
179  // Properties of solar beam, set to zero as they are not needed
180  Numeric fbeam =0.;
181  Numeric umu0=0.;
182  Numeric phi0=0.;
183 
184  // surface, Lambertian if set to TRUE_
185  Index lamber = TRUE_;
186  Numeric albedo = 1-surface_emissivity_field(0,0);
187  // only needed for bidirectional reflecting surface
188  Vector hl(1,0.);
189 
190  //temperature of surface and cloudbox top
191  Numeric btemp = t_field(0,0,0);
192  Numeric ttemp = t_field(cloudbox_limits[1], 0, 0);
193 
194  // Top of the atmosphere, emissivity = 0
195  Numeric temis = 0.;
196 
197  // we don't need delta-scaling in microwave region
198  Index deltam = FALSE_;
199 
200  // include thermal emission (very important)
201  Index plank = TRUE_;
202 
203  // calculate also intensities, not only fluxes
204  Index onlyfl = FALSE_;
205 
206  // Convergence criterium
207  Numeric accur = 0.005;
208 
209  // Specify what to be printed --> normally nothing
210  Index *prnt = new Index[7];
211  prnt[0]=FALSE_; // Input variables
212  prnt[1]=FALSE_; // fluxes
213  prnt[2]=FALSE_; // azimuthally averaged intensities at user
214  //and comp. angles
215  prnt[3]=FALSE_; // azimuthally averaged intensities at user levels
216  //and angles
217  prnt[4]=FALSE_; // intensities at user levels and angles
218  prnt[5]=FALSE_; // planar transmissivity and albedo
219  prnt[6]=FALSE_; // phase function moments
220 
221  char header[127];
222  memset (header, 0, 127);
223  Index header_len = 127;
224 
225  Index maxcly = nlyr; // Maximum number of layers
226  Index maxulv = nlyr+1; // Maximum number of user defined tau
227  Index maxumu = scat_za_grid.nelem(); // maximum number of zenith angles
228  Index maxcmu = n_legendre-1; // maximum number of Legendre polynomials
229  Index maxphi = 1; //no azimuthal dependance
230 
231  // Declaration of Output variables
232  Vector rfldir(maxulv);
233  Vector rfldn(maxulv);
234  Vector flup(maxulv);
235  Vector dfdt(maxulv);
236  Vector uavg(maxulv);
237  Tensor3 uu(maxphi, maxulv, scat_za_grid.nelem(), 0.); // Intensity
238  Matrix u0u(maxulv, scat_za_grid.nelem()); // Azimuthally averaged intensity
239  Vector albmed(scat_za_grid.nelem()); // Albedo of cloudbox
240  Vector trnmed(scat_za_grid.nelem()); // Transmissivity
241 
242  Vector t(nlyr+1);
243 
244  for (Index i = 0; i < t.nelem(); i++)
245  {
246  t[i] = t_field(cloudbox_limits[1]-i,0,0);
247  }
248 
249  //dummies
250  Index ntau = 0;
251  Vector utau(maxulv,0.);
252 
253  // Loop over frequencies
254  for (f_index = 0; f_index < f_grid.nelem(); f_index ++)
255  {
256  dtauc=0.;
257  ssalb=0.;
258  phase_function=0.;
259  pmom=0.;
260 
261  scat_data_monoCalc(scat_data_mono, scat_data_raw, f_grid, f_index);
262 
263  dtauc_ssalbCalc(ws, dtauc, ssalb, opt_prop_part_agenda,
264  abs_scalar_gas_agenda, spt_calc_agenda,
265  pnd_field,
266  t_field, z_field, p_grid, vmr_field, f_index);
267  //cout << "dtauc " << dtauc << endl
268  // << "ssalb " << ssalb << endl;
269 
270  phase_functionCalc(phase_function, scat_data_mono, pnd_field);
271  //cout << "phase function" << phase_function(15,joker) << "\n";
272 
273  pmomCalc(pmom, phase_function, scat_angle_grid, n_legendre);
274  //for (Index i=0; i<nlyr; i++)
275  // cout << "pmom " << pmom(i,joker) << "\n";
276 
277  // Wavenumber in [1/cm^2]
278  Numeric wvnmlo = f_grid[f_index]/(100*SPEED_OF_LIGHT);
279  Numeric wvnmhi = wvnmlo;
280 
281  // calculate radiant quantities at boundary of computational layers.
282  Index usrtau = FALSE_;
283 
284  // Cosmic background
285  Numeric fisot = planck2( f_grid[f_index], COSMIC_BG_TEMP );
286 
287  // Call disort
288  disort_(&nlyr, dtauc.get_c_array(),
289  ssalb.get_c_array(), pmom.get_c_array(),
290  t.get_c_array(), &wvnmlo, &wvnmhi,
291  &usrtau, &ntau, utau.get_c_array(),
292  &nstr, &usrang, &numu,
293  umu.get_c_array(), &nphi,
294  phi.get_c_array(),
295  &ibcnd, &fbeam,
296  &umu0, &phi0, &fisot,
297  &lamber,
298  &albedo, hl.get_c_array(),
299  &btemp, &ttemp, &temis,
300  &deltam,
301  &plank, &onlyfl, &accur,
302  prnt, header,
303  &maxcly, &maxulv,
304  &maxumu, &maxcmu,
305  &maxphi, rfldir.get_c_array(),
306  rfldn.get_c_array(),
307  flup.get_c_array(), dfdt.get_c_array(),
308  uavg.get_c_array(),
309  uu.get_c_array(), u0u.get_c_array(),
310  albmed.get_c_array(),
311  trnmed.get_c_array(),
312  header_len);
313 
314  // cout << "intensity " << uu << endl;
315 
316 
317  for(Index j = 0; j<numu; j++)
318  {
319  for(Index k = 0; k< nlyr; k++)
320  doit_i_field1D_spectrum(f_index, k+1, j, 0) =
321  uu(0,nlyr-k-1,j);
322 
323  scat_i_p(f_index, 0, 0, 0, j, 0, 0) =
324  uu(0, nlyr-1, j );
325  scat_i_p(f_index, 1, 0, 0, j, 0, 0) =
326  uu(0, 0, j);
327  }
328  }
329  delete [] prnt;
330 
331 #else
333  // WS Output:
334  Tensor7&,
335  Tensor7&,
336  Tensor7&,
337  Index&,
339  Tensor4&,
340  // WS Input
341  const ArrayOfIndex&,
342  const Index&,
343  const Agenda&,
344  const Agenda&,
345  const Agenda&,
346  const Tensor4&,
347  const Tensor3&,
348  const Tensor3&,
349  const Vector&,
350  const Tensor4&,
352  const Vector&,
353  const Vector&,
354  const Matrix&,
355  const Verbosity&)
356 {
357  throw runtime_error ("This version of ARTS was compiled without DISORT support.");
358 #endif /* ENABLE_DISORT */
359 
360 }
361 
362 
363 
Matrix
The Matrix class.
Definition: matpackI.h:767
Tensor4::resize
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1404
auto_md.h
Tensor3
The Tensor3 class.
Definition: matpackIII.h:340
SPEED_OF_LIGHT
const Numeric SPEED_OF_LIGHT
Tensor4
The Tensor4 class.
Definition: matpackIV.h:375
array.h
This file contains the definition of Array.
COSMIC_BG_TEMP
const Numeric COSMIC_BG_TEMP
PI
const Numeric PI
Agenda
The Agenda class.
Definition: agenda_class.h:44
pmomCalc
void pmomCalc(MatrixView pmom, ConstMatrixView phase_function, ConstVectorView scat_angle_grid, const Index n_legendre, const Verbosity &verbosity)
pmomCalc
Definition: disort.cc:256
Array< Index >
disort_DISORT.h
Tensor7::resize
void resize(Index l, Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackVII.cc:5341
RAD2DEG
const Numeric RAD2DEG
messages.h
Declarations having to do with the four output streams.
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:175
phase_functionCalc
void phase_functionCalc(MatrixView phase_function, const ArrayOfSingleScatteringData &scat_data_mono, ConstTensor4View pnd_field)
phase_functionCalc
Definition: disort.cc:190
ConstTensor4View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:78
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Verbosity
Definition: messages.h:50
ConstTensor4View::npages
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:66
TRUE_
#define TRUE_
Definition: continua.cc:12966
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
planck2
Numeric planck2(const Numeric &f, const Numeric &t)
planck
Definition: disort.cc:365
FALSE_
#define FALSE_
Definition: continua.cc:12967
disort.h
Functions for disort interface.
cloudboxSetDisort
void cloudboxSetDisort(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Vector &p_grid, const Verbosity &)
WORKSPACE METHOD: cloudboxSetDisort.
Definition: m_disort.cc:60
Workspace
Workspace class.
Definition: workspace_ng.h:47
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Vector
The Vector class.
Definition: matpackI.h:555
ScatteringDisort
void ScatteringDisort(Workspace &, Tensor7 &, Tensor7 &, Tensor7 &, Index &, ArrayOfSingleScatteringData &, Tensor4 &, const ArrayOfIndex &, const Index &, const Agenda &, const Agenda &, const Agenda &, const Tensor4 &, const Tensor3 &, const Tensor3 &, const Vector &, const Tensor4 &, const ArrayOfSingleScatteringData &, const Vector &, const Vector &, const Matrix &, const Verbosity &)
WORKSPACE METHOD: ScatteringDisort.
Definition: m_disort.cc:332
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
wsv_aux.h
Auxiliary header stuff related to workspace variable groups.
Tensor7
The Tensor7 class.
Definition: matpackVII.h:1912
arts.h
The global header file for ARTS.
xml_io.h
This file contains basic functions to handle XML data files.
m_general.h
Template functions for general supergeneric ws methods.
dtauc_ssalbCalc
void dtauc_ssalbCalc(Workspace &ws, VectorView dtauc, VectorView ssalb, const Agenda &opt_prop_part_agenda, const Agenda &abs_scalar_gas_agenda, const Agenda &spt_calc_agenda, ConstTensor4View pnd_field, ConstTensor3View t_field, ConstTensor3View z_field, ConstVectorView p_grid, ConstTensor4View vmr_field, const Index &f_index)
dtauc_ssalbCalc
Definition: disort.cc:68