OSHUN  beta
Arbitrary Order Spherical-Harmonic 1D-3P Vlasov-Fokker-Planck-Maxwell code
interspeciescollisions.cpp
Go to the documentation of this file.
1 
13 // Standard libraries
14  #include <iostream>
15  #include <vector>
16  #include <valarray>
17  #include <complex>
18  #include <algorithm>
19  #include <cstdlib>
20 
21  #include <math.h>
22  #include <map>
23 
24 // My libraries
25  #include "lib-array.h"
26  #include "lib-algorithms.h"
27 
28 // Declarations
29  #include "input.h"
30  #include "state.h"
31  #include "formulary.h"
32  #include "nmethods.h"
33  #include "interspeciescollisions.h"
34  // #include "collisions.h"
35 
36 
37 //*******************************************************************
38 //-------------------------------------------------------------------
39  interspecies_f00_explicit_step::interspecies_f00_explicit_step(const DistFunc1D& DF1, const DistFunc1D& DF2, const double& deltat)//, int tout_start) //DistFunc1D& DFin,
40 //-------------------------------------------------------------------
41 // Constructor
42 //-------------------------------------------------------------------
43  : dt(deltat),
44 // pgrid_s1(Algorithms::MakeAxis(DF1.pmax()/(2.0*DF1(0,0).nump()-1.0),DF1.pmax(),DF1(0,0).nump())),
45 // pgrid_s2(Algorithms::MakeAxis(DF2.pmax()/(2.0*DF2(0,0).nump()-1.0),DF2.pmax(),DF2(0,0).nump())),
46  pgrid_s1(Algorithms::MakeCAxis(0.0,DF1.pmax(),DF1(0,0).nump())),
47  pgrid_s2(Algorithms::MakeCAxis(0.0,DF2.pmax(),DF2(0,0).nump())),
48  // f1(DF1(0,0)),f2(DF2(0,0)),
49  fslope(0.0, DF1(0,0).nump()),
50  // f0(0.0, DF1(0,0).nump()),
51  df0(0.0, DF1(0,0).nump()),
52 
53  U4(0.0, DF2(0,0).nump()),
54  U4m1(0.0, DF2(0,0).nump()),
55  U2(0.0, DF2(0,0).nump()),
56  U2m1(0.0, DF2(0,0).nump()),
57  U1(0.0, DF2(0,0).nump()),
58  U1m1(0.0, DF2(0,0).nump()),
59 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
60 
61  J1_s2(0.0, DF2(0,0).nump()),
62  I2_s2(0.0, DF2(0,0).nump()),
63  I4_s2(0.0, DF2(0,0).nump()),
64 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65  U3(0.0, DF2(0,0).nump()),
66  Qn(0.0, DF2(0,0).nump()),
67  Pn(0.0, DF2(0,0).nump()),
68 
69  J1_s1(0.0, DF2(0,0).nump()),
70  I2_s1(0.0, DF2(0,0).nump()),
71  I4_s1(0.0, DF2(0,0).nump())
72  {
73 
75  szx = Input::List().NxLocal[0];
76 
77  m2 = DF2.mass() ; m1 = DF1.mass();
78  z2 = DF2.q(); z1 = DF1.q();
79 
80 
81 
82  double re(2.8179402894e-13); //classical electron radius
83  double kp(sqrt(4.0*M_PI*(Input::List().density_np)*re));
84  kpre = re*kp;
85 
86  // f1.reserve(DF1(0,0).nump());
87 
88 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
89  // Determine U4, U4m1, U2, U2m1, U1, U1m1
90  for (size_t i(1); i < DF2(0,0).nump(); ++i) {
91  U4[i] = 0.5 * pow(pgrid_s2[i],4) * (pgrid_s2[i]-pgrid_s2[i-1]);
92  U4m1[i] = 0.5 * pow(pgrid_s2[i-1],4) * (pgrid_s2[i]-pgrid_s2[i-1]);
93  U2[i] = 0.5 * pgrid_s2[i]*pgrid_s2[i] * (pgrid_s2[i]-pgrid_s2[i-1]);
94  U2m1[i] = 0.5 * pgrid_s2[i-1]*pgrid_s2[i-1] * (pgrid_s2[i]-pgrid_s2[i-1]);
95  U1[i] = 0.5 * pgrid_s2[i] * (pgrid_s2[i]-pgrid_s2[i-1]);
96  U1m1[i] = 0.5 * pgrid_s2[i-1] * (pgrid_s2[i]-pgrid_s2[i-1]);
97  }
98 
99 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100  // Determine U3
101  for (size_t i(0); i < U3.size(); ++i) {
102  U3[i] = pow(pgrid_s2[i],3);
103  }
104  // Determine Qn
105  Qn[0] = 1.0 / ((pgrid_s2[0]*pgrid_s2[0]*pgrid_s2[1])/2.0);
106  for (size_t i(1); i < Qn.size()-1; ++i) {
107  Qn[i] = 1.0 / (pgrid_s2[i]*pgrid_s2[i]*(pgrid_s2[i+1]-pgrid_s2[i-1])/2.0);
108  }
109  // Determine Pn
110  for (size_t i(0); i < Pn.size()-1; ++i) {
111  Pn[i] = 1.0 / ((pgrid_s2[i+1]-pgrid_s2[i])/2.0*(pgrid_s2[i+1]+pgrid_s2[i]));
112  }
113 
114  }
115 //-------------------------------------------------------------------
116 //------------------------------------------------------------------------------
124  // SHarmonic1D& interspecies_f00_explicit_step::takestep(const SHarmonic1D& f1in, const SHarmonic1D& f2in) {
125  valarray<double> interspecies_f00_explicit_step::takestep(const valarray<double>& f1in, const valarray<double>& f2in) {
126 
127  // valarray<double> temp(f1in.size());
128  double temp = 0.0;
129  double mu = m2/m1;
130 
131  calculateintegrals(f1in,f2in);
132  remapintegrals();
133 
134  for (int n(1); n < f1in.size()-1; ++n) {
135  df0[n] = f1in[n+1]-f1in[n-1];
136  df0[n] /= pgrid_s1[n+1]-pgrid_s1[n-1];
137  }
138 
139  df0[0] = f1in[1]-f1in[0];
140  df0[0]/= pgrid_s1[1]-pgrid_s1[0];
141 
142  df0[f1in.size()-1] = f1in[f1in.size()-1]-f1in[f1in.size()-2];
143  df0[f1in.size()-1]/= pgrid_s1[f1in.size()-1]-pgrid_s1[f1in.size()-2];
144 
145  int ipp(1);
146  int ipm(0);
147 
148  Gamma12 = -1.0*kpre*n2*(z1*z1*z2*z2)*formulary.LOGii(m1,z1,n1,T1,
149  m2,z2,n2,T2);
150 
151  temp = (I4_s1[ipp]+J1_s1[ipp])*df0[ipp]*pgrid_s1[ipp]+3.0/mu*I2_s1[ipp]*f1in[ipp];
152  temp -= (I4_s1[ipm]+J1_s1[ipm])*df0[ipm]*pgrid_s1[ipm]+3.0/mu*I2_s1[ipm]*f1in[ipm];
153  temp /= pgrid_s1[ipp]-pgrid_s1[ipm];
154  temp /= 3.0*(0.25*pow(pgrid_s1[ipm]+pgrid_s1[ipp],2.0));
155 
156  fslope[0] = temp;
157  // std::cout << "\n fslope[0]=" << temp*Gamma12*dt << "\n\n";
158 
159  for (int ip(1);ip < f1in.size()-2;++ip)
160  {
161  ipp=ip+1;
162  ipm=ip-1;
163  temp = (I4_s1[ipp]+J1_s1[ipp])*df0[ipp]*pgrid_s1[ipp]+3.0/mu*I2_s1[ipp]*f1in[ipp];
164  // std::cout << "\n fslope1[ " << ip << "]="<< temp << "\n\n";
165  temp -= (I4_s1[ipm]+J1_s1[ipm])*df0[ipm]*pgrid_s1[ipm]+3.0/mu*I2_s1[ipm]*f1in[ipm];
166  // std::cout << "\n fslope2[ " << ip << "]="<< temp << "\n\n";
167  temp /= pgrid_s1[ipp]-pgrid_s1[ipm];
168  // std::cout << "\n fslope3[ " << ip << "]="<< temp << "\n\n";
169  temp /= 3.0*(0.25*pow(pgrid_s1[ipm]+pgrid_s1[ipp],2.0));
170  // std::cout << "\n fslope4[ " << ip << "]="<< temp << "\n\n";
171  // temp *= Gamma12*dt;
172  fslope[ip] = temp;
173 
174  // std::cout << "\n fslope[ " << ip << "]="<< temp*Gamma12*dt << "\n\n";
175  }
176  // std::cout << "\n fslope5[ " << Gamma12 << "\n\n";
177  ipp=f1in.size()-1;ipm=f1in.size()-2;
178 
179  temp = (I4_s1[ipp]+J1_s1[ipp])*df0[ipp]*pgrid_s1[ipp]+3.0/mu*I2_s1[ipp]*f1in[ipp];
180  temp -= (I4_s1[ipm]+J1_s1[ipm])*df0[ipm]*pgrid_s1[ipm]+3.0/mu*I2_s1[ipm]*f1in[ipm];
181  temp /= pgrid_s1[ipp]-pgrid_s1[ipm];
182  temp /= 3.0*(0.25*pow(pgrid_s1[ipm]+pgrid_s1[ipp],2.0));
183 
184  fslope[f1in.size()-1] = temp;
185  // std::cout << "\n fslope[last]=" << temp*Gamma12*dt << "\n\n";
186 
188  // fslope[f1in.size()-1] = 0.0;
189  // }
190  // exit(1);
191  return fslope;
192  }
193 
194 //-------------------------------------------------------------------
195 //------------------------------------------------------------------------------
198  void interspecies_f00_explicit_step::calculateintegrals(const valarray<double>& f1in, const valarray<double>& f2in) {
199 
200 
201 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
202 // Evaluate the integrals in a standard manner
203  I4_s2[0] = 0;
204  for (int n(1); n < I4_s2.size(); ++n) {
205  I4_s2[n] = U4[n]*f2in[n]+U4m1[n]*f2in[n-1];
206  I4_s2[n] += I4_s2[n-1];
207  // std::cout << "\n I4= " << I4_s2[n] << "\n\n";
208  }
209 
210  I2_s2[0] = 0;
211  for (int n(1); n < I2_s2.size(); ++n) {
212  I2_s2[n] = U2[n]*f2in[n]+U2m1[n]*f2in[n-1];
213  I2_s2[n] += I2_s2[n-1];
214  // std::cout << "\n I2= " << I2_s2[n] << "\n\n";
215  }
216 
218  n2 = (4.0*M_PI*I2_s2[I2_s2.size()-1]);
219 
220  T2 = m2*(I4_s2[I4_s2.size()-1]/3.0/I2_s2[I2_s2.size()-1]);
221 
222  // std::cout << "\n n2= " << n2 << "\n\n";
223  // std::cout << "\n T2= " << T2 << "\n\n";
224 
225  J1_s2[J1_s2.size()-1] = 0;
226  for (int n(J1_s2.size()-2); n > -1; --n) {
227  J1_s2[n] = U1[n+1]*f2in[n+1]+U1m1[n+1]*f2in[n];
228  J1_s2[n] += J1_s2[n+1];
229  }
230 
231  // for (int k(0); k < I2_s2.size(); ++k){
232  // I4_s2[k] /= pgrid_s2[k]*pgrid_s2[k];
233  // J1_s2[k] *= pgrid_s2[k];
234  // }
235 
236  I4_s2 *= 4.0 * M_PI;
237  I2_s2 *= 4.0 * M_PI;
238  J1_s2 *= 4.0 * M_PI;
239 
240 
242  // for (size_t ip(0); ip < f1in.size() ; ++ip)
243  // {
244  // std::cout << "f1[" << pgrid_s1[ip] << "] = " << f1in[ip] << "\n";
245 
246  // // f1[ip]=f1in[ip];
247  // }
248  n1 = 4.0*M_PI*(Algorithms::moment(f1in,pgrid_s1,2.0));
249  T1 = 4.0*M_PI*m1*(Algorithms::moment(f1in,pgrid_s1,4.0))/3.0/n1;
250 
251 
252 
253  // exit(1);
254 
255 }
256 //-------------------------------------------------------------------
257 
258 //-------------------------------------------------------------------
259 //------------------------------------------------------------------------------
263 
264 
265  double cell_s2 = 0;
266  double dp_s2 = pgrid_s2[2]-pgrid_s2[1];
267  double dist = 0.0;
268 
270  I4_s1[0] = 0.0;
271  I2_s1[0] = 0.0;
272  J1_s1[J1_s1.size()-1] = 0.0;
273 
274  int n(0);
275 
276  while ( (n < pgrid_s1.size()) && (pgrid_s1[n] < pgrid_s2[pgrid_s2.size()-1]))
277  {
278  dist = modf( pgrid_s1[n]/dp_s2 , &cell_s2 );
279  // std::cout << "p[" << n << "]=" << pgrid_s1[n] << ", dist=" << dist << ", cell_s2 = " << cell_s2 << "\n";
280  I4_s1[n] = I4_s2[static_cast<size_t>(cell_s2)]*(1.0-dist) + I4_s2[static_cast<size_t>(cell_s2)+1]*dist;
281  I2_s1[n] = I2_s2[static_cast<size_t>(cell_s2)]*(1.0-dist) + I2_s2[static_cast<size_t>(cell_s2)+1]*dist;
282  J1_s1[n] = J1_s2[static_cast<size_t>(cell_s2)]*(1.0-dist) + J1_s2[static_cast<size_t>(cell_s2)+1]*dist;
283  ++n;
284  }
285  while (n < pgrid_s1.size())
286  {
287  I4_s1[n] = I4_s2[I4_s2.size()];
288  I2_s1[n] = I2_s2[I2_s2.size()];
289  J1_s1[n] = 0.0;
290  ++n;
291  }
292 
293  }
294 //-------------------------------------------------------------------
295 //*******************************************************************
296 //------------------------------------------------------------------------------
303  :collide(DF1,DF2,smalldt){}
304 //--------------------------------------------------------------
305  void interspecies_f00_RKfunctor::operator()(const valarray<double>& fin1, const valarray<double>& fin2, valarray<double>& fslope) {
306  fslope = collide.takestep(fin1,fin2);
307  }
308  void interspecies_f00_RKfunctor::operator()(const valarray<double>& fin1, valarray<double>& fslope) {}
309  void interspecies_f00_RKfunctor::operator()(const valarray<double>& fin1, valarray<double>& fslope, size_t dir) {}
310 
311 //*******************************************************************
312 //-------------------------------------------------------------------
313  interspecies_f00_explicit_collisions::interspecies_f00_explicit_collisions(const DistFunc1D& DF1,const DistFunc1D& DF2, const double& deltat)//, int tout_start) //DistFunc1D& DFin,
314 //-------------------------------------------------------------------
315 // Constructor
316 //-------------------------------------------------------------------
317  :
318  rkf00(DF1, DF2, deltat),
319  fin1(0.0,DF1(0,0).nump()), fin2(0.0,DF2(0,0).nump()),
320  RK4(fin1),
321  num_h(size_t(deltat/Input::List().small_dt)+1)
322  // h(Input::List().small_dt)
323  {
324 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
325  h = deltat/static_cast<double>(num_h);
327  szx = Input::List().NxLocal[0]; //Input::List().numx; // size of useful x axis
328  }
329 //-------------------------------------------------------------------
330 
331 
332 //-------------------------------------------------------------------
334 //-------------------------------------------------------------------
335 // This loop scans all the locations in configuration space
336 // and calls the RK4 for explicit integration at each location
337 //-------------------------------------------------------------------
338  // std::cout << "\n\n DF1 = " << fin1.size();
339  // std::cout << ", DF2 = " << fin2.size() << " \n\n";
340  // valarray<double> fin1(0.0,SH1.nump()),fin2(0.0,SH2.nump());
341  for (size_t ix(0); ix < szx-2*Nbc; ++ix){
342 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
343  // Copy data for a specific location in space to valarray
344  for (size_t ip(0); ip < fin1.size(); ++ip){
345  fin1[ip] = (SH1(ip,ix+Nbc)).real();
346  }
347 
348  for (size_t ip(0); ip < fin2.size(); ++ip){
349  fin2[ip] = (SH2(ip,ix+Nbc)).real();
350  }
351 
352  // // Time loop: Update the valarray
353  for (size_t h_step(0); h_step < num_h; ++h_step){
354 // fin1 = RK4(fin1,fin2,h,&rkf00);
355  }
356  // // std::cout << "\n\n 11 \n\n";
357  // // Return updated data to the harmonic
358  for (int ip(0); ip < fin1.size(); ++ip){
359  // std::cout << "\n\nfin[" << ip << "] = "<< fin1[ip];
360  SH1(ip,ix+Nbc) = fin1[ip];
361  }
362 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
363  }
364 
365  }
366 
367 //*******************************************************************
368 //*******************************************************************
369 // Definition of collisions with high order harmonics FLM
370 //*******************************************************************
371 //*******************************************************************
372 
373 
374 //*******************************************************************
375 //--------------------------------------------------------------
377 //--------------------------------------------------------------
378 // Constructor
379 //--------------------------------------------------------------
380  :
381 // Pre-Calculated Constants
382 // INCLUDED pmax[0] here only because pmax currently is vector having elements for two species
383 // vr(Algorithms::MakeAxis(pmax/(2.0*nump-1.0),pmax,nump)),
384  vr(Algorithms::MakeCAxis(0.0,pmax,nump)),
385 // Constants for Integrals
386  U4(0.0, nump),
387  U4m1(0.0,nump),
388  U2(0.0, nump),
389  U2m1(0.0,nump),
390  U1(0.0, nump),
391  U1m1(0.0,nump),
392 // Integrals
393  J1m(0.0, nump),
394  I0(0.0, nump),
395  I2(0.0, nump),
396  Scattering_Term(0.0, nump),
397  df0(0.0, nump),
398  ddf0(0.0, nump),
399 // Matrices
400  Alpha_Tri(nump, nump),
401  if_tridiagonal(Input::List().if_tridiagonal)
402 // Make matrix vk/vn
403  {
404 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
405 
406  double re(2.8179402894e-13); //classical electron radius
407  double kp(sqrt(4.0*M_PI*(Input::List().density_np)*re));
408  kpre = re*kp;
409 
410  // Determine vr
411  for (size_t i(0); i < vr.size(); ++i) {
412  vr[i] = vr[i] / (sqrt(1.0+vr[i]*vr[i]));
413  }
414 
415  // Determine U4, U4m1, U2, U2m1, U1, U1m1 for the integrals
416  for (size_t i(1); i < U4.size(); ++i) {
417  U4[i] = 0.5 * pow(vr[i],4) * (vr[i]-vr[i-1]);
418  U4m1[i] = 0.5 * pow(vr[i-1],4) * (vr[i]-vr[i-1]);
419  U2[i] = 0.5 * vr[i]*vr[i] * (vr[i]-vr[i-1]);
420  U2m1[i] = 0.5 * vr[i-1]*vr[i-1] * (vr[i]-vr[i-1]);
421  U1[i] = 0.5 * vr[i] * (vr[i]-vr[i-1]);
422  U1m1[i] = 0.5 * vr[i-1] * (vr[i]-vr[i-1]);
423  }
424  }
425 //--------------------------------------------------------------
426 
427 //------------------------------------------------------------------------------
433  void interspecies_flm_implicit_step::reset_coeff(const valarray<double>& fin, const double Delta_t) {
434 //-------------------------------------------------------------------
435 // Reset the coefficients based on f_0^0
436 //-------------------------------------------------------------------
437 
438 // Calculate Dt
439  Dt = Delta_t;
440 
441 // INTEGRALS
442 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
443 // Temperature integral I2 = 4*pi / (v^2) * int_0^v f(u)*u^4du
444  I2[0] = 0;
445  for (int k(1); k < I2.size(); ++k) {
446  I2[k] = U4[k]*fin[k]+U4m1[k]*fin[k-1];
447  I2[k] += I2[k-1];
448  }
449  I2 *= 4.0 * M_PI;
450  I2_temperature = I2[I2.size()-1];
451  for (int k(0); k < I2.size(); ++k){
452  I2[k] /= vr[k]*vr[k];
453  }
454 
455 // Density integral I0 = 4*pi*int_0^v f(u)*u^2du
456  I0[0] = 0;
457  for (int k(1); k < I0.size(); ++k) {
458  I0[k] = U2[k]*fin[k]+U2m1[k]*fin[k-1];
459  I0[k] += I0[k-1];
460  }
461  I0 *= 4.0 * M_PI;
462  I0_density = I0[I0.size()-1];
463 
464 // Integral J_(-1) = 4*pi * v * int_0^v f(u)*u^4du
465  J1m[J1m.size()-1] = 0;
466  for (int k(J1m.size()-2); k > -1; --k) {
467  J1m[k] = U1[k+1]*fin[k+1]+U1m1[k+1]*fin[k];
468  J1m[k] += J1m[k+1];
469  }
470  for (int k(0); k < J1m.size(); ++k){
471  J1m[k] *= 4.0 * M_PI *vr[k];
472  }
473 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
474 
475 // COULOMB LOGARITHMS
476 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
479 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
480 
481 
482 // BASIC INTEGRALS FOR THE TRIDIAGONAL PART
483 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
484 // Temporary arrays
485  valarray<double> TriI1(fin), TriI2(fin);
486 
487  for (int i(0); i < TriI1.size(); ++i){
488  TriI1[i] = I0[i] + (2.0*J1m[i] - I2[i]) / 3.0 ; // (-I2 + 2*J_{-1} + 3*I0) / 3
489  TriI2[i] = ( I2[i] + J1m[i] ) / 3.0 ; // ( I2 + J_{-1} ) / 3
490  }
491 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
492 
493 
494 // SCATTERING TERM
495 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
496  Scattering_Term = TriI1;
497  Scattering_Term *= _LOGee; // Electron-electron contribution
498  Scattering_Term[0] = 0.0;
499  Scattering_Term += _ZLOGei * I0_density; // Ion-electron contribution
500  for (int i(0); i < Scattering_Term.size(); ++i){ // Multiply by 1/v^3
501  Scattering_Term[i] /= pow(vr[i],3);
502  }
503  Scattering_Term *= kpre * Dt;
504 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
505 
506 
507 // MAKE TRIDIAGONAL ARRAY
508 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
509  Alpha_Tri = 0.0;
510  double IvDnDm1, IvDnDp1, Ivsq2Dn;
511  Alpha_Tri(0,0) = 8.0 * M_PI * fin[0]; // 8*pi*f0[0]
512  for (int i(1); i < TriI1.size()-1; ++i){
513  IvDnDm1 = 1.0 / (vr[i] * 0.5*(vr[i+1]-vr[i-1]) * (vr[i] -vr[i-1])); // ( v*D_n*D_{n-1/2} )^(-1)
514  IvDnDp1 = 1.0 / (vr[i] * 0.5*(vr[i+1]-vr[i-1]) * (vr[i+1]-vr[i] )); // ( v*D_n*D_{n+1/2} )^(-1)
515  Ivsq2Dn = 1.0 / (vr[i] * vr[i] * (vr[i+1]-vr[i-1])); // ( v^2 * 2*D_n )^(-1)
516  Alpha_Tri(i, i ) = 8.0 * M_PI * fin[i] - TriI2[i] * (IvDnDm1 + IvDnDp1);
517  Alpha_Tri(i, i-1) = TriI2[i] * IvDnDm1 - TriI1[i] * Ivsq2Dn;
518  Alpha_Tri(i, i+1) = TriI2[i] * IvDnDp1 + TriI1[i] * Ivsq2Dn;
519  }
520  Alpha_Tri *= (-1.0) * _LOGee * kpre * Dt; // (-1) because the matrix moves to the LHS in the equation
521 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
522 
523 // CALCULATE DERIVATIVES
524 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
525 
526 // Evaluate the derivative
527  for (int n(1); n < fin.size()-1; ++n) {
528  df0[n] = fin[n+1]-fin[n-1];
529  df0[n] /= vr[n+1]-vr[n-1];
530  }
531 
532 // Evaluate the second derivative
533 // -df/dv_{n-1/2}
534  for (int n(1); n < fin.size(); ++n) {
535  ddf0[n] = (fin[n-1]-fin[n]) ;
536  ddf0[n] /= vr[n] - vr[n-1] ;
537  }
538 // D(df/dv)/Dv
539  for (int n(1); n < fin.size()-1; ++n) {
540  ddf0[n] -= ddf0[n+1];
541  ddf0[n] /= 0.5*(vr[n+1]-vr[n-1]);
542  }
543 
544 // Calculate zeroth cell
545  double f00 = ( fin[0] - ( (vr[0]*vr[0])/(vr[1]*vr[1]) ) *fin[1] )
546  / (1.0 - (vr[0]*vr[0])/(vr[1]*vr[1]));
547  ddf0[0] = 2.0 * (fin[1] - f00) / (vr[1]*vr[1]);
548  df0[0] = ddf0[0] * vr[0];
549 
550 // Calculate 1/(2v)*(d^2f)/(dv^2), 1/v^2*df/dv
551  for (int n(0); n < fin.size()-1; ++n) {
552  df0[n] /= vr[n]*vr[n];
553  ddf0[n] /= 2.0 *vr[n];
554  }
555 
556 
557 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
558 
559  }
560 //-------------------------------------------------------------------
561 
562 //------------------------------------------------------------------------------
568  void interspecies_flm_implicit_step::advance(valarray<complex<double> >& fin, const int el) {
569 //-------------------------------------------------------------------
570 // Collisions
571 //-------------------------------------------------------------------
572  Array2D<double> Alpha(Alpha_Tri);
573  valarray<complex<double> > fout(fin);
574 
575 
576 // ZEROTH CELL FOR TRIDIAGONAL ARRAY
577 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
578  if (el > 1) {
579  Alpha(0,0) = 0.0;
580  }
581 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
582 
583  if ( !(if_tridiagonal) ) {
584 
585 // CONSTRUCT COEFFICIENTS and then full array
586 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
587  double LL(el);
588  double A1( (LL+1.0)*(LL+2.0) / ((2.0*LL+1.0)*(2.0*LL+3.0)) );
589  double A2( (-1.0) *(LL-1.0)* LL / ((2.0*LL+1.0)*(2.0*LL-1.0)) );
590  double B1( (-1.0) *( 0.5 *LL*(LL+1.0) +(LL+1.0) ) / ((2.0*LL+1.0)*(2.0*LL+3.0)) );
591  double B2( ( (-0.5)*LL*(LL+1.0) +(LL+2.0) ) / ((2.0*LL+1.0)*(2.0*LL+3.0)) );
592  double B3( ( 0.5 *LL*(LL+1.0) +(LL-1.0) ) / ((2.0*LL+1.0)*(2.0*LL-1.0)) );
593  double B4( ( 0.5 *LL*(LL+1.0) - LL ) / ((2.0*LL+1.0)*(2.0*LL-1.0)) );
594 
595 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
596  for (int i(0); i < Alpha.dim1()-1; ++i){
597  double t1( A1*ddf0[i] + B1*df0[i] );
598  t1 *= (-1.0) * _LOGee * kpre * Dt;
599  double t2( A1*ddf0[i] + B2*df0[i] );
600  t2 *= (-1.0) * _LOGee * kpre * Dt;
601  double t3( A2*ddf0[i] + B3*df0[i] );
602  t3 *= (-1.0) * _LOGee * kpre * Dt;
603  double t4( A2*ddf0[i] + B4*df0[i] );
604  t4 *= (-1.0) * _LOGee * kpre * Dt;
605 
606  Alpha(i,0) += t1 * ( 2.0*M_PI*pow(vr[0]/vr[i],el+2)*vr[0]*vr[0]*(vr[1]-vr[0]) );
607  Alpha(i,0) += t3 * ( 2.0*M_PI*pow(vr[0]/vr[i],el) *vr[0]*vr[0]*(vr[1]-vr[0]) );
608 
609  for (int j(1); j < i; ++j){
610  Alpha(i,j) += t1 * ( 2.0*M_PI*pow(vr[j]/vr[i],el+2)*vr[j]*vr[j]*(vr[j+1]-vr[j-1]) );
611  Alpha(i,j) += t3 * ( 2.0*M_PI*pow(vr[j]/vr[i],el) *vr[j]*vr[j]*(vr[j+1]-vr[j-1]) );
612  }
613 
614  Alpha(i,i) += t1 * ( 2.0*M_PI *vr[i]*vr[i]*(vr[i]-vr[i-1]) );
615  Alpha(i,i) += t3 * ( 2.0*M_PI *vr[i]*vr[i]*(vr[i]-vr[i-1]) );
616 
617  Alpha(i,i) += t2 * ( 2.0*M_PI *vr[i]*vr[i]*(vr[i+1]-vr[i]) );
618  Alpha(i,i) += t4 * ( 2.0*M_PI *vr[i]*vr[i]*(vr[i+1]-vr[i]) );
619 
620  for (int j(i+1); j < Alpha.dim2()-1; ++j){
621  Alpha(i,j) += t2 * ( 2.0*M_PI*pow(vr[j]/vr[i],-el-1)*vr[j]*vr[j]*(vr[j+1]-vr[j-1]) );
622  Alpha(i,j) += t4 * ( 2.0*M_PI*pow(vr[j]/vr[i],-el+1)*vr[j]*vr[j]*(vr[j+1]-vr[j-1]) );
623  }
624  }
625 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
626  }
627 
628 // INCLUDE SCATTERING TERM
629 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
630  double ll1(static_cast<double>(el));
631  ll1 *= (-0.5)*(ll1 + 1.0);
632 
633  for (int i(0); i < Alpha.dim1(); ++i){
634  Alpha(i,i) += 1.0 - ll1 * Scattering_Term[i];
635  }
636 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
637 
638 
639 // SOLVE A * Fout = Fin
640 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
641  //for (int i(0); i < fin.size(); ++i){ // Estimate Fout = Fin / A(i,i)
642  // fout[i] /= Alpha(i,i);
643  //}
644 
645  if ( if_tridiagonal ) {
646  if ( !(Thomas_Tridiagonal(Alpha, fin, fout)) ) { // Invert A * fout = fin
647  cout << "WARNING: Matrix is not diagonally dominant" << endl;
648  }
649  }
650  else {
651  if ( !(Gauss_Seidel(Alpha, fin, fout)) ) { // Invert A * fout = fin
652  cout << "WARNING: Matrix is not diagonally dominant" << endl;
653  }
654  }
655 
656  fin = fout;
657 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
658 
659  }
660 //-------------------------------------------------------------------
661 //*******************************************************************
662 
663 
664 //*******************************************************************
665 //*******************************************************************
666 // Definition for the Anisotropic Collisions
667 //*******************************************************************
668 //*******************************************************************
669 
670 
671 //*******************************************************************
672 //-------------------------------------------------------------------
674 //-------------------------------------------------------------------
675 // Constructor
676 //-------------------------------------------------------------------
677  : f00(0.0, DFin(0).nump()),
678  fc(0.0,DFin(0).nump()),
679  l0(DFin.l0()),
680  m0(DFin.m0()),//Yin.SH(0,0).m0())
681  implicit_step(DFin.pmax(),DFin(0).nump()),
682  Dt(deltat) //
683  {
684 
685 
687  szx = Input::List().NxLocal[0];
688 
689  }
690 //-------------------------------------------------------------------
691 
692 
693 //-------------------------------------------------------------------
695 //-------------------------------------------------------------------
696 // This is the calculation for the harmonics f10, f11
697 // To be specific, this routine does just l=1
698 // To be specific, this routine differs from 'f1_loop1D' above only in one place: the loop is on m=0 and m=1
699 //-------------------------------------------------------------------
700 
701  // For every location in space within the domain of this node
702 
703  for (size_t ix(0); ix < szx-2*Nbc; ++ix){
704 
705 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
706  // "00" harmonic --> Valarray
707  for (size_t ip(0); ip < fc.size(); ++ip){
708  f00[ip] = (DF(0,0)(ip,ix+Nbc)).real();
709  }
710  // Reset the integrals and coefficients
712 
713  // Loop over the harmonics for this (x,y)
714  for(int m(0); m < 2; ++m){
715 
716  // This harmonic --> Valarray
717  for (int ip(0); ip < DF(1,m).nump(); ++ip) {
718  fc[ip] = DF(1,m)(ip,ix+Nbc);
719  }
720 
721  // Take an implicit step
723 
724  // Valarray --> This harmonic
725  for (int ip(0); ip < DF(1,m).nump(); ++ip) {
726  DF(1,m)(ip,ix+Nbc) = fc[ip];
727  }
728  }
729 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
730  }
731  }
732 //-------------------------------------------------------------------
733 
734 
735 
736 //-------------------------------------------------------------------
738  {
739 //-------------------------------------------------------------------
740 // This is the calculation for the high order harmonics
741 // To be specific, this routine does l=2 to l0
742 // To be specific, this routine differs from 'flm_loop1D' aboe only in one place: the loop over m all m from 0 to ((m0 < l)? m0:l)
743 //-------------------------------------------------------------------
744 
745  // For every location in space within the domain of this node
746 
747  for (size_t ix(0); ix < szx-2*Nbc; ++ix){
748 
749 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
750  // "00" harmonic --> Valarray
751  for (size_t ip(0); ip < fc.size(); ++ip){
752  f00[ip] = (DF(0,0)(ip,ix+Nbc)).real();
753  }
754  // Reset the integrals and coefficients
755  // --> Assume you did that when you called f1_loop
757  // Loop over the harmonics for this (x,y)
758  for(int l(2); l < l0+1 ; ++l){
759  for(int m(0); m < ((m0 < l)? m0:l)+1; ++m){
760 
761  // This harmonic --> Valarray
762  for (size_t ip(0); ip < fc.size(); ++ip){
763  fc[ip] = (DF(l,m))(ip,ix+Nbc);
764  }
765 
766  // Take an implicit step
768 
769  // Valarray --> This harmonic
770  for (size_t ip(0); ip < fc.size(); ++ip){
771  DF(l,m)(ip,ix+Nbc) = fc[ip];
772  }
773  }
774  }
775  }
776 
777  return;
778 
779  }
780 //-------------------------------------------------------------------
781 
782 
784 //-------------------------------------------------------------------
785  interspecies_collisions::interspecies_collisions(const State1D& Yin, const size_t& sind, const double& deltat)
786 //-------------------------------------------------------------------
787 // Constructor
788 //-------------------------------------------------------------------
789  // : interspecies_f00_collisions(WS, deltat),
790  // interspecies_flm_collisions(DFin, deltat){
791  {
792 
793  // size_t sind(0);
794  for (size_t s(0); s<Yin.Species(); ++s){
795  if (s!=sind) {
796 
797  interspecies_f00_collisions.push_back(interspecies_f00_explicit_collisions(Yin.DF(sind),Yin.DF(s),deltat));
798  std::cout << "\n\n sind,s = " << sind << "," << s << ", size = " <<interspecies_f00_collisions.size() << "\n\n";
799  }
800  }
801 
802  }
803 
804 //-------------------------------------------------------------------
805 
806 //-------------------------------------------------------------------
807 //-------------------------------------------------------------------
808  // void interspecies_collisions::advanceflm(DistFunc1D& DFin){
809 //-------------------------------------------------------------------
810  // interspecies_flm_collisions.advanceflm(DFin);
811 // }
812 
813 
814 //-------------------------------------------------------------------
815  // void interspecies_collisions::advancef1(DistFunc1D& DFin){
816 //-------------------------------------------------------------------
817 // interspecies_flm_collisions.advancef1(DFin);
818 // }
819 //-------------------------------------------------------------------
820 //*******************************************************************
821 //-------------------------------------------------------------------
822 //------------------------------------------------------------------------------
825 // interspecies_collisions::interspecies_collisions(const State1D& Yin, const size_t sin, const double& deltat)
826 //-------------------------------------------------------------------
827 // Constructor
828 //-------------------------------------------------------------------
829 
830 
831  // }
832 
833 //-------------------------------------------------------------------
834 //------------------------------------------------------------------------------
837 void interspecies_collisions::advancef00( State1D& Yin, const size_t& sind){
838 // //-------------------------------------------------------------------
839  // size_t sind(0);
840 
841  for (size_t s(0); s<Yin.Species(); ++s){
842  if (s!=sind) {
843 
844  interspecies_f00_collisions[sind].rkloop(Yin.SH(sind,0,0),Yin.SH(s,0,0));
845  std::cout << "\n\n sind,s = " << sind << "," << s << "\n\n";
846  // ++sind;
847  }
848 
849  }
850 }
851 
852 //-------------------------------------------------------------------
853 //------------------------------------------------------------------------------
856 // void interspecies_collisions::advancef1( State1D& Yin, const size_t sin){
857 // // //-------------------------------------------------------------------
858 // size_t sind(0);
859 // for (size_t s(0); s<Yin.Species(); ++s){
860 // // sind=0;
861 // // for (size_t so(0); so<Yin.Species(); ++s)
862 // // {
863 // if (s!=sin) {
864 // interspecies_flm_collisions[sind].advancef1(Yin.DF(sin,0,0),Yin.SH(s,0,0));
865 // ++sind;
866 // // }
867 // }
868 // }
869 // }
870 
871 // //-------------------------------------------------------------------
872 // //------------------------------------------------------------------------------
873 // /// @brief Advance f1 collisions for all species
874 // ///
875 // void interspecies_collisions::advanceflm( State1D& Yin, const size_t sin){
876 // // //-------------------------------------------------------------------
877 // size_t sind(0);
878 // for (size_t s(0); s<Yin.Species(); ++s){
879 // // sind=0;
880 // // for (size_t so(0); so<Yin.Species(); ++s)
881 // // {
882 // if (s!=sin) {
883 // interspecies_flm_collisions[sind].advancef1(Yin.SH(sin,0,0),Yin.SH(s,0,0));
884 // ++sind;
885 // // }
886 // }
887 // }
888 // }
889 //*******************************************************************
890 
891 //*******************************************************************
void advancef00(State1D &Y, const size_t &sind)
Remap Distribution to momentum grid of colliding particles.
Algorithms
Plasma Formulary and Units - Declarations.
void operator()(const valarray< double > &fin1, valarray< double > &fslope)
bool Thomas_Tridiagonal(Array2D< double > &A, valarray< double > &d, valarray< double > &xk)
The tridiagonal solver for implicit collisions.
Definition: nmethods.cpp:216
interspecies_f00_RKfunctor(const DistFunc1D &DF1, const DistFunc1D &DF2, const double &smalldt)
Constructor for RK4 method on f00.
std::vector< size_t > NxLocal
Definition: input.h:168
Input reader - Declarations.
valarray< complex< double > > fc
Dummy array.
Underlying data structures.
int szx
Total cells including boundary cells in x-direction.
double Zeta
Definition: formulary.h:104
valarray< double > J1_s1
The integrals.
Interspecies Collisions - Definitions.
interspecies_f00_explicit_step collide
double LOGee(double ne, double Te)
Definition: formulary.cpp:226
double mass() const
Definition: state.h:400
size_t dim1() const
Definition: lib-array.h:289
void remapintegrals()
Remap Distribution to momentum grid of colliding particles.
interspecies_f00_explicit_collisions(const DistFunc1D &DF1, const DistFunc1D &DF2, const double &deltat)
Constructors/Destructors.
valarray< double > J1_s2
The integrals.
interspecies_flm_implicit_step implicit_step
The object that is responsible for performing the algebra required for the integrals.
size_t dim2() const
Definition: lib-array.h:290
int szx
Total cells including boundary cells in x-direction.
double LOGei(double ne, double Te, double Z)
Definition: formulary.cpp:249
int Nbc
Number of boundary cells in each direction.
void calculateintegrals(const valarray< double > &f1in, const valarray< double > &f2in)
Remap Distribution to momentum grid of colliding particles.
A 1D Spherical Harmonic.
Definition: state.h:57
int Nbc
Number of boundary cells in each direction.
Definition: state.h:577
void advancef1(DistFunc1D &DF)
Advance f1_loop for 2D code.
void rkloop(SHarmonic1D &SH1, const SHarmonic1D &SH2)
double q() const
Definition: state.h:399
interspecies_flm_implicit_step(double pmax, size_t nump)
DistFunc1D & DF(size_t s)
Definition: state.h:602
interspecies_flm_implicit_collisions(const DistFunc1D &DFin, const double &deltat)
Constructors/Destructors.
SHarmonic1D & SH(size_t s, size_t lh, size_t mh)
Definition: state.h:605
Fields, Distributions, Harmonics, States - Declarations.
double LOGii(double m1, double Z1, double n1, double T1, double m2, double Z2, double n2, double T2)
Definition: formulary.cpp:271
void reset_coeff(const valarray< double > &f00, const double Delta_t)
Resets coefficients and integrals to use in the matrix solve.
int Nbc
Number of boundary cells in each direction.
valarray< double > f00
Array for isotropic component distribution function. Needed for calculating coefficients.
valarray< T > MakeCAxis(const T min, const T max, const size_t N)
Input_List & List()
Definition: input.cpp:1585
valarray< double > takestep(const valarray< double > &f1in, const valarray< double > &f2in)
Collisions between species 1 and 2 in 0,0 harmonic.
interspecies_collisions(const State1D &Yin, const size_t &sind, const double &deltat)
Constructors/Destructors.
int szx
Total cells including boundary cells in x-direction.
void advanceflm(DistFunc1D &DF)
Advance flm_loop for 2D code.
Definition: input.h:18
int BoundaryCells
Definition: input.h:50
interspecies_f00_explicit_step(const DistFunc1D &DF1, const DistFunc1D &DF2, const double &deltat)
Constructors/Destructors.
size_t Species() const
Definition: state.h:596
bool Gauss_Seidel(Array2D< double > &A, valarray< complex< double > > &b, valarray< complex< double > > &xk)
Performs Gauss-Seidel method on Ax = b.
Definition: nmethods.cpp:29
The 1D distribution function is the container for all SHarmonic1D per species.
Definition: state.h:376
T moment(const vector< T > q, const vector< T > x, const int p)
void advance(valarray< complex< double > > &fin, const int el)
Perform a matrix solve to calculate effect of collisions on f >= 1.
Numerical Methods - Declarations.