58 assert(n_new_grid == pos.
nelem());
64 for (
Index i = 0; i < n_new_grid; ++i) {
69 while (
abs(new_grid[i] - old_grid[j]) >
70 max(
abs(new_grid[i]),
abs(old_grid[j])) * DBL_EPSILON) {
72 if (j >= n_old_grid) {
74 os <<
"Cannot find new frequency " << i <<
" (" << new_grid[i]
75 <<
"Hz) in the lookup table frequency grid.";
76 throw runtime_error(os.str());
81 out3 <<
" " << new_grid[i] <<
" found, index = " << pos[i] <<
".\n";
125 const Index n_current_species = current_species.
nelem();
126 const Index n_current_f_grid = current_f_grid.
nelem();
134 out2 <<
" Original table: " << n_species <<
" species, " << n_f_grid
136 <<
" Adapt to: " << n_current_species <<
" species, "
137 << n_current_f_grid <<
" frequencies.\n";
140 out2 <<
" Table contains no nonlinear species.\n";
145 for (
Index s = 0; s < n_nls; ++s) {
150 out2 <<
" Table contains no temperature perturbations.\n";
162 if (0 == n_species) {
164 os <<
"The lookup table should have at least one species.";
165 throw runtime_error(os.str());
172 os <<
"The table must not have duplicate nonlinear species.\n"
174 throw runtime_error(os.str());
178 for (
Index i = 0; i < n_nls; ++i) {
180 os <<
"nonlinear_species[" << i <<
"]";
206 if (0 == n_nls_pert) {
208 os <<
"The vector nls_pert should contain the perturbations\n"
209 <<
"for the nonlinear species, but it is empty.";
210 throw runtime_error(os.str());
229 chk_size(
"xsec",
xsec, 1, n_species, n_f_grid, n_p_grid);
247 Index b = n_species + n_nls * (n_nls_pert - 1);
258 for (
Index i = 0, sp = 0; i < n_species; ++i) {
259 original_spec_pos_in_xsec[i] = sp;
269 if (0 == n_current_species) {
271 os <<
"The list of current species should not be empty.";
272 throw runtime_error(os.str());
282 out3 <<
" Looking for species in lookup table:\n";
283 for (
Index i = 0; i < n_current_species; ++i) {
287 i_current_species[i] =
292 const Index spec_type = current_species[i][0].Type();
297 i_current_species[i] = -1;
301 <<
" is missing in absorption lookup table.";
302 throw runtime_error(os.str());
306 out3 <<
"found (or trivial).\n";
310 Index n_current_nonlinear_species = 0;
316 out3 <<
" Finding out which of the current species are nonlinear:\n";
317 for (
Index i = 0; i < n_current_species; ++i) {
318 if (i_current_species[i] >= 0)
321 if (non_linear[i_current_species[i]]) {
324 current_non_linear[i] = 1;
325 ++n_current_nonlinear_species;
338 out3 <<
" Looking for Frequencies in lookup table:\n";
350 new_table.
species.resize(n_current_species);
351 for (
Index i = 0; i < n_current_species; ++i) {
352 if (i_current_species[i] >= 0) {
361 new_table.
species[i] = current_species[i];
367 for (
Index i = 0; i < n_current_f_grid; ++i) {
377 for (
Index i = 0; i < n_current_species; ++i) {
378 if (i_current_species[i] >= 0) {
406 n_current_species + n_current_nonlinear_species * (n_nls_pert - 1),
415 for (
Index i_s = 0, sp = 0; i_s < n_current_species; ++i_s) {
418 if (current_non_linear[i_s])
427 for (
Index i_f = 0; i_f < n_current_f_grid; ++i_f) {
428 if (i_current_species[i_s] >= 0) {
431 Range(original_spec_pos_in_xsec[i_current_species[i_s]], n_v),
432 i_current_f_grid[i_f],
516 const Index& p_interp_order,
517 const Index& t_interp_order,
518 const Index& h2o_interp_order,
519 const Index& f_interp_order,
524 const Numeric& extpolfac)
const {
547 const Index n_new_f_grid = new_f_grid.
nelem();
558 Index h2o_index = -1;
567 if (h2o_index == -1) {
569 os <<
"With nonlinear species, at least one species must be a H2O species.";
570 throw runtime_error(os.str());
587 b = n_species + n_nls * (n_nls_pert - 1);
606 os <<
"The lookup table internal variable log_p_grid is not initialized.\n"
607 <<
"Use the abs_lookupAdapt method!";
608 throw runtime_error(os.str());
617 if ((n_p_grid < p_interp_order + 1)) {
619 os <<
"The number of pressure grid points in the table (" << n_p_grid
620 <<
") 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)) {
627 os <<
"The number of humidity perturbation grid points in the table ("
629 <<
") 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)) {
636 os <<
"The number of temperature perturbation grid points in the table ("
637 << n_t_pert <<
") is not enough for the desired order of interpolation ("
638 << t_interp_order <<
").";
639 throw runtime_error(os.str());
642 if ((n_f_grid < f_interp_order + 1)) {
644 os <<
"The number of frequency grid points in the table (" << n_f_grid
645 <<
") is not enough for the desired order of interpolation ("
646 << f_interp_order <<
").";
647 throw runtime_error(os.str());
655 os <<
"Number of species in lookup table does not match number\n"
656 <<
"of species for which you want to extract absorption.\n"
657 <<
"Have you used abs_lookupAdapt? Or did you miss to add\n"
658 <<
"some VRM fields (e.g. for free electrons or particles)?\n";
659 throw runtime_error(os.str());
675 if (f_interp_order == 0) {
682 const Numeric allowed_f_margin = 0.09;
684 if (n_new_f_grid == n_f_grid) {
690 if (
abs(
f_grid[0] - new_f_grid[0]) > allowed_f_margin)
693 os <<
"First frequency in f_grid inconsistent with lookup table.\n"
694 <<
"f_grid[0] = " <<
f_grid[0] <<
"\n"
695 <<
"new_f_grid[0] = " << new_f_grid[0] <<
".";
696 throw runtime_error(os.str());
700 if (
abs(
f_grid[n_f_grid - 1] - new_f_grid[n_new_f_grid - 1]) > allowed_f_margin)
703 os <<
"Last frequency in f_grid inconsistent with lookup table.\n"
704 <<
"f_grid[n_f_grid-1] = " <<
f_grid[n_f_grid - 1]
706 <<
"new_f_grid[n_new_f_grid-1] = " << new_f_grid[n_new_f_grid - 1]
708 throw runtime_error(os.str());
710 }
else if (n_new_f_grid == 1) {
716 if (
abs(
f_grid[fgp_local[0].idx[0]] - new_f_grid[0]) > allowed_f_margin)
719 os <<
"Cannot find a matching lookup table frequency for frequency "
720 << new_f_grid[0] <<
".\n"
721 <<
"(This check has not been properly tested, so perhaps this is\n"
722 <<
"a false alarm. Check for this in file gas_abs_lookup.cc.)";
723 throw runtime_error(os.str());
727 os <<
"With f_interp_order 0 the frequency grid has to have the same\n"
728 <<
"size as in the lookup table, or exactly one element.";
729 throw runtime_error(os.str());
735 if (new_f_grid[0] < f_min) {
737 os <<
"Problem with gas absorption lookup table.\n"
738 <<
"At least one frequency is outside the range covered by the lookup table.\n"
739 <<
"Your new frequency value is " << new_f_grid[0] <<
" Hz.\n"
740 <<
"The allowed range is " << f_min <<
" to " << f_max <<
" Hz.";
741 throw runtime_error(os.str());
743 if (new_f_grid[n_new_f_grid - 1] > f_max) {
745 os <<
"Problem with gas absorption lookup table.\n"
746 <<
"At least one frequency is outside the range covered by the lookup table.\n"
747 <<
"Your new frequency value is " << new_f_grid[n_new_f_grid - 1]
749 <<
"The allowed range is " << f_min <<
" to " << f_max <<
" Hz.";
750 throw runtime_error(os.str());
755 fgp_local.resize(n_new_f_grid);
763 const Index do_T = n_t_pert;
767 for (
Index s = 0; s < n_nls; ++s) {
783 if ((p > p_max) || (p < p_min)) {
785 os <<
"Problem with gas absorption lookup table.\n"
786 <<
"Pressure p is outside the range covered by the lookup table.\n"
787 <<
"Your p value is " << p <<
" Pa.\n"
788 <<
"The allowed range is " << p_min <<
" to " << p_max <<
".\n"
789 <<
"The pressure grid range in the table is " <<
p_grid[n_p_grid - 1]
790 <<
" to " <<
p_grid[0] <<
".\n"
791 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
792 throw runtime_error(os.str());
804 pitw.
resize(p_interp_order + 1);
812 gp_trivial[0].idx.resize(1);
813 gp_trivial[0].w.resize(1);
814 gp_trivial[0].idx[0] = 0;
815 gp_trivial[0].w[0] = 1;
822 Index this_t_interp_order;
824 this_t_interp_order = t_interp_order;
829 this_t_interp_order = 0;
857 xsec_pre_interpolated.
resize(
858 p_interp_order + 1, n_species, 1, 1, n_new_f_grid);
863 Tensor4 itw_withH2O, itw_noH2O, *itw;
865 for (
Index pi = 0; pi < p_interp_order + 1; ++pi) {
884 const Index this_p_grid_index = pgp[0].idx[pi];
916 const Numeric effective_T_ref =
t_ref[this_p_grid_index];
919 const Numeric T_offset = T - effective_T_ref;
928 extpolfac * (
t_pert[n_t_pert - 1] -
t_pert[n_t_pert - 2]);
929 if ((T_offset > t_max) || (T_offset < t_min)) {
931 os <<
"Problem with gas absorption lookup table.\n"
932 <<
"Temperature T is outside the range covered by the lookup table.\n"
933 <<
"Your temperature was " << T <<
" K at a pressure of " << p
935 <<
"The temperature offset value is " << T_offset <<
".\n"
936 <<
"The allowed range is " << t_min <<
" to " << t_max <<
".\n"
937 <<
"The temperature perturbation grid range in the table is "
939 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
940 throw runtime_error(os.str());
970 const Numeric effective_vmr_ref =
vmrs_ref(h2o_index, this_p_grid_index);
984 if ((VMR_frac > x_max) || (VMR_frac < x_min)) {
986 os <<
"Problem with gas absorption lookup table.\n"
987 <<
"VMR for H2O (species " << h2o_index
988 <<
") is outside the range covered by the lookup table.\n"
989 <<
"Your VMR was " <<
abs_vmrs[h2o_index] <<
" at a pressure of "
991 <<
"The reference VMR value there is " << effective_vmr_ref <<
"\n"
992 <<
"The fractional VMR relative to the reference value is "
994 <<
"The allowed range is " << x_min <<
" to " << x_max <<
".\n"
995 <<
"The fractional VMR perturbation grid range in the table is "
997 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
998 throw runtime_error(os.str());
1007 if (n_nls < n_species) {
1014 (this_t_interp_order + 1) * (1) *
1015 (f_interp_order + 1));
1024 (this_t_interp_order + 1) * (h2o_interp_order + 1) *
1025 (f_interp_order + 1));
1031 for (
Index si = 0; si < n_species; ++si) {
1034 const Index do_VMR = non_linear[si];
1049 os <<
"Problem with gas absorption lookup table.\n"
1050 <<
"VMR interpolation is not allowed for species \""
1051 <<
species[si][0].Name() <<
"\"";
1052 throw runtime_error(os.str());
1060 Index this_h2o_extent;
1063 this_h2o_extent = n_nls_pert;
1067 this_h2o_extent = 1;
1074 Range(fpi, this_h2o_extent),
1108 sga.
resize(n_species, n_new_f_grid);
1110 for (
Index pi = 0; pi < p_interp_order + 1; ++pi) {
1118 xsec_pre_interpolated(
1130 for (
Index si = 0; si < n_species; ++si)
1142 os <<
"GasAbsLookup: Output operator not implemented";