58 assert( n_new_grid == pos.
nelem() );
68 for (
Index i=0; i<n_new_grid; ++i )
74 while (
abs(new_grid[i]-old_grid[j]) > tolerance )
80 os <<
"Cannot find new frequency " << i
81 <<
" (" << new_grid[i] <<
"Hz) in the lookup table frequency grid.";
82 throw runtime_error( os.str() );
87 out3 <<
" " << new_grid[i] <<
" found, index = " << pos[i] <<
".\n";
132 const Index n_current_species = current_species.
nelem();
133 const Index n_current_f_grid = current_f_grid.
nelem();
141 out2 <<
" Original table: " << n_species <<
" species, " 142 << n_f_grid <<
" frequencies.\n" 143 <<
" Adapt to: " << n_current_species <<
" species, " 144 << n_current_f_grid <<
" frequencies.\n";
148 out2 <<
" Table contains no nonlinear species.\n";
153 for (
Index s=0; s<n_nls; ++s )
160 out2 <<
" Table contains no temperature perturbations.\n";
172 if ( 0 == n_species )
175 os <<
"The lookup table should have at least one species.";
176 throw runtime_error( os.str() );
184 os <<
"The table must not have duplicate nonlinear species.\n" 186 throw runtime_error( os.str() );
190 for (
Index i=0; i<n_nls; ++i )
193 os <<
"nonlinear_species[" << i <<
"]";
225 if ( 0 == n_nls_pert )
228 os <<
"The vector nls_pert should contain the perturbations\n" 229 <<
"for the nonlinear species, but it is empty.";
230 throw runtime_error( os.str() );
282 + n_nls * ( n_nls_pert - 1 );
293 for (
Index i=0,sp=0; i<n_species; ++i)
295 original_spec_pos_in_xsec[i] = sp;
296 if (non_linear[i]) sp += n_nls_pert;
305 if ( 0==n_current_species )
308 os <<
"The list of current species should not be empty.";
309 throw runtime_error( os.str() );
320 out3 <<
" Looking for species in lookup table:\n";
321 for (
Index i=0; i<n_current_species; ++i )
326 i_current_species[i] =
332 const Index spec_type = current_species[i][0].Type();
338 i_current_species[i] = -1;
344 <<
" is missing in absorption lookup table.";
345 throw runtime_error( os.str() );
349 out3 <<
"found (or trivial).\n";
353 Index n_current_nonlinear_species = 0;
359 out3 <<
" Finding out which of the current species are nonlinear:\n";
360 for (
Index i=0; i<n_current_species; ++i )
362 if (i_current_species[i]>=0)
365 if (non_linear[i_current_species[i]])
369 current_non_linear[i] = 1;
370 ++n_current_nonlinear_species;
383 out3 <<
" Looking for Frequencies in lookup table:\n";
398 new_table.
species.resize( n_current_species );
399 for (
Index i=0; i<n_current_species; ++i )
401 if (i_current_species[i]>=0)
406 if (current_non_linear[i])
414 new_table.
species[i] = current_species[i];
420 for (
Index i=0; i<n_current_f_grid; ++i )
432 for (
Index i=0; i<n_current_species; ++i )
434 if (i_current_species[i]>=0)
465 n_current_species+n_current_nonlinear_species*(n_nls_pert-1),
474 for (
Index i_s=0,sp=0; i_s<n_current_species; ++i_s )
478 if (current_non_linear[i_s])
487 for (
Index i_f=0; i_f<n_current_f_grid; ++i_f )
489 if (i_current_species[i_s]>=0)
497 Range(original_spec_pos_in_xsec[i_current_species[i_s]],n_v),
498 i_current_f_grid[i_f],
594 const Index& p_interp_order,
595 const Index& t_interp_order,
596 const Index& h2o_interp_order,
597 const Index& f_interp_order,
602 const Numeric& extpolfac)
const 626 const Index n_new_f_grid = new_f_grid.
nelem();
637 Index h2o_index = -1;
647 if ( h2o_index == -1 )
650 os <<
"With nonlinear species, at least one species must be a H2O species.";
651 throw runtime_error( os.str() );
664 if ( 0 == n_t_pert ) a = 1;
666 b = n_species + n_nls * ( n_nls_pert - 1 );
686 os <<
"The lookup table internal variable log_p_grid is not initialized.\n" 687 <<
"Use the abs_lookupAdapt method!";
688 throw runtime_error( os.str() );
697 if ( (n_p_grid < p_interp_order+1) )
700 os <<
"The number of pressure grid points in the table (" 701 << n_p_grid <<
") is not enough for the desired order of interpolation (" 702 << p_interp_order <<
").";
703 throw runtime_error( os.str() );
706 if ( (n_nls_pert != 0) && (n_nls_pert < h2o_interp_order+1) )
709 os <<
"The number of humidity perturbation grid points in the table (" 710 << n_nls_pert <<
") is not enough for the desired order of interpolation (" 711 << h2o_interp_order <<
").";
712 throw runtime_error( os.str() );
715 if ( (n_t_pert != 0) && (n_t_pert < t_interp_order+1) )
718 os <<
"The number of temperature perturbation grid points in the table (" 719 << n_t_pert <<
") is not enough for the desired order of interpolation (" 720 << t_interp_order <<
").";
721 throw runtime_error( os.str() );
724 if ( (n_f_grid < f_interp_order+1) )
727 os <<
"The number of frequency grid points in the table (" 728 << n_f_grid <<
") is not enough for the desired order of interpolation (" 729 << f_interp_order <<
").";
730 throw runtime_error( os.str() );
737 if ( !
is_size( abs_vmrs, n_species ) )
740 os <<
"Number of species in lookup table does not match number\n" 741 <<
"of species for which you want to extract absorption.\n" 742 <<
"Have you used abs_lookupAdapt? Or did you miss to add\n" 743 <<
"some VRM fields (e.g. for free electrons or particles)?\n";
744 throw runtime_error( os.str() );
761 if (f_interp_order==0)
763 if (n_new_f_grid==n_f_grid) {
777 os <<
"First frequency in f_grid inconsistent with lookup table.\n" 778 <<
"f_grid[0] = " <<
f_grid[0] <<
"\n" 779 <<
"new_f_grid[0] = " << new_f_grid[0] <<
".";
780 throw runtime_error( os.str() );
783 if (
abs(
f_grid[n_f_grid-1]-new_f_grid[n_new_f_grid-1]) > 1)
787 os <<
"Last frequency in f_grid inconsistent with lookup table.\n" 788 <<
"f_grid[n_f_grid-1] = " <<
f_grid[n_f_grid-1] <<
"\n" 789 <<
"new_f_grid[n_new_f_grid-1] = " << new_f_grid[n_new_f_grid-1] <<
".";
790 throw runtime_error( os.str() );
793 else if (n_new_f_grid==1) {
799 if (fgp_local[0].
w[0]!=1)
802 os <<
"Cannot find a matching lookup table frequency for frequency\n" 803 << new_f_grid[0] <<
".";
804 throw runtime_error( os.str() );
809 os <<
"With f_interp_order 0 the frequency grid has to have the same\n" 810 <<
"size as in the lookup table, or exactly one element.";
811 throw runtime_error( os.str() );
818 fgp_local.resize(n_new_f_grid);
827 const Index do_T = n_t_pert;
832 for (
Index s=0; s<n_nls; ++s )
850 if ( ( p > p_max ) ||
854 os <<
"Problem with gas absorption lookup table.\n" 855 <<
"Pressure p is outside the range covered by the lookup table.\n" 856 <<
"Your p value is " << p <<
" Pa.\n" 857 <<
"The allowed range is " << p_min <<
" to " << p_max <<
".\n" 858 <<
"The pressure grid range in the table is " <<
p_grid[n_p_grid-1]
859 <<
" to " <<
p_grid[0] <<
".\n" 860 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
861 throw runtime_error( os.str() );
877 pitw.
resize(p_interp_order+1);
886 gp_trivial[0].idx.resize(1);
887 gp_trivial[0].w.resize(1);
888 gp_trivial[0].idx[0] = 0;
889 gp_trivial[0].w[0] = 1;
896 Index this_t_interp_order;
899 this_t_interp_order = t_interp_order;
906 this_t_interp_order = 0;
936 xsec_pre_interpolated.
resize(p_interp_order+1, n_species,
937 1, 1, n_new_f_grid );
942 Tensor4 itw_withH2O, itw_noH2O, *itw;
944 for (
Index pi=0; pi<p_interp_order+1; ++pi )
964 const Index this_p_grid_index = pgp[0].idx[pi];
998 const Numeric effective_T_ref =
t_ref[this_p_grid_index];
1001 const Numeric T_offset = T - effective_T_ref;
1009 if ( ( T_offset > t_max ) ||
1010 ( T_offset < t_min ) )
1013 os <<
"Problem with gas absorption lookup table.\n" 1014 <<
"Temperature T is outside the range covered by the lookup table.\n" 1015 <<
"Your temperature was " << T
1016 <<
" K at a pressure of " << p <<
" Pa.\n" 1017 <<
"The temperature offset value is " << T_offset <<
".\n" 1018 <<
"The allowed range is " << t_min <<
" to " << t_max <<
".\n" 1019 <<
"The temperature perturbation grid range in the table is " 1021 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
1022 throw runtime_error( os.str() );
1053 const Numeric effective_vmr_ref =
vmrs_ref(h2o_index, this_p_grid_index);
1057 const Numeric VMR_frac = abs_vmrs[h2o_index] / effective_vmr_ref;
1066 if ( ( VMR_frac > x_max ) ||
1067 ( VMR_frac < x_min ) )
1070 os <<
"Problem with gas absorption lookup table.\n" 1071 <<
"VMR for H2O (species " << h2o_index
1072 <<
") is outside the range covered by the lookup table.\n" 1073 <<
"Your VMR was " << abs_vmrs[h2o_index]
1074 <<
" at a pressure of " << p <<
" Pa.\n" 1075 <<
"The reference VMR value there is " << effective_vmr_ref <<
"\n" 1076 <<
"The fractional VMR relative to the reference value is " 1077 << VMR_frac <<
".\n" 1078 <<
"The allowed range is " << x_min <<
" to " << x_max <<
".\n" 1079 <<
"The fractional VMR perturbation grid range in the table is " 1081 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
1082 throw runtime_error( os.str() );
1092 if (n_nls<n_species) {
1096 itw_noH2O.
resize(1, 1, n_new_f_grid,
1097 (this_t_interp_order+1)*
1099 (f_interp_order+1));
1105 itw_withH2O.
resize(1, 1, n_new_f_grid,
1106 (this_t_interp_order+1)*
1107 (h2o_interp_order+1)*
1108 (f_interp_order+1));
1114 for (
Index si=0; si<n_species; ++si )
1118 const Index do_VMR = non_linear[si];
1137 os <<
"Problem with gas absorption lookup table.\n" 1138 <<
"VMR interpolation is not allowed for species \"" 1139 <<
species[si][0].Name() <<
"\"";
1140 throw runtime_error(os.str());
1148 Index this_h2o_extent;
1151 this_h2o_extent = n_nls_pert;
1155 this_h2o_extent = 1;
1162 Range(fpi,this_h2o_extent),
1164 this_p_grid_index );
1194 sga.
resize(n_species, n_new_f_grid);
1196 for (
Index pi=0; pi<p_interp_order+1; ++pi )
1205 xsec_pre_interpolated(pi,
1213 sga += xsec_pre_interpolated(pi,
Range(
joker),
1221 for (
Index si=0; si<n_species; ++si )
1222 sga(si,
Range(
joker)) *= ( n * abs_vmrs[si] );
1244 os <<
"GasAbsLookup: Output operator not implemented";
INDEX Index
The type to use for all integer numbers and indices.
void find_new_grid_in_old_grid(ArrayOfIndex &pos, ConstVectorView old_grid, ConstVectorView new_grid, const Verbosity &verbosity)
Find positions of new grid points in old grid.
Index nelem() const
Number of elements.
Vector nls_pert
The vector of perturbations for the VMRs of the nonlinear species.
void resize(Index s, Index b, Index p, Index r, Index c)
Resize function.
Vector t_pert
The vector of temperature perturbations [K].
Declarations having to do with the four output streams.
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
ostream & operator<<(ostream &os, const GasAbsLookup &)
Output operatior for GasAbsLookup.
Index npages() const
Returns the number of pages.
cmplx FADDEEVA() w(cmplx z, double relerr)
ArrayOfIndex nonlinear_species
The species tags with non-linear treatment.
Header file for interpolation.cc.
void Adapt(const ArrayOfArrayOfSpeciesTag ¤t_species, ConstVectorView current_f_grid, const Verbosity &verbosity)
Adapt lookup table to current calculation.
Vector log_p_grid
The natural log of the pressure grid.
Numeric number_density(const Numeric &p, const Numeric &t)
number_density
Index nelem() const
Returns the number of elements.
bool is_unique(const ArrayOfIndex &x)
Checks if an ArrayOfIndex is unique, i.e., has no duplicate values.
Tensor4 xsec
Absorption cross sections.
Matrix vmrs_ref
The reference VMR profiles.
Vector f_grid
The frequency grid [Hz].
An absorption lookup table.
const Vector & GetFgrid() const
NUMERIC Numeric
The type to use for all floating point numbers.
Declarations for the gas absorption lookup table.
void gridpos_poly(ArrayOfGridPosPoly &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Index order, const Numeric &extpolfac)
Set up grid positions for higher order interpolation.
Index species_index_from_species_name(String name)
Return species index for given species name.
Vector t_ref
The reference temperature profile [K].
Header file for logic.cc.
Vector p_grid
The pressure grid for the table [Pa].
This can be used to make arrays out of anything.
Header file for interpolation_poly.cc.
void Extract(Matrix &sga, const Index &p_interp_order, const Index &t_interp_order, const Index &h2o_interp_order, const Index &f_interp_order, const Numeric &p, const Numeric &T, ConstVectorView abs_vmrs, ConstVectorView new_f_grid, const Numeric &extpolfac) const
Extract scalar gas absorption coefficients from the lookup table.
The class MakeVector is a special kind of Vector that can be initialized explicitly from one or more ...
void resize(Index n)
Assignment operator from VectorView.
A constant view of a Tensor3.
A constant view of a Vector.
const Vector & GetPgrid() const
Index nbooks() const
Returns the number of books.
void transform(VectorView y, double(&my_func)(double), ConstVectorView x)
A generic transform function for vectors, which can be used to implement mathematical functions opera...
ArrayOfGridPosPoly fgp_default
Frequency grid positions.
Subclasses of runtime_error.
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
Index ncols() const
Returns the number of columns.
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
ArrayOfArrayOfSpeciesTag species
The species tags for which the table is valid.
void resize(Index b, Index p, Index r, Index c)
Resize function.
void resize(Index r, Index c)
Resize function.