OSHUN  beta
Arbitrary Order Spherical-Harmonic 1D-3P Vlasov-Fokker-Planck-Maxwell code
implicitE.cpp
Go to the documentation of this file.
1 
12 // Standard libraries
13  #include <iostream>
14  #include <vector>
15  #include <valarray>
16  #include <complex>
17  #include <algorithm>
18  #include <cstdlib>
19  #include <float.h>
20  #include <math.h>
21  #include <map>
22  #include <limits>
23 
24 // My libraries
25  #include "lib-array.h"
26  #include "lib-algorithms.h"
27 
28 // Declarations
29  #include "input.h"
30 
31  #include "state.h"
32  #include "fluid.h"
33  #include "vlasov.h"
34  #include "functors.h"
35  #include "formulary.h"
36  #include "nmethods.h"
37  #include "collisions.h"
38 
39  #include "implicitE.h"
40 //**************************************************************
41 
42 
43 // vector<float> vfloat(const vector<complex<double> > vDouble);
44 // vector<float> vfloat_complex(const vector<complex<double> > vDouble);
45 //**************************************************************
46 //**************************************************************
47 //*******THE CLASS FOR THE CURRENT DEFINITION ******************
48 //**************************************************************
49 //**************************************************************
50 
51 //**************************************************************
52 //--------------------------------------------------------------
54 //--------------------------------------------------------------
55 // Constructor
56 //--------------------------------------------------------------
57  : jayx(emf.Ex()),
58  jayy(emf.Ex()),
59  jayz(emf.Ex()),
60  // p3og(Algorithms::MakeAxis(
61  // static_cast< complex<double> >(Input::List().pmin),
62  // static_cast< complex<double> >(Input::List().pmaxs[0]),
63  // Input::List().ps[0])),
64  // Delta_p(static_cast< complex<double> >((Input::List().pmaxs[0]-Input::List().pmin)/Input::List().ps[0])),
65  // small(static_cast< complex<double> >(Input::List().pmin)),
66  tempx(0.0,emf.Ex().numx()),
67  tempy(0.0,emf.Ex().numx()),
68  tempz(0.0,emf.Ex().numx()),
69  fourpioverthree(4.0*M_PI/3.0,0.0)
70  {
72  szx = Input::List().NxLocal[0];
73  // for (size_t s(0); s<Yin.Species();++s)
74  // {
75  // for (size_t i(0); i<p3og.size(); ++i) { // calculate p^3/g
76  // p3og[i] = (p3og[i]*p3og[i])*(p3og[i]/sqrt(1.0+p3og[i]*p3og[i]));
77  // }
78  // p3ogv.push_back(p3og);
79  // }
80  // small *= small; small *= small; small *= Input::List().pmin;
81  // small *= 0.2; small *= 1.0/(Input::List().pmin+Delta_p);
82  }
83 //--------------------------------------------------------------
84 
85 //--------------------------------------------------------------
87 //--------------------------------------------------------------
88 // Return the current component 1 --> x, 2 --> y, 3 --> z
89 //--------------------------------------------------------------
90 
91  switch (component) {
92  case 1: {
93  return Jx();
94  break;
95  }
96  case 2: {
97  return Jy();
98  break;
99  }
100  case 3: {
101  return Jz();
102  break;
103  }
104  default: {
105  cout << "There is no such component for the current!" << endl;
106  exit(1);
107  break;
108  }
109  }
110  return Jx();
111 }
112 //--------------------------------------------------------------
113 
114 //--------------------------------------------------------------
116  return jayx;
117  }
118 //--------------------------------------------------------------
119 
120 //--------------------------------------------------------------
122  return jayy;
123  }
124 //--------------------------------------------------------------
125 
126 //--------------------------------------------------------------
128  return jayz;
129  }
130 //--------------------------------------------------------------
131 
132 
133 //--------------------------------------------------------------
136 //--------------------------------------------------------------
137 // Update the total current
138 //--------------------------------------------------------------
139  complex<double> c01(0.0,1.0);
140  complex<double> pmin, pmax;
141  size_t nump;
142  Array2D<double> current(3,Yin.EMF().Ex().numx());
143 
144  // jayx=0.0;jayy=0.0;jayz=0.0;
145  jayx = static_cast<complex<double> >(0.0);
146  jayy = static_cast<complex<double> >(0.0);
147  jayz = static_cast<complex<double> >(0.0);
148 
149 
150  for (size_t s(0); s < Yin.Species(); ++s){
151  current = Yin.DF(s).getcurrent();
152  for (size_t ix(0); ix < Yin.EMF().Ex().numx(); ++ix)
153  {
154  jayx(ix) += static_cast<complex<double>>(current(0,ix));
155  jayy(ix) += static_cast<complex<double>>(current(1,ix));
156  jayz(ix) += static_cast<complex<double>>(current(2,ix));
157 
158  }
159 
160  // jayx.array() += static_cast<complex<double>>(Yin.DF(s).getcurrent(0));
161  // jayy.array() += static_cast<complex<double>>(Yin.DF(s).getcurrent(1));
162  // jayz.array() += static_cast<complex<double>>(Yin.DF(s).getcurrent(2));
163  }
164 }
165 //--------------------------------------------------------------
166 
167 //**************************************************************
168 //--------------------------------------------------------------
170 //--------------------------------------------------------------
171 // Constructor
172 //--------------------------------------------------------------
173  : efieldx(emf.Ex()),
174  efieldy(emf.Ey()),
175  efieldz(emf.Ez()) {
176  }
177 //--------------------------------------------------------------
178 
179 //--------------------------------------------------------------
181 //--------------------------------------------------------------
182 // Return the current component 1 --> x, 2 --> y, 3 --> z
183 //--------------------------------------------------------------
184 
185  switch (component) {
186  case 1: {
187  return Ex();
188  break;
189  }
190  case 2: {
191  return Ey();
192  break;
193  }
194  case 3: {
195  return Ez();
196  break;
197  }
198  default: {
199  cout << "There is no such component for the current!" << endl;
200  exit(1);
201  break;
202  }
203  }
204  return Ex();
205 }
206 //--------------------------------------------------------------
207 
208 //--------------------------------------------------------------
210  return efieldx;
211  }
212 //--------------------------------------------------------------
213 
214 //--------------------------------------------------------------
216  return efieldy;
217  }
218 //--------------------------------------------------------------
219 
220 //--------------------------------------------------------------
222  return efieldz;
223  }
224 //--------------------------------------------------------------
225 //**************************************************************
226 
227 
228 
229 //**************************************************************
230 //--------------------------------------------------------------
231 // Definition of the pure virtual destructor for the abstract
232 // class Explicit_Method
233 //--------------------------------------------------------------
236 //**************************************************************
237 
238 
239 //**************************************************************
240 //**************************************************************
241 // Definition for the implicit electric field
242 //**************************************************************
243 //**************************************************************
244 
245 
246 //**************************************************************
247 //--------------------------------------------------------------
249  Implicit_E_Field(EMF1D& emf, const double& deltat, const double& deltax)://, int tout_start)
250 //--------------------------------------------------------------
251 // Constructor for the implicit electric field
252 //--------------------------------------------------------------
253  JN(emf), J0(emf), // New current, Current from E = 0
254  J_Ex(emf), J_Ey(emf), J_Ez(emf), // Current due to the effect of Ex, Ey, Ez
255  EN(emf), E0(emf), DE(emf), // New E, old E, perturbation E
256 
257  dt(deltat),
258  idx(static_cast< complex<double> >(0.5/deltax))
259  {
260 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
262  szx = Input::List().NxLocal[0];
263  }
264 //--------------------------------------------------------------
265 
266 //--------------------------------------------------------------
268  advance(Algorithms::RK3<State1D>* rk, State1D& Yin, collisions& coll, VlasovFunctor1D_implicitE_p2* rkF){//, double time, double dt){
269 //--------------------------------------------------------------
270 // Calculate the implicit electric field
271 //--------------------------------------------------------------
272 
273  int zeros_in_det(1); // This counts the number of zeros in the determinant
274  int execution_attempt(0); // This counts the number of attempts to find invert the E-field
275  State1D Yh(Yin);
276  Yh = 0.0;
277 
278  // vector<SHarmonic1D> f00;
279  // vector<SHarmonic1D> f10;vector<SHarmonic1D> f11;
280  // vector<SHarmonic1D> f20;vector<SHarmonic1D> f21;vector<SHarmonic1D> f22;
281 
282  // for (size_t s(0); s < Yin.Species(); ++s){
283  // f00.push_back(Yin.SH(s,0,0));
284  // f10.push_back(Yin.SH(s,1,0));f11.push_back(Yin.SH(s,1,1));
285  // f20.push_back(Yin.SH(s,2,0));f21.push_back(Yin.SH(s,2,1));f22.push_back(Yin.SH(s,2,2));
286  // }
287 
288  FindDE(Yin.EMF()); // Reset DE
289 
290 // - - - - - - - - - - - - - - - - - - - - - -
291  while ( (zeros_in_det > 0) && ( execution_attempt < 4) ) { // Execute this loop at most twice
292  zeros_in_det = 0; // Count the zeros of the determinant
293  ++execution_attempt; // Count the execusion attempts
294 // - - - - - - - - - - - - - - - - - - - - - -
295 // - - - - - - - - - - - - - - - - - - - - - -
296  // Effect of E = 0 on f00, f10, f11
297 
298  coll.advancef1(Yin,Yh); // Collisions for f10, f11
299  // for (size_t s(0); s < Yin.Species(); ++s){
300  // Yin.SH(s,1,0) = Yh.SH(s,1,0);
301  // Yin.SH(s,1,1) = Yh.SH(s,1,0);
302  // }
303  J0.calculate_J(Yh);
304 
305 
306  // for (size_t s(0); s < Yin.Species(); ++s){
307  // Yin.SH(s,0,0) = f00[s];
308  // Yin.SH(s,1,0) = f10[s];Yin.SH(s,1,1) = f11[s];
309  // // Yin.SH(s,2,0) = f20[s];Yin.SH(s,2,1) = f21[s];Yin.SH(s,2,2) = f22[s];
310  // }
311 
312  Yin.EMF().Ex() = DE.Ex(); // Ex = DEx
313  Yin = (*rk)(Yin, dt, rkF, 1); // Effect of DEx on Y00, Y10, Y11, Y20, Y21, Y22
314  coll.advancef1(Yin,Yh); // Collisions for f10, f11
315  // for (size_t s(0); s < Yin.Species(); ++s){
316  // Yin.SH(s,1,0) = Yh.SH(s,1,0);
317  // Yin.SH(s,1,1) = Yh.SH(s,1,0);
318  // } // Collisions for f10, f11
319  J_Ex.calculate_J(Yh); // Evaluate J(DEx)
320 
321  // Ytemp = Yin;
322  // for (size_t s(0); s < Yin.Species(); ++s){
323  // Yin.SH(s,0,0) = f00[s];
324  // Yin.SH(s,1,0) = f10[s];Yin.SH(s,1,1) = f11[s];
325  // Yin.SH(s,2,0) = f20[s];Yin.SH(s,2,1) = f21[s];Yin.SH(s,2,2) = f22[s];
326  // }
327 
328  //
329  Yin.EMF().Ey() = DE.Ey(); // Ey = DEy
330  Yin = (*rk)(Yin, dt, rkF, 2); // Effect of DEy on Y00, Y10, Y11, Y20, Y21, Y22
331  coll.advancef1(Yin,Yh); // Collisions for f10, f11
332  // for (size_t s(0); s < Yin.Species(); ++s){
333  // Yin.SH(s,1,0) = Yh.SH(s,1,0);
334  // Yin.SH(s,1,1) = Yh.SH(s,1,0);
335  // } // Collisions for f10, f11
336  J_Ey.calculate_J(Yh); // Evaluate J(DEy)
337 
338  // Ytemp = Yin;
339  // for (size_t s(0); s < Yin.Species(); ++s){
340  // Yin.SH(s,0,0) = f00[s];
341  // Yin.SH(s,1,0) = f10[s];Yin.SH(s,1,1) = f11[s];
342  // Yin.SH(s,2,0) = f20[s];Yin.SH(s,2,1) = f21[s];Yin.SH(s,2,2) = f22[s];
343  // }
344 // - - - - - - - - - - - - - - - - - - - - - -
345 
346 
347  Yin.EMF().Ez() = DE.Ez(); // Ey = DEy
348  Yin = (*rk)(Yin, dt, rkF, 3); // Effect of DEy on Y00, Y10, Y11, Y20, Y21, Y22
349 
350  coll.advancef1(Yin,Yh); // Collisions for f10, f11
351  // for (size_t s(0); s < Yin.Species(); ++s){
352  // Yin.SH(s,1,0) = Yh.SH(s,1,0);
353  // Yin.SH(s,1,1) = Yh.SH(s,1,0);
354  // }
355 
356  J_Ez.calculate_J(Yh); //exit(1); // Evaluate J(DEy)
357 
358  // Ytemp = Yin;
359  // for (size_t s(0); s < Yin.Species(); ++s){
360  // Yin.SH(s,0,0) = f00[s];
361  // Yin.SH(s,1,0) = f10[s];Yin.SH(s,1,1) = f11[s];
362  // Yin.SH(s,2,0) = f20[s];Yin.SH(s,2,1) = f21[s];Yin.SH(s,2,2) = f22[s];
363  // }
364 // - - - - - - - - - - - - - - - - - - - - - -
365 
366 
367  Ampere(Yin.EMF()); // Calculate JN
368 
369 
370 // - - - - - - - - - - - - - - - - - - - - - -
371 
372  // calculate new EN
373 
374  Array2D< complex<double> > sgm(3,3);
375  valarray< complex<double> > clm(3);
376 
377 
378  // for (size_t iy(0); iy < szy; ++iy){
379  for (size_t ix(0); ix < szx; ++ix){
380  sgm(0,0) = ( J_Ex.Jx()(ix) - J0.Jx()(ix) ) / DE.Ex()(ix); // sxx = dJ(E_x)_x/DE_x
381  sgm(0,1) = ( J_Ey.Jx()(ix) - J0.Jx()(ix) ) / DE.Ey()(ix); // sxy = dJ(E_y)_x/DE_y
382  sgm(0,2) = ( J_Ez.Jx()(ix) - J0.Jx()(ix) ) / DE.Ez()(ix); // sxz = dJ(E_z)_x/DE_z
383 
384  sgm(1,0) = ( J_Ex.Jy()(ix) - J0.Jy()(ix) ) / DE.Ex()(ix); // syx = dJ(E_x)_y/DE_x
385  sgm(1,1) = ( J_Ey.Jy()(ix) - J0.Jy()(ix) ) / DE.Ey()(ix); // syy = dJ(E_y)_y/DE_y
386  sgm(1,2) = ( J_Ez.Jy()(ix) - J0.Jy()(ix) ) / DE.Ez()(ix); // syz = dJ(E_z)_y/DE_z
387 
388  sgm(2,0) = ( J_Ex.Jz()(ix) - J0.Jz()(ix) ) / DE.Ex()(ix); // szx = dJ(E_x)_z/DE_x
389  sgm(2,1) = ( J_Ey.Jz()(ix) - J0.Jz()(ix) ) / DE.Ey()(ix); // szy = dJ(E_y)_z/DE_y
390  sgm(2,2) = ( J_Ez.Jz()(ix) - J0.Jz()(ix) ) / DE.Ez()(ix); // szz = dJ(E_z)_z/DE_z
391 
392  clm[0] = JN.Jx()(ix) - J0.Jx()(ix);
393  clm[1] = JN.Jy()(ix) - J0.Jy()(ix);
394  clm[2] = JN.Jz()(ix) - J0.Jz()(ix);
395 
396 
397 
398  // std::cout << "\n\n" << sgm(0,0) << " , " << sgm(0,1) << " , " << sgm(0,2) << "\n";
399  // std::cout << sgm(1,0) << " , " << sgm(1,1) << " , " << sgm(1,2) << "\n";
400  // std::cout << sgm(2,0) << " , " << sgm(2,1) << " , " << sgm(2,2) << "\n";
401 
402 
403  // Solve the 3 by 3 system of equations
404  complex<double> D_sgm( Det33(sgm) ); // The Determinant of the conductivity tensor
405  if ( abs( D_sgm.real() ) > 6.0*DBL_MIN ) {
406  EN.Ex()(ix) = Detx33(clm, sgm) / D_sgm;
407  EN.Ey()(ix) = Dety33(clm, sgm) / D_sgm;
408  EN.Ez()(ix) = Detz33(clm, sgm) / D_sgm;
409  }
410  else {
411  ++zeros_in_det; // Try again with a new perturbation as below
412  // exit(1);
413  DE.Ex()(ix) *= 2; // DEx is 2 times larger than before
414  DE.Ey()(ix) *= 1.3; // DEy is 1.3 times larger than before
415 
416  EN.Ex()(ix) = 0.0;
417  EN.Ey()(ix) = 0.0;
418  EN.Ez()(ix) = 0.0;
419  }
420  }
421  // }
422 // - - - - - - - - - - - - - - - - - - - - - -
423 
424  } // End the while statement
425 // - - - - - - - - - - - - - - - - - - - - - -
426 
427 // - - - - - - - - - - - - - - - - - - - - - -
428  Yin.EMF().Ex() = EN.Ex();
429  Yin.EMF().Ey() = EN.Ey();
430  Yin.EMF().Ez() = EN.Ez();
431 
432  if ( zeros_in_det > 0) {
433  cout << "WARNING, Det = 0 in "<<zeros_in_det <<"locations" << endl;
434  if ( zeros_in_det > 8) { exit(1);}
435  }
436 
437  // return Ytemp;
438  }
439 // }
440 //--------------------------------------------------------------
441 
442 
443 // //--------------------------------------------------------------
444 // bool Electric_Field_Methods::Implicit_E_Field::
445 // implicitE() const {
446 // return true;
447 // }
448 //--------------------------------------------------------------
449 
450 //--------------------------------------------------------------
452 //--------------------------------------------------------------
453 // Reset DE
454 //--------------------------------------------------------------
455  double Eps(16.0*numeric_limits<double>::epsilon());
456  double LargeEps(sqrt(Eps));
457 
458  DE.Ex() = emf.Ex();
459  DE.Ey() = emf.Ey();
460  DE.Ez() = emf.Ez();
461 
462  // Calculate DEx = LargeEps*(|E|)+Eps
463  // for (size_t iy(0); iy < szy; ++iy){
464  for (size_t ix(0); ix < szx; ++ix){
465  DE.Ex()(ix) *= DE.Ex()(ix);
466  DE.Ey()(ix) *= DE.Ey()(ix);
467  DE.Ez()(ix) *= DE.Ez()(ix);
468 
469  DE.Ex()(ix) += DE.Ey()(ix);
470  DE.Ex()(ix) += DE.Ez()(ix);
471  DE.Ex()(ix) = sqrt(DE.Ex()(ix));
472  DE.Ex()(ix) *= LargeEps;
473  DE.Ex()(ix) += Eps;
474  }
475  // }
476  DE.Ey() = DE.Ex();
477  DE.Ez() = DE.Ex();
478 
479  }
480 //--------------------------------------------------------------
481 
482 
483 //--------------------------------------------------------------
485 //--------------------------------------------------------------
486 // Use Ampere's law to calculate JN
487 //--------------------------------------------------------------
488  Field1D tmpJi(emf.Bz());
489 
490 // Jx = dBz/dy
491 // tmpJi = Yin.EMF().Bz(); (same as assignment above)
492  // tmpJi *= idy;
493  // JN.Jx() = tmpJi.Dy();
494 
495 // Jy = -dBz/dx
496  tmpJi = emf.Bz();
497  tmpJi *= (-1.0) * idx;
498  tmpJi.Dx();
499  // tmpJi(tmpJi.numx()-1) = 0.0;
500  JN.Jy() = tmpJi;
501 
502 // Jz = -dBx/dy
503  // tmpJi = Y.EMF().Bx();
504  // tmpJi *= (-1.0) * idy;
505  // JN.Jz() = tmpJi.Dy();
506 
507 // Jz += dBy/dx
508  tmpJi = emf.By();
509  tmpJi *= idx;
510  tmpJi.Dx();
511  // tmpJi(tmpJi.numx()-1) = 0.0;
512  JN.Jz() += tmpJi;
513  }
514 //--------------------------------------------------------------
515 
516 //--------------------------------------------------------------
517 
518 //**************************************************************
Implicit_E_Field(EMF1D &emf, const double &deltat, const double &deltax)
Definition: implicitE.cpp:249
Algorithms
Plasma Formulary and Units - Declarations.
size_t numx() const
Definition: state.h:197
void advance(Algorithms::RK3< State1D > *rk, State1D &Y, collisions &coll, VlasovFunctor1D_implicitE_p2 *rkF)
Definition: implicitE.cpp:268
std::vector< size_t > NxLocal
Definition: input.h:168
Field1D & By()
Definition: state.h:294
Input reader - Declarations.
A 1D Field.
Definition: state.h:184
Underlying data structures.
complex< double > Detx33(valarray< complex< double >> &D, Array2D< complex< double >> &A)
Definition: nmethods.cpp:346
complex< double > Detz33(valarray< complex< double >> &D, Array2D< complex< double >> &A)
Definition: nmethods.cpp:366
Collisions - Declarations.
Functors for various time-integration methodds - Declarations.
Field1D & E(int component)
Definition: implicitE.cpp:180
Field1D & Ez()
Definition: state.h:292
Definition: state.h:577
Field1D & Bz()
Definition: state.h:295
DistFunc1D & DF(size_t s)
Definition: state.h:602
complex< double > Det33(Array2D< complex< double >> &A)
Definition: nmethods.cpp:336
Field1D & J(int component)
Definition: implicitE.cpp:86
Fields, Distributions, Harmonics, States - Declarations.
Field1D & Ex()
Definition: state.h:290
Definition: state.h:271
Input_List & List()
Definition: input.cpp:1585
Field1D & Ey()
Definition: state.h:291
void advancef1(State1D &Y, State1D &Yh)
complex< double > Dety33(valarray< complex< double >> &D, Array2D< complex< double >> &A)
Definition: nmethods.cpp:356
valarray< double > getcurrent(size_t dir)
Definition: state.cpp:965
int BoundaryCells
Definition: input.h:50
size_t Species() const
Definition: state.h:596
EMF1D & EMF() const
Definition: state.h:610
Numerical Methods - Declarations.