ARTS  2.2.66
m_cloudbox.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2012
2  Patrick Eriksson <patrick.eriksson@chalmers.se>
3  Stefan Buehler <sbuehler@ltu.se>
4  Claudia Emde <claudia.emde@dlr.de>
5  Cory Davis <cory.davis@metservice.com>
6 
7  This program is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2, or (at your option) any
10  later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20  USA. */
21 
22 
23 
24 /*===========================================================================
25  === File description
26  ===========================================================================*/
27 
40 /*===========================================================================
41  === External declarations
42  ===========================================================================*/
43 
44 #include <stdexcept>
45 #include <cstdlib>
46 #include <cmath>
47 
48 #include "arts.h"
49 #include "array.h"
50 #include "auto_md.h"
51 #include "check_input.h"
52 #include "xml_io.h"
53 #include "messages.h"
54 #include "gridded_fields.h"
55 #include "logic.h"
56 #include "rte.h"
57 #include "interpolation.h"
58 #include "special_interp.h"
59 #include "cloudbox.h"
60 #include "optproperties.h"
61 #include "math_funcs.h"
62 #include "physics_funcs.h"
63 #include "sorting.h"
64 
65 extern const Index GFIELD3_P_GRID;
66 extern const Index GFIELD3_LAT_GRID;
67 extern const Index GFIELD3_LON_GRID;
68 extern const Numeric PI;
69 
70 
71 /*===========================================================================
72  === The functions (in alphabetical order)
73  ===========================================================================*/
74 
75 /* Workspace method: Doxygen documentation will be auto-generated */
77  Index& cloudbox_on,
78  ArrayOfIndex& cloudbox_limits,
79  Agenda& iy_cloudbox_agenda,
80  Tensor4& pnd_field,
81  ArrayOfSingleScatteringData& scat_data_array,
82  Matrix& particle_masses,
83  const Verbosity&)
84 {
85  cloudbox_on = 0;
86  cloudbox_limits.resize ( 0 );
87  iy_cloudbox_agenda = Agenda();
88  iy_cloudbox_agenda.set_name ( "iy_cloudbox_agenda" );
89  pnd_field.resize(0,0,0,0);
90  scat_data_array.resize(0);
91  particle_masses.resize(0,0);
92 }
93 
94 
95 
96 /* Workspace method: Doxygen documentation will be auto-generated */
97 void cloudboxSetAutomatically (// WS Output:
98  //Workspace& /* ws */,
99  Index& cloudbox_on,
100  ArrayOfIndex& cloudbox_limits,
101  //Agenda& iy_cloudbox_agenda,
102  // WS Input:
103  const Index& atmosphere_dim,
104  const Vector& p_grid,
105  const Vector& lat_grid,
106  const Vector& lon_grid,
107  const Tensor4& massdensity_field,
108  // Control Parameters
109  const Numeric& cloudbox_margin,
110  const Verbosity& verbosity)
111 {
112  // Variables
113  //const Index np = massdensity_field.npages();
114  Index p1 = massdensity_field.npages()-1;
115  Index p2 = 0;
116  DEBUG_ONLY(
117  Index lat1 = massdensity_field.nrows()-1;
118  Index lat2 = 0;
119  Index lon1 = massdensity_field.ncols()-1;
120  Index lon2 = 0;
121  )
122 
123  Index i, j, k, l;
124 
125  // initialize flag, telling if all selected *massdensity_fields* are
126  // zero(false) or not(true)
127  bool x = false;
128 
129 
130  // Check existing WSV
131  chk_if_in_range ( "atmosphere_dim", atmosphere_dim, 1, 3 );
132  // includes p_grid chk_if_decresasing
133  chk_atm_grids ( atmosphere_dim, p_grid, lat_grid, lon_grid );
134  // Set cloudbox_on
135  cloudbox_on = 1;
136 
137  // Allocate cloudbox_limits
138  cloudbox_limits.resize ( atmosphere_dim*2 );
139 
140  //--------- Start loop over particles ----------------------------------------
141  for ( l=0; l<massdensity_field.nbooks(); l++ )
142  {
143  bool y; // empty_flag
144  //y is set to true, if a single value of massdensity_field is unequal zero
146  atmosphere_dim,
147  massdensity_field ( l, joker, joker, joker ),
148  p_grid,
149  lat_grid,
150  lon_grid );
151 
152  //-----------Start setting cloudbox limits----------------------------------
153  if ( y )
154  {
155  //massdensity_field unequal zero -> x is true
156  x = true;
157 
158  if ( atmosphere_dim == 1 )
159  {
160  // Pressure limits
161  ConstVectorView hydro_p = massdensity_field ( l, joker, 0 , 0 );
162 
163 
164  // set lower cloudbox_limit to surface if margin = -1
165  if ( cloudbox_margin == -1 )
166  {
167  cloudbox_limits[0] = 0;
168  i = p1 = 0;
169  }
170  else
171  {
172  // find index of first pressure level where hydromet_field is
173  // unequal 0, starting from the surface
174  for ( i=0; i<hydro_p.nelem(); i++ )
175  {
176  if ( hydro_p[i] != 0.0 )
177  {
178  // check if p1 is the lowest index in all selected
179  // massdensity fields
180  if ( p1 > i )
181  {
182  p1 = i;
183  }
184  break;
185  }
186  }
187 
188  }
189  // find index of highest pressure level, where massdensity_field is
190  // unequal 0, starting from top of the atmosphere
191  for ( j=hydro_p.nelem()-1; j>=i; j-- )
192  {
193  if ( hydro_p[j] != 0.0 )
194  {
195  // check if p2 is the highest index in all selected
196  // massdensity fields
197  if ( p2 < j )
198  {
199  p2 = j;
200  }
201  break;
202  }
203  }
204 
205  }
206  }
207 
208  /* //NOT WORKING YET
209  // Latitude limits
210  else if ( atmosphere_dim == 2 )
211  {
212  MatrixView hydro_lat = hydromet_field ( nhyd, joker, joker, 0 );
213 
214  for ( i=0; i<hydro_lat.nrows(); i++ )
215  {
216  for ( j=0; j<hydro_lat.ncols(); j++ )
217  {
218  if ( hydro_lat[i,j] != 0.0 )
219  {
220 
221  if ( lat1 <= j ) lat1 =j;
222  //cloudbox_limits[2] = lat1;
223  //break;
224  }
225 
226  }
227  if ( p1 <= i ) p1 = i;
228  }
229 
230  for ( k=hydro_lat.nelem()-1; k>=i; k-- )
231  {
232  if ( hydro_lat[k] != 0.0 )
233  {
234  lat2 = k;
235  cloudbox_limits[3] = lat2;
236  break;
237 
238  }
239 
240  }
241  }
242 
243  // Longitude limits
244  if ( atmosphere_dim == 3 )
245  {
246  Tensor3View hydro_lon = hydromet_field ( nhyd, joker, joker, joker );
247 
248  for ( i=0; i<hydro_lon.nelem(); i++ )
249  {
250  if ( hydro_lon[i] != 0.0 )
251  {
252  lon1 = i;
253  cloudbox_limits[4] = lon1;
254  break;
255  }
256 
257  }
258  for ( j=hydro_lon.nelem()-1; j>=i; j-- )
259  {
260  if ( hydro_lon[j] != 0.0 )
261  {
262  lon2 = j;
263  cloudbox_limits[5] = lon2;
264  break;
265 
266  }
267 
268 
269 }*/
270  }
271  // decrease lower cb limit by one to ensure that linear interpolation of
272  // particle number densities is possible.
273  Index p0 = 0; //only for the use of function *max*
274  p1 = max(p1-1, p0);
275 
276  Numeric p_margin1;
277 
278  // alter lower cloudbox_limit by cloudbox_margin, using barometric
279  // height formula
280  p_margin1 = barometric_heightformula ( p_grid[p1], cloudbox_margin );
281  k = 0;
282  while ( p_grid[k+1] >= p_margin1 && k+1 < p_grid.nelem() ) k++;
283  cloudbox_limits[0]= k;
284 
285  // increase upper cb limit by one to ensure that linear interpolation of
286  // particle number densities is possible.
287  p2 = min(p2+1, massdensity_field.npages()-1);
288  // set upper cloudbox_limit
289  // if cloudbox reaches to the upper most pressure level
290  if ( p2 >= massdensity_field.npages()-1)
291  {
292  CREATE_OUT2;
293  out2<<"The cloud reaches to TOA!\n"
294  <<"Check massdensity_field data, if realistic!\n";
295  }
296  cloudbox_limits[1] = p2;
297 
298  //out0<<"\n"<<p2<<"\n"<<p_grid[p2]<<"\n";
299 
300  // check if all selected massdensity fields are zero at each level,
301  // than switch cloudbox off, skipping scattering calculations
302  if ( !x )
303  {
304  CREATE_OUT0;
305  //cloudboxOff ( cloudbox_on, cloudbox_limits, iy_cloudbox_agenda );
306  cloudbox_on = 0;
307  out0<<"Cloudbox is switched off!\n";
308 
309  return;
310  }
311 
312 
313  // assert keyword arguments
314 
315  // The pressure in *p1* must be bigger than the pressure in *p2*.
316  assert ( p_grid[p1] > p_grid[p2] );
317  // The pressure in *p1* must be larger than the last value in *p_grid*.
318  assert ( p_grid[p1] > p_grid[p_grid.nelem()-1] );
319  // The pressure in *p2* must be smaller than the first value in *p_grid*."
320  assert ( p_grid[p2] < p_grid[0] );
321 
322  if ( atmosphere_dim >= 2 )
323  {
324  // The latitude in *lat2* must be bigger than the latitude in *lat1*.
325  assert ( lat_grid[lat2] > lat_grid[lat1] );
326  // The latitude in *lat1* must be >= the second value in *lat_grid*.
327  assert ( lat_grid[lat1] >= lat_grid[1] );
328  // The latitude in *lat2* must be <= the next to last value in *lat_grid*.
329  assert ( lat_grid[lat2] <= lat_grid[lat_grid.nelem()-2] );
330  }
331  if ( atmosphere_dim == 3 )
332  {
333  // The longitude in *lon2* must be bigger than the longitude in *lon1*.
334  assert ( lon_grid[lon2] > lon_grid[lon1] );
335  // The longitude in *lon1* must be >= the second value in *lon_grid*.
336  assert ( lon_grid[lon1] >= lon_grid[1] );
337  // The longitude in *lon2* must be <= the next to last value in *lon_grid*.
338  assert ( lon_grid[lon2] <= lon_grid[lon_grid.nelem()-2] );
339  }
340 }
341 
342 /* Workspace method: Doxygen documentation will be auto-generated */
343 void cloudboxSetFullAtm(//WS Output
344  Index& cloudbox_on,
345  ArrayOfIndex& cloudbox_limits,
346  // WS Input
347  const Index& atmosphere_dim,
348  const Vector& p_grid,
349  const Verbosity&)
350 {
351  if( atmosphere_dim > 1 )
352  {
353  ostringstream os;
354  os << "WSM *cloudboxSetFullAtm* only available for atmosphere_dim=1.";
355  throw runtime_error( os.str() );
356  }
357  cloudbox_on = 1;
358  cloudbox_limits.resize(2);
359  cloudbox_limits[0] = 0;
360  cloudbox_limits[1] = p_grid.nelem()-1;
361 }
362 
363 
364 /* Workspace method: Doxygen documentation will be auto-generated */
365 void cloudboxSetManually(// WS Output:
366  Index& cloudbox_on,
367  ArrayOfIndex& cloudbox_limits,
368  // WS Input:
369  const Index& atmosphere_dim,
370  const Vector& p_grid,
371  const Vector& lat_grid,
372  const Vector& lon_grid,
373  // Control Parameters:
374  const Numeric& p1,
375  const Numeric& p2,
376  const Numeric& lat1,
377  const Numeric& lat2,
378  const Numeric& lon1,
379  const Numeric& lon2,
380  const Verbosity&)
381 {
382  // Check existing WSV
383  chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
384  chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
385 
386  // Check keyword arguments
387  if( p1 <= p2 )
388  throw runtime_error( "The pressure in *p1* must be bigger than the "
389  "pressure in *p2*." );
390  if( p1 <= p_grid[p_grid.nelem()-1] )
391  throw runtime_error( "The pressure in *p1* must be larger than the "
392  "last value in *p_grid*." );
393  if( p2 >= p_grid[0] )
394  throw runtime_error( "The pressure in *p2* must be smaller than the "
395  "first value in *p_grid*." );
396  if( atmosphere_dim >= 2 )
397  {
398  if( lat2 <= lat1 )
399  throw runtime_error( "The latitude in *lat2* must be bigger than the "
400  "latitude in *lat1*.");
401  if( lat1 < lat_grid[1] )
402  throw runtime_error( "The latitude in *lat1* must be >= the "
403  "second value in *lat_grid*." );
404  if( lat2 > lat_grid[lat_grid.nelem()-2] )
405  throw runtime_error( "The latitude in *lat2* must be <= the "
406  "next to last value in *lat_grid*." );
407  }
408  if( atmosphere_dim == 3 )
409  {
410  if( lon2 <= lon1 )
411  throw runtime_error( "The longitude in *lon2* must be bigger than the "
412  "longitude in *lon1*.");
413  if( lon1 < lon_grid[1] )
414  throw runtime_error( "The longitude in *lon1* must be >= the "
415  "second value in *lon_grid*." );
416  if( lon2 > lon_grid[lon_grid.nelem()-2] )
417  throw runtime_error( "The longitude in *lon2* must be <= the "
418  "next to last value in *lon_grid*." );
419  }
420 
421  // Set cloudbox_on
422  cloudbox_on = 1;
423 
424  // Allocate cloudbox_limits
425  cloudbox_limits.resize( atmosphere_dim*2 );
426 
427  // Pressure limits
428  if( p1 > p_grid[1] )
429  {
430  cloudbox_limits[0] = 0;
431  }
432  else
433  {
434  for( cloudbox_limits[0]=1; p_grid[cloudbox_limits[0]+1]>=p1;
435  cloudbox_limits[0]++ ) {}
436  }
437  if( p2 < p_grid[p_grid.nelem()-2] )
438  {
439  cloudbox_limits[1] = p_grid.nelem() - 1;
440  }
441  else
442  {
443  for( cloudbox_limits[1]=p_grid.nelem()-2;
444  p_grid[cloudbox_limits[1]-1]<=p2; cloudbox_limits[1]-- ) {}
445  }
446 
447  // Latitude limits
448  if( atmosphere_dim >= 2 )
449  {
450  for( cloudbox_limits[2]=1; lat_grid[cloudbox_limits[2]+1]<=lat1;
451  cloudbox_limits[2]++ ) {}
452  for( cloudbox_limits[3]=lat_grid.nelem()-2;
453  lat_grid[cloudbox_limits[3]-1]>=lat2; cloudbox_limits[3]-- ) {}
454  }
455 
456  // Longitude limits
457  if( atmosphere_dim == 3 )
458  {
459  for( cloudbox_limits[4]=1; lon_grid[cloudbox_limits[4]+1]<=lon1;
460  cloudbox_limits[4]++ ) {}
461  for( cloudbox_limits[5]=lon_grid.nelem()-2;
462  lon_grid[cloudbox_limits[5]-1]>=lon2; cloudbox_limits[5]-- ) {}
463  }
464 }
465 
466 
467 /* Workspace method: Doxygen documentation will be auto-generated */
468 void cloudboxSetManuallyAltitude(// WS Output:
469  Index& cloudbox_on,
470  ArrayOfIndex& cloudbox_limits,
471  // WS Input:
472  const Index& atmosphere_dim,
473  const Tensor3& z_field,
474  const Vector& lat_grid,
475  const Vector& lon_grid,
476  // Control Parameters:
477  const Numeric& z1,
478  const Numeric& z2,
479  const Numeric& lat1,
480  const Numeric& lat2,
481  const Numeric& lon1,
482  const Numeric& lon2,
483  const Verbosity&)
484 {
485  // Check existing WSV
486  chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
487 
488  // Check keyword arguments
489  if( z1 >= z2 )
490  throw runtime_error( "The altitude in *z1* must be smaller than the "
491  "altitude in *z2*." );
492  /* These cases are in fact handled
493  if( z1 <= z_field(0, 0, 0) )
494  throw runtime_error( "The altitude in *z1* must be larger than the "
495  "first value in *z_field*." );
496  if( z2 >= z_field(z_field.npages()-1, 0, 0) )
497  throw runtime_error( "The altitude in *z2* must be smaller than the "
498  "last value in *z_field*." );
499  */
500  if( atmosphere_dim == 3 )
501  {
502  if( lat2 <= lat1 )
503  throw runtime_error( "The latitude in *lat2* must be bigger than the "
504  " latitude in *lat1*.");
505  if( lat1 < lat_grid[1] )
506  throw runtime_error( "The latitude in *lat1* must be >= the "
507  "second value in *lat_grid*." );
508  if( lat2 > lat_grid[lat_grid.nelem()-2] )
509  throw runtime_error( "The latitude in *lat2* must be <= the "
510  "next to last value in *lat_grid*." );
511  if( lon2 <= lon1 )
512  throw runtime_error( "The longitude in *lon2* must be bigger than the "
513  "longitude in *lon1*.");
514  if( lon1 < lon_grid[1] )
515  throw runtime_error( "The longitude in *lon1* must be >= the "
516  "second value in *lon_grid*." );
517  if( lon2 > lon_grid[lon_grid.nelem()-2] )
518  throw runtime_error( "The longitude in *lon2* must be <= the "
519  "next to last value in *lon_grid*." );
520  }
521 
522  // Set cloudbox_on
523  cloudbox_on = 1;
524 
525  // Allocate cloudbox_limits
526  cloudbox_limits.resize( atmosphere_dim*2 );
527 
528  // Pressure/altitude limits
529  if( z1 < z_field(1, 0, 0) )
530  {
531  cloudbox_limits[0] = 0;
532  }
533  else
534  {
535  for( cloudbox_limits[0]=1; z_field(cloudbox_limits[0]+1, 0, 0) <= z1;
536  cloudbox_limits[0]++ ) {}
537  }
538  if( z2 > z_field(z_field.npages()-2, 0, 0) )
539  {
540  cloudbox_limits[1] = z_field.npages() - 1;
541  }
542  else
543  {
544  for( cloudbox_limits[1]=z_field.npages()- 2;
545  z_field(cloudbox_limits[1]-1, 0, 0) >= z2; cloudbox_limits[1]-- ) {}
546  }
547 
548  // Latitude limits
549  if( atmosphere_dim >= 2 )
550  {
551  for( cloudbox_limits[2]=1; lat_grid[cloudbox_limits[2]+1]<=lat1;
552  cloudbox_limits[2]++ ) {}
553  for( cloudbox_limits[3]=lat_grid.nelem()-2;
554  lat_grid[cloudbox_limits[3]-1]>=lat2; cloudbox_limits[3]-- ) {}
555  }
556 
557  // Longitude limits
558  if( atmosphere_dim == 3 )
559  {
560  for( cloudbox_limits[4]=1; lon_grid[cloudbox_limits[4]+1]<=lon1;
561  cloudbox_limits[4]++ ) {}
562  for( cloudbox_limits[5]=lon_grid.nelem()-2;
563  lon_grid[cloudbox_limits[5]-1]>=lon2; cloudbox_limits[5]-- ) {}
564  }
565 }
566 
567 
568 
569 /* Workspace method: Doxygen documentation will be auto-generated */
570 void Massdensity_cleanup (//WS Output:
571  Tensor4& massdensity_field,
572  //WS Input:
573  const Numeric& massdensity_threshold,
574  const Verbosity&)
575 {
576  // Check that massdensity_fields contain realistic values
577  //(values smaller than massdensity_threshold will be set to 0)
578  for ( Index i=0; i<massdensity_field.nbooks(); i++ )
579  {
580  for ( Index j=0; j<massdensity_field.npages(); j++ )
581  {
582  for ( Index k=0; k<massdensity_field.nrows(); k++ )
583  {
584  for ( Index l=0; l<massdensity_field.ncols(); l++ )
585  {
586  if ( massdensity_field ( i,j,k,l ) < massdensity_threshold )
587  {
588  massdensity_field ( i,j,k,l ) = 0.0;
589  }
590  }
591  }
592  }
593  }
594 }
595 
596 
597 /* Workspace method: Doxygen documentation will be auto-generated */
598 void ParticleSpeciesInit (ArrayOfString& part_species,
599  const Verbosity&)
600 {
601  part_species.resize ( 0 );
602 }
603 
604 
605 /* Workspace method: Doxygen documentation will be auto-generated */
606 void ParticleSpeciesSet (// WS Generic Output:
607  ArrayOfString& part_species,
608  // Control Parameters:
609  const ArrayOfString& particle_tags,
610  const String& delim,
611  const Verbosity& verbosity)
612 {
613  CREATE_OUT3;
614 
615  part_species.resize ( particle_tags.nelem() );
616  //assign input strings to part_species
617  part_species = particle_tags;
618 
619  chk_part_species (part_species, delim);
620 
621  // Print list of particle settings to the most verbose output stream:
622  out3 << " Defined particle settings: ";
623  for ( Index i=0; i<part_species.nelem(); ++i )
624  {
625  out3 << "\n " << i << ": "<<part_species[i];
626 
627  }
628  out3 << '\n';
629 }
630 
631 /* Workspace method: Doxygen documentation will be auto-generated */
632 void ParticleTypeInit (//WS Output:
633  ArrayOfSingleScatteringData& scat_data_array,
634  ArrayOfGriddedField3& pnd_field_raw,
635  const Verbosity&)
636 {
637  scat_data_array.resize(0);
638  pnd_field_raw.resize(0);
639 }
640 
641 
642 /* Workspace method: Doxygen documentation will be auto-generated */
643 void ParticleTypeAdd( //WS Output:
644  ArrayOfSingleScatteringData& scat_data_array,
645  ArrayOfGriddedField3& pnd_field_raw,
646  // WS Input (needed for checking the datafiles):
647  const Index& atmosphere_dim,
648  const Vector& f_grid,
649 // const Vector& p_grid,
650 // const Vector& lat_grid,
651 // const Vector& lon_grid,
652  // Keywords:
653  const String& scat_data_file,
654  const String& pnd_field_file,
655  const Verbosity& verbosity)
656 {
657  CREATE_OUT2;
658 
659  //--- Check input ---------------------------------------------------------
660 
661  // Atmosphere
662  chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
663  //chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
664 
665  // Frequency grid
666  if( f_grid.nelem() == 0 )
667  throw runtime_error( "The frequency grid is empty." );
668  chk_if_increasing( "f_grid", f_grid );
669 
670 
671  //--- Reading the data ---------------------------------------------------
672 
673  // Append *scat_data_array* and *pnd_field_raw* with empty Arrays of Tensors.
674  SingleScatteringData scat_data;
675  scat_data_array.push_back(scat_data);
676 
677  GriddedField3 pnd_field_data;
678  pnd_field_raw.push_back(pnd_field_data);
679 
680  out2 << " Read single scattering data\n";
681  xml_read_from_file(scat_data_file, scat_data_array[scat_data_array.nelem()-1],
682  verbosity);
683 
684  chk_scat_data(scat_data_array[scat_data_array.nelem()-1],
685  scat_data_file, f_grid, verbosity);
686 
687  out2 << " Read particle number density field\n";
688  if (pnd_field_file.nelem() < 1)
689  {
690  CREATE_OUT1;
691  out1 << "Warning: No pnd_field_file specified. Ignored. \n";
692  }
693  else
694  {
695  xml_read_from_file(pnd_field_file, pnd_field_raw[pnd_field_raw.nelem()-1],
696  verbosity);
697 
698  chk_pnd_data(pnd_field_raw[pnd_field_raw.nelem()-1],
699  pnd_field_file, atmosphere_dim, verbosity);
700  }
701 }
702 
703 
704 /* Workspace method: Doxygen documentation will be auto-generated */
705 void ParticleTypeAddAll (//WS Output:
706  ArrayOfSingleScatteringData& scat_data_array,
707  ArrayOfGriddedField3& pnd_field_raw,
708  // WS Input(needed for checking the datafiles):
709  const Index& atmosphere_dim,
710  const Vector& f_grid,
711 // const Vector& p_grid,
712 // const Vector& lat_grid,
713 // const Vector& lon_grid,
714  // Keywords:
715  const String& filelist_scat_data,
716  const String& pnd_fieldarray_file,
717  const Verbosity& verbosity)
718 {
719  CREATE_OUT2;
720 
721  //--- Check input ---------------------------------------------------------
722 
723  // Atmosphere
724  chk_if_in_range ( "atmosphere_dim", atmosphere_dim, 1, 3 );
725  //chk_atm_grids ( atmosphere_dim, p_grid, lat_grid, lon_grid );
726 
727  // Frequency grid
728  if ( f_grid.nelem() == 0 )
729  throw runtime_error ( "The frequency grid is empty." );
730  chk_if_increasing ( "f_grid", f_grid );
731 
732 
733  //--- Reading the data ---------------------------------------------------
734  ArrayOfString data_files;
735  xml_read_from_file ( filelist_scat_data, data_files, verbosity );
736  scat_data_array.resize ( data_files.nelem() );
737 
738  for ( Index i = 0; i<data_files.nelem(); i++ )
739  {
740 
741  out2 << " Read single scattering data\n";
742  xml_read_from_file ( data_files[i], scat_data_array[i], verbosity );
743 
744  chk_scat_data ( scat_data_array[i],
745  data_files[i], f_grid,
746  verbosity );
747 
748  }
749 
750  out2 << " Read particle number density data \n";
751  xml_read_from_file ( pnd_fieldarray_file, pnd_field_raw, verbosity );
752 
753  chk_pnd_raw_data ( pnd_field_raw,
754  pnd_fieldarray_file, atmosphere_dim, verbosity);
755 }
756 
757 
758 /* Workspace method: Doxygen documentation will be auto-generated */
759 void ParticleType2abs_speciesAdd( //WS Output:
760  ArrayOfSingleScatteringData& scat_data_array,
761  ArrayOfGriddedField3& vmr_field_raw,
762  ArrayOfArrayOfSpeciesTag& abs_species,
763  Index& propmat_clearsky_agenda_checked,
764  Index& abs_xsec_agenda_checked,
765  // WS Input (needed for checking the datafiles):
766  const Index& atmosphere_dim,
767  const Vector& f_grid,
768 // const Vector& p_grid,
769 // const Vector& lat_grid,
770 // const Vector& lon_grid,
771  // Keywords:
772  const String& scat_data_file,
773  const String& pnd_field_file,
774  const Verbosity& verbosity)
775 {
776  CREATE_OUT2;
777 
778  //--- Check input ---------------------------------------------------------
779 
780  // Atmosphere
781  chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
782  //chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
783 
784  // Frequency grid
785  if( f_grid.nelem() == 0 )
786  throw runtime_error( "The frequency grid is empty." );
787  chk_if_increasing( "f_grid", f_grid );
788 
789 
790  //--- Reading the data ---------------------------------------------------
791 
792  // Append *scat_data_array* and (later on) *vmr_field_raw* with empty Arrays of
793  // Tensors, then fill those from file.
794  SingleScatteringData scat_data;
795  scat_data_array.push_back(scat_data);
796 
797  out2 << " Read single scattering data\n";
798  xml_read_from_file(scat_data_file, scat_data_array[scat_data_array.nelem()-1],
799  verbosity);
800 
801  chk_scat_data(scat_data_array[scat_data_array.nelem()-1],
802  scat_data_file, f_grid, verbosity);
803 
804  out2 << " Read particle number density field\n";
805  if (pnd_field_file.nelem() < 1)
806  {
807  CREATE_OUT1;
808  out1 << "Warning: No pnd_field_file specified. Ignored here,\n"
809  << "but user HAS TO add that later on!\n";
810  }
811  else
812  {
813  GriddedField3 pnd_field_data;
814  vmr_field_raw.push_back(pnd_field_data);
815 
816  xml_read_from_file(pnd_field_file, vmr_field_raw[vmr_field_raw.nelem()-1],
817  verbosity);
818 
819  chk_pnd_data(vmr_field_raw[vmr_field_raw.nelem()-1],
820  pnd_field_file, atmosphere_dim, verbosity);
821  }
822 
823  out2 << " Append 'particle' field to abs_species\n";
824  ArrayOfString species;
825  species.push_back("particles");
826 
827  abs_speciesAdd( abs_species,
828  propmat_clearsky_agenda_checked, abs_xsec_agenda_checked,
829  species, verbosity );
830 }
831 
832 
833 
834 /* Workspace method: Doxygen documentation will be auto-generated */
836  ArrayOfSingleScatteringData& scat_data_array,
837  ArrayOfScatteringMetaData& scat_meta_array,
838  const Vector& f_grid,
839  // Keywords:
840  const String& filename_scat_data,
841  const String& filename_scat_meta_data,
842  const Verbosity& verbosity)
843 {
844  CREATE_OUT3;
845 
846  //--- Reading the data ---------------------------------------------------
847  ArrayOfString data_files;
848  ArrayOfString meta_data_files;
849 
850  // single scattering data read to temporary ArrayOfSingleScatteringData
851  xml_read_from_file ( filename_scat_data, data_files, verbosity );
852  scat_data_array.resize ( data_files.nelem() );
853 
854  for ( Index i = 0; i<data_files.nelem(); i++ )
855  {
856  out3 << " Read single scattering data\n";
857  xml_read_from_file ( data_files[i], scat_data_array[i], verbosity );
858 
859  chk_scat_data ( scat_data_array[i],
860  data_files[i], f_grid,
861  verbosity );
862 
863  }
864 
865  // scattering meta data read to temporary ArrayOfScatteringMetaData
866  xml_read_from_file ( filename_scat_meta_data, meta_data_files, verbosity );
867  scat_meta_array.resize ( meta_data_files.nelem() );
868 
869  for ( Index i = 0; i<meta_data_files.nelem(); i++ )
870  {
871 
872  out3 << " Read scattering meta data\n";
873  xml_read_from_file ( meta_data_files[i], scat_meta_array[i], verbosity );
874 
875  //FIXME: currently nothing is done in chk_scattering_meta_data!
876  chk_scattering_meta_data ( scat_meta_array[i],
877  meta_data_files[i], verbosity );
878 
879  }
880 
881  // check if arrays have same size
882  chk_scattering_data ( scat_data_array,
883  scat_meta_array, verbosity );
884 
885 }
886 
887 
888 /* Workspace method: Doxygen documentation will be auto-generated */
889 void ScatteringParticlesSelect (//WS Output:
890  ArrayOfSingleScatteringData& scat_data_array,
891  ArrayOfScatteringMetaData& scat_meta_array,
892  ArrayOfIndex& scat_data_per_part_species,
893  // WS Input:
894  const ArrayOfString& part_species,
895  const String& delim,
896  const Verbosity& verbosity)
897 {
898  CREATE_OUT1;
899  CREATE_OUT3;
900  //--- Adjusting data to user specified input (part_species)-------------------
901 
902  Index intarr_total = 0;
903  ArrayOfIndex intarr;
904 
905  // make temporary copy
906  ArrayOfSingleScatteringData scat_data_array_tmp = scat_data_array;
907  ArrayOfScatteringMetaData scat_meta_array_tmp = scat_meta_array;
908 
909  scat_data_per_part_species.resize( part_species.nelem() );
910 
911  ArrayOfIndex selected;
912  selected.resize(scat_meta_array_tmp.nelem());
913  selected = 0;
914  // loop over array of part_species--------------------------------------------
915  for ( Index k=0; k<part_species.nelem(); k++ )
916  {
917 
918  String part_material;
919  String partfield_name;
920  Numeric sizemin;
921  Numeric sizemax;
922 
923  //split part_species string and copy values to parameter
924  parse_partfield_name( partfield_name, part_species[k], delim);
925  parse_part_material( part_material, part_species[k], delim);
926  parse_part_size(sizemin, sizemax, part_species[k], delim);
927 
928  // choosing the specified SingleScatteringData and ScatteringMetaData
929  for ( Index j=0; j<scat_meta_array_tmp.nelem(); j++ )
930  {
931  // check for particle (material/phase) type (e.g. "Ice", "Water",...)
932  if ( scat_meta_array_tmp[j].material == part_material )
933  {
934  // particle radius is calculated from particle volume given in
935  // scattering meta data
936  Numeric r_particle =
937  pow ( 3./4. * scat_meta_array_tmp[j].volume * 1e18 / PI , 1./3. );
938 
939  // check if particle is in size range
940  // (sizemax < 0 results from wildcard usage and means consider all sizes on
941  // the upper end)
942  if ( r_particle >= sizemin &&
943  ( sizemax >= r_particle || sizemax < 0. ))
944  {
945  // fill ArrayOfIndex with indices of selected scattering data
946  intarr.push_back ( j );
947  }
948  selected[j] = 1;
949  out3 << "Selecting particle " << j+1 << "/" << scat_meta_array_tmp.nelem()
950  << " (" << scat_meta_array_tmp[j].material << ")\n";
951  }
952  }
953  // WSV scat_data_per_part_species gets the number of elements of scattering data
954  // connected to each selection String in *part_species*
955  scat_data_per_part_species[k] = intarr.nelem() - intarr_total;
956  intarr_total = intarr.nelem();
957 
958  // Use particle profile without corresponding ScattData poses high risk of
959  // accidentially neglecting those particles. That's unlikely what the user
960  // intends. Hence throw error.
961  if (scat_data_per_part_species[k]<1)
962  {
963  ostringstream os;
964  os << "Particle species " << partfield_name << " of type " << part_material
965  << " requested.\n"
966  << "But no Scattering Data found for it!\n";
967  throw runtime_error ( os.str() );
968  }
969  }
970 
971  // check if array is empty
972  if ( !intarr.nelem() )
973  {
974  /* don't throw error. just a warning (should only apply when part_species is empty)!
975  ostringstream os;
976  os << "The selection in " << part_species <<
977  " is NOT choosing any of the given Scattering Data.\n"
978  "--> Does the selection in *part_species* fit any of the "
979  "Single Scattering Data input? \n";
980  throw runtime_error ( os.str() );*/
981  out1 << "WARNING! No ScatteringData selected.\n"
982  << "Continuing with no particles.\n";
983  }
984 
985  // check if we ignored any ScatteringMetaData entry
986  /* JM120401: what's the meaning of this? does it work properly?
987  uncomment again, when answered.
988  for ( Index j = 0; j<selected.nelem(); j++)
989  {
990  if (selected[j]==0)
991  {
992  out1 << "WARNING! Ignored ScatteringMetaData[" << j << "] ("
993  << scat_meta_array_tmp[j].type << ")!\n";
994  }
995  } */
996 
997 
998  // resize WSVs to size of intarr
999  scat_data_array.resize ( intarr.nelem() );
1000  scat_meta_array.resize ( intarr.nelem() );
1001 
1002  for ( Index j=0; j<intarr.nelem(); j++ )
1003  {
1004  //append to WSV Arrays
1005  scat_meta_array[j] = scat_meta_array_tmp[intarr[j]] ;
1006  scat_data_array[j] = scat_data_array_tmp[intarr[j]] ;
1007  }
1008 
1009 
1010 }
1011 
1012 
1013 
1014 /* Workspace method: Doxygen documentation will be auto-generated */
1016  Matrix& particle_masses,
1017  const ArrayOfScatteringMetaData& scat_meta_array,
1018  const Verbosity&)
1019 {
1020  const Index np = scat_meta_array.nelem();
1021 
1022  particle_masses.resize(np,1);
1023 
1024  for( Index i=0; i<np; i++ )
1025  {
1026  if( scat_meta_array[i].density <= 0 ||
1027  scat_meta_array[i].density > 20e3 )
1028  {
1029  ostringstream os;
1030  os << "A presumably incorrect value found for "
1031  << "scat_meta_array[" << i << "].density.\n"
1032  << "The value is " << scat_meta_array[i].density;
1033  throw std::runtime_error(os.str());
1034  }
1035 
1036  if( scat_meta_array[i].volume <= 0 ||
1037  scat_meta_array[i].volume > 0.01 )
1038  {
1039  ostringstream os;
1040  os << "A presumably incorrect value found for "
1041  << "scat_meta_array[" << i << "].volume.\n"
1042  << "The value is " << scat_meta_array[i].volume;
1043  throw std::runtime_error(os.str());
1044  }
1045 
1046  particle_masses(i,0) = scat_meta_array[i].density *
1047  scat_meta_array[i].volume;
1048  }
1049 }
1050 
1051 
1052 
1053 /* Workspace method: Doxygen documentation will be auto-generated */
1055  (//WS Output:
1056  Matrix& particle_masses,
1057  // WS Input:
1058  const ArrayOfScatteringMetaData& scat_meta_array,
1059  const ArrayOfIndex& scat_data_per_part_species,
1060  const ArrayOfString& part_species,
1061  const Verbosity& )
1062 {
1063  // checks
1064  if (scat_data_per_part_species.nelem() != part_species.nelem())
1065  {
1066  ostringstream os;
1067  os << "Dimensions of part_species and scat_data_per_part_species do not agree.";
1068  throw runtime_error(os.str());
1069  }
1070 
1071  // resize particle_masses to required diemsions and properly initialize values
1072  particle_masses.resize ( scat_meta_array.nelem(), part_species.nelem() );
1073  particle_masses = 0.;
1074  Index scat_data_start = 0;
1075 
1076  // calculate and set particle_masses
1077  for ( Index k=0; k<part_species.nelem(); k++ )
1078  {
1079  for ( Index j=scat_data_start; j<scat_data_start+scat_data_per_part_species[k]; j++ )
1080  {
1081  particle_masses (j, k) =
1082  scat_meta_array[j].density * scat_meta_array[j].volume;
1083  }
1084 
1085  scat_data_start += scat_data_per_part_species[k];
1086 
1087  }
1088 }
1089 
1090 
1091 /* Workspace method: Doxygen documentation will be auto-generated */
1092 void pnd_fieldCalc(//WS Output:
1093  Tensor4& pnd_field,
1094  //WS Input
1095  const Vector& p_grid,
1096  const Vector& lat_grid,
1097  const Vector& lon_grid,
1098  const ArrayOfGriddedField3& pnd_field_raw,
1099  const Index& atmosphere_dim,
1100  const ArrayOfIndex& cloudbox_limits,
1101  const Index& zeropadding,
1102  const Verbosity& verbosity)
1103 {
1104  // Basic checks of input variables
1105  //
1106  // Particle number density data
1107  //
1108  if (pnd_field_raw.nelem() == 0)
1109  throw runtime_error(
1110  "No particle number density data given. Please\n"
1111  "use WSMs *ParticleTypeInit* and \n"
1112  "*ParticleTypeAdd(All)* for reading cloud particle\n"
1113  "data.\n"
1114  );
1115 
1116  chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
1117  ArrayOfIndex cloudbox_limits_tmp;
1118  /*if ( cloudbox_limits.nelem()== 0 )
1119  {
1120  //If no limits set, the cloud(box) is supposed to cover the
1121  //complete atmosphere. This particularly to facilitate use of
1122  //scat_data&pnd_fields for non-scatt, greybody cloud calculations.
1123  //Hence, set the limits to first & last elements of the different grids.
1124  //Note: no margin left at lat/lon_grid edges!.
1125  cloudbox_limits_tmp.resize(2*atmosphere_dim);
1126 
1127  // Pressure limits
1128  cloudbox_limits_tmp[0] = 0;
1129  cloudbox_limits_tmp[1] = p_grid.nelem() - 1;
1130  // Latitude limits
1131  if( atmosphere_dim >= 2 )
1132  {
1133  cloudbox_limits_tmp[2] = 0;
1134  cloudbox_limits_tmp[3] = lat_grid.nelem() - 1;
1135  }
1136  // Longitude limits
1137  if( atmosphere_dim == 3 )
1138  {
1139  cloudbox_limits_tmp[4] = 0;
1140  cloudbox_limits_tmp[5] = lon_grid.nelem() - 1;
1141  }
1142  }
1143  else */
1144  if ( cloudbox_limits.nelem()!= 2*atmosphere_dim)
1145  throw runtime_error(
1146  "*cloudbox_limits* is a vector which contains the"
1147  "upper and lower limit of the cloud for all "
1148  "atmospheric dimensions. So its dimension must"
1149  "be 2 x *atmosphere_dim*");
1150  else
1151  cloudbox_limits_tmp = cloudbox_limits;
1152 
1153  // Check that pnd_field_raw has at least 2 grid-points in each dimension.
1154  // Otherwise, interpolation further down will fail with assertion.
1155 
1156  for (Index d = 0; d < atmosphere_dim; d++)
1157  {
1158  for (Index i = 0; i < pnd_field_raw.nelem(); i++)
1159  {
1160  if (pnd_field_raw[i].get_grid_size(d) < 2)
1161  {
1162  ostringstream os;
1163  os << "Error in pnd_field_raw data. ";
1164  os << "Dimension " << d << " (name: \"";
1165  os << pnd_field_raw[i].get_grid_name(d);
1166  os << "\") has only ";
1167  os << pnd_field_raw[i].get_grid_size(d);
1168  os << " element";
1169  os << ((pnd_field_raw[i].get_grid_size(d)==1) ? "" : "s");
1170  os << ". Must be at least 2.";
1171  throw runtime_error(os.str());
1172  }
1173  }
1174  }
1175  const Index Np_cloud = cloudbox_limits_tmp[1]-cloudbox_limits_tmp[0]+1;
1176 
1177  ConstVectorView p_grid_cloud = p_grid[Range(cloudbox_limits_tmp[0], Np_cloud)];
1178 
1179  // Check that no scatterers exist outside the cloudbox
1180  chk_pnd_field_raw_only_in_cloudbox(atmosphere_dim, pnd_field_raw,
1181  p_grid, lat_grid, lon_grid,
1182  cloudbox_limits_tmp);
1183 
1184  //==========================================================================
1185  if ( atmosphere_dim == 1)
1186  {
1187  ArrayOfGriddedField3 pnd_field_tmp;
1188 
1189  GriddedFieldPRegrid(pnd_field_tmp, p_grid_cloud, pnd_field_raw,
1190  1, zeropadding, verbosity);
1191 
1192  FieldFromGriddedField(pnd_field,
1193  p_grid_cloud,
1194  pnd_field_tmp[0].get_numeric_grid(1),
1195  pnd_field_tmp[0].get_numeric_grid(2),
1196  pnd_field_tmp, verbosity);
1197  }
1198  else if(atmosphere_dim == 2)
1199  {
1200  const Index Nlat_cloud = cloudbox_limits_tmp[3]-cloudbox_limits_tmp[2]+1;
1201 
1202  ConstVectorView lat_grid_cloud =
1203  lat_grid[Range(cloudbox_limits_tmp[2],Nlat_cloud)];
1204 
1205  if (zeropadding)
1206  {
1207  // FIXME: OLE: Implement this
1208  CREATE_OUT0;
1209  out0 << "WARNING: zeropadding currently only supported for 1D.";
1210  }
1211 
1212  //Resize variables
1213  pnd_field.resize( pnd_field_raw.nelem(), Np_cloud, Nlat_cloud, 1 );
1214 
1215  // Gridpositions:
1216  ArrayOfGridPos gp_p(Np_cloud);
1217  ArrayOfGridPos gp_lat(Nlat_cloud);
1218 
1219  // Interpolate pnd_field.
1220  // Loop over the particle types:
1221  for (Index i = 0; i < pnd_field_raw.nelem(); ++ i)
1222  {
1223  // Calculate grid positions:
1224  p2gridpos( gp_p, pnd_field_raw[i].get_numeric_grid(GFIELD3_P_GRID),
1225  p_grid_cloud);
1226  gridpos( gp_lat, pnd_field_raw[i].get_numeric_grid(GFIELD3_LAT_GRID),
1227  lat_grid_cloud);
1228 
1229  // Interpolation weights:
1230  Tensor3 itw( Np_cloud, Nlat_cloud, 4 );
1231  interpweights( itw, gp_p, gp_lat );
1232 
1233  // Interpolate:
1234  interp( pnd_field(i,joker,joker,0), itw,
1235  pnd_field_raw[i].data(joker,joker,0), gp_p, gp_lat );
1236  }
1237  }
1238  else
1239  {
1240  const Index Nlat_cloud = cloudbox_limits_tmp[3]-cloudbox_limits_tmp[2]+1;
1241  const Index Nlon_cloud = cloudbox_limits_tmp[5]-cloudbox_limits_tmp[4]+1;
1242 
1243  if (zeropadding)
1244  {
1245  // FIXME: OLE: Implement this
1246  CREATE_OUT0;
1247  out0 << "WARNING: zeropadding currently only supported for 1D.";
1248  }
1249 
1250  ConstVectorView lat_grid_cloud =
1251  lat_grid[Range(cloudbox_limits_tmp[2],Nlat_cloud)];
1252  ConstVectorView lon_grid_cloud =
1253  lon_grid[Range(cloudbox_limits_tmp[4],Nlon_cloud)];
1254 
1255  //Resize variables
1256  pnd_field.resize( pnd_field_raw.nelem(), Np_cloud, Nlat_cloud,
1257  Nlon_cloud );
1258 
1259  // Gridpositions:
1260  ArrayOfGridPos gp_p(Np_cloud);
1261  ArrayOfGridPos gp_lat(Nlat_cloud);
1262  ArrayOfGridPos gp_lon(Nlon_cloud);
1263 
1264  // Interpolate pnd_field.
1265  // Loop over the particle types:
1266  for (Index i = 0; i < pnd_field_raw.nelem(); ++ i)
1267  {
1268  // Calculate grid positions:
1269  p2gridpos( gp_p, pnd_field_raw[i].get_numeric_grid(GFIELD3_P_GRID),
1270  p_grid_cloud);
1271  gridpos( gp_lat, pnd_field_raw[i].get_numeric_grid(GFIELD3_LAT_GRID),
1272  lat_grid_cloud);
1273  gridpos( gp_lon, pnd_field_raw[i].get_numeric_grid(GFIELD3_LON_GRID),
1274  lon_grid_cloud);
1275 
1276  // Interpolation weights:
1277  Tensor4 itw( Np_cloud, Nlat_cloud, Nlon_cloud, 8 );
1278  interpweights( itw, gp_p, gp_lat, gp_lon );
1279 
1280  // Interpolate:
1281  interp( pnd_field(i,joker,joker,joker), itw,
1282  pnd_field_raw[i].data, gp_p, gp_lat, gp_lon );
1283  }
1284  }
1285 }
1286 
1287 
1288 /* Workspace method: Doxygen documentation will be auto-generated */
1289 void pnd_fieldExpand1D(Tensor4& pnd_field,
1290  const Index& atmosphere_dim,
1291  const Index& cloudbox_on,
1292  const ArrayOfIndex& cloudbox_limits,
1293  const Index& nzero,
1294  const Verbosity&)
1295 {
1296 /* if( !cloudbox_checked )
1297  throw runtime_error( "The cloudbox must be flagged to have passed a "
1298  "consistency check (cloudbox_checked=1)." );
1299 */
1300  if( atmosphere_dim == 1 )
1301  { throw runtime_error( "No use in calling this method for 1D." ); }
1302  if( !cloudbox_on )
1303  { throw runtime_error(
1304  "No use in calling this method with cloudbox off." ); }
1305 
1306  if( nzero < 1 )
1307  { throw runtime_error( "The argument *nzero must be > 0." ); }
1308 
1309  // Sizes
1310  const Index npart = pnd_field.nbooks();
1311  const Index np = cloudbox_limits[1] - cloudbox_limits[0] + 1;
1312  const Index nlat = cloudbox_limits[3] - cloudbox_limits[2] + 1;
1313  Index nlon = 1;
1314  if( atmosphere_dim == 3 )
1315  { nlon = cloudbox_limits[5] - cloudbox_limits[4] + 1; }
1316 
1317  if( pnd_field.npages() != np || pnd_field.nrows() != 1 ||
1318  pnd_field.ncols() != 1 )
1319  { throw runtime_error( "The input *pnd_field* is either not 1D or does not "
1320  "match pressure size of cloudbox." );}
1321 
1322  // Temporary container
1323  Tensor4 pnd_temp = pnd_field;
1324 
1325  // Resize and fill
1326  pnd_field.resize( npart, np, nlat, nlon );
1327  pnd_field = 0;
1328  //
1329  for( Index ilon=nzero; ilon<nlon-nzero; ilon++ )
1330  {
1331  for( Index ilat=nzero; ilat<nlat-nzero; ilat++ )
1332  {
1333  for( Index ip=0; ip<np; ip++ )
1334  {
1335  for( Index is=0; is<npart; is++ )
1336  { pnd_field(is,ip,ilat,ilon) = pnd_temp(is,ip,0,0); }
1337  }
1338  }
1339  }
1340 }
1341 
1342 
1343 /* Workspace method: Doxygen documentation will be auto-generated */
1344 void pnd_fieldZero(//WS Output:
1345  Tensor4& pnd_field,
1346  ArrayOfSingleScatteringData& scat_data_array,
1347  //WS Input:
1348  const Vector& p_grid,
1349  const Vector& lat_grid,
1350  const Vector& lon_grid,
1351  const Verbosity&)
1352 {
1353  // 3D atmosphere
1354  if (lat_grid.nelem()>1)
1355  {
1356  //Resize pnd_field and set it to 0:
1357  pnd_field.resize(1, p_grid.nelem(), lat_grid.nelem(), lon_grid.nelem());
1358  pnd_field = 0.;
1359  }
1360  else // 1D atmosphere
1361  {
1362  //Resize pnd_field and set it to 0:
1363  pnd_field.resize(1, p_grid.nelem(), 1, 1);
1364  pnd_field = 0.;
1365  }
1366 
1367  //Resize scat_data_array and set it to 0:
1368  // Number iof particle types
1369  scat_data_array.resize(1);
1370  scat_data_array[0].particle_type = PARTICLE_TYPE_MACROS_ISO;
1371  scat_data_array[0].description = " ";
1372  // Grids which contain full ranges which one wants to calculate
1373  nlinspace(scat_data_array[0].f_grid, 1e9, 3.848043e+13 , 5);
1374  nlinspace(scat_data_array[0].T_grid, 0, 400, 5);
1375  nlinspace(scat_data_array[0].za_grid, 0, 180, 5);
1376  nlinspace(scat_data_array[0].aa_grid, 0, 360, 5);
1377  // Resize the data arrays
1378  scat_data_array[0].pha_mat_data.resize(5,5,5,1,1,1,6);
1379  scat_data_array[0].pha_mat_data = 0.;
1380  scat_data_array[0].ext_mat_data.resize(5,5,1,1,1);
1381  scat_data_array[0].ext_mat_data = 0.;
1382  scat_data_array[0].abs_vec_data.resize(5,5,1,1,1);
1383  scat_data_array[0].abs_vec_data = 0.;
1384 }
1385 
1386 
1387 /* Workspace method: Doxygen documentation will be auto-generated */
1388 void pnd_fieldSetup (//WS Output:
1389  Tensor4& pnd_field,
1390  //WS Input:
1391  const Index& atmosphere_dim,
1392  const Index& cloudbox_on,
1393  const ArrayOfIndex& cloudbox_limits,
1394  const Tensor4& massdensity_field,
1395  const Tensor3& t_field,
1396  const ArrayOfScatteringMetaData& scat_meta_array,
1397  const ArrayOfString& part_species,
1398  const ArrayOfIndex& scat_data_per_part_species,
1399  const String& delim,
1400  const Verbosity& verbosity)
1401 {
1402  CREATE_OUT1;
1403 
1404  // Cloudbox on/off?
1405  if ( !cloudbox_on )
1406  {
1407  /* Must initialise pnd_field anyway; but empty */
1408  pnd_field.resize(0, 0, 0, 0);
1409  return;
1410  }
1411 
1412  // ------- set pnd_field boundaries to cloudbox boundaries -------------------
1413  //set pnd_field boundaries
1414  ArrayOfIndex limits(6);
1415  //pressure
1416  limits[0] = cloudbox_limits[0];
1417  limits[1] = cloudbox_limits[1]+1;
1418  //latitude
1419  if ( atmosphere_dim > 1 )
1420  {
1421  limits[2] = cloudbox_limits[2];
1422  limits[3] = cloudbox_limits[3]+1;
1423  }
1424  else
1425  {
1426  limits[2] = 0;
1427  limits[3] = 1;
1428  }
1429  if ( atmosphere_dim > 2 )
1430  {
1431  limits[4] = cloudbox_limits[4];
1432  limits[5] = cloudbox_limits[5]+1;
1433  }
1434  else
1435  {
1436  limits[4] = 0;
1437  limits[5] = 1;
1438  }
1439 
1440  /* Do some checks. Not foolproof, but catches at least some. */
1441 
1442  if ((limits[1] > massdensity_field.npages()) ||
1443  (limits[1] > t_field.npages()) ||
1444  (limits[3] > massdensity_field.nrows()) ||
1445  (limits[3] > t_field.nrows()) ||
1446  (limits[5] > massdensity_field.ncols()) ||
1447  (limits[5] > t_field.ncols()))
1448  {
1449  ostringstream os;
1450  os << "Cloudbox out of bounds compared to fields. "
1451  << "Upper limits: (p, lat, lon): "
1452  << "(" << limits[1] << ", " << limits[3] << ", " << limits[5] << "). "
1453  << "*massdensity_field*: "
1454  << "(" << massdensity_field.npages() << ", "
1455  << massdensity_field.nrows() << ", "
1456  << massdensity_field.ncols() << "). "
1457  << "*t_field*: "
1458  << "(" << t_field.npages() << ", "
1459  << t_field.nrows() << ", "
1460  << t_field.ncols() << ").";
1461  throw runtime_error(os.str());
1462  }
1463 
1464  //resize pnd_field to required atmospheric dimension and scatt particles
1465  pnd_field.resize ( scat_meta_array.nelem(), limits[1]-limits[0],
1466  limits[3]-limits[2], limits[5]-limits[4] );
1467  Index scat_data_start = 0;
1468  ArrayOfIndex intarr;
1469 
1470  //-------- Start pnd_field calculations---------------------------------------
1471 
1472  // loop over nelem of part_species
1473  for ( Index k=0; k<part_species.nelem(); k++ )
1474  {
1475 
1476  String psd_param;
1477  String partfield_name;
1478  String part_material;
1479  String psd;
1480 
1481  //split String and copy to ArrayOfString
1482  parse_psd_param( psd_param, part_species[k], delim);
1483  parse_partfield_name( partfield_name, part_species[k], delim);
1484  parse_part_material( part_material, part_species[k], delim);
1485 
1486  // initialize control parameters
1487  Vector vol_unsorted ( scat_data_per_part_species[k], 0.0 );
1488  Vector d_max_unsorted (scat_data_per_part_species[k], 0.0);
1489  Vector vol ( scat_data_per_part_species[k], 0.0 );
1490  Vector dm ( scat_data_per_part_species[k], 0.0 );
1491  Vector r ( scat_data_per_part_species[k], 0.0 );
1492  Vector rho ( scat_data_per_part_species[k], 0.0 );
1493  Vector pnd ( scat_data_per_part_species[k], 0.0 );
1494  //Vector pnd2 ( scat_data_per_part_species[k], 0.0 ); //temporary
1495  Vector dN ( scat_data_per_part_species[k], 0.0 );
1496  //Vector dN2 ( scat_data_per_part_species[k], 0.0 ); //temporary
1497  //Vector dlwc ( scat_data_per_part_species[k], 0.0 ); //temporary
1498 
1499  //Tensor3 md_field = massdensity_field ( k, joker, joker, joker );
1500 
1501  //---- pnd_field calculations for MH97 -------------------------------
1502  if ( psd_param.substr(0,4) == "MH97" )
1503  {
1504  psd = "MH97";
1505 
1506  //check for expected particle field name
1507  if ( partfield_name != "IWC" )
1508  {
1509  out1 << "WARNING! The particle field name is unequal 'IWC'.\n"
1510  << psd << " should should only be applied to cloud"
1511  << " ice.\n";
1512  }
1513 
1514  //check for expected particle phase
1515  if ( part_material != "Ice" )
1516  {
1517  out1 << "WARNING! The particle phase is unequal 'Ice'.\n"
1518  << psd << " should only be applied to ice"
1519  << " particles.\n";
1520  }
1521 
1522  pnd_fieldMH97( pnd_field,
1523  massdensity_field ( k, joker, joker, joker ),
1524  t_field, limits,
1525  scat_meta_array, scat_data_start,
1526  scat_data_per_part_species[k], part_species[k], delim,
1527  verbosity);
1528  }
1529 
1530  //---- pnd_field calculations for H11 ----------------------------
1531  else if ( psd_param == "H11" )
1532  {
1533  psd = "H11";
1534 
1535  //check for expected particle field name
1536  if ( partfield_name != "IWC" && partfield_name != "Snow")
1537  {
1538  out1 << "WARNING! The particle field name is unequal 'IWC' and 'Snow'.\n"
1539  << psd << " should only be applied to cloud or precipitating"
1540  << " ice.\n";
1541  }
1542 
1543  //check for expected particle phase
1544  //check for correct particle phase
1545  if ( part_material != "Ice" && part_material != "Water" )
1546  {
1547  out1 << "WARNING! The particle phase is unequal 'Ice'.\n"
1548  << psd << " should only be applied to ice (cloud ice or snow)"
1549  << " particles.\n";
1550  }
1551  pnd_fieldH11 (pnd_field,
1552  massdensity_field ( k, joker, joker, joker ),
1553  t_field, limits,
1554  scat_meta_array, scat_data_start,
1555  scat_data_per_part_species[k], part_species[k], delim,
1556  verbosity);
1557  }
1558 
1559  //---- pnd_field calculations for H13 ----------------------------
1560  else if ( psd_param == "H13" )
1561  {
1562  psd = "H13";
1563 
1564  //check for expected particle field name
1565  if ( partfield_name != "IWC" && partfield_name != "Snow")
1566  {
1567  out1 << "WARNING! The particle field name is unequal 'IWC' and 'Snow'.\n"
1568  << psd << " should only be applied to cloud or precipitating"
1569  << " ice.\n";
1570  }
1571 
1572  //check for expected particle phase
1573  //check for correct particle phase
1574  if ( part_material != "Ice" && part_material != "Water" )
1575  {
1576  out1 << "WARNING! The particle phase is unequal 'Ice'.\n"
1577  << psd << " should only be applied to ice (cloud ice or snow)"
1578  << " particles.\n";
1579  }
1580 
1581  pnd_fieldH13 (pnd_field,
1582  massdensity_field ( k, joker, joker, joker ),
1583  t_field, limits,
1584  scat_meta_array, scat_data_start,
1585  scat_data_per_part_species[k], part_species[k], delim,
1586  verbosity);
1587  }
1588 
1589 //---- pnd_field calculations for H13Shape ----------------------------
1590  else if ( psd_param == "H13Shape" )
1591  {
1592  psd = "H13Shape";
1593 
1594  //check for expected particle field name
1595  if ( partfield_name != "IWC" && partfield_name != "Snow")
1596  {
1597  out1 << "WARNING! The particle field name is unequal 'IWC' and 'Snow'.\n"
1598  << psd << " should only be applied to cloud or precipitating"
1599  << " ice.\n";
1600  }
1601 
1602  //check for expected particle phase
1603  //check for correct particle phase
1604  if ( part_material != "Ice" && part_material != "Water" )
1605  {
1606  out1 << "WARNING! The particle phase is unequal 'Ice'.\n"
1607  << psd << " should only be applied to ice (cloud ice or snow)"
1608  << " particles.\n";
1609  }
1610 
1611  pnd_fieldH13Shape (pnd_field,
1612  massdensity_field ( k, joker, joker, joker ),
1613  t_field, limits,
1614  scat_meta_array, scat_data_start,
1615  scat_data_per_part_species[k], part_species[k], delim,
1616  verbosity);
1617  }
1618 
1619  //---- pnd_field calculations for F07TR ----------------------------
1620  else if ( psd_param == "F07TR" )
1621  {
1622  psd = "F07TR";
1623 
1624  //check for expected particle field name
1625  if ( partfield_name != "SWC" && partfield_name != "IWC")
1626  {
1627  out1 << "WARNING! The particle field name is unequal 'IWC' and 'SWC'.\n"
1628  << psd << " should only be applied to cloud or precipitating"
1629  << " ice.\n";
1630  }
1631 
1632  //check for expected particle phase
1633  //check for correct particle phase
1634  if ( part_material != "Ice" && part_material != "Snow" )
1635  {
1636  out1 << "WARNING! The particle phase is unequal 'Ice'.\n"
1637  << psd << " should only be applied to ice (cloud ice or snow)"
1638  << " particles.\n";
1639  }
1640 
1641  pnd_fieldF07TR (pnd_field,
1642  massdensity_field ( k, joker, joker, joker ),
1643  t_field, limits,
1644  scat_meta_array, scat_data_start,
1645  scat_data_per_part_species[k], part_species[k], delim,
1646  verbosity);
1647  }
1648  //---- pnd_field calculations for F07ML ----------------------------
1649  else if ( psd_param == "F07ML" )
1650  {
1651  psd = "F07ML";
1652 
1653  //check for expected particle field name
1654  if ( partfield_name != "SWC" && partfield_name != "IWC")
1655  {
1656  out1 << "WARNING! The particle field name is unequal 'IWC' and 'SWC'.\n"
1657  << psd << " should only be applied to cloud or precipitating"
1658  << " ice.\n";
1659  }
1660 
1661  //check for expected particle phase
1662  //check for correct particle phase
1663  if ( part_material != "Ice" && part_material != "Snow" )
1664  {
1665  out1 << "WARNING! The particle phase is unequal 'Ice'.\n"
1666  << psd << " should only be applied to ice (cloud ice or snow)"
1667  << " particles.\n";
1668  }
1669 
1670  pnd_fieldF07ML (pnd_field,
1671  massdensity_field ( k, joker, joker, joker ),
1672  t_field, limits,
1673  scat_meta_array, scat_data_start,
1674  scat_data_per_part_species[k], part_species[k], delim,
1675  verbosity);
1676  }
1677 
1678  //---- pnd_field calculations for MGD_LWC -------------------------------
1679  else if ( psd_param == "MGD_LWC" )
1680  {
1681  psd = "MGD_LWC";
1682 
1683  //check for expected particle field name
1684  if ( partfield_name != "LWC")
1685  {
1686  out1 << "WARNING! The particle field name is unequal LWC.\n"
1687  << psd << " should only be applied to cloud liquid water.\n";
1688  }
1689 
1690  //check for expected particle phase
1691  if ( part_material != "Water" )
1692  {
1693  out1 << "WARNING! The particle phase is unequal 'Water'.\n"
1694  << psd << " should only be applied to liquid water.\n";
1695  }
1696 
1697  pnd_fieldMGD_LWC( pnd_field,
1698  massdensity_field ( k, joker, joker, joker ),
1699  limits,
1700  scat_meta_array, scat_data_start,
1701  scat_data_per_part_species[k], part_species[k], delim,
1702  verbosity);
1703  }
1704 
1705  //---- pnd_field calculations for MGD_LWC -------------------------------
1706  else if ( psd_param == "MGD_IWC" )
1707  {
1708  psd = "MGD_IWC";
1709 
1710  //check for expected particle field name
1711  if ( partfield_name != "IWC")
1712  {
1713  out1 << "WARNING! The particle field name is unequal IWC.\n"
1714  << psd << " should only be applied to cloud ice.\n";
1715  }
1716 
1717  //check for expected particle phase
1718  if ( part_material != "Ice" )
1719  {
1720  out1 << "WARNING! The particle phase is unequal 'Ice'.\n"
1721  << psd << " should only be applied to ice.\n";
1722  }
1723 
1724  pnd_fieldMGD_IWC( pnd_field,
1725  massdensity_field ( k, joker, joker, joker ),
1726  limits,
1727  scat_meta_array, scat_data_start,
1728  scat_data_per_part_species[k], part_species[k], delim,
1729  verbosity);
1730  }
1731 
1732  //---- pnd_field calculations for GM58 -------------------------------
1733  else if ( psd_param == "GM58" )
1734  {
1735  psd = "GM58";
1736 
1737  //check for expected particle field name
1738  if ( partfield_name != "Snow")
1739  {
1740  out1 << "WARNING! The particle field name is unequal 'Snow'.\n"
1741  << psd << " should only be applied to frozen"
1742  << " precipitation.\n";
1743  }
1744 
1745  //check for expected particle phase
1746  if ( part_material != "Ice")
1747  {
1748  out1 << "WARNING! The particle phase is unequal 'Ice' and 'Water'.\n"
1749  << psd << " should only be applied to ice particles.\n";
1750  }
1751 
1752  pnd_fieldGM58( pnd_field,
1753  massdensity_field ( k, joker, joker, joker ),
1754  limits,
1755  scat_meta_array, scat_data_start,
1756  scat_data_per_part_species[k], part_species[k], delim,
1757  verbosity);
1758  }
1759 
1760  //---- pnd_field calculations for SS70 -------------------------------
1761  else if ( psd_param == "SS70" )
1762  {
1763  psd = "SS70";
1764 
1765  //check for expected particle field name
1766  if ( partfield_name != "Snow")
1767  {
1768  out1 << "WARNING! The particle field name is unequal 'Snow'.\n"
1769  << psd << " should only be applied to frozen"
1770  << " precipitation.\n";
1771  }
1772 
1773  //check for expected particle phase
1774  if ( part_material != "Ice")
1775  {
1776  out1 << "WARNING! The particle phase is unequal 'Ice' and 'Water'.\n"
1777  << psd << " should only be applied to ice particles.\n";
1778  }
1779 
1780  pnd_fieldSS70( pnd_field,
1781  massdensity_field ( k, joker, joker, joker ),
1782  limits,
1783  scat_meta_array, scat_data_start,
1784  scat_data_per_part_species[k], part_species[k], delim,
1785  verbosity);
1786  }
1787 
1788 
1789  //---- pnd_field calculations for MP48 -------------------------------
1790  else if ( psd_param == "MP48" )
1791  {
1792  psd = "MP48";
1793 
1794  //check for expected particle field name
1795  if ( partfield_name != "Rain" && partfield_name != "Snow")
1796  {
1797  out1 << "WARNING! The particle field name is unequal 'Rain' and 'Snow'.\n"
1798  << psd << " should only be applied to liquid or frozen"
1799  << " precipitation.\n";
1800  }
1801 
1802  //check for expected particle phase
1803  if ( part_material != "Ice" && part_material != "Water" )
1804  {
1805  out1 << "WARNING! The particle phase is unequal 'Ice' and 'Water'.\n"
1806  << psd << " should only be applied to liquid water or water"
1807  << " ice particles.\n";
1808  }
1809 
1810  pnd_fieldMP48( pnd_field,
1811  massdensity_field ( k, joker, joker, joker ),
1812  limits,
1813  scat_meta_array, scat_data_start,
1814  scat_data_per_part_species[k], part_species[k], delim,
1815  verbosity);
1816  }
1817 
1818  // ---- pnd_field calculations for liquid water clouds ---------------------
1819  // (parameters from Hess98, Stratus continental)
1820  else if ( psd_param == "H98_STCO" || psd_param == "STCO" || psd_param == "liquid" )
1821  {
1822  psd = "H98_STCO";
1823 
1824  //check for expected particle field name
1825  if ( partfield_name != "LWC")
1826  {
1827  out1 << "WARNING! The particle field name is unequal 'LWC'.\n"
1828  << psd << " should should only be applied to liquid or frozen"
1829  << " precipitation.\n";
1830  }
1831 
1832  //check for expected particle phase
1833  if ( part_material != "Water" )
1834  {
1835  out1 << "WARNING! The particle phase is unequal 'Water'.\n"
1836  << psd << " should only be applied to liquid water"
1837  << " particles.\n";
1838  }
1839 
1840  pnd_fieldH98 (pnd_field,
1841  massdensity_field ( k, joker, joker, joker ),
1842  limits,
1843  scat_meta_array, scat_data_start,
1844  scat_data_per_part_species[k], part_species[k], delim,
1845  verbosity);
1846  }
1847 
1848  else
1849  {
1850  ostringstream os;
1851  os << "Size distribution function '" << psd_param << "' is unknown!\n";
1852  throw runtime_error( os.str() );
1853  }
1854 
1855  // alter starting index of current scattering data array to starting index
1856  // of next iteration step
1857  scat_data_start = scat_data_start + scat_data_per_part_species[k];
1858 
1859  }
1860 }
1861 
1862 /* Workspace method: Doxygen documentation will be auto-generated */
1863 void dN_MH97 (//WS Output:
1864  Vector& dN,
1865  //WS Input:
1866  const Vector& Dme,
1867  const Numeric& IWC,
1868  const Numeric& t,
1869  const Vector& density,
1870  const Index& noisy,
1871  const Verbosity&)
1872 {
1873  Index n = Dme.nelem();
1874 
1875  if ( density.nelem() != n )
1876  {
1877  ostringstream os;
1878  os << "Particle size and particle density vectors need to be of\n"
1879  << "identical size, but are not.";
1880  throw runtime_error(os.str());
1881  }
1882 
1883  dN.resize(n);
1884 
1885  for ( Index i=0; i<n; i++ )
1886  {
1887  // calculate particle size distribution with MH97
1888  // [# m^-3 m^-1]
1889  dN[i] = IWCtopnd_MH97 ( IWC, Dme[i], t, density[i], noisy );
1890  }
1891 }
1892 
1893 /* Workspace method: Doxygen documentation will be auto-generated */
1894 void dN_H11 (//WS Output:
1895  Vector& dN,
1896  //WS Input:
1897  const Vector& Dmax,
1898  const Numeric& t,
1899  const Verbosity&)
1900 {
1901  Index n = Dmax.nelem();
1902  dN.resize(n);
1903 
1904  for ( Index i=0; i<n; i++ ) //loop over number of particles
1905  {
1906  // calculate particle size distribution for H11
1907  // [# m^-3 m^-1]
1908  dN[i] = IWCtopnd_H11 ( Dmax[i], t );
1909  }
1910 }
1911 
1912 /* Workspace method: Doxygen documentation will be auto-generated */
1913 void dN_Ar_H13 (//WS Output:
1914  Vector& dN,
1915  Vector& Ar,
1916  //WS Input:
1917  const Vector& Dmax,
1918  const Numeric& t,
1919  const Verbosity&)
1920 {
1921  Index n = Dmax.nelem();
1922  dN.resize(n);
1923  Ar.resize(n);
1924 
1925  for ( Index i=0; i<n; i++ ) //loop over number of particles
1926  {
1927  // calculate particle size distribution for H13Shape
1928  // [# m^-3 m^-1]
1929  dN[i] = IWCtopnd_H13Shape ( Dmax[i], t );
1930  // calculate Area ratio distribution for H13Shape
1931  Ar[i] = area_ratioH13 ( Dmax[i], t );
1932  }
1933 }
1934 
1935 /* Workspace method: Doxygen documentation will be auto-generated */
1936 void dN_F07TR (//WS Output:
1937  Vector& dN,
1938  //WS Input:
1939  const Vector& diameter_max,
1940  const Numeric& SWC,
1941  const Numeric& t,
1942  const Numeric& alpha,
1943  const Numeric& beta,
1944  const Verbosity&)
1945 {
1946  Index n_se = diameter_max.nelem();
1947  dN.resize(n_se);
1948 
1949  for ( Index i=0; i<n_se; i++ )
1950  {
1951  // calculate particle size distribution with MH97
1952  // [# m^-3 m^-1]
1953  dN[i] = IWCtopnd_F07TR(diameter_max[i], t, SWC, alpha, beta) ;
1954  }
1955 }
1956 
1957 /* Workspace method: Doxygen documentation will be auto-generated */
1958 void dN_F07ML (//WS Output:
1959  Vector& dN,
1960  //WS Input:
1961  const Vector& diameter_max,
1962  const Numeric& SWC,
1963  const Numeric& t,
1964  const Numeric& alpha,
1965  const Numeric& beta,
1966  const Verbosity&)
1967 {
1968  Index n_se = diameter_max.nelem();
1969  dN.resize(n_se);
1970 
1971  for ( Index i=0; i<n_se; i++ )
1972  {
1973  // calculate particle size distribution with MH97
1974  // [# m^-3 m^-1]
1975  dN[i] = IWCtopnd_F07ML(diameter_max[i], t, SWC, alpha, beta) ;
1976  }
1977 }
1978 
1979 
1980 /* Workspace method: Doxygen documentation will be auto-generated */
1981 void dN_MGD_LWC (//WS Output:
1982  Vector& dN,
1983  //WS Input:
1984  const Vector& deq,
1985  const Numeric& rho,
1986  const Numeric& LWC,
1987  const Verbosity&)
1988 {
1989  Index n_se = deq.nelem();
1990  dN.resize(n_se);
1991 
1992  for ( Index i=0; i<n_se; i++ )
1993  {
1994  // calculate particle size distribution with MH97
1995  // [# m^-3 m^-1]
1996  dN[i] = LWCtopnd_MGD_LWC( deq[i],rho ,LWC );
1997  }
1998 }
1999 
2000 /* Workspace method: Doxygen documentation will be auto-generated */
2001 void dN_MGD_IWC (//WS Output:
2002  Vector& dN,
2003  //WS Input:
2004  const Vector& deq,
2005  const Numeric& rho,
2006  const Numeric& IWC,
2007  const Verbosity&)
2008 {
2009  Index n_se = deq.nelem();
2010  dN.resize(n_se);
2011 
2012  for ( Index i=0; i<n_se; i++ )
2013  {
2014  // calculate particle size distribution with MH97
2015  // [# m^-3 m^-1]
2016  dN[i] = IWCtopnd_MGD_IWC( deq[i],rho,IWC );
2017  }
2018 }
2019 
2020 
2021 
2022 /* Workspace method: Doxygen documentation will be auto-generated */
2023 void dN_H98 (//WS Output:
2024  Vector& dN,
2025  //WS Input:
2026  const Vector& R,
2027  const Numeric& LWC,
2028  const Vector& density,
2029  const Verbosity&)
2030 {
2031  Index n = R.nelem();
2032 
2033  if ( density.nelem() != n )
2034  {
2035  ostringstream os;
2036  os << "Particle size and particle density vectors need to be of\n"
2037  << "identical size, but are not.";
2038  throw runtime_error(os.str());
2039  }
2040 
2041  dN.resize(n);
2042 
2043  for ( Index i=0; i<n; i++ )
2044  {
2045  // calculate particle size distribution for liquid
2046  // [# m^-3 m^-1]
2047  dN[i] = LWCtopnd ( LWC, density[i], R[i] );
2048  }
2049 }
2050 
2051 /* Workspace method: Doxygen documentation will be auto-generated */
2052 void dN_MP48 (//WS Output:
2053  Vector& dN,
2054  //WS Input:
2055  const Vector& Dme,
2056  const Numeric& PR,
2057  const Verbosity&)
2058 {
2059  Index n = Dme.nelem();
2060 
2061  // derive particle number density for all given sizes
2062  for ( Index i=0; i<n; i++ )
2063  {
2064  // calculate particle size distribution with MP48
2065  // output: [# m^-3 m^-1]
2066  dN[i] = PRtopnd_MP48 ( PR, Dme[i]);
2067  }
2068 }
2069 
2070 
2071 /* Workspace method: Doxygen documentation will be auto-generated */
2072 void pndFromdN (//WS Output:
2073  Vector& pnd,
2074  //WS Input:
2075  const Vector& dN,
2076  const Vector& diameter,
2077  const Numeric& total_content,
2078  const Vector& scatelem_volume,
2079  const Vector& scatelem_density,
2080  const Verbosity& verbosity)
2081 {
2082  pnd.resize( diameter.nelem() );
2083 
2084  // scale dNdD by size bin width
2085  if (diameter.nelem() > 1)
2086  scale_pnd( pnd, diameter, dN ); //[# m^-3]
2087  else
2088  pnd = dN;
2089 
2090  // scaling pnd to real mass/number density/flux (some PSDs have implicit
2091  // scaling - then this is only a check -, others don't
2092  chk_pndsum ( pnd, total_content, scatelem_volume, scatelem_density,
2093  0, 0, 0, "your field", verbosity );
2094 }
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:35
void cloudboxSetManually(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Numeric &p1, const Numeric &p2, const Numeric &lat1, const Numeric &lat2, const Numeric &lon1, const Numeric &lon2, const Verbosity &)
WORKSPACE METHOD: cloudboxSetManually.
Definition: m_cloudbox.cc:365
Numeric IWCtopnd_MGD_IWC(const Numeric d, const Numeric rho, const Numeric iwc)
Definition: cloudbox.cc:3402
void chk_massdensity_field(bool &empty_flag, const Index &dim, const Tensor3 &massdensity, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid)
Check whether hydromet grid size is equal to atmospheric grid size and if hydromet profile is zero (n...
Definition: cloudbox.cc:70
void cloudboxSetManuallyAltitude(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Tensor3 &z_field, const Vector &lat_grid, const Vector &lon_grid, const Numeric &z1, const Numeric &z2, const Numeric &lat1, const Numeric &lat2, const Numeric &lon1, const Numeric &lon2, const Verbosity &)
WORKSPACE METHOD: cloudboxSetManuallyAltitude.
Definition: m_cloudbox.cc:468
void ScatteringParticlesSelect(ArrayOfSingleScatteringData &scat_data_array, ArrayOfScatteringMetaData &scat_meta_array, ArrayOfIndex &scat_data_per_part_species, const ArrayOfString &part_species, const String &delim, const Verbosity &verbosity)
WORKSPACE METHOD: ScatteringParticlesSelect.
Definition: m_cloudbox.cc:889
Numeric LWCtopnd_MGD_LWC(const Numeric d, const Numeric rho, const Numeric lwc)
Definition: cloudbox.cc:3363
void pnd_fieldH11(Tensor4View pnd_field, const Tensor3 &IWC_field, const Tensor3 &t_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:1045
void pnd_fieldMGD_LWC(Tensor4View pnd_field, const Tensor3 &LWC_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:1821
void pnd_fieldSS70(Tensor4View pnd_field, const Tensor3 &PR_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:2278
void pnd_fieldH13(Tensor4View pnd_field, const Tensor3 &IWC_field, const Tensor3 &t_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:1165
The Agenda class.
Definition: agenda_class.h:44
const Numeric PI
Index nelem() const
Number of elements.
Definition: array.h:176
void pnd_fieldF07TR(Tensor4View pnd_field, const Tensor3 &SWC_field, const Tensor3 &t_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:1517
void parse_part_size(Numeric &sizemin, Numeric &sizemax, const String &part_string, const String &delim)
Definition: cloudbox.cc:3830
Declarations having to do with the four output streams.
Numeric IWCtopnd_F07TR(const Numeric d, const Numeric t, const Numeric swc, const Numeric alpha, const Numeric beta)
Definition: cloudbox.cc:3121
Numeric PRtopnd_MP48(const Numeric R, const Numeric D)
Definition: cloudbox.cc:3438
void pnd_fieldMH97(Tensor4View pnd_field, const Tensor3 &IWC_field, const Tensor3 &t_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:924
void chk_if_increasing(const String &x_name, const ArrayOfIndex &x)
chk_if_increasing
Definition: check_input.cc:132
void dN_MGD_LWC(Vector &dN, const Vector &deq, const Numeric &rho, const Numeric &LWC, const Verbosity &)
WORKSPACE METHOD: dN_MGD_LWC.
Definition: m_cloudbox.cc:1981
void dN_Ar_H13(Vector &dN, Vector &Ar, const Vector &Dmax, const Numeric &t, const Verbosity &)
WORKSPACE METHOD: dN_Ar_H13.
Definition: m_cloudbox.cc:1913
void ParticleType2abs_speciesAdd(ArrayOfSingleScatteringData &scat_data_array, ArrayOfGriddedField3 &vmr_field_raw, ArrayOfArrayOfSpeciesTag &abs_species, Index &propmat_clearsky_agenda_checked, Index &abs_xsec_agenda_checked, const Index &atmosphere_dim, const Vector &f_grid, const String &scat_data_file, const String &pnd_field_file, const Verbosity &verbosity)
WORKSPACE METHOD: ParticleType2abs_speciesAdd.
Definition: m_cloudbox.cc:759
The Vector class.
Definition: matpackI.h:556
Numeric IWCtopnd_H11(const Numeric d, const Numeric t)
Definition: cloudbox.cc:2921
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
void chk_scattering_meta_data(const ScatteringMetaData &scat_meta, const String &scat_meta_file, const Verbosity &verbosity)
Check scattering data meta files.
Definition: cloudbox.cc:567
void dN_F07ML(Vector &dN, const Vector &diameter_max, const Numeric &SWC, const Numeric &t, const Numeric &alpha, const Numeric &beta, const Verbosity &)
WORKSPACE METHOD: dN_F07ML.
Definition: m_cloudbox.cc:1958
The Tensor4 class.
Definition: matpackIV.h:383
The range class.
Definition: matpackI.h:148
void chk_pnd_field_raw_only_in_cloudbox(const Index &dim, const ArrayOfGriddedField3 &pnd_field_raw, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, const ArrayOfIndex &cloudbox_limits)
chk_pnd_field_raw_only_in_cloudbox
Definition: cloudbox.cc:390
void dN_F07TR(Vector &dN, const Vector &diameter_max, const Numeric &SWC, const Numeric &t, const Numeric &alpha, const Numeric &beta, const Verbosity &)
WORKSPACE METHOD: dN_F07TR.
Definition: m_cloudbox.cc:1936
void ScatteringParticleTypeAndMetaRead(ArrayOfSingleScatteringData &scat_data_array, ArrayOfScatteringMetaData &scat_meta_array, const Vector &f_grid, const String &filename_scat_data, const String &filename_scat_meta_data, const Verbosity &verbosity)
WORKSPACE METHOD: ScatteringParticleTypeAndMetaRead.
Definition: m_cloudbox.cc:835
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:69
void chk_part_species(const ArrayOfString &part_species, const String &delim)
Check validity of part_species setting.
Definition: cloudbox.cc:480
void abs_speciesAdd(ArrayOfArrayOfSpeciesTag &abs_species, Index &propmat_clearsky_agenda_checked, Index &abs_xsec_agenda_checked, const ArrayOfString &names, const Verbosity &verbosity)
WORKSPACE METHOD: abs_speciesAdd.
This file contains basic functions to handle XML data files.
void p2gridpos(ArrayOfGridPos &gp, ConstVectorView old_pgrid, ConstVectorView new_pgrid, const Numeric &extpolfac)
p2gridpos
Structure which describes the single scattering properties of a particle or a particle distribution...
Definition: optproperties.h:84
Header file for interpolation.cc.
void ParticleTypeAdd(ArrayOfSingleScatteringData &scat_data_array, ArrayOfGriddedField3 &pnd_field_raw, const Index &atmosphere_dim, const Vector &f_grid, const String &scat_data_file, const String &pnd_field_file, const Verbosity &verbosity)
WORKSPACE METHOD: ParticleTypeAdd.
Definition: m_cloudbox.cc:643
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:146
void pnd_fieldMGD_IWC(Tensor4View pnd_field, const Tensor3 &IWC_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:1970
Index nrows() const
Returns the number of rows.
Definition: matpackIV.cc:75
void parse_psd_param(String &psd_param, const String &part_string, const String &delim)
Definition: cloudbox.cc:3749
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:180
Contains sorting routines.
void parse_part_material(String &part_material, const String &part_string, const String &delim)
Definition: cloudbox.cc:3793
void ParticleTypeAddAll(ArrayOfSingleScatteringData &scat_data_array, ArrayOfGriddedField3 &pnd_field_raw, const Index &atmosphere_dim, const Vector &f_grid, const String &filelist_scat_data, const String &pnd_fieldarray_file, const Verbosity &verbosity)
WORKSPACE METHOD: ParticleTypeAddAll.
Definition: m_cloudbox.cc:705
Numeric barometric_heightformula(const Numeric &p, const Numeric &dh)
This file contains the definition of Array.
void scale_pnd(Vector &w, const Vector &x, const Vector &y)
Definition: cloudbox.cc:3469
const Index GFIELD3_LON_GRID
The implementation for String, the ARTS string class.
Definition: mystring.h:63
void chk_scattering_data(const ArrayOfSingleScatteringData &scat_data_array, const ArrayOfScatteringMetaData &scat_meta_array, const Verbosity &)
Check scattering data general.
Definition: cloudbox.cc:541
The Tensor3 class.
Definition: matpackIII.h:348
The global header file for ARTS.
#define DEBUG_ONLY(...)
Definition: debug.h:37
const Index GFIELD3_LAT_GRID
void chk_pnd_raw_data(const ArrayOfGriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files (pnd_field_raw)
Definition: cloudbox.cc:352
void pnd_fieldZero(Tensor4 &pnd_field, ArrayOfSingleScatteringData &scat_data_array, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Verbosity &)
WORKSPACE METHOD: pnd_fieldZero.
Definition: m_cloudbox.cc:1344
void chk_pndsum(Vector &pnd, const Numeric xwc, const Vector &vol, const Vector &density, const Index &p, const Index &lat, const Index &lon, const String &partfield_name, const Verbosity &verbosity)
Definition: cloudbox.cc:3517
void chk_scat_data(const SingleScatteringData &scat_data_array, const String &scat_data_file, ConstVectorView f_grid, const Verbosity &verbosity)
Check single scattering data files.
Definition: cloudbox.cc:605
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:149
void dN_H98(Vector &dN, const Vector &R, const Numeric &LWC, const Vector &density, const Verbosity &)
WORKSPACE METHOD: dN_H98.
Definition: m_cloudbox.cc:2023
#define max(a, b)
Definition: continua.cc:20461
void dN_H11(Vector &dN, const Vector &Dmax, const Numeric &t, const Verbosity &)
WORKSPACE METHOD: dN_H11.
Definition: m_cloudbox.cc:1894
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
Definition: math_funcs.cc:261
void Massdensity_cleanup(Tensor4 &massdensity_field, const Numeric &massdensity_threshold, const Verbosity &)
WORKSPACE METHOD: Massdensity_cleanup.
Definition: m_cloudbox.cc:570
#define CREATE_OUT1
Definition: messages.h:212
void FieldFromGriddedField(Matrix &field_out, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const GriddedField2 &gfraw_in, const Verbosity &)
WORKSPACE METHOD: FieldFromGriddedField.
void pnd_fieldGM58(Tensor4View pnd_field, const Tensor3 &PR_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:2110
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
void pnd_fieldExpand1D(Tensor4 &pnd_field, const Index &atmosphere_dim, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &nzero, const Verbosity &)
WORKSPACE METHOD: pnd_fieldExpand1D.
Definition: m_cloudbox.cc:1289
void xml_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads data from XML file.
Definition: xml_io.cc:831
const Joker joker
void GriddedFieldPRegrid(GriddedField3 &gfraw_out, const Vector &p_grid, const GriddedField3 &gfraw_in_orig, const Index &interp_order, const Index &zeropadding, const Verbosity &verbosity)
WORKSPACE METHOD: GriddedFieldPRegrid.
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:29
void dN_MH97(Vector &dN, const Vector &Dme, const Numeric &IWC, const Numeric &t, const Vector &density, const Index &noisy, const Verbosity &)
WORKSPACE METHOD: dN_MH97.
Definition: m_cloudbox.cc:1863
The Matrix class.
Definition: matpackI.h:788
Index nelem() const
Number of elements.
Definition: mystring.h:278
void pnd_fieldH98(Tensor4View pnd_field, const Tensor3 &LWC_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:2638
void pnd_fieldF07ML(Tensor4View pnd_field, const Tensor3 &SWC_field, const Tensor3 &t_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:1674
Numeric IWCtopnd_H13Shape(const Numeric d, const Numeric t)
Definition: cloudbox.cc:3025
void ParticleSpeciesInit(ArrayOfString &part_species, const Verbosity &)
WORKSPACE METHOD: ParticleSpeciesInit.
Definition: m_cloudbox.cc:598
void pnd_fieldH13Shape(Tensor4View pnd_field, const Tensor3 &IWC_field, const Tensor3 &t_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:1303
void pnd_fieldMP48(Tensor4View pnd_field, const Tensor3 &PR_field, const ArrayOfIndex &limits, const ArrayOfScatteringMetaData &scat_meta_array, const Index &scat_data_start, const Index &npart, const String &part_string, const String &delim, const Verbosity &verbosity)
Definition: cloudbox.cc:2449
void ParticleTypeInit(ArrayOfSingleScatteringData &scat_data_array, ArrayOfGriddedField3 &pnd_field_raw, const Verbosity &)
WORKSPACE METHOD: ParticleTypeInit.
Definition: m_cloudbox.cc:632
Numeric area_ratioH13(const Numeric d, const Numeric t)
Definition: cloudbox.cc:3078
Header file for special_interp.cc.
void particle_massesFromMetaDataSingleCategory(Matrix &particle_masses, const ArrayOfScatteringMetaData &scat_meta_array, const Verbosity &)
WORKSPACE METHOD: particle_massesFromMetaDataSingleCategory.
Definition: m_cloudbox.cc:1015
Header file for logic.cc.
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:143
void dN_MP48(Vector &dN, const Vector &Dme, const Numeric &PR, const Verbosity &)
WORKSPACE METHOD: dN_MP48.
Definition: m_cloudbox.cc:2052
This can be used to make arrays out of anything.
Definition: array.h:40
void cloudboxSetFullAtm(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Vector &p_grid, const Verbosity &)
WORKSPACE METHOD: cloudboxSetFullAtm.
Definition: m_cloudbox.cc:343
void cloudboxOff(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, Agenda &iy_cloudbox_agenda, Tensor4 &pnd_field, ArrayOfSingleScatteringData &scat_data_array, Matrix &particle_masses, const Verbosity &)
WORKSPACE METHOD: cloudboxOff.
Definition: m_cloudbox.cc:76
void particle_massesFromMetaDataAndPart_species(Matrix &particle_masses, const ArrayOfScatteringMetaData &scat_meta_array, const ArrayOfIndex &scat_data_per_part_species, const ArrayOfString &part_species, const Verbosity &)
WORKSPACE METHOD: particle_massesFromMetaDataAndPart_species.
Definition: m_cloudbox.cc:1055
void chk_if_in_range(const String &x_name, const Index &x, const Index &x_low, const Index &x_high)
chk_if_in_range
Definition: check_input.cc:101
void set_name(const String &nname)
Set agenda name.
void parse_partfield_name(String &partfield_name, const String &part_string, const String &delim)
Definition: cloudbox.cc:3700
Numeric IWCtopnd_MH97(const Numeric iwc, const Numeric dm, const Numeric t, const Numeric density, const bool noisy)
Definition: cloudbox.cc:2755
void resize(Index n)
Assignment operator from VectorView.
Definition: matpackI.cc:798
const Index GFIELD3_P_GRID
#define min(a, b)
Definition: continua.cc:20460
A constant view of a Vector.
Definition: matpackI.h:292
Numeric IWCtopnd_F07ML(const Numeric d, const Numeric t, const Numeric swc, const Numeric alpha, const Numeric beta)
Definition: cloudbox.cc:3215
void pnd_fieldSetup(Tensor4 &pnd_field, const Index &atmosphere_dim, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Tensor4 &massdensity_field, const Tensor3 &t_field, const ArrayOfScatteringMetaData &scat_meta_array, const ArrayOfString &part_species, const ArrayOfIndex &scat_data_per_part_species, const String &delim, const Verbosity &verbosity)
WORKSPACE METHOD: pnd_fieldSetup.
Definition: m_cloudbox.cc:1388
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:63
void pnd_fieldCalc(Tensor4 &pnd_field, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfGriddedField3 &pnd_field_raw, const Index &atmosphere_dim, const ArrayOfIndex &cloudbox_limits, const Index &zeropadding, const Verbosity &verbosity)
WORKSPACE METHOD: pnd_fieldCalc.
Definition: m_cloudbox.cc:1092
void chk_pnd_data(const GriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files.
Definition: cloudbox.cc:294
Implementation of gridded fields.
#define CREATE_OUT0
Definition: messages.h:211
#define beta
Definition: continua.cc:21194
#define CREATE_OUT3
Definition: messages.h:214
void dN_MGD_IWC(Vector &dN, const Vector &deq, const Numeric &rho, const Numeric &IWC, const Verbosity &)
WORKSPACE METHOD: dN_MGD_IWC.
Definition: m_cloudbox.cc:2001
Internal cloudbox functions.
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:81
void pndFromdN(Vector &pnd, const Vector &dN, const Vector &diameter, const Numeric &total_content, const Vector &scatelem_volume, const Vector &scatelem_density, const Verbosity &verbosity)
WORKSPACE METHOD: pndFromdN.
Definition: m_cloudbox.cc:2072
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
void ParticleSpeciesSet(ArrayOfString &part_species, const ArrayOfString &particle_tags, const String &delim, const Verbosity &verbosity)
WORKSPACE METHOD: ParticleSpeciesSet.
Definition: m_cloudbox.cc:606
void chk_atm_grids(const Index &dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid)
chk_atm_grids
#define CREATE_OUT2
Definition: messages.h:213
Scattering database structure and functions.
Numeric LWCtopnd(const Numeric lwc, const Numeric density, const Numeric r)
Definition: cloudbox.cc:3305
void cloudboxSetAutomatically(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor4 &massdensity_field, const Numeric &cloudbox_margin, const Verbosity &verbosity)
WORKSPACE METHOD: cloudboxSetAutomatically.
Definition: m_cloudbox.cc:97
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1403
Declaration of functions in rte.cc.
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1580