00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00032
00033
00034
00035
00036 #include <stdexcept>
00037 #include <iostream>
00038 #include <cstdlib>
00039 #include <cmath>
00040 #include "arts.h"
00041 #include "array.h"
00042 #include "auto_md.h"
00043 #include "messages.h"
00044 #include "xml_io.h"
00045 #include "m_general.h"
00046 #include "wsv_aux.h"
00047 #include "disort.h"
00048
00049 #include "disort_DISORT.h"
00050
00051 extern const Numeric PI;
00052 extern const Numeric RAD2DEG;
00053 extern const Numeric SPEED_OF_LIGHT;
00054 extern const Numeric COSMIC_BG_TEMP;
00055
00056
00057
00058
00059 void cloudboxSetDisort(
00060 Index& cloudbox_on,
00061 ArrayOfIndex& cloudbox_limits,
00062
00063 const Vector& p_grid
00064 )
00065 {
00066 cloudbox_on = 1;
00067 cloudbox_limits.resize(2);
00068 cloudbox_limits[0] = 0;
00069 cloudbox_limits[1] = p_grid.nelem()-1;
00070 }
00071
00072
00073
00074 #ifdef ENABLE_DISORT
00075 void ScatteringDisort(Workspace& ws,
00076
00077 Tensor7& scat_i_p,
00078 Tensor7& scat_i_lat,
00079 Tensor7& scat_i_lon,
00080 Index& f_index,
00081 ArrayOfSingleScatteringData& scat_data_mono,
00082 Tensor4& doit_i_field1D_spectrum,
00083
00084 const ArrayOfIndex& cloudbox_limits,
00085 const Index& stokes_dim,
00086 const Agenda& opt_prop_part_agenda,
00087 const Agenda& abs_scalar_gas_agenda,
00088 const Agenda& spt_calc_agenda,
00089 const Tensor4& pnd_field,
00090 const Tensor3& t_field,
00091 const Tensor3& z_field,
00092 const Vector& p_grid,
00093 const Tensor4& vmr_field,
00094 const ArrayOfSingleScatteringData& scat_data_raw,
00095 const Vector& f_grid,
00096 const Vector& scat_za_grid,
00097 const Matrix& surface_emissivity_field)
00098 {
00099
00100 out1<< "Start DISORT calculation...\n";
00101
00102 if(pnd_field.ncols() != 1)
00103 throw runtime_error(
00104 "*pnd_field* is not 1D! \n"
00105 "DISORT can only be used for 1D! \n" );
00106
00107 if (stokes_dim != 1)
00108 throw runtime_error( "DISORT can only be used for unpolarized \n"
00109 "calculations (i.e., stokes_dim=1),\n" );
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 Index nlyr=pnd_field.npages()-1;
00120
00121
00122
00123 if(cloudbox_limits.nelem()!=2 || cloudbox_limits[0] != 0 ||
00124 cloudbox_limits[1] != pnd_field.npages()-1)
00125 throw runtime_error("The cloudbox is not set correctly for DISORT.\n"
00126 "Please use *cloudboxSetDisort*. \n");
00127
00128 scat_i_p.resize(f_grid.nelem(), 2, 1, 1,
00129 scat_za_grid.nelem(), 1, 1);
00130
00131 scat_i_p = 0.;
00132
00133 doit_i_field1D_spectrum.resize(f_grid.nelem(), pnd_field.npages(),
00134 scat_za_grid.nelem(), 1);
00135
00136 doit_i_field1D_spectrum= 0;
00137
00138 scat_i_lat.resize(1,1,1,1,1,1,1);
00139 scat_i_lat = 0.;
00140 scat_i_lon.resize(1,1,1,1,1,1,1);
00141 scat_i_lon = 0.;
00142
00143
00144
00145 Vector dtauc(nlyr, 0.);
00146
00147 Vector ssalb(nlyr, 0.);
00148
00149
00150 Matrix phase_function(nlyr,scat_data_raw[0].za_grid.nelem(), 0.);
00151
00152
00153 Vector scat_angle_grid(scat_data_raw[0].za_grid.nelem(), 0.);
00154 scat_angle_grid = scat_data_raw[0].za_grid;
00155
00156
00157 Index nstr=8 ;
00158 Index n_legendre=nstr+1;
00159
00160
00161 Matrix pmom(nlyr, n_legendre, 0.);
00162
00163
00164 Index usrang = TRUE_;
00165 Index numu = scat_za_grid.nelem();
00166 Vector umu(numu);
00167
00168 for (Index i = 0; i<numu; i++)
00169 umu[i]=cos(scat_za_grid[numu-i-1]*PI/180);
00170
00171
00172 Index nphi = 1;
00173 Vector phi(nphi, 0.);
00174
00175 Index ibcnd=0;
00176
00177
00178 Numeric fbeam =0.;
00179 Numeric umu0=0.;
00180 Numeric phi0=0.;
00181
00182
00183 Index lamber = TRUE_;
00184 Numeric albedo = 1-surface_emissivity_field(0,0);
00185
00186 Vector hl(1,0.);
00187
00188
00189 Numeric btemp = t_field(0,0,0);
00190 Numeric ttemp = t_field(cloudbox_limits[1], 0, 0);
00191
00192
00193 Numeric temis = 0.;
00194
00195
00196 Index deltam = FALSE_;
00197
00198
00199 Index plank = TRUE_;
00200
00201
00202 Index onlyfl = FALSE_;
00203
00204
00205 Numeric accur = 0.005;
00206
00207
00208 Index *prnt = new Index[7];
00209 prnt[0]=FALSE_;
00210 prnt[1]=FALSE_;
00211 prnt[2]=FALSE_;
00212
00213 prnt[3]=FALSE_;
00214
00215 prnt[4]=FALSE_;
00216 prnt[5]=FALSE_;
00217 prnt[6]=FALSE_;
00218
00219 char header[127];
00220 memset (header, 0, 127);
00221 Index header_len = 127;
00222
00223 Index maxcly = nlyr;
00224 Index maxulv = nlyr+1;
00225 Index maxumu = scat_za_grid.nelem();
00226 Index maxcmu = n_legendre-1;
00227 Index maxphi = 1;
00228
00229
00230 Vector rfldir(maxulv);
00231 Vector rfldn(maxulv);
00232 Vector flup(maxulv);
00233 Vector dfdt(maxulv);
00234 Vector uavg(maxulv);
00235 Tensor3 uu(maxphi, maxulv, scat_za_grid.nelem(), 0.);
00236 Matrix u0u(maxulv, scat_za_grid.nelem());
00237 Vector albmed(scat_za_grid.nelem());
00238 Vector trnmed(scat_za_grid.nelem());
00239
00240 Vector t(nlyr+1);
00241
00242 for (Index i = 0; i < t.nelem(); i++)
00243 {
00244 t[i] = t_field(cloudbox_limits[1]-i,0,0);
00245 }
00246
00247
00248 Index ntau = 0;
00249 Vector utau(maxulv,0.);
00250
00251
00252 for (f_index = 0; f_index < f_grid.nelem(); f_index ++)
00253 {
00254 dtauc=0.;
00255 ssalb=0.;
00256 phase_function=0.;
00257 pmom=0.;
00258
00259 scat_data_monoCalc(scat_data_mono, scat_data_raw, f_grid, f_index);
00260
00261 dtauc_ssalbCalc(ws, dtauc, ssalb, opt_prop_part_agenda,
00262 abs_scalar_gas_agenda, spt_calc_agenda,
00263 pnd_field,
00264 t_field, z_field, p_grid, vmr_field, f_index);
00265
00266
00267
00268 phase_functionCalc(phase_function, scat_data_mono, pnd_field);
00269
00270
00271 pmomCalc(pmom, phase_function, scat_angle_grid, n_legendre);
00272
00273
00274
00275
00276 Numeric wvnmlo = f_grid[f_index]/(100*SPEED_OF_LIGHT);
00277 Numeric wvnmhi = wvnmlo;
00278
00279
00280 Index usrtau = FALSE_;
00281
00282
00283 Numeric fisot = planck2( f_grid[f_index], COSMIC_BG_TEMP );
00284
00285
00286 disort_(&nlyr, dtauc.get_c_array(),
00287 ssalb.get_c_array(), pmom.get_c_array(),
00288 t.get_c_array(), &wvnmlo, &wvnmhi,
00289 &usrtau, &ntau, utau.get_c_array(),
00290 &nstr, &usrang, &numu,
00291 umu.get_c_array(), &nphi,
00292 phi.get_c_array(),
00293 &ibcnd, &fbeam,
00294 &umu0, &phi0, &fisot,
00295 &lamber,
00296 &albedo, hl.get_c_array(),
00297 &btemp, &ttemp, &temis,
00298 &deltam,
00299 &plank, &onlyfl, &accur,
00300 prnt, header,
00301 &maxcly, &maxulv,
00302 &maxumu, &maxcmu,
00303 &maxphi, rfldir.get_c_array(),
00304 rfldn.get_c_array(),
00305 flup.get_c_array(), dfdt.get_c_array(),
00306 uavg.get_c_array(),
00307 uu.get_c_array(), u0u.get_c_array(),
00308 albmed.get_c_array(),
00309 trnmed.get_c_array(),
00310 header_len);
00311
00312
00313
00314
00315 for(Index j = 0; j<numu; j++)
00316 {
00317 for(Index k = 0; k< nlyr; k++)
00318 doit_i_field1D_spectrum(f_index, k+1, j, 0) =
00319 uu(0,nlyr-k-1,j);
00320
00321 scat_i_p(f_index, 0, 0, 0, j, 0, 0) =
00322 uu(0, nlyr-1, j );
00323 scat_i_p(f_index, 1, 0, 0, j, 0, 0) =
00324 uu(0, 0, j);
00325 }
00326 }
00327 delete [] prnt;
00328
00329 #else
00330 void ScatteringDisort(Workspace&,
00331
00332 Tensor7&,
00333 Tensor7&,
00334 Tensor7&,
00335 Index&,
00336 ArrayOfSingleScatteringData&,
00337 Tensor4&,
00338
00339 const ArrayOfIndex&,
00340 const Index&,
00341 const Agenda&,
00342 const Agenda&,
00343 const Agenda&,
00344 const Tensor4&,
00345 const Tensor3&,
00346 const Tensor3&,
00347 const Vector&,
00348 const Tensor4&,
00349 const ArrayOfSingleScatteringData&,
00350 const Vector&,
00351 const Vector&,
00352 const Matrix&)
00353 {
00354 throw runtime_error ("This version of ARTS was compiled without DISORT support.");
00355 #endif
00356
00357 }
00358
00359
00360