ARTS  2.3.1285(git:92a29ea9-dirty)
test_propmat_partials.cc
Go to the documentation of this file.
1 /* Copyright (C) 2015 Richard Larsson <ric.larsson@gmail.com>
2  *
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the
5  * Free Software Foundation; either version 2, or (at your option) any
6  * later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  * USA. */
17 
26 #include "absorption.h"
27 #include "jacobian.h"
28 #include "linescaling.h"
29 #include "lineshapes.cc"
30 #include "lin_alg.h"
31 #include "rte.h"
32 
34 {
35  const ArrayOfNumeric empty_aon;
36 
37  const LineRecord line(6,0,61150556350.7454,0.0,4.03935532732085e-19,
38  296.0,2.5505950629926e-21,13255.072408981,13047.9619025907,0.8,0.8,
39  0.0,empty_aon,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
40 
41  const Numeric vmr=0.2, dT = 1e-1;
42 
43  Numeric tmp1,tmp2,tmp3,tmp4, g_0, df_0, dg, ddf, g_1, df_1;
44  ArrayOfIndex empty1;
45  const Vector vmrs(1,vmr);
46  Verbosity none;
47 
48  for(Numeric p =-2;p<6;p++)
49  {
50  const Numeric P = pow(10.,p);
51  for(Numeric T = 150; T<350; T+=20)
52  {
53  line.PressureBroadening().GetPressureBroadeningParams(g_0,tmp1,tmp2,df_0,tmp3,tmp4,
54  line.Ti0()/T, P, vmr*P,0,-1,empty1,vmrs,none);
55 
56  line.PressureBroadening().GetPressureBroadeningParams(g_1,tmp1,tmp2,df_1,tmp3,tmp4,
57  line.Ti0()/(T+dT), P, vmr*P,0,-1,empty1,vmrs,none);
58 
59  line.PressureBroadening().GetPressureBroadeningParams_dT(dg,ddf, T,
60  line.Ti0(),P,
61  vmr*P,0,-1,
62  empty1,
63  vmrs,none);
64  //std::cout<<((g_1-g_0)/dT-dg)/dg<< "\n";
65  /* This gives relative errors of (minus) 0.001 at 150 K and 0.0001 at 300 K. Constant with pressure. */
66  }
67  }
68 }
69 
71 {
72  const ArrayOfNumeric empty_aon;
73 
74  const LineFunctionData test(istringstream("VP none 3 SELF T1 16000 0.7 T1 100 1.3 CO2 T1 16001 0.71 T1 101 1.31 AIR T1 16002 0.72 T1 102 1.32"));
75  String x = test.HumanReadable();
76  std::cout<<x<<"\n";
77 }
78 
80 {
81  return x*x;
82 }
84 {
85 
86  const ArrayOfNumeric empty_aon;
87  const LineRecord line(species_index_from_species_name("O2"),0,61150556350.7454,0.0,4.03935532732085e-19,
88  296.0,2.5505950629926e-21,13255.072408981,13047.9619025907,0.8,0.8,
89  0.0,empty_aon,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
90 
91  Numeric qt_cache, qt_cache_d, qref_cache, qref_cache_d, dqt;
92 
93  const Numeric dT =1e-1;
94 
95  Numeric x = 7.315888e-01;
96  Vector part_data;
97  part_data={ 4.016432e-01, 7.315888e-01, -3.313678e-05, 6.642877e-08 };//O2 66 partition function
98 
99 
100 
101  for(Numeric T = 150; T<350; T+=20)
102  {
103  CalculatePartitionFctFromCoeff(qref_cache,qt_cache,line.Ti0(),T,part_data);
104  CalculatePartitionFctFromCoeff(qref_cache_d,qt_cache_d,line.Ti0(),T+dT,part_data);
105 
106  CalculatePartitionFctFromCoeff_dT(dqt, T, part_data);
107 
108  //std::cout<<(((qref_cache_d/qt_cache_d - qref_cache/qt_cache) /dT) -
109  //-qref_cache/qt_cache/qt_cache * dqt) /(-qref_cache/qt_cache/qt_cache * dqt) <<"\n";
110  /* This gives relative errors of less than (minus) 0.001 */
111  }
112 }
113 
115 {
116  // Physical constants
117  extern const Numeric PLANCK_CONST;
118  extern const Numeric BOLTZMAN_CONST;
119 
120  const ArrayOfNumeric empty_aon;
121  const LineRecord line(species_index_from_species_name("O2"),0,61150556350.7454,0.0,4.03935532732085e-19,
122  296.0,2.5505950629926e-21,13255.072408981,13047.9619025907,0.8,0.8,
123  0.0,empty_aon,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
124 
125  const Numeric dT = 0.1;
126 
127  for(Numeric T = 150; T<350; T+=20)
128  {
129  // Following Futbolin's division into two parts for the Boltzmann ratio because
130  // gamma is also used for the NLTE part later on
131  const Numeric gamma = exp( - PLANCK_CONST * line.F() / ( BOLTZMAN_CONST * T ) );
132  const Numeric gamma_ref = exp( - PLANCK_CONST * line.F() / ( BOLTZMAN_CONST * line.Ti0()) );
133  // Stimulated emission
134  const Numeric K2 = (1.-gamma)/(1.-gamma_ref);
135  // Boltzmann level
136  const Numeric K1 = exp( line.Elow() / BOLTZMAN_CONST * (T-line.Ti0())/(T*line.Ti0()) );
137 
138  // Following Futbolin's division into two parts for the Boltzmann ratio because
139  // gamma is also used for the NLTE part later on
140  const Numeric gamma_d = exp( - PLANCK_CONST * line.F() / ( BOLTZMAN_CONST * (T+dT) ) );
141  // Stimulated emission
142  const Numeric K2_d = (1.-gamma_d)/(1.-gamma_ref);
143  // Boltzmann level
144  const Numeric K1_d = exp( line.Elow() / BOLTZMAN_CONST * ((T+dT)-line.Ti0())/((T+dT)*line.Ti0()) );
145 
146  const Numeric dK1 = line.Elow()/BOLTZMAN_CONST/T/T * K1;
147  const Numeric dK2 = -line.F()*PLANCK_CONST/BOLTZMAN_CONST/T/T * (gamma/(1.0-gamma_ref));
148 
149  //std::cout<< (((K2_d-K2)/dT)- dK2)/dK2 <<"\n";
150  /* This gives relative errors of just above (minus) 0.001,
151  and is fairly constant with Temperature */
152 
153  //std::cout<<((K1_d-K1)/dT-dK1)/dK1<<"\n";
154  /* This gives relative errors of just above (minus) 0.0001,
155  and is fairly constant with Temperature */
156 
157  if(!(abs(((K1_d-K1)/dT-dK1)/dK1)<0.001))
158  std::cout<<"K1 partial checks out bad.\n";
159  if(!(abs((((K2_d-K2)/dT)- dK2)/dK2)<0.01))
160  std::cout<<"K1 partial checks out bad.\n";
161  }
162 }
163 
165 {
166  // Physical constants
167  extern const Numeric DOPPLER_CONST;
168 
169  static const Numeric doppler_const = DOPPLER_CONST;
170  const ArrayOfNumeric empty_aon;
171 
172  const LineRecord line(6,0,61150556350.7454,0.0,4.03935532732085e-19,
173  296.0,2.5505950629926e-21,13255.072408981,13047.9619025907,0.8,0.8,
174  0.0,empty_aon,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
175 
176  const Numeric vmr=0.2, dT = 1e-1;
177 
178  Numeric tmp1,tmp2,tmp3,tmp4, g, df, g_d, df_d, dg, ddf;
179  ArrayOfIndex empty1;
180  const Vector vmrs(1,vmr);
181  Verbosity none;
182  Vector empty_vector;
183 
184  Vector f_grid(5);
185  f_grid[0]=line.F()-1.0e6;
186  f_grid[1]=line.F()-50.0e3;
187  f_grid[2]=line.F();
188  f_grid[3]=line.F()+50.0e3;
189  f_grid[4]=line.F()+1.0e6;
190 
191  Vector ls(5,0.0),ls_d(5,0.0),ls_phase(5,0.0),dls_dx(5,0.0),dls_dy(5,0.0),dx_dT(5,0.0);
192 
193  for(Numeric p =-2;p<6;p++)
194  {
195  const Numeric P = pow(10., p);
196  //std::cout<<"\nPressure: "<<P<<" Pa. dT: "<<dT<<" K\n";
197  for(Numeric T = 150; T<350; T+=20)
198  {
199  line.PressureBroadening().GetPressureBroadeningParams(g,tmp1,tmp2,df,tmp3,tmp4,
200  line.Ti0()/T, P, vmr*P,0,-1,empty1,vmrs,none);
201 
202  line.PressureBroadening().GetPressureBroadeningParams(g_d,tmp1,tmp2,df_d,tmp3,tmp4,
203  line.Ti0()/(T+dT), P, vmr*P,0,-1,empty1,vmrs,none);
204 
205  line.PressureBroadening().GetPressureBroadeningParams_dT(dg,ddf, T,
206  line.Ti0(),P,
207  vmr*P,0,-1,
208  empty1,
209  vmrs,none);
210 
211  const Numeric sigma = line.F() * doppler_const
212  *sqrt( T / 31.989830);//mass is O2-66
213 
214  const Numeric dsigma_dT = line.F() * doppler_const
215  *sqrt( T / 31.989830)/T/2.0;//mass is O2-66
216 
217  const Numeric sigma_d = line.F() * doppler_const
218  *sqrt( (T+dT) / 31.989830);//mass is O2-66
219 
220  //std::cout<<((sigma_d-sigma)/dT - dsigma_dT)/dsigma_dT<<"\n";
221  /* This gives relative errors of just above (minus) 0.0001,
222  for 150 K and much less at higher temperatures*/
223 
225  ls_phase,
226  dls_dx,
227  empty_vector,
228  dls_dy,
229  empty_vector,
230  empty_vector,
231  line.F(),
232  g,
233  0.0,0.0,0.0,0.0,
234  sigma,
235  0.0,
236  f_grid,
237  false,
238  true);
239 
241  empty_vector,
242  empty_vector,
243  empty_vector,
244  empty_vector,
245  empty_vector,
246  empty_vector,
247  line.F(),
248  g_d,
249  0.0,0.0,0.0,0.0,
250  sigma_d,
251  0.0,
252  f_grid,
253  false,
254  false);
255 
256  Numeric dy_dT,dnorm_dT;
257  w_x_plus_iy_dT(dx_dT,
258  dy_dT,
259  dnorm_dT,
260  f_grid,
261  line.F(), // Note that this is NOT the line center, but the shifted center (normally, and in our case the shift is nil)
262  sigma,
263  df,
264  0.0,
265  dsigma_dT,
266  g,
267  dg);
268 
269 // std::cout<<"Temperature: "<<T<<" K\n";
270 // for(Index iv=0;iv<5; iv++)
271 // {
272 // std::cout<<((ls_d[iv]-ls[iv])/dT - dx_dT[iv]*dls_dx[iv]
273 // - dy_dT*dls_dy[iv] - dnorm_dT*ls[iv])/
274 // (dx_dT[iv]*dls_dx[iv] + dy_dT*dls_dy[iv] + dnorm_dT*ls[iv])<<" ";
275 // }
276 // std::cout<<"\n";
277  /* This gives relative errors of just above (minus) 4% at 0.01 Pa and 230 K
278  near the Doppler half-width but much less at line center and far from
279  the line, where errors are generally less than 1%. For pressures above
280  1 Pa, the errors are on magnitude of less than (minus) 0.001.*/
281  }
282  }
283 }
284 
286 {
287  // Startup
288  Matrix tmp(4,4);
289  Numeric length;
290 
291  // Below are examples from one run.
292 
293  // length for ip
294  length=8407.36;
295  //dtdx for ip
296  tmp(0,0)=1.06286e-08; tmp(0,1)=3.81257e-10; tmp(0,2)=7.23907e-10; tmp(0,3)=-5.71387e-09;
297  tmp(1,0)=3.81268e-10; tmp(1,1)=1.06286e-08; tmp(1,2)=1.0299e-08; tmp(1,3)=4.25483e-09;
298  tmp(2,0)=7.23901e-10; tmp(2,1)=-1.0299e-08; tmp(2,2)=1.06286e-08; tmp(2,3)=-2.24089e-09;
299  tmp(3,0)=-5.71387e-09; tmp(3,1)=-4.25481e-09; tmp(3,2)=2.24093e-09; tmp(3,3)=1.06286e-08;
300  const Matrix dtdx=tmp;
301  //ppath_ext for ip+1
302  tmp(0,0)=6.57435e-10; tmp(0,1)=2.38216e-11; tmp(0,2)=4.52381e-11; tmp(0,3)=-3.49977e-10;
303  tmp(1,0)=2.38216e-11; tmp(1,1)=6.57435e-10; tmp(1,2)=6.81735e-10; tmp(1,3)=2.71398e-10;
304  tmp(2,0)=4.52381e-11; tmp(2,1)=-6.81735e-10; tmp(2,2)=6.57435e-10; tmp(2,3)=-1.42913e-10;
305  tmp(3,0)=-3.49977e-10; tmp(3,1)=-2.71398e-10; tmp(3,2)=1.42913e-10; tmp(3,3)=6.57435e-10;
306  const Matrix ppath_ext_1=tmp;
307  //ppath_ext for ip
308  tmp(0,0)=2.08609e-10; tmp(0,1)=7.33668e-12; tmp(0,2)=1.39302e-11; tmp(0,3)=-1.11706e-10;
309  tmp(1,0)=7.33668e-12; tmp(1,1)=2.08609e-10; tmp(1,2)=2.13876e-10; tmp(1,3)=8.65063e-11;
310  tmp(2,0)=1.39302e-11; tmp(2,1)=-2.13876e-10; tmp(2,2)=2.08609e-10; tmp(2,3)=-4.55607e-11;
311  tmp(3,0)=-1.11706e-10; tmp(3,1)=-8.65063e-11; tmp(3,2)=4.55607e-11; tmp(3,3)=2.08609e-10;
312  const Matrix ppath_ext_0=tmp
313  ;//dppath_ext_dx for ip
314  tmp(0,0)=2.08609e-10; tmp(0,1)=7.33668e-12; tmp(0,2)=1.39302e-11; tmp(0,3)=-1.11706e-10;
315  tmp(1,0)=7.33668e-12; tmp(1,1)=2.08609e-10; tmp(1,2)=0; tmp(1,3)=0;
316  tmp(2,0)=1.39302e-11; tmp(2,1)=0; tmp(2,2)=2.08609e-10; tmp(2,3)=0;
317  tmp(3,0)=-1.11706e-10; tmp(3,1)=0; tmp(3,2)=0; tmp(3,3)=2.08609e-10;
318  const Matrix ppath_ext_0_test=tmp
319  ;//dppath_ext_dx for ip
320  tmp(0,0)=-2.53045e-12; tmp(0,1)=-9.07729e-14; tmp(0,2)=-1.72351e-13; tmp(0,3)=1.36037e-12;
321  tmp(1,0)=-9.07729e-14; tmp(1,1)=-2.53045e-12; tmp(1,2)=-2.59077e-12; tmp(1,3)=-1.2184e-12;
322  tmp(2,0)=-1.72351e-13; tmp(2,1)=2.59077e-12; tmp(2,2)=-2.53045e-12; tmp(2,3)=6.41701e-13;
323  tmp(3,0)=1.36037e-12; tmp(3,1)=1.2184e-12; tmp(3,2)=-6.41701e-13; tmp(3,3)=-2.53045e-12;
324  const Matrix dppath_ext_dx=tmp;
325  tmp(0,0)=-2.53045e-12; tmp(0,1)=-9.07729e-14; tmp(0,2)=-1.72351e-13; tmp(0,3)=1.36037e-12;
326  tmp(1,0)=-9.07729e-14; tmp(1,1)=-2.53045e-12; tmp(1,2)=0; tmp(1,3)=0;
327  tmp(2,0)=-1.72351e-13; tmp(2,1)=0; tmp(2,2)=-2.53045e-12; tmp(2,3)=0;
328  tmp(3,0)=1.36037e-12; tmp(3,1)=0; tmp(3,2)=0; tmp(3,3)=-2.53045e-12;
329  const Matrix dppath_ext_dx_test=tmp;
330  //ppath_ext_dt for ip
331  tmp(0,0)=2.08356e-10; tmp(0,1)=7.32761e-12; tmp(0,2)=1.3913e-11; tmp(0,3)=-1.1157e-10;
332  tmp(1,0)=7.32761e-12; tmp(1,1)=2.08356e-10; tmp(1,2)=2.13631e-10; tmp(1,3)=8.64051e-11;
333  tmp(2,0)=1.3913e-11; tmp(2,1)=-2.13631e-10; tmp(2,2)=2.08356e-10; tmp(2,3)=-4.55074e-11;
334  tmp(3,0)=-1.1157e-10; tmp(3,1)=-8.64051e-11; tmp(3,2)=4.55074e-11; tmp(3,3)=2.08356e-10;
335  const Matrix ppath_ext_dt=tmp;
336  //trans_partial for ip
337  tmp(0,0)=0.999996; tmp(0,1)=-1.30978e-07; tmp(0,2)=-2.48724e-07; tmp(0,3)=1.94076e-06;
338  tmp(1,0)=-1.3098e-07; tmp(1,1)=0.999996; tmp(1,2)=-3.76485e-06; tmp(1,3)=-1.50451e-06;
339  tmp(2,0)=-2.48723e-07; tmp(2,1)=3.76485e-06; tmp(2,2)=0.999996; tmp(2,3)=7.92277e-07;
340  tmp(3,0)=1.94076e-06; tmp(3,1)=1.50451e-06; tmp(3,2)=-7.92283e-07; tmp(3,3)=0.999996;
341  const Matrix trans_partial=tmp;
342 
343 
344  Matrix T(4,4),dT(4,4), A(4,4),dA(4,4);
345 
346  A=ppath_ext_0;
347  A*=-length;
348  dA=dppath_ext_dx;
349  dA*=-0.5*length;
350  matrix_exp_dmatrix_exp(T,dT,A,dA,6);
351 
352  tmp=dtdx;
353  tmp-=dT;
354  tmp/=dT;
355 
356 // std::cout<<"test:\n";
357 // std::cout<<tmp<<"\n\ndtdx:\n";
358 // Really large relative errors of almost 20%. Still believable results since relative change is less than 1e-4 for normal cases.
359 }
360 
361 int main()
362 {
363  std::cout<<"Testing Propmat Partials\n";
364 // test_pressurebroadening();
365 // test_partitionfunction();
366 // test_K1_and_K2();
367 // test_lineshape();
368 // test_matrixexp();
370  return 0;
371 }
Numeric Ti0() const
Reference temperature for I0 in K:
Definition: linerecord.h:375
const Numeric PLANCK_CONST
Global constant, the Planck constant [Js].
void matrix_exp_dmatrix_exp(MatrixView F, Tensor3View dF, ConstMatrixView A, ConstTensor3View dA, const Index &q)
General exponential of a Matrix with their derivatives.
Definition: lin_alg.cc:1926
Vector vmrs(const ConstVectorView &atmospheric_vmrs, const ArrayOfArrayOfSpeciesTag &atmospheric_species, const QuantumIdentifier &self, const ArrayOfSpeciesTag &lineshape_species, bool self_in_list, bool bath_in_list, Type type)
Returns a VMR vector for this model&#39;s main calculations.
void faddeeva_algorithm_916(Vector &ls_attenuation, Vector &ls_phase, Vector &ls_dattenuation_dfrequency_term, Vector &ls_dphase_dfrequency_term, Vector &ls_dattenuation_dpressure_term, Vector &ls_dphase_dpressure_term, Vector &, const Numeric f0, const Numeric gamma, const Numeric, const Numeric, const Numeric, const Numeric, const Numeric sigma, const Numeric, ConstVectorView f_grid, const bool do_phase, const bool do_partials)
Definition: lineshapes.cc:1476
const Numeric BOLTZMAN_CONST
Global constant, the Boltzmann constant [J/K].
Stuff related to lineshape functions.
Routines for setting up the jacobian.
The Vector class.
Definition: matpackI.h:860
#define abs(x)
void test_linefunctionsdata()
Linear algebra functions.
Numeric Elow() const
Lower state energy in cm^-1:
Definition: linerecord.h:378
void test_K1_and_K2()
basic_istringstream< char, string_char_traits< char >, alloc > istringstream
Definition: sstream.h:203
Numeric test2(Numeric x)
void test_partitionfunction()
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
The Matrix class.
Definition: matpackI.h:1193
Declarations required for the calculation of absorption coefficients.
Numeric pow(const Rational base, Numeric exp)
Power of.
Definition: rational.h:628
Index species_index_from_species_name(String name)
Return species index for given species name.
Definition: absorption.cc:531
void test_matrixexp()
This can be used to make arrays out of anything.
Definition: array.h:40
Constains various line scaling functions.
void test_pressurebroadening()
void w_x_plus_iy_dT(Vector &dx_dT, Numeric &dy_dT, Numeric &dFu_dT, ConstVectorView f, const Numeric &f0, const Numeric &sigma, const Numeric &dPF_dT, const Numeric &dDF_dT, const Numeric &dsigma_dT, const Numeric &gamma, const Numeric &dgamma_dT)
Definition: lineshapes.cc:1541
void test_lineshape()
const Numeric DOPPLER_CONST
Numeric F() const
The line center frequency in Hz.
Definition: linerecord.h:349
Declaration of functions in rte.cc.
Numeric sqrt(const Rational r)
Square root.
Definition: rational.h:620
int main()