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";
128 const Index n_current_species = current_species.
nelem();
129 const Index n_current_f_grid = current_f_grid.
nelem();
137 out2 <<
" Original table: " << n_species <<
" species, "
138 << n_f_grid <<
" frequencies.\n"
139 <<
" Adapt to: " << n_current_species <<
" species, "
140 << n_current_f_grid <<
" frequencies.\n";
144 out2 <<
" Table contains no nonlinear species.\n";
149 for (
Index s=0; s<n_nls; ++s )
156 out2 <<
" Table contains no temperature perturbations.\n";
168 if ( 0 == n_species )
171 os <<
"The lookup table should have at least one species.";
172 throw runtime_error( os.str() );
180 os <<
"The table must not have duplicate nonlinear species.\n"
182 throw runtime_error( os.str() );
186 for (
Index i=0; i<n_nls; ++i )
189 os <<
"nonlinear_species[" << i <<
"]";
221 if ( 0 == n_nls_pert )
224 os <<
"The vector nls_pert should contain the perturbations\n"
225 <<
"for the nonlinear species, but it is empty.";
226 throw runtime_error( os.str() );
278 + n_nls * ( n_nls_pert - 1 );
289 for (
Index i=0,sp=0; i<n_species; ++i)
291 original_spec_pos_in_xsec[i] = sp;
292 if (non_linear[i]) sp += n_nls_pert;
301 if ( 0==n_current_species )
304 os <<
"The list of current species should not be empty.";
305 throw runtime_error( os.str() );
316 out3 <<
" Looking for species in lookup table:\n";
317 for (
Index i=0; i<n_current_species; ++i )
323 i_current_species[i] =
329 Index n_current_nonlinear_species = 0;
335 out3 <<
" Finding out which of the current species are nonlinear:\n";
336 for (
Index i=0; i<n_current_species; ++i )
339 if (non_linear[i_current_species[i]])
343 current_non_linear[i] = 1;
344 ++n_current_nonlinear_species;
356 out3 <<
" Looking for Frequencies in lookup table:\n";
371 new_table.
species.resize( n_current_species );
372 for (
Index i=0; i<n_current_species; ++i )
377 if (current_non_linear[i])
383 for (
Index i=0; i<n_current_f_grid; ++i )
395 for (
Index i=0; i<n_current_species; ++i )
421 n_current_species+n_current_nonlinear_species*(n_nls_pert-1),
430 for (
Index i_s=0,sp=0; i_s<n_current_species; ++i_s )
434 if (current_non_linear[i_s])
443 for (
Index i_f=0; i_f<n_current_f_grid; ++i_f )
451 Range(original_spec_pos_in_xsec[i_current_species[i_s]],n_v),
452 i_current_f_grid[i_f],
518 const Index& p_interp_order,
519 const Index& t_interp_order,
520 const Index& h2o_interp_order,
521 const Index& f_index,
556 Index h2o_index = -1;
566 if ( h2o_index == -1 )
569 os <<
"With nonlinear species, at least one species must be a H2O species.";
570 throw runtime_error( os.str() );
583 if ( 0 == n_t_pert ) a = 1;
585 b = n_species + n_nls * ( n_nls_pert - 1 );
605 os <<
"The lookup table internal variable log_p_grid is not initialized.\n"
606 <<
"Use the abs_lookupAdapt method!";
607 throw runtime_error( os.str() );
616 if ( (n_p_grid < p_interp_order+1) )
619 os <<
"The number of pressure grid points in the table ("
620 << n_p_grid <<
") is not enough for the desired order of interpolation ("
621 << p_interp_order <<
").";
622 throw runtime_error( os.str() );
625 if ( (n_nls_pert != 0) && (n_nls_pert < h2o_interp_order+1) )
628 os <<
"The number of humidity perturbation grid points in the table ("
629 << n_nls_pert <<
") is not enough for the desired order of interpolation ("
630 << h2o_interp_order <<
").";
631 throw runtime_error( os.str() );
634 if ( (n_t_pert != 0) && (n_t_pert < t_interp_order+1) )
637 os <<
"The number of temperature perturbation grid points in the table ("
638 << n_t_pert <<
") is not enough for the desired order of interpolation ("
639 << t_interp_order <<
").";
640 throw runtime_error( os.str() );
647 if ( !
is_size( abs_vmrs, n_species ) )
650 os <<
"Number of species in lookup table does not match number\n"
651 <<
"of species for which you want to extract absorption.\n"
652 <<
"Have you used abs_lookupAdapt?";
653 throw runtime_error( os.str() );
660 Index f_start, f_extent;
673 if ( f_index >= n_f_grid )
676 os <<
"Problem with gas absorption lookup table.\n"
677 <<
"Frequency index f_index is too high, you have " << f_index
678 <<
", the largest allowed value is " << n_f_grid-1 <<
".";
679 throw runtime_error( os.str() );
685 const Range f_range(f_start,f_extent);
690 for (
Index s=0; s<n_nls; ++s )
708 if ( ( p > p_max ) ||
712 os <<
"Problem with gas absorption lookup table.\n"
713 <<
"Pressure p is outside the range covered by the lookup table.\n"
714 <<
"Your p value is " << p <<
" Pa.\n"
715 <<
"The allowed range is " << p_min <<
" to " << p_max <<
".\n"
716 <<
"The pressure grid range in the table is " <<
p_grid[n_p_grid-1]
717 <<
" to " <<
p_grid[0] <<
".\n"
718 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
719 throw runtime_error( os.str() );
735 pitw.
resize(p_interp_order+1);
746 xsec_pre_interpolated.
resize( p_interp_order+1, f_extent, n_species );
748 for (
Index pi=0; pi<p_interp_order+1; ++pi )
751 const Index this_p_grid_index = pgp[0].idx[pi];
755 const Index do_T = n_t_pert;
790 const Numeric effective_T_ref =
t_ref[this_p_grid_index];
793 const Numeric T_offset = T - effective_T_ref;
801 if ( ( T_offset > t_max ) ||
802 ( T_offset < t_min ) )
805 os <<
"Problem with gas absorption lookup table.\n"
806 <<
"Temperature T is outside the range covered by the lookup table.\n"
807 <<
"Your temperature was " << T
808 <<
" K at a pressure of " << p <<
" Pa.\n"
809 <<
"The temperature offset value is " << T_offset <<
".\n"
810 <<
"The allowed range is " << t_min <<
" to " << t_max <<
".\n"
811 <<
"The temperature perturbation grid range in the table is "
813 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
814 throw runtime_error( os.str() );
846 const Numeric effective_vmr_ref =
vmrs_ref(h2o_index, this_p_grid_index);
850 const Numeric VMR_frac = abs_vmrs[h2o_index] / effective_vmr_ref;
859 if ( ( VMR_frac > x_max ) ||
860 ( VMR_frac < x_min ) )
863 os <<
"Problem with gas absorption lookup table.\n"
864 <<
"VMR for H2O (species " << h2o_index
865 <<
") is outside the range covered by the lookup table.\n"
866 <<
"Your VMR was " << abs_vmrs[h2o_index]
867 <<
" at a pressure of " << p <<
" Pa.\n"
868 <<
"The reference VMR value there is " << effective_vmr_ref <<
"\n"
869 <<
"The fractional VMR relative to the reference value is "
871 <<
"The allowed range is " << x_min <<
" to " << x_max <<
".\n"
872 <<
"The fractional VMR perturbation grid range in the table is "
874 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
875 throw runtime_error( os.str() );
885 for (
Index si=0; si<n_species; ++si )
889 const Index do_VMR = non_linear[si];
911 itw.
resize( (t_interp_order+1)*
912 (h2o_interp_order+1) );
919 Range(fpi,n_nls_pert),
932 for (
Index r=0; r<t_interp_order+1; ++r )
933 for (
Index c=0; c<h2o_interp_order+1; ++c )
935 for (
Index f=0; f<f_extent; ++f )
936 res[f] += itw[iti] * this_xsec( tgp[0].idx[r], vgp[0].idx[c], f );
948 itw.
resize(t_interp_order+1);
968 for (
Index r=0; r<t_interp_order+1; ++r )
970 for (
Index f=0; f<f_extent; ++f )
971 res[f] += itw[iti] * this_xsec( tgp[0].idx[r], f );
984 itw.
resize(h2o_interp_order+1);
991 Range(fpi,n_nls_pert),
1004 for (
Index c=0; c<h2o_interp_order+1; ++c )
1006 for (
Index f=0; f<f_extent; ++f )
1007 res[f] += itw[iti] * this_xsec( vgp[0].idx[c], f );
1019 res =
xsec(0,fpi,f_range,this_p_grid_index);
1044 sga.
resize(f_extent, n_species);
1046 for (
Index pi=0; pi<p_interp_order+1; ++pi )
1059 for (
Index si=0; si<n_species; ++si )
1060 sga(
Range(
joker),si) *= ( n * abs_vmrs[si] );
1081 os <<
"GasAbsLookup: Output operator not implemented";