00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00028 #include <stdexcept>
00029 #include <iostream>
00030 #include <cstdlib>
00031 #include <cmath>
00032 #include "array.h"
00033 #include "agenda_class.h"
00034 #include "messages.h"
00035 #include "xml_io.h"
00036 #include "logic.h"
00037 #include "check_input.h"
00038 #include "auto_md.h"
00039 #include "interpolation.h"
00040
00041 extern const Numeric PI;
00042 extern const Numeric PLANCK_CONST;
00043 extern const Numeric SPEED_OF_LIGHT;
00044 extern const Numeric BOLTZMAN_CONST;
00045
00047
00068 void dtauc_ssalbCalc(Workspace& ws,
00069 VectorView dtauc,
00070 VectorView ssalb,
00071 const Agenda& opt_prop_part_agenda,
00072 const Agenda& abs_scalar_gas_agenda,
00073 const Agenda& spt_calc_agenda,
00074 ConstTensor4View pnd_field,
00075 ConstTensor3View t_field,
00076 ConstTensor3View z_field,
00077 ConstVectorView p_grid,
00078 ConstTensor4View vmr_field,
00079 const Index& f_index
00080 )
00081 {
00082
00083 const Index N_pt = pnd_field.nbooks();
00084
00085 const Index Np_cloud = pnd_field.npages();
00086 const Index stokes_dim = 1;
00087
00088 assert( dtauc.nelem() == Np_cloud-1);
00089 assert( ssalb.nelem() == Np_cloud-1);
00090
00091
00092 Matrix abs_vec_spt_local(N_pt, stokes_dim, 0.);
00093 Tensor3 ext_mat_spt_local(N_pt, stokes_dim, stokes_dim, 0.);
00094 Matrix abs_vec_local;
00095 Tensor3 ext_mat_local;
00096 Numeric rte_temperature_local;
00097 Numeric rte_pressure_local;
00098 Matrix abs_scalar_gas_local;
00099 Vector ext_vector(Np_cloud);
00100 Vector abs_vector(Np_cloud);
00101 Vector rte_vmr_list_local(vmr_field.nbooks());
00102
00103
00104 abs_scalar_gas_local = 0.;
00105
00106
00107 for(Index scat_p_index_local = 0; scat_p_index_local < Np_cloud;
00108 scat_p_index_local ++)
00109 {
00110 rte_temperature_local =
00111 t_field(scat_p_index_local, 0, 0);
00112
00113
00114 spt_calc_agendaExecute(ws,
00115 ext_mat_spt_local,
00116 abs_vec_spt_local,
00117 scat_p_index_local, 0, 0,
00118 rte_temperature_local,
00119 0, 0,
00120 spt_calc_agenda);
00121
00122 opt_prop_part_agendaExecute(ws,
00123 ext_mat_local, abs_vec_local,
00124 ext_mat_spt_local,
00125 abs_vec_spt_local,
00126 scat_p_index_local, 0, 0,
00127 opt_prop_part_agenda);
00128
00129 ext_vector[scat_p_index_local] = ext_mat_local(0,0,0);
00130 abs_vector[scat_p_index_local] = abs_vec_local(0,0);
00131 }
00132
00133
00134
00135
00136 for (Index i = 0; i < Np_cloud-1; i++)
00137 {
00138 Numeric ext = 0.;
00139 Numeric abs = 0.;
00140
00141 if ((ext_vector[i] && ext_vector[i+1])!=0 )
00142 {
00143 ext=.5*(ext_vector[i]+ext_vector[i+1]);
00144 abs=.5*(abs_vector[i]+abs_vector[i+1]);
00145 }
00146
00147 if (ext!=0)
00148 ssalb[Np_cloud-2-i]=(ext-abs)/ext;
00149
00150 rte_pressure_local = 0.5 * (p_grid[i] + p_grid[i+1]);
00151 rte_temperature_local = 0.5 * (t_field(i,0,0) + t_field(i+1,0,0));
00152
00153
00154 for (Index j = 0; j < vmr_field.nbooks(); j++)
00155 rte_vmr_list_local[j] = 0.5 * (vmr_field(j, i, 0, 0) +
00156 vmr_field(j, i+1, 0, 0));
00157
00158
00159 abs_scalar_gas_agendaExecute(ws,
00160 abs_scalar_gas_local,
00161 f_index,
00162 rte_pressure_local,
00163 rte_temperature_local,
00164 rte_vmr_list_local,
00165 abs_scalar_gas_agenda);
00166
00167 Numeric abs_total = abs_scalar_gas_local(0,joker).sum();
00168
00169 dtauc[Np_cloud-2-i]=(ext+abs+abs_total)*
00170 (z_field(i+1, 0, 0)-z_field(i, 0, 0));
00171 }
00172 }
00173
00175
00189 void phase_functionCalc(
00190 MatrixView phase_function,
00191
00192 const ArrayOfSingleScatteringData& scat_data_mono,
00193 ConstTensor4View pnd_field)
00194 {
00195 Matrix phase_function_level(pnd_field.npages(),
00196 scat_data_mono[0].za_grid.nelem(), 0.);
00197
00198
00199 for (Index i_p = 0; i_p < pnd_field.npages(); i_p++)
00200 {
00201
00202 for (Index i_t = 0; i_t < scat_data_mono[0].za_grid.nelem(); i_t++)
00203 {
00204
00205 Numeric sca_coeff=0.;
00206
00207 for (Index j = 0; j < scat_data_mono.nelem(); j++)
00208 sca_coeff += pnd_field(j, i_p, 0, 0) *
00209 (scat_data_mono[j].ext_mat_data(0, 0, 0, 0, 0)-
00210 scat_data_mono[j].abs_vec_data(0, 0, 0, 0, 0));
00211
00212
00213 for (Index j = 0; j < scat_data_mono.nelem(); j++)
00214 {
00215 if (sca_coeff != 0)
00216 phase_function_level(i_p, i_t) +=
00217 pnd_field(j, i_p, 0, 0) *
00218 scat_data_mono[j].pha_mat_data(0, 0, i_t, 0, 0, 0, 0)
00219 *4*PI/sca_coeff;
00220 }
00221
00222 }
00223 }
00224
00225
00226
00227 for (Index i_l = 0; i_l < pnd_field.npages()-1; i_l++)
00228 {
00229 for (Index i_t=0; i_t < phase_function_level.ncols(); i_t++)
00230 {
00231 if (phase_function_level(i_l, i_t) !=0 &&
00232 phase_function_level(i_l+1, i_t) !=0)
00233 phase_function(i_l, i_t) = .5*
00234 (phase_function_level(i_l, i_t)+
00235 phase_function_level(i_l+1, i_t));
00236 }
00237 }
00238
00239 }
00240
00242
00255 void pmomCalc(
00256 MatrixView pmom,
00257
00258 ConstMatrixView phase_function,
00259 ConstVectorView scat_angle_grid,
00260 const Index n_legendre
00261 )
00262 {
00263 Numeric pint;
00264 Numeric p0_1, p0_2, p1_1, p1_2, p2_1, p2_2;
00265
00266 Vector za_grid(181);
00267 Vector u(181);
00268
00269 for (Index i = 0; i< 181; i++)
00270 za_grid[i] = double(i);
00271
00272 ArrayOfGridPos gp(181);
00273 gridpos(gp, scat_angle_grid, za_grid);
00274
00275 Matrix itw(gp.nelem(),2);
00276 interpweights(itw,gp);
00277
00278 Matrix phase_int(phase_function.nrows(),181);
00279 for (Index i_l=0; i_l < phase_function.nrows(); i_l++)
00280 interp(phase_int(i_l, joker), itw, phase_function(i_l, joker), gp);
00281
00282 for (Index i = 0; i<za_grid.nelem(); i++)
00283 u[i] = cos(za_grid[i] *PI/180.);
00284
00285 for (Index i_l=0; i_l < phase_function.nrows(); i_l++)
00286 {
00287 pint = 0.;
00288
00289 for (Index i = 0; i<za_grid.nelem()-1; i++)
00290 pint+=0.5*(phase_int(i_l, i)+phase_int(i_l, i+1))*
00291 abs(u[i+1] - u[i]);
00292
00293 if (pint != 0){
00294 if (abs(2.-pint) > 1e-4)
00295 out1 << "Warning: The phase function is not normalized to 2\n"
00296 << "The value is:" << pint << "\n";
00297
00298 pmom(i_l, joker)= 0.;
00299
00300 for (Index i = 0; i<za_grid.nelem()-1; i++)
00301 {
00302 p0_1=1.;
00303 p0_2=1.;
00304
00305 pmom(phase_function.nrows()-1-i_l,0)=1.;
00306
00307
00308
00309
00310
00311 p1_1=u[i];
00312 p1_2=u[i+1];
00313
00314 pmom(phase_function.nrows()-1-i_l,1)+=0.5*0.5*
00315 (p1_1*phase_int(i_l, i)+
00316 p1_2*phase_int(i_l, i+1))
00317 *abs(u[i+1]-u[i]);
00318
00319 for (Index l=2; l<n_legendre; l++)
00320 {
00321 p2_1=(2*(double)l-1)/(double)l*u[i]*p1_1-((double)l-1)/
00322 (double)l*p0_1;
00323 p2_2=(2*(double)l-1)/(double)l*u[i+1]*p1_2-((double)l-1)/
00324 (double)l*p0_2;
00325
00326 pmom(phase_function.nrows()-1-i_l, l)+=0.5*0.5*
00327 (p2_1*phase_int(i_l, i)+
00328 p2_2*phase_int(i_l, i+1))
00329 *abs(u[i+1]-u[i]);
00330
00331 p0_1=p1_1;
00332 p0_2=p1_2;
00333 p1_1=p2_1;
00334 p1_2=p2_2;
00335 }
00336 }
00337
00338
00339 }
00340 }
00341 }
00342
00344
00361 Numeric planck2(
00362 const Numeric& f,
00363 const Numeric& t )
00364 {
00365 assert( f > 0 );
00366 assert( t >= 0 );
00367
00368
00369 static const double a = 2 * PLANCK_CONST / (SPEED_OF_LIGHT*SPEED_OF_LIGHT);
00370 static const double b = PLANCK_CONST / BOLTZMAN_CONST;
00371
00372 return a * f*f*f / ( exp( b*f/t ) - 1 );
00373 }
00374