ARTS  2.3.1285(git:92a29ea9-dirty)
linemixingdata.cc
Go to the documentation of this file.
1 /* Copyright (C) 2014
2 Richard Larsson <ric.larsson@gmail.com>
3 
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA. */
18 
26 #include "linemixingdata.h"
27 #include "check_input.h"
28 
29 
31 // Line mixing interactions to get cross section goes below here
33 
34 
35 void LineMixingData::GetLineMixingParams(Numeric& Y, Numeric& G, Numeric& DV, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit, const Index& order) const
36 {
37  Y=G=DV=0.0;
38  if(mtype == LM_NONE) {} // The standard case
39  else if(mtype == LM_LBLRTM) // The LBLRTM case
40  GetLBLRTM(Y,G,Temperature,Pressure,Pressure_Limit,order);
41  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM case
42  GetLBLRTM_O2NonResonant(G); // Note that they only act like Y and G
43  else if(mtype == LM_2NDORDER) // The 2nd order case
44  Get2ndOrder(Y,G,DV,Temperature,Pressure,Pressure_Limit);
45  else if(mtype == LM_1STORDER) // The 1st order case
46  Get1stOrder(Y,Temperature,Pressure,Pressure_Limit);
47  else if(mtype == LM_BYBAND) // The band class
48  throw std::runtime_error("You are trying to return line mixing data for a line despite having\n"
49  "declared the line absorption can only be understood by full band calculations..\n");
50  else
51  throw std::runtime_error("You are trying to return a line mixing type that is unknown to ARTS.\n");
52 }
53 
54 
55 void LineMixingData::GetLineMixingParams_dT(Numeric& dY_dT, Numeric& dG_dT, Numeric& dDV_dT, const Numeric& Temperature, const Numeric& dt, const Numeric& Pressure, const Numeric& Pressure_Limit, const Index& order) const
56 {
57  dY_dT=dG_dT=dDV_dT=0.0;
58  if(mtype == LM_NONE) {} // The standard case
59  else if(mtype == LM_LBLRTM) // The LBLRTM case
60  GetLBLRTM_dT(dY_dT,dG_dT,Temperature,dt,Pressure,Pressure_Limit,order);
61  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM case
62  {/*Nothing to do here but still a valid case*/}
63  else if(mtype == LM_2NDORDER) // The 2nd order case
64  Get2ndOrder_dT(dY_dT,dG_dT,dDV_dT,Temperature,Pressure,Pressure_Limit);
65  else if(mtype == LM_1STORDER) // The 1st order case
66  Get1stOrder_dT(dY_dT,Temperature,Pressure,Pressure_Limit);
67  else if(mtype == LM_BYBAND) // The band class
68  throw std::runtime_error("You are trying to return line mixing data for a line despite having\n"
69  "declared the line absorption can only be understood by full band calculations..\n");
70  else
71  throw std::runtime_error("You are trying to return a line mixing type that is unknown to ARTS.\n");
72 }
73 
74 
76  const ArrayOfRetrievalQuantity& /*ppd*/,
77  const QuantumIdentifier& /*QI*/,
78  const Numeric& /*temperature*/,
79  const Numeric& /*pressure*/,
80  const Numeric& /*pressure_limit*/) const
81 {
82 // const Index nppd = ppd.nelem();
83 //
84 // Numeric dY0, dY1, dG0, dG1, dDV0, dDV1, dYe, dGe, dDVe;
85 // bool zeroth=false, first=false, exponent=false;
86 //
87 // ComplexVector res(10);
88 //
89 // Index ipd = 0;
90 //
91 // for(Index iq = 0; iq < nppd; iq++)
92 // {
93 // if(ppd[iq] == JacPropMatType::LineMixingY0)
94 // {
95 // if(QI > ppd[iq].QuantumIdentity())
96 // {
97 // if(not zeroth)
98 // {
99 // GetLineMixingParams_dZerothOrder(dY0, dG0, dDV0, temperature, pressure, pressure_limit);
100 // zeroth = true;
101 // }
102 // res[ipd] = Complex(0, -dY0);
103 // }
104 // else
105 // continue;
106 // }
107 // else if(ppd[iq] == JacPropMatType::LineMixingG0)
108 // {
109 // if(QI > ppd[iq].QuantumIdentity())
110 // {
111 // if(not zeroth)
112 // {
113 // GetLineMixingParams_dZerothOrder(dY0, dG0, dDV0, temperature, pressure, pressure_limit);
114 // zeroth = true;
115 // }
116 // res[ipd] = dG0;
117 // }
118 // else
119 // continue;
120 // }
121 // else if(ppd[iq] == JacPropMatType::LineMixingDF0)
122 // {
123 // if(QI > ppd[iq].QuantumIdentity())
124 // {
125 // if(not zeroth)
126 // {
127 // GetLineMixingParams_dZerothOrder(dY0, dG0, dDV0, temperature, pressure, pressure_limit);
128 // zeroth = true;
129 // }
130 // res[ipd] = dDV0;
131 // }
132 // else
133 // continue;
134 // }
135 // else if(ppd[iq] == JacPropMatType::LineMixingY1)
136 // {
137 // if(QI > ppd[iq].QuantumIdentity())
138 // {
139 // if(not first)
140 // {
141 // GetLineMixingParams_dFirstOrder(dY1, dG1, dDV1, temperature, pressure, pressure_limit);
142 // first = true;
143 // }
144 // res[ipd] = Complex(0, -dY1);
145 // }
146 // else
147 // continue;
148 // }
149 // else if(ppd[iq] == JacPropMatType::LineMixingG1)
150 // {
151 // if(QI > ppd[iq].QuantumIdentity())
152 // {
153 // if(not first)
154 // {
155 // GetLineMixingParams_dFirstOrder(dY1, dG1, dDV1, temperature, pressure, pressure_limit);
156 // first = true;
157 // }
158 // res[ipd] = dG1;
159 // }
160 // else
161 // continue;
162 // }
163 // else if(ppd[iq] == JacPropMatType::LineMixingDF1)
164 // {
165 // if(QI > ppd[iq].QuantumIdentity())
166 // {
167 // if(not first)
168 // {
169 // GetLineMixingParams_dFirstOrder(dY1, dG1, dDV1, temperature, pressure, pressure_limit);
170 // first = true;
171 // }
172 // res[ipd] = dDV1;
173 // }
174 // else
175 // continue;
176 // }
177 // else if(ppd[iq] == JacPropMatType::LineMixingYExp)
178 // {
179 // if(QI > ppd[iq].QuantumIdentity())
180 // {
181 // if(not exponent)
182 // {
183 // GetLineMixingParams_dExponent(dYe, dGe, dDVe, temperature, pressure, pressure_limit);
184 // exponent = true;
185 // }
186 // res[ipd] = Complex(0, -dYe);
187 // }
188 // else
189 // continue;
190 // }
191 // else if(ppd[iq] == JacPropMatType::LineMixingGExp)
192 // {
193 // if(QI > ppd[iq].QuantumIdentity())
194 // {
195 // if(not exponent)
196 // {
197 // GetLineMixingParams_dExponent(dYe, dGe, dDVe, temperature, pressure, pressure_limit);
198 // exponent = true;
199 // }
200 // res[ipd] = dGe;
201 // }
202 // else
203 // continue;
204 // }
205 // else if(ppd[iq] == JacPropMatType::LineMixingDFExp)
206 // {
207 // if(QI > ppd[iq].QuantumIdentity())
208 // {
209 // if(not exponent)
210 // {
211 // GetLineMixingParams_dExponent(dYe, dGe, dDVe, temperature, pressure, pressure_limit);
212 // exponent = true;
213 // }
214 // res[ipd] = dDVe;
215 // }
216 // else
217 // continue;
218 // }
219 // else
220 // continue;
221 //
222 // // Only activate this when something hit the target
223 // ++ipd;
224 // }
225 //
226 // derivatives.resize(ipd);
227 // for(Index iq = 0; iq < ipd; iq++)
228 // derivatives[iq] = res[iq];
229 }
230 
231 
232 
234  const Numeric& Temperature, const Numeric& Pressure,
235  const Numeric& Pressure_Limit) const
236 {
237  if(mtype == LM_NONE) {} // The standard case
238  else if(mtype == LM_LBLRTM) // The LBLRTM case
239  throw std::runtime_error("LBLRTM mode of line mixing does not have coefficients but are gridded. Use \"Line Mixing Y\" and equivalent instead.\n");
240  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM case
241  throw std::runtime_error("Non-resonant partial derivatives not supported.\n");
242  else if(mtype == LM_2NDORDER) // The 2nd order case
243  Get2ndOrder_dZerothOrder(dY0,dG0,dDV0,Temperature,Pressure,Pressure_Limit);
244  else if(mtype == LM_1STORDER) // The 1st order case
245  {
246  Get1stOrder_dZerothOrder(dY0,Temperature,Pressure,Pressure_Limit);
247  dG0=0.;
248  dDV0=0.;
249  }
250  else if(mtype == LM_BYBAND) // The band class
251  throw std::runtime_error("You are trying to return line mixing data for a line despite having\n"
252  "declared the line absorption can only be understood by full band calculations..\n");
253  else
254  throw std::runtime_error("You are trying to return a line mixing type that is unknown to ARTS.\n");
255 }
256 
257 
259  const Numeric& Temperature, const Numeric& Pressure,
260  const Numeric& Pressure_Limit) const
261 {
262  if(mtype == LM_NONE) {} // The standard case
263  else if(mtype == LM_LBLRTM) // The LBLRTM case
264  throw std::runtime_error("LBLRTM mode of line mixing does not have coefficients but are gridded. Use \"Line Mixing Y\" and equivalent instead.\n");
265  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM case
266  throw std::runtime_error("Non-resonant partial derivatives not supported.\n");
267  else if(mtype == LM_2NDORDER) // The 2nd order case
268  Get2ndOrder_dFirstOrder(dY1,dG1,dDV1,Temperature,Pressure,Pressure_Limit);
269  else if(mtype == LM_1STORDER) // The 1st order case
270  throw std::runtime_error("1st Order mode of line mixing only have zeroth order coefficients.\n");
271  else if(mtype == LM_BYBAND) // The band class
272  throw std::runtime_error("You are trying to return line mixing data for a line despite having\n"
273  "declared the line absorption can only be understood by full band calculations..\n");
274  else
275  throw std::runtime_error("You are trying to return a line mixing type that is unknown to ARTS.\n");
276 }
277 
278 
280  const Numeric& Temperature, const Numeric& Pressure,
281  const Numeric& Pressure_Limit) const
282 {
283  if(mtype == LM_NONE) {} // The standard case
284  else if(mtype == LM_LBLRTM) // The LBLRTM case
285  throw std::runtime_error("LBLRTM mode of line mixing does not have coefficients but are gridded. Use \"Line Mixing Y\" and equivalent instead.\n");
286  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM case
287  throw std::runtime_error("Non-resonant partial derivatives not supported.\n");
288  else if(mtype == LM_2NDORDER) // The 2nd order case
289  Get2ndOrder_dExponent(dYexp,dGexp,dDVexp,Temperature,Pressure,Pressure_Limit);
290  else if(mtype == LM_1STORDER) // The 1st order case
291  {
292  Get1stOrder_dExponent(dYexp,Temperature,Pressure,Pressure_Limit);
293  dGexp=0.;
294  dDVexp=0.;
295  }
296  else if(mtype == LM_BYBAND) // The band class
297  throw std::runtime_error("You are trying to return line mixing data for a line despite having\n"
298  "declared the line absorption can only be understood by full band calculations..\n");
299  else
300  throw std::runtime_error("You are trying to return a line mixing type that is unknown to ARTS.\n");
301 }
302 
303 
304 //Note that first order is used by LBLRTM on the data we have.
305 void LineMixingData::GetLBLRTM(Numeric& Y, Numeric& G, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit, const Index& order=1) const
306 {
307  assert( mtype == LM_LBLRTM );
308  assert(mdata.nelem() == 3);
309  assert(mdata[0].nelem() == 4 && mdata[1].nelem() == 4 && mdata[2].nelem() == 4);
310 
311  if(Pressure>Pressure_Limit)
312  {
313  // Helper to understand the following interpolation
314  const Vector& t = mdata[0];
315  const Vector& y = mdata[1];
316  const Vector& g = mdata[2];
317 
318  const Vector T0(1,Temperature);
319  Vector tmp(1);
320 
321  // Interpolation variables
322  ArrayOfGridPosPoly gp(1);
323 
324  Matrix itw;
325  itw.resize(gp.nelem(),order+1);
326 
327  // Allow extrapolation using the pressure limit variable --- this is ugly but using this feature at all is ugly so the sytnax does not matter
328  Numeric extrapol = 0.0;
329  if(Pressure_Limit < 0.0)
330  extrapol = abs(Pressure_Limit);
331 
332  chk_interpolation_grids("Line mixing data temperature interpolation",
333  t,
334  T0,
335  order,
336  extrapol);
337 
338  // Interpolation variale determination
339  gridpos_poly(gp, t, T0, order, extrapol);
340  interpweights(itw, gp);
341 
342  // Interpolated values
343  interp(tmp, itw, y, gp);
344  Y = tmp[0] * Pressure;
345  interp(tmp,itw, g, gp);
346  G = tmp[0] * Pressure * Pressure;
347  }
348  else
349  Y=G=0;
350 }
351 
352 
353 //Note that first order is used by LBLRTM on the data we have.
354 void LineMixingData::GetLBLRTM_dT(Numeric& dY_dT, Numeric& dG_dT, const Numeric& Temperature, const Numeric& dt, const Numeric& Pressure, const Numeric& Pressure_Limit, const Index& order=1) const
355 {
356  assert( mtype == LM_LBLRTM );
357  assert(mdata.nelem() == 3);
358  assert(mdata[0].nelem() == 4 && mdata[1].nelem() == 4 && mdata[2].nelem() == 4);
359 
360  if(Pressure>Pressure_Limit)
361  {
362  // Helper to understand the following interpolation
363  const Vector& t = mdata[0];
364  const Vector& y = mdata[1];
365  const Vector& g = mdata[2];
366 
367  const Vector T0(1,Temperature);
368  Vector tmp1(1), tmp2(1);
369 
370  // Interpolation variables
371  ArrayOfGridPosPoly gp1(1),gp2(1);
372 
373  Matrix itw1,itw2;
374  itw1.resize(gp1.nelem(),order+1);
375  itw2.resize(gp2.nelem(),order+1);
376 
377  // Allow extrapolation using the pressure limit variable --- this is ugly but using this feature at all is ugly so the sytnax does not matter
378  Numeric extrapol = 0.0;
379  if(Pressure_Limit < 0.0)
380  extrapol = abs(Pressure_Limit);
381 
382  chk_interpolation_grids("Line mixing data temperature interpolation",
383  t,
384  T0,
385  order,
386  extrapol);
387 
388  // Interpolation variale determination... FIXME: use interp to get local derivative directly...
389  gridpos_poly(gp1, t, T0, order, extrapol);
390  interpweights(itw1, gp1);
391 
392  Vector t2=t;
393  t2+=dt;
394  gridpos_poly(gp2, t2, T0, order, extrapol);
395  interpweights(itw2, gp2);
396 
397  // Interpolated values
398  interp(tmp1, itw1, y, gp1);
399  interp(tmp2, itw2, y, gp2);
400  dY_dT = (tmp2[0]-tmp1[0])/dt * Pressure;
401  interp(tmp1,itw1, g, gp1);
402  interp(tmp2,itw2, g, gp2);
403  dG_dT = (tmp2[0]-tmp1[0])/dt * Pressure * Pressure;
404  }
405  else
406  dY_dT=dG_dT=0;
407 }
408 
409 
411 {
412  assert( mtype == LM_LBLRTM_O2NonResonant );
413  assert(mdata.nelem() == 1);
414  assert(mdata[0].nelem() == 1);
415 
416  G = mdata[0][0];
417 }
418 
419 
420 void LineMixingData::Get2ndOrder(Numeric& Y, Numeric& G, Numeric& DV, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
421 {
422  assert( mtype == LM_2NDORDER );
423  assert(mdata.nelem() == 4);
424  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 3 && mdata[2].nelem() == 3 && mdata[3].nelem() == 3);
425 
426 
427  if(Pressure>Pressure_Limit)
428  {
429  // Helper to understand the following interpolation
430  const Numeric& T0 = mdata[0][0];
431  const Vector& y = mdata[1];
432  const Vector& g = mdata[2];
433  const Vector& dv = mdata[3];
434 
435  const Numeric Theta = T0/Temperature;
436 
437  Y = ( ( y[0] + y[1] * ( Theta-1. ) ) * pow( Theta, y[2] ) ) * Pressure;
438  G = ( ( g[0] + g[1] * ( Theta-1. ) ) * pow( Theta, g[2] ) ) * Pressure * Pressure;
439  DV = ( ( dv[0] + dv[1] * ( Theta-1. ) ) * pow( Theta, dv[2] ) ) * Pressure * Pressure;
440  }
441  else
442  Y=DV=G=0;
443 }
444 
445 
446 void LineMixingData::Get2ndOrder_dT(Numeric& dY_dT, Numeric& dG_dT, Numeric& dDV_dT, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
447 {
448  assert( mtype == LM_2NDORDER );
449  assert(mdata.nelem() == 4);
450  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 3 && mdata[2].nelem() == 3 && mdata[3].nelem() == 3);
451 
452  if(Pressure>Pressure_Limit)
453  {
454  // Helper to understand the following interpolation
455  const Numeric& T0 = mdata[0][0];
456  const Vector& y = mdata[1];
457  const Vector& g = mdata[2];
458  const Vector& dv = mdata[3];
459 
460  const Numeric Theta = T0/Temperature;
461  const Numeric T2 = Temperature*Temperature;
462 
463  dY_dT = - (T0* y[1]*pow(Theta, y[2]))/T2 - (T0* y[2]*pow(Theta,( y[2] - 1))*( y[0] + y[1]*(Theta - 1)))/T2;
464  dG_dT = - (T0* g[1]*pow(Theta, g[2]))/T2 - (T0* g[2]*pow(Theta,( g[2] - 1))*( g[0] + g[1]*(Theta - 1)))/T2;
465  dDV_dT = - (T0*dv[1]*pow(Theta,dv[2]))/T2 - (T0*dv[2]*pow(Theta,(dv[2] - 1))*(dv[0] + dv[1]*(Theta - 1)))/T2;
466 
467  dY_dT*= Pressure;
468  dG_dT*=Pressure*Pressure;
469  dDV_dT*=Pressure*Pressure;
470  }
471  else
472  dY_dT=dG_dT=dDV_dT=0;
473 }
474 
475 
476 void LineMixingData::Get2ndOrder_dZerothOrder(Numeric& dY0, Numeric& dG0, Numeric& dDV0, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
477 {
478  assert( mtype == LM_2NDORDER );
479  assert(mdata.nelem() == 4);
480  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 3 && mdata[2].nelem() == 3 && mdata[3].nelem() == 3);
481 
482 
483  if(Pressure>Pressure_Limit)
484  {
485  // Helper to understand the following interpolation
486  const Numeric& T0 = mdata[0][0];
487  const Vector& y = mdata[1];
488  const Vector& g = mdata[2];
489  const Vector& dv = mdata[3];
490 
491  const Numeric Theta = T0/Temperature;
492 
493  dY0 = pow( Theta, y[2] ) * Pressure;
494  dG0 = pow( Theta, g[2] ) * Pressure * Pressure;
495  dDV0 = pow( Theta, dv[2] ) * Pressure * Pressure;
496  }
497  else
498  dY0=dDV0=dG0=0;
499 }
500 
501 
502 void LineMixingData::Get2ndOrder_dFirstOrder(Numeric& dY1, Numeric& dG1, Numeric& dDV1, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
503 {
504  assert( mtype == LM_2NDORDER );
505  assert(mdata.nelem() == 4);
506  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 3 && mdata[2].nelem() == 3 && mdata[3].nelem() == 3);
507 
508 
509  if(Pressure>Pressure_Limit)
510  {
511  // Helper to understand the following interpolation
512  const Numeric& T0 = mdata[0][0];
513  const Vector& y = mdata[1];
514  const Vector& g = mdata[2];
515  const Vector& dv = mdata[3];
516 
517  const Numeric Theta = T0/Temperature;
518 
519  dY1 = ( ( ( Theta-1. ) ) * pow( Theta, y[2] ) ) * Pressure;
520  dG1 = ( ( ( Theta-1. ) ) * pow( Theta, g[2] ) ) * Pressure * Pressure;
521  dDV1 = ( ( ( Theta-1. ) ) * pow( Theta, dv[2] ) ) * Pressure * Pressure;
522  }
523  else
524  dY1=dDV1=dG1=0;
525 }
526 
527 
528 void LineMixingData::Get2ndOrder_dExponent(Numeric& dYexp, Numeric& dGexp, Numeric& dDVexp, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
529 {
530  assert( mtype == LM_2NDORDER );
531  assert(mdata.nelem() == 4);
532  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 3 && mdata[2].nelem() == 3 && mdata[3].nelem() == 3);
533 
534 
535  if(Pressure>Pressure_Limit)
536  {
537  // Helper to understand the following interpolation
538  const Numeric& T0 = mdata[0][0];
539  const Vector& y = mdata[1];
540  const Vector& g = mdata[2];
541  const Vector& dv = mdata[3];
542 
543  const Numeric Theta = T0/Temperature;
544  const Numeric logTheta = log(Theta);
545 
546  dYexp = ( ( y[0] + y[1] * ( Theta-1. ) ) * pow( Theta, y[2] ) ) * Pressure * logTheta;
547  dGexp = ( ( g[0] + g[1] * ( Theta-1. ) ) * pow( Theta, g[2] ) ) * Pressure * Pressure * logTheta;
548  dDVexp = ( ( dv[0] + dv[1] * ( Theta-1. ) ) * pow( Theta, dv[2] ) ) * Pressure * Pressure * logTheta;
549  }
550  else
551  dYexp=dDVexp=dGexp=0;
552 }
553 
554 
555 void LineMixingData::Get1stOrder(Numeric& Y, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
556 {
557  assert( mtype == LM_1STORDER );
558  assert(mdata.nelem() == 3);
559  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 1 && mdata[2].nelem() == 1);
560 
561  if(Pressure>Pressure_Limit)
562  {
563  // Helper to understand the following interpolation
564  const Numeric& T0 = mdata[0][0];
565  const Numeric& y = mdata[1][0];
566  const Numeric& x = mdata[2][0];
567 
568  Y = y * pow(T0/Temperature, x) * Pressure;
569  }
570  else
571  Y=0;
572 }
573 
574 
575 void LineMixingData::Get1stOrder_dT(Numeric& dY_dT, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
576 {
577  assert( mtype == LM_1STORDER );
578  assert(mdata.nelem() == 3);
579  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 1 && mdata[2].nelem() == 1);
580 
581  if(Pressure>Pressure_Limit)
582  {
583  // Helper to understand the following interpolation
584  const Numeric& T0 = mdata[0][0];
585  const Numeric& y = mdata[1][0];
586  const Numeric& x = mdata[2][0];
587 
588  const Numeric Theta = T0/Temperature;
589  const Numeric T2 = Temperature*Temperature;
590 
591  dY_dT = y * (-(T0*x*pow((Theta),(x - 1)))/T2) * Pressure;
592  }
593  else
594  dY_dT=0;
595 }
596 
597 void LineMixingData::Get1stOrder_dZerothOrder(Numeric& dY0, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
598 {
599  assert( mtype == LM_1STORDER );
600  assert(mdata.nelem() == 3);
601  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 1 && mdata[2].nelem() == 1);
602 
603  if(Pressure>Pressure_Limit)
604  {
605  // Helper to understand the following interpolation
606  const Numeric& T0 = mdata[0][0];
607  const Numeric& x = mdata[2][0];
608 
609  dY0 = pow(T0/Temperature, x) * Pressure;
610  }
611  else
612  dY0=0;
613 }
614 
615 
616 void LineMixingData::Get1stOrder_dExponent(Numeric& dYexp, const Numeric& Temperature, const Numeric& Pressure, const Numeric& Pressure_Limit) const
617 {
618  assert( mtype == LM_1STORDER );
619  assert(mdata.nelem() == 3);
620  assert(mdata[0].nelem() == 1 && mdata[1].nelem() == 1 && mdata[2].nelem() == 1);
621 
622  if(Pressure>Pressure_Limit)
623  {
624  // Helper to understand the following interpolation
625  const Numeric& T0 = mdata[0][0];
626  const Numeric& y = mdata[1][0];
627  const Numeric& x = mdata[2][0];
628 
629  dYexp = y * pow(T0/Temperature, x) * Pressure * log(T0/Temperature);
630  }
631  else
632  dYexp = 0;
633 }
634 
636 // Change functions
638 void LineMixingData::ChangeY0(const Numeric& change, const bool relative)
639 {
640  switch(mtype) {
641  case LM_1STORDER:
642  case LM_2NDORDER:
643  if(relative)
644  mdata[1][0] *= 1 + change;
645  else
646  mdata[1][0] += change;
647  break;
648  default:
649  throw std::runtime_error("Unsupported change");
650  }
651 }
652 void LineMixingData::ChangeY1(const Numeric& change, const bool relative)
653 {
654  switch(mtype) {
655  case LM_2NDORDER:
656  if(relative)
657  mdata[1][1] *= 1 + change;
658  else
659  mdata[1][1] += change;
660  break;
661  default:
662  throw std::runtime_error("Unsupported change");
663  }
664 }
665 void LineMixingData::ChangeYexp(const Numeric& change, const bool relative)
666 {
667  switch(mtype) {
668  case LM_1STORDER:
669  if(relative)
670  mdata[2][0] *= 1 + change;
671  else
672  mdata[2][0] += change;
673  break;
674  case LM_2NDORDER:
675  if(relative)
676  mdata[1][2] *= 1 + change;
677  else
678  mdata[1][2] += change;
679  break;
680  default:
681  throw std::runtime_error("Unsupported change");
682  }
683 }
684 void LineMixingData::ChangeG0(const Numeric& change, const bool relative)
685 {
686  switch(mtype) {
687  case LM_2NDORDER:
688  if(relative)
689  mdata[2][0] *= 1 + change;
690  else
691  mdata[2][0] += change;
692  break;
693  default:
694  throw std::runtime_error("Unsupported change");
695  }
696 }
697 void LineMixingData::ChangeG1(const Numeric& change, const bool relative)
698 {
699  switch(mtype) {
700  case LM_2NDORDER:
701  if(relative)
702  mdata[2][1] *= 1 + change;
703  else
704  mdata[2][1] += change;
705  break;
706  default:
707  throw std::runtime_error("Unsupported change");
708  }
709 }
710 void LineMixingData::ChangeGexp(const Numeric& change, const bool relative)
711 {
712  switch(mtype) {
713  case LM_2NDORDER:
714  if(relative)
715  mdata[2][2] *= 1 + change;
716  else
717  mdata[2][2] += change;
718  break;
719  default:
720  throw std::runtime_error("Unsupported change");
721  }
722 }
723 void LineMixingData::ChangeDF0(const Numeric& change, const bool relative)
724 {
725  switch(mtype) {
726  case LM_2NDORDER:
727  if(relative)
728  mdata[3][0] *= 1 + change;
729  else
730  mdata[3][0] += change;
731  break;
732  default:
733  throw std::runtime_error("Unsupported change");
734  }
735 }
736 void LineMixingData::ChangeDF1(const Numeric& change, const bool relative)
737 {
738  switch(mtype) {
739  case LM_2NDORDER:
740  if(relative)
741  mdata[3][1] *= 1 + change;
742  else
743  mdata[3][1] += change;
744  break;
745  default:
746  throw std::runtime_error("Unsupported change");
747  }
748 }
749 void LineMixingData::ChangeDFexp(const Numeric& change, const bool relative)
750 {
751  switch(mtype) {
752  case LM_2NDORDER:
753  if(relative)
754  mdata[3][2] *= 1 + change;
755  else
756  mdata[3][2] += change;
757  break;
758  default:
759  throw std::runtime_error("Unsupported change");
760  }
761 }
762 
764 // Line mixing interactions to get cross section goes above here
765 // Below is line mixing storage functions.
767 
768 
769 // This will parse any Vector by the own mtype to the right settings for mdata
771 {
772  if(mtype == LM_NONE) // The standard case
773  Vector2NoneData(input);
774  else if(mtype == LM_LBLRTM) // The LBLRTM case
775  Vector2LBLRTMData(input);
776  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM case
778  else if(mtype == LM_2NDORDER) // The 2nd order case
779  Vector2SecondOrderData(input);
780  else if(mtype == LM_1STORDER) // The 1st order case
781  Vector2FirstOrderData(input);
782  else if(mtype == LM_BYBAND) // The band class
783  throw std::runtime_error("You are trying to set line mixing data for a line despite having\n"
784  "declared the line absorption can only be understood by full band calculations..\n");
785  else
786  throw std::runtime_error("You are trying to store a line mixing type that is unknown to ARTS.\n");
787 }
788 
789 
790 // This will be used to know how many parameters must be read from the catalog
792 {
793  if(mtype == LM_NONE) // The standard case
794  return 0;
795  else if(mtype == LM_LBLRTM) // The LBLRTM case
796  return 12;
797  else if(mtype == LM_LBLRTM_O2NonResonant) // Nonresonant is just a tag
798  return 1;
799  else if(mtype == LM_2NDORDER) // The 2nd order case
800  return 10;
801  else if(mtype == LM_1STORDER) // The 2nd order case
802  return 3;
803  else if(mtype == LM_BYBAND) // The band class
804  return 1;
805  else
806  throw std::runtime_error("You are trying to store a line mixing type that is unknown to ARTS.\n");
807 }
808 
809 
810 // This will convert the read vector to the LBLRTM data format
812 {
813  assert(mtype == LineMixingData::LM_LBLRTM);
814 
815  if(input.nelem() != ExpectedVectorLengthFromType())
816  {
817  throw std::runtime_error("The line mixing data vector is not of the right length for LBLRTM.\n");
818  }
819 
820  // Then this is a three-long ArrayOfVector
821  mdata.resize(3);
822 
823  // This is supposed to be the temperature vector
824  mdata[0].resize(4);
825  mdata[0][0] = input[0];
826  mdata[0][1] = input[1];
827  mdata[0][2] = input[2];
828  mdata[0][3] = input[3];
829 
830  // This is supposed to be the Y-vector
831  mdata[1].resize(4);
832  mdata[1][0] = input[4];
833  mdata[1][1] = input[5];
834  mdata[1][2] = input[6];
835  mdata[1][3] = input[7];
836 
837  // This is supposed to be the G vector
838  mdata[2].resize(4);
839  mdata[2][0] = input[8];
840  mdata[2][1] = input[9];
841  mdata[2][2] = input[10];
842  mdata[2][3] = input[11];
843 }
844 
845 
846 // This will convert the read vector to the LBLRTM O2 non-resonant data format
848 {
850  if(input.nelem() != ExpectedVectorLengthFromType())
851  {
852  throw std::runtime_error("The line mixing data vector is not of the right length for LBLRTM non-resonant.\n");
853  }
854 
855  mdata.resize(1);
856  mdata[0].resize(1);
857  mdata[0][0] = input[0];
858 }
859 
860 
861 // This will convert the read vector to the none data format
863 { // Setting mdata.resize(0) is probably a better method for this...
864  assert(mtype == LineMixingData::LM_NONE);
865  if( input.nelem() != ExpectedVectorLengthFromType() )
866  throw std::runtime_error("You are trying to set line mixing data to a none line mixed line.\n");
867 }
868 
869 
870 // This will convert the read vector to the 2nd order data format
872 {
874  if(input.nelem() != ExpectedVectorLengthFromType())
875  throw std::runtime_error("The line mixing data vector is not of the right length for 2ndOrder.\n");
876 
877  // Then this is a four-long ArrayOfVector
878  mdata.resize(4);
879 
880  // This is supposed to be the temperature vector
881  mdata[0].resize(1);
882  mdata[0][0] = input[6];
883 
884  // This is supposed to be the Y components
885  mdata[1].resize(3);
886  mdata[1][0] = input[0];
887  mdata[1][1] = input[1];
888  mdata[1][2] = input[7];
889 
890  // This is supposed to be the G components
891  mdata[2].resize(3);
892  mdata[2][0] = input[2];
893  mdata[2][1] = input[3];
894  mdata[2][2] = input[8];
895 
896  // This is supposed to be the DV components
897  mdata[3].resize(3);
898  mdata[3][0] = input[4];
899  mdata[3][1] = input[5];
900  mdata[3][2] = input[9];
901 }
902 
903 
904 // This will convert the read vector to the 1st order data format
906 {
908  if(input.nelem() != ExpectedVectorLengthFromType())
909  throw std::runtime_error("The line mixing data vector is not of the right length for 1stOrder.\n");
910 
911  // Then this is a three-long ArrayOfVector
912  mdata.resize(3);
913 
914  // This is supposed to be the temperature vector
915  mdata[0].resize(1);
916  mdata[0][0] = input[0];
917 
918  // This is supposed to be value
919  mdata[1].resize(1);
920  mdata[1][0] = input[1];
921 
922  // This is supposed to be exponential value
923  mdata[2].resize(1);
924  mdata[2][0] = input[2];
925 
926 }
927 
928 
929 // This will convert the stored two char string to LM_Type
931  {
932  if(input == "NA") // The standard case
933  mtype = LM_NONE;
934  else if(input == "LL") // The LBLRTM case
935  mtype = LM_LBLRTM;
936  else if(input == "NR") // The LBLRTM O2 non-resonant case
938  else if(input == "L2") // The 2nd order case
939  mtype = LM_2NDORDER;
940  else if(input == "L1") // The 2nd order case
941  mtype = LM_1STORDER;
942  else if(input == "BB") // The band class
943  mtype = LM_BYBAND;
944  else
945  throw std::runtime_error("You are trying to read a line mixing type that is unknown to ARTS.\n");
946 }
947 
948 
949 // This will convert the LBLRTM data format to a vector for storage
951 {
952  output.resize(12);
953 
954  // This is the T-vector
955  output[0] = mdata[0][0];
956  output[1] = mdata[0][1];
957  output[2] = mdata[0][2];
958  output[3] = mdata[0][3];
959 
960  // This is the Y-vector
961  output[4] = mdata[1][0];
962  output[5] = mdata[1][1];
963  output[6] = mdata[1][2];
964  output[7] = mdata[1][3];
965 
966  // This is the G-vector
967  output[8] = mdata[2][0];
968  output[9] = mdata[2][1];
969  output[10] = mdata[2][2];
970  output[11] = mdata[2][3];
971 }
972 
973 
974 // This will convert the LBLRTM data format to a vector for storage
976 {
977  output.resize(1);
978  output[0]=mdata[0][0];
979 }
980 
981 
982 // This will convert the 2ndOrder data format to a vector for storage
984 {
985  output.resize(10);
986 
987  // This is the temperature vector
988  output[6] = mdata[0][0];
989 
990  // This is the Y components
991  output[0] = mdata[1][0];
992  output[1] = mdata[1][1];
993  output[7] = mdata[1][2];
994 
995  // This is the G components
996  output[2] = mdata[2][0];
997  output[3] = mdata[2][1];
998  output[8] = mdata[2][2];
999 
1000  // This is the DV components
1001  output[4] = mdata[3][0];
1002  output[5] = mdata[3][1];
1003  output[9] = mdata[3][2];
1004 }
1005 
1006 
1007 // This will convert the 1stOrder data format to a vector for storage
1009 {
1010  output.resize(3);
1011 
1012  // This is the temperature
1013  output[0] = mdata[0][0];
1014 
1015  // This is the y-value
1016  output[1] = mdata[1][0];
1017 
1018  // This is the exponent
1019  output[2] = mdata[2][0];
1020 }
1021 
1022 
1024 {
1025  if(mtype == LM_NONE) // The standard case
1026  output.resize(0);
1027  else if(mtype == LM_LBLRTM) // The LBLRTM case
1028  LBLRTMData2Vector(output);
1029  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM O2 non-resonant case
1031  else if(mtype == LM_2NDORDER) // The 2nd order case
1032  SecondOrderData2Vector(output);
1033  else if(mtype == LM_1STORDER) // The 1st order case
1034  FirstOrderData2Vector(output);
1035  else if(mtype == LM_BYBAND) // The band class
1036  {
1037  output.resize(1);
1038  output[0] = -1;
1039  }
1040  else
1041  throw std::runtime_error("You are trying to store a line mixing type that is unknown to ARTS.\n");
1042 }
1043 
1044 
1045 // This will convert LM_Type to a two char string for storage
1047 {
1048  String output;
1049  output.resize(2); // ARTS format specify that this is the size of the tag
1050 
1051  if(mtype == LM_NONE) // The standard case
1052  output = "NA";
1053  else if(mtype == LM_LBLRTM) // The LBLRTM case
1054  output = "LL";
1055  else if(mtype == LM_LBLRTM_O2NonResonant) // The LBLRTM O2 non-resonant case
1056  output = "NR";
1057  else if(mtype == LM_2NDORDER) // The 2nd order case
1058  output = "L2";
1059  else if(mtype == LM_1STORDER) // The 1st order case
1060  output = "L1";
1061  else if(mtype == LM_BYBAND) // The band class
1062  output = "BB";
1063  else
1064  throw std::runtime_error("You are trying to store a line mixing type that is unknown to ARTS.\n");
1065 
1066  return output;
1067 }
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
void GetLineMixingParams_dT(Numeric &dY_dT, Numeric &dG_dG, Numeric &dDV_dT, const Numeric &Temperature, const Numeric &dt, const Numeric &Pressure, const Numeric &Pressure_Limit, const Index &order=1) const
void GetVectorFromData(Vector &output) const
void ChangeYexp(const Numeric &change, const bool relative=false)
void Vector2LBLRTMData(const Vector &input)
void ChangeG0(const Numeric &change, const bool relative=false)
Index nelem() const
Number of elements.
Definition: array.h:195
void ChangeDF1(const Numeric &change, const bool relative=false)
The Vector class.
Definition: matpackI.h:860
#define abs(x)
void GetLBLRTM_O2NonResonant(Numeric &G) const
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
void GetLBLRTM_dT(Numeric &dY_dT, Numeric &dG_dT, const Numeric &Temperature, const Numeric &dt, const Numeric &Pressure, const Numeric &Pressure_Limit, const Index &order) const
void SecondOrderData2Vector(Vector &output) const
String Type2StorageTag() const
void LBLRTMData2Vector(Vector &output) const
void Get1stOrder_dZerothOrder(Numeric &dY0, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void FirstOrderData2Vector(Vector &output) const
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
void SetInternalDerivatives(ComplexVector &derivatives, const ArrayOfRetrievalQuantity &ppd, const QuantumIdentifier &QI, const Numeric &temperature, const Numeric &pressure, const Numeric &pressure_limit) const
void chk_interpolation_grids(const String &which_interpolation, ConstVectorView old_grid, ConstVectorView new_grid, const Index order, const Numeric &extpolfac, const bool islog)
Check interpolation grids.
Definition: check_input.cc:989
ArrayOfVector mdata
void Vector2NoneData(const Vector &)
void GetLineMixingParams_dZerothOrder(Numeric &dY0, Numeric &dG0, Numeric &dDV0, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void Get2ndOrder_dExponent(Numeric &dYexp, Numeric &dGexp, Numeric &dDVexp, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void ChangeDF0(const Numeric &change, const bool relative=false)
void StorageTag2SetType(const String &input)
void SetDataFromVectorWithKnownType(ConstVectorView)
void Get2ndOrder(Numeric &Y, Numeric &G, Numeric &DV, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void ChangeY0(const Numeric &change, const bool relative=false)
Class to identify and match lines by their quantum numbers.
Definition: quantum.h:390
void Vector2SecondOrderData(const Vector &input)
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
void GetLineMixingParams_dFirstOrder(Numeric &dY1, Numeric &dG1, Numeric &dDV1, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void GetLineMixingParams(Numeric &Y, Numeric &G, Numeric &DV, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit, const Index &order=1) const
The Matrix class.
Definition: matpackI.h:1193
void gridpos_poly(ArrayOfGridPosPoly &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Index order, const Numeric &extpolfac)
The maximum difference from 1 that we allow for a sum check.
void Get1stOrder_dT(Numeric &dY_dT, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
Numeric pow(const Rational base, Numeric exp)
Power of.
Definition: rational.h:628
The ComplexVector class.
Definition: complex.h:573
void Vector2LBLRTM_O2NonResonantData(const Vector &input)
void Get2ndOrder_dFirstOrder(Numeric &dY1, Numeric &dG1, Numeric &dDV1, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
This can be used to make arrays out of anything.
Definition: array.h:40
Contains the line mixing data class definition.
void ChangeDFexp(const Numeric &change, const bool relative=false)
void Vector2FirstOrderData(const Vector &input)
void resize(Index n)
Resize function.
Definition: matpackI.cc:404
void GetLBLRTM(Numeric &Y, Numeric &G, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit, const Index &order) const
void Get2ndOrder_dT(Numeric &dY_dT, Numeric &dG_dT, Numeric &dDV_dT, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void Get1stOrder(Numeric &Y, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
A constant view of a Vector.
Definition: matpackI.h:476
Index nelem(const Lines &l)
Number of lines.
void Get1stOrder_dExponent(Numeric &dYexp, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
Index ExpectedVectorLengthFromType() const
void ChangeY1(const Numeric &change, const bool relative=false)
void LBLRTM_O2NonResonantData2Vector(Vector &output) const
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
void GetLineMixingParams_dExponent(Numeric &dYexp, Numeric &dGexp, Numeric &dDVexp, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void ChangeGexp(const Numeric &change, const bool relative=false)
void ChangeG1(const Numeric &change, const bool relative=false)
void Get2ndOrder_dZerothOrder(Numeric &dY0, Numeric &dG0, Numeric &dDV0, const Numeric &Temperature, const Numeric &Pressure, const Numeric &Pressure_Limit) const
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1056