OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
PartBunch.cpp
Go to the documentation of this file.
1 //
2 // Class PartBunch
3 // Particle Bunch.
4 // A representation of a particle bunch as a vector of particles.
5 //
6 // Copyright (c) 2008 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
7 // All rights reserved
8 //
9 // This file is part of OPAL.
10 //
11 // OPAL is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
18 //
19 #include "Algorithms/PartBunch.h"
20 
21 #include <cfloat>
22 #include <memory>
23 #include <utility>
24 
25 #include "FixedAlgebra/FMatrix.h"
26 #include "FixedAlgebra/FVector.h"
28 
29 #include "Algorithms/ListElem.h"
31 #include "Structure/FieldSolver.h"
33 
34 #ifdef DBG_SCALARFIELD
35  #include "Structure/FieldWriter.h"
36 #endif
37 
38 //#define FIELDSTDOUT
39 
40 PartBunch::PartBunch(const PartData *ref): // Layout is set using setSolver()
41  PartBunchBase<double, 3>(new PartBunch::pbase_t(new Layout_t()), ref),
42  interpolationCacheSet_m(false)
43 {
44 
45 }
46 
47 
49 
50 }
51 
52 // PartBunch::pbase_t* PartBunch::clone() {
53 // return new pbase_t(new Layout_t());
54 // }
55 
56 
58  Layout_t* layout = static_cast<Layout_t*>(&getLayout());
59  layout->getLayout().changeDomain(*fLayout);
60 }
61 
62 
65 
66  pbase_t* underlyingPbase =
67  dynamic_cast<pbase_t*>(pbase_m.get());
68 
69  BinaryRepartition(*underlyingPbase);
70  update();
72  boundp();
73 }
74 
75 
76 void PartBunch::computeSelfFields(int binNumber) {
78 
80  throw GeneralClassicException("PartBunch::computeSelfFields(int binNumber)",
81  "P3M solver not available during emission");
82  }
83 
86  rho_m = 0.0;
87  Field_t imagePotential = rho_m;
88 
90  eg_m = Vector_t(0.0);
91 
92  if(fs_m->hasValidSolver()) {
94  resizeMesh();
95 
97  this->Q *= this->dt;
101  } else {
103  getLocalNum(),
104  true);
105  }
107  this->Q.scatter(this->rho_m, this->R, IntrplCIC_t(), interpolationCache_m);
108  } else {
110  }
111 
112  this->Q /= this->dt;
113  this->rho_m /= getdT();
114 
116  double scaleFactor = 1;
117  // double scaleFactor = Physics::c * getdT();
118  double gammaz = getBinGamma(binNumber);
119 
122  double tmp2 = 1 / hr_m[0] * 1 / hr_m[1] * 1 / hr_m[2] / (scaleFactor * scaleFactor * scaleFactor) / gammaz;
123  rho_m *= tmp2;
124 
127  Vector_t hr_scaled = hr_m * Vector_t(scaleFactor);
128  hr_scaled[2] *= gammaz;
129 
132  imagePotential = rho_m;
133 
134  fs_m->solver_m->computePotential(rho_m, hr_scaled);
135 
137  rho_m *= hr_scaled[0] * hr_scaled[1] * hr_scaled[2];
138 
142 
145  eg_m = -Grad(rho_m, eg_m);
146 
149  eg_m *= Vector_t(gammaz / (scaleFactor), gammaz / (scaleFactor), 1.0 / (scaleFactor * gammaz));
150 
151  // If desired write E-field and potential to terminal
152 #ifdef FIELDSTDOUT
153  // Immediate debug output:
154  // Output potential and e-field along the x-, y-, and z-axes
155  int mx = (int)nr_m[0];
156  int mx2 = (int)nr_m[0] / 2;
157  int my = (int)nr_m[1];
158  int my2 = (int)nr_m[1] / 2;
159  int mz = (int)nr_m[2];
160  int mz2 = (int)nr_m[2] / 2;
161 
162  for (int i=0; i<mx; i++ )
163  *gmsg << "Bin " << binNumber
164  << ", Self Field along x axis E = " << eg_m[i][my2][mz2]
165  << ", Pot = " << rho_m[i][my2][mz2] << endl;
166 
167  for (int i=0; i<my; i++ )
168  *gmsg << "Bin " << binNumber
169  << ", Self Field along y axis E = " << eg_m[mx2][i][mz2]
170  << ", Pot = " << rho_m[mx2][i][mz2] << endl;
171 
172  for (int i=0; i<mz; i++ )
173  *gmsg << "Bin " << binNumber
174  << ", Self Field along z axis E = " << eg_m[mx2][my2][i]
175  << ", Pot = " << rho_m[mx2][my2][i] << endl;
176 #endif
177 
183  //Eftmp.gather(eg_m, this->R, IntrplCIC_t());
184 
192  double betaC = std::sqrt(gammaz * gammaz - 1.0) / gammaz / Physics::c;
193 
194  Bf(0) = Bf(0) - betaC * Eftmp(1);
195  Bf(1) = Bf(1) + betaC * Eftmp(0);
196 
197  Ef += Eftmp;
198 
201 
203  NDIndex<3> domain = getFieldLayout().getDomain();
204  Vector_t origin = rho_m.get_mesh().get_origin();
205  double hz = rho_m.get_mesh().get_meshSpacing(2);
206  double zshift = -(2 * origin(2) + (domain[2].first() + domain[2].last() + 1) * hz) * gammaz * scaleFactor;
207 
210  fs_m->solver_m->computePotential(imagePotential, hr_scaled, zshift);
211 
213  imagePotential *= hr_scaled[0] * hr_scaled[1] * hr_scaled[2];
214 
217  imagePotential *= getCouplingConstant();
218 
219 #ifdef DBG_SCALARFIELD
220  const int dumpFreq = 100;
221  VField_t tmp_eg = eg_m;
222 
223  if ((localTrackStep_m + 1) % dumpFreq == 0) {
224  FieldWriter fwriter;
225  fwriter.dumpField(rho_m, "phi", "V", localTrackStep_m / dumpFreq, &imagePotential);
226  }
227 #endif
228 
232  eg_m = -Grad(imagePotential, eg_m);
233 
236  eg_m *= Vector_t(gammaz / (scaleFactor), gammaz / (scaleFactor), 1.0 / (scaleFactor * gammaz));
237 
238  // If desired write E-field and potential to terminal
239 #ifdef FIELDSTDOUT
240  // Immediate debug output:
241  // Output potential and e-field along the x-, y-, and z-axes
242  //int mx = (int)nr_m[0];
243  //int mx2 = (int)nr_m[0] / 2;
244  //int my = (int)nr_m[1];
245  //int my2 = (int)nr_m[1] / 2;
246  //int mz = (int)nr_m[2];
247  //int mz2 = (int)nr_m[2] / 2;
248 
249  for (int i=0; i<mx; i++ )
250  *gmsg << "Bin " << binNumber
251  << ", Image Field along x axis E = " << eg_m[i][my2][mz2]
252  << ", Pot = " << rho_m[i][my2][mz2] << endl;
253 
254  for (int i=0; i<my; i++ )
255  *gmsg << "Bin " << binNumber
256  << ", Image Field along y axis E = " << eg_m[mx2][i][mz2]
257  << ", Pot = " << rho_m[mx2][i][mz2] << endl;
258 
259  for (int i=0; i<mz; i++ )
260  *gmsg << "Bin " << binNumber
261  << ", Image Field along z axis E = " << eg_m[mx2][my2][i]
262  << ", Pot = " << rho_m[mx2][my2][i] << endl;
263 #endif
264 
265 #ifdef DBG_SCALARFIELD
266  tmp_eg += eg_m;
267  if ((localTrackStep_m + 1) % dumpFreq == 0) {
268  FieldWriter fwriter;
269  fwriter.dumpField(tmp_eg, "e", "V/m", localTrackStep_m / dumpFreq);
270  }
271 #endif
272 
277  Eftmp.gather(eg_m, IntrplCIC_t(), interpolationCache_m);
278  //Eftmp.gather(eg_m, this->R, IntrplCIC_t());
279 
288  Bf(0) = Bf(0) + betaC * Eftmp(1);
289  Bf(1) = Bf(1) - betaC * Eftmp(0);
290 
291  Ef += Eftmp;
292 
293  }
295 }
296 
299  return;
300  }
301 
302  double xmin = fs_m->solver_m->getXRangeMin();
303  double xmax = fs_m->solver_m->getXRangeMax();
304  double ymin = fs_m->solver_m->getYRangeMin();
305  double ymax = fs_m->solver_m->getYRangeMax();
306 
307  if(xmin > rmin_m[0] || xmax < rmax_m[0] ||
308  ymin > rmin_m[1] || ymax < rmax_m[1]) {
309 
310  for (unsigned int n = 0; n < getLocalNum(); n++) {
311 
312  if(R[n](0) < xmin || R[n](0) > xmax ||
313  R[n](1) < ymin || R[n](1) > ymax) {
314 
315  // delete the particle
316  INFOMSG(level2 << "destroyed particle with id=" << ID[n] << endl);
317  destroy(1, n);
318  }
319 
320  }
321 
322  update();
323  boundp();
325  }
326 
327  Vector_t origin = Vector_t(0.0, 0.0, 0.0);
328 
329  // update the mesh origin and mesh spacing hr_m
330  fs_m->solver_m->resizeMesh(origin, hr_m, rmin_m, rmax_m, dh_m);
331 
332  getMesh().set_meshSpacing(&(hr_m[0]));
333  getMesh().set_origin(origin);
334 
336  getFieldLayout(),
338  bc_m);
340  getFieldLayout(),
342  vbc_m);
343 
344  update();
345 
346 // setGridIsFixed();
347 }
348 
351  rho_m = 0.0;
352  eg_m = Vector_t(0.0);
353 
354  if(fs_m->hasValidSolver()) {
355  //mesh the whole domain
356  resizeMesh();
357 
358  //scatter charges onto grid
359  this->Q *= this->dt;
360  this->Q.scatter(this->rho_m, this->R, IntrplCIC_t());
361  this->Q /= this->dt;
362  this->rho_m /= getdT();
363 
364  //calculating mesh-scale factor
365  double gammaz = sum(this->P)[2] / getTotalNum();
366  gammaz *= gammaz;
367  gammaz = std::sqrt(gammaz + 1.0);
368  double scaleFactor = 1;
369  // double scaleFactor = Physics::c * getdT();
370  //and get meshspacings in real units [m]
371  Vector_t hr_scaled = hr_m * Vector_t(scaleFactor);
372  hr_scaled[2] *= gammaz;
373 
374  //double tmp2 = 1/hr_m[0] * 1/hr_m[1] * 1/hr_m[2] / (scaleFactor*scaleFactor*scaleFactor) / gammaz;
375  double tmp2 = 1 / hr_scaled[0] * 1 / hr_scaled[1] * 1 / hr_scaled[2];
376  //divide charge by a 'grid-cube' volume to get [C/m^3]
377  rho_m *= tmp2;
378 
379  double Npoints = nr_m[0] * nr_m[1] * nr_m[2];
380  rmsDensity_m = std::sqrt((1.0 /Npoints) * sum((rho_m / Physics::q_e) * (rho_m / Physics::q_e)));
381 
382  calcDebyeLength();
383 
384 
385 #ifdef DBG_SCALARFIELD
386  FieldWriter fwriter;
387  fwriter.dumpField(rho_m, "rho", "C/m^3", localTrackStep_m);
388 #endif
389 
390  // charge density is in rho_m
391  fs_m->solver_m->computePotential(rho_m, hr_scaled);
392 
393  //do the multiplication of the grid-cube volume coming
394  //from the discretization of the convolution integral.
395  //this is only necessary for the FFT solver
396  //FIXME: later move this scaling into FFTPoissonSolver
399  rho_m *= hr_scaled[0] * hr_scaled[1] * hr_scaled[2];
400  }
401 
402  // the scalar potential is given back in rho_m in units
403  // [C/m] = [F*V/m] and must be divided by
404  // 4*pi*\epsilon_0 [F/m] resulting in [V]
406 
407  //write out rho
408 #ifdef DBG_SCALARFIELD
409  fwriter.dumpField(rho_m, "phi", "V", localTrackStep_m);
410 #endif
411 
412  // IPPL Grad divides by hr_m [m] resulting in
413  // [V/m] for the electric field
414  eg_m = -Grad(rho_m, eg_m);
415 
416  //write out e field
417 #ifdef FIELDSTDOUT
418  // Immediate debug output:
419  // Output potential and e-field along the x-, y-, and z-axes
420  int mx = (int)nr_m[0];
421  int mx2 = (int)nr_m[0] / 2;
422  int my = (int)nr_m[1];
423  int my2 = (int)nr_m[1] / 2;
424  int mz = (int)nr_m[2];
425  int mz2 = (int)nr_m[2] / 2;
426 
427  for (int i=0; i<mx; i++ )
428  *gmsg << "Field along x axis Ex = " << eg_m[i][my2][mz2] << " Pot = " << rho_m[i][my2][mz2] << endl;
429 
430  for (int i=0; i<my; i++ )
431  *gmsg << "Field along y axis Ey = " << eg_m[mx2][i][mz2] << " Pot = " << rho_m[mx2][i][mz2] << endl;
432 
433  for (int i=0; i<mz; i++ )
434  *gmsg << "Field along z axis Ez = " << eg_m[mx2][my2][i] << " Pot = " << rho_m[mx2][my2][i] << endl;
435 #endif
436 
437 #ifdef DBG_SCALARFIELD
438  fwriter.dumpField(eg_m, "e", "V/m", localTrackStep_m);
439 #endif
440 
441  // interpolate electric field at particle positions. We reuse the
442  // cached information about where the particles are relative to the
443  // field, since the particles have not moved since this the most recent
444  // scatter operation.
445  Ef.gather(eg_m, this->R, IntrplCIC_t());
446 
448  fs_m->solver_m->calculatePairForces(this,gammaz);
449  }
450 
451  Ef = Ef * Vector_t(gammaz / (scaleFactor), gammaz / (scaleFactor), 1.0 / (scaleFactor * gammaz));
452 
460  double betaC = std::sqrt(gammaz * gammaz - 1.0) / gammaz / Physics::c;
461 
462  Bf(0) = Bf(0) - betaC * Ef(1);
463  Bf(1) = Bf(1) + betaC * Ef(0);
464  }
466 }
467 
482 
484 
486  throw GeneralClassicException("PartBunch::computeSelfFields_cycl(double gamma)",
487  "P3M solver not available yet for cyclotrons");
488  }
489 
491  rho_m = 0.0;
492 
494  eg_m = Vector_t(0.0);
495 
496  if(fs_m->hasValidSolver()) {
498  resizeMesh();
499 
501  this->Q.scatter(this->rho_m, this->R, IntrplCIC_t());
502 
505  Vector_t hr_scaled = hr_m ;
506  hr_scaled[1] *= gamma;
507 
509  double tmp2 = 1.0 / (hr_scaled[0] * hr_scaled[1] * hr_scaled[2]);
510  rho_m *= tmp2;
511 
512  double Npoints = nr_m[0] * nr_m[1] * nr_m[2];
513  rmsDensity_m = std::sqrt((1.0 /Npoints) * sum((rho_m / Physics::q_e) * (rho_m / Physics::q_e)));
514 
515  calcDebyeLength();
516 
517  // If debug flag is set, dump scalar field (charge density 'rho') into file under ./data/
518 #ifdef DBG_SCALARFIELD
519  FieldWriter fwriter;
520  fwriter.dumpField(rho_m, "rho", "C/m^3", localTrackStep_m);
521 #endif
522 
525  fs_m->solver_m->computePotential(rho_m, hr_scaled);
526 
527  //do the multiplication of the grid-cube volume coming
528  //from the discretization of the convolution integral.
529  //this is only necessary for the FFT solver
530  //TODO FIXME: later move this scaling into FFTPoissonSolver
533  rho_m *= hr_scaled[0] * hr_scaled[1] * hr_scaled[2];
534  }
535 
538 
539  // If debug flag is set, dump scalar field (potential 'phi') into file under ./data/
540 #ifdef DBG_SCALARFIELD
541  fwriter.dumpField(rho_m, "phi", "V", localTrackStep_m);
542 #endif
543 
545  eg_m = -Grad(rho_m, eg_m);
546 
551  eg_m *= Vector_t(gamma, 1.0 / gamma, gamma);
552 
553 #ifdef FIELDSTDOUT
554  // Immediate debug output:
555  // Output potential and e-field along the x-, y-, and z-axes
556  int mx = (int)nr_m[0];
557  int mx2 = (int)nr_m[0] / 2;
558  int my = (int)nr_m[1];
559  int my2 = (int)nr_m[1] / 2;
560  int mz = (int)nr_m[2];
561  int mz2 = (int)nr_m[2] / 2;
562 
563  for (int i=0; i<mx; i++ )
564  *gmsg << "Field along x axis Ex = " << eg_m[i][my2][mz2] << " Pot = " << rho_m[i][my2][mz2] << endl;
565 
566  for (int i=0; i<my; i++ )
567  *gmsg << "Field along y axis Ey = " << eg_m[mx2][i][mz2] << " Pot = " << rho_m[mx2][i][mz2] << endl;
568 
569  for (int i=0; i<mz; i++ )
570  *gmsg << "Field along z axis Ez = " << eg_m[mx2][my2][i] << " Pot = " << rho_m[mx2][my2][i] << endl;
571 #endif
572 
573 #ifdef DBG_SCALARFIELD
574  fwriter.dumpField(eg_m, "e", "V/m", localTrackStep_m);
575 #endif
576 
578  Ef.gather(eg_m, this->R, IntrplCIC_t());
579 
580 
581 
583  // Relativistic E&M says gamma*v/c^2 = gamma*beta/c = sqrt(gamma*gamma-1)/c
584  // but because we already transformed E_trans into the moving frame we have to
585  // add 1/gamma so we are using the E_trans from the rest frame -DW
586  double betaC = std::sqrt(gamma * gamma - 1.0) / gamma / Physics::c;
587 
589  Bf(0) = betaC * Ef(2);
590  Bf(2) = -betaC * Ef(0);
591 
592  }
593 
594  /*
595  *gmsg << "gamma =" << gamma << endl;
596  *gmsg << "dx,dy,dz =(" << hr_m[0] << ", " << hr_m[1] << ", " << hr_m[2] << ") [m] " << endl;
597  *gmsg << "max of bunch is (" << rmax_m(0) << ", " << rmax_m(1) << ", " << rmax_m(2) << ") [m] " << endl;
598  *gmsg << "min of bunch is (" << rmin_m(0) << ", " << rmin_m(1) << ", " << rmin_m(2) << ") [m] " << endl;
599  */
600 
602 }
603 
623 
625  throw GeneralClassicException("PartBunch::computeSelfFields_cycl(int bin)",
626  "P3M solver not available yet for cyclotrons");
627  }
628 
630  rho_m = 0.0;
631 
633  eg_m = Vector_t(0.0);
634 
636  double gamma = getBinGamma(bin);
637 
638  if(fs_m->hasValidSolver()) {
640  resizeMesh();
641 
643  this->Q.scatter(this->rho_m, this->R, IntrplCIC_t());
644 
647  Vector_t hr_scaled = hr_m ;
648  hr_scaled[1] *= gamma;
649 
651  double tmp2 = 1.0 / (hr_scaled[0] * hr_scaled[1] * hr_scaled[2]);
652  rho_m *= tmp2;
653 
654  // If debug flag is set, dump scalar field (charge density 'rho') into file under ./data/
655 #ifdef DBG_SCALARFIELD
656  FieldWriter fwriter;
657  fwriter.dumpField(rho_m, "rho", "C/m^3", localTrackStep_m);
658 #endif
659 
662  fs_m->solver_m->computePotential(rho_m, hr_scaled);
663 
664  // Do the multiplication of the grid-cube volume coming from the discretization of the convolution integral.
665  // This is only necessary for the FFT solver. FIXME: later move this scaling into FFTPoissonSolver
668  rho_m *= hr_scaled[0] * hr_scaled[1] * hr_scaled[2];
669  }
670 
673 
674  // If debug flag is set, dump scalar field (potential 'phi') into file under ./data/
675 #ifdef DBG_SCALARFIELD
676  fwriter.dumpField(rho_m, "phi", "V", localTrackStep_m);
677 #endif
678 
680  eg_m = -Grad(rho_m, eg_m);
681 
686  eg_m *= Vector_t(gamma, 1.0 / gamma, gamma);
687 
688 #ifdef FIELDSTDOUT
689  // Immediate debug output:
690  // Output potential and e-field along the x-, y-, and z-axes
691  int mx = (int)nr_m[0];
692  int mx2 = (int)nr_m[0] / 2;
693  int my = (int)nr_m[1];
694  int my2 = (int)nr_m[1] / 2;
695  int mz = (int)nr_m[2];
696  int mz2 = (int)nr_m[2] / 2;
697 
698  for (int i=0; i<mx; i++ )
699  *gmsg << "Bin " << bin
700  << ", Field along x axis Ex = " << eg_m[i][my2][mz2]
701  << ", Pot = " << rho_m[i][my2][mz2] << endl;
702 
703  for (int i=0; i<my; i++ )
704  *gmsg << "Bin " << bin
705  << ", Field along y axis Ey = " << eg_m[mx2][i][mz2]
706  << ", Pot = " << rho_m[mx2][i][mz2] << endl;
707 
708  for (int i=0; i<mz; i++ )
709  *gmsg << "Bin " << bin
710  << ", Field along z axis Ez = " << eg_m[mx2][my2][i]
711  << ", Pot = " << rho_m[mx2][my2][i] << endl;
712 #endif
713 
714  // If debug flag is set, dump vector field (electric field) into file under ./data/
715 #ifdef DBG_SCALARFIELD
716  fwriter.dumpField(eg_m, "e", "V/m", localTrackStep_m);
717 #endif
718 
720  Eftmp.gather(eg_m, this->R, IntrplCIC_t());
721 
722 
723 
725  double betaC = std::sqrt(gamma * gamma - 1.0) / gamma / Physics::c;
726 
728  Bf(0) = Bf(0) + betaC * Eftmp(2);
729  Bf(2) = Bf(2) - betaC * Eftmp(0);
730 
731  Ef += Eftmp;
732  }
733 
734  /*
735  *gmsg << "gamma =" << gamma << endl;
736  *gmsg << "dx,dy,dz =(" << hr_m[0] << ", " << hr_m[1] << ", " << hr_m[2] << ") [m] " << endl;
737  *gmsg << "max of bunch is (" << rmax_m(0) << ", " << rmax_m(1) << ", " << rmax_m(2) << ") [m] " << endl;
738  *gmsg << "min of bunch is (" << rmin_m(0) << ", " << rmin_m(1) << ", " << rmin_m(2) << ") [m] " << endl;
739  */
740 
741 
743 }
744 
745 
746 // void PartBunch::setMesh(Mesh_t* mesh) {
747 // Layout_t* layout = static_cast<Layout_t*>(&getLayout());
748 // // layout->getLayout().setMesh(mesh);
749 // }
750 
751 
752 // void PartBunch::setFieldLayout(FieldLayout_t* fLayout) {
753 // Layout_t* layout = static_cast<Layout_t*>(&getLayout());
754 // // layout->getLayout().setFieldLayout(fLayout);
755 // // layout->rebuild_neighbor_data();
756 // layout->getLayout().changeDomain(*fLayout);
757 // }
758 
759 
761  Layout_t* layout = static_cast<Layout_t*>(&getLayout());
762  return dynamic_cast<FieldLayout_t &>(layout->getLayout().getFieldLayout());
763 }
764 
766  for (int i = 0; i < 2 * 3; ++i) {
767 
768  if (Ippl::getNodes()>1) {
770  //std periodic boundary conditions for gradient computations etc.
772  }
773  else {
775  //std periodic boundary conditions for gradient computations etc.
777  }
779  }
780  dcBeam_m=true;
781  INFOMSG(level3 << "BC set all periodic" << endl);
782 }
783 
785  for (int i = 0; i < 2 * 3; ++i) {
788  getBConds()[i] = ParticleNoBCond;
789  }
790  dcBeam_m=false;
791  INFOMSG(level3 << "BC set for normal Beam" << endl);
792 }
793 
795  for (int i = 0; i < 2 * 3; ++ i) {
796  if (i >= 4) {
797  if (Ippl::getNodes() > 1) {
800  } else {
803  }
804 
806  } else {
809  getBConds()[i] = ParticleNoBCond;
810  }
811  }
812  dcBeam_m=true;
813  INFOMSG(level3 << "BC set for DC-Beam, longitudinal periodic" << endl);
814 }
815 
816 
818  NDIndex<3> domain = getFieldLayout().getDomain();
819  for (unsigned int i = 0; i < Dimension; i++)
820  grid[i] = domain[i].length();
821 }
822 
823 
824 void PartBunch::updateFields(const Vector_t& /*hr*/, const Vector_t& origin) {
825  getMesh().set_meshSpacing(&(hr_m[0]));
826  getMesh().set_origin(origin);
828  getFieldLayout(),
830  bc_m);
832  getFieldLayout(),
834  vbc_m);
835 }
836 
837 inline
839  const Vector_t maxE = max(eg_m);
840  // const double maxL = max(dot(eg_m,eg_m));
841  const Vector_t minE = min(eg_m);
842  // INFOMSG("MaxE= " << maxE << " MinE= " << minE << endl);
843  return VectorPair_t(maxE, minE);
844 }
845 
846 
847 inline
848 void PartBunch::resetInterpolationCache(bool clearCache) {
849  interpolationCacheSet_m = false;
850  if(clearCache) {
852  }
853 }
854 
855 void PartBunch::swap(unsigned int i, unsigned int j) {
856 
857  // FIXME
859 
861  std::swap(interpolationCache_m[i], interpolationCache_m[j]);
862 }
863 
864 
867 }
void setBCAllOpen()
Definition: PartBunch.cpp:784
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
void initialize(Layout_t &)
RegionLayout< T, Dim, Mesh > & getLayout()
ParticleLayout< double, 3 > & getLayout()
Definition: PartBunch.h:120
void setBCForDCBeam()
Definition: PartBunch.cpp:794
virtual double getYRangeMin(unsigned short level=0)=0
void resetInterpolationCache(bool clearCache=false)
Definition: PartBunch.cpp:848
void set_meshSpacing(MFLOAT *const del)
void initialize(FieldLayout_t *fLayout)
Definition: PartBunch.cpp:57
PartBunch()=delete
virtual double getXRangeMax(unsigned short level=0)=0
virtual void destroy(size_t M, size_t I, bool optDestroy=true)
void computeSelfFields()
Definition: PartBunch.cpp:349
void swap(unsigned int i, unsigned int j)
Definition: PartBunch.cpp:855
Vector_t hr_m
meshspacing of cartesian mesh
ParticleAttrib< Vector_t > P
void updateDomainLength(Vektor< int, 3 > &grid)
Definition: PartBunch.cpp:817
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
void computeSelfFields_cycl(double gamma)
Calculates the self electric field from the charge density distribution for use in cyclotrons...
Definition: PartBunch.cpp:481
void BinaryRepartition(FieldLayout< Dim > &layout, BareField< double, Dim > &weights)
void destroy(size_t M, size_t I, bool doNow=false)
Definition: TSVMeta.h:24
ParticleAttrib< Vector_t > Ef
Inform & print(Inform &os)
size_t size(void) const
Vektor< int, 3 > nr_m
meshsize of cartesian mesh
bool hasValidSolver()
void get_bounds(Vector_t &rmin, Vector_t &rmax) const
double getCouplingConstant() const
long long localTrackStep_m
step in a TRACK command
void setBCAllPeriodic()
Definition: PartBunch.cpp:765
Field_t rho_m
scalar potential
Definition: PartBunch.h:94
ParticleAttrib< CacheDataCIC< double, 3U > > interpolationCache_m
Definition: PartBunch.h:117
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
virtual void computePotential(Field_t &rho, Vector_t hr)=0
virtual void calculatePairForces(PartBunchBase< double, 3 > *, double)
Definition: PoissonSolver.h:74
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
FieldLayout_t & getFieldLayout()
Definition: PartBunch.cpp:760
void resizeMesh()
resize mesh to geometry specified
Definition: PartBunch.cpp:297
ParticleAttrib< Vector_t > Bf
Inform & print(Inform &os)
Definition: PartBunch.cpp:865
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
IpplTimings::TimerRef selfFieldTimer_m
timer for selfField calculation
static int getNodes()
Definition: IpplInfo.cpp:670
void do_binaryRepart()
Definition: PartBunch.cpp:63
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1111
size_t getTotalNum() const
void dumpField(FieldType &field, std::string name, std::string unit, long long step, FieldType *image=nullptr)
Dump a scalar or vector field to a file.
Definition: FieldWriter.hpp:29
FieldSolver * fs_m
stores the used field solver
ParticleAttrib< Vector_t > Eftmp
size_t getLocalNum() const
Field< Vektor< T, 1U >, 1U, Cartesian< 1U, MFLOAT >, Cell > & Grad(Field< T, 1U, Cartesian< 1U, MFLOAT >, Vert > &x, Field< Vektor< T, 1U >, 1U, Cartesian< 1U, MFLOAT >, Cell > &r)
Definition: Cartesian.hpp:2702
Definition: Inform.h:42
FieldSolverType getFieldSolverType() const
Definition: FieldSolver.h:164
void set_origin(const Vektor< MFLOAT, Dim > &o)
IntCIC IntrplCIC_t
Definition: PBunchDefs.h:17
FieldLayout< Dim > & getFieldLayout()
Definition: RegionLayout.h:137
void calcDebyeLength()
Compute the (global) Debye length for the beam.
VField_t eg_m
vector field on the grid
Definition: PartBunch.h:97
ParticleAttrib< double > Q
virtual void swap(unsigned int i, unsigned int j)
void scatter(Field< T, Dim, M, C > &f, const ParticleAttrib< Vektor< PT, Dim > > &pp, const IntOp &) const
constexpr double q_e
The elementary charge in As.
Definition: Physics.h:69
double getBinGamma(int bin)
Get gamma of one bin.
static const unsigned Dimension
Definition: PartBunchBase.h:59
ParticleAttrib< double > dt
Mesh_t & get_mesh() const
Definition: Field.h:110
void changeDomain(FieldLayout< Dim > &)
virtual double getXRangeMin(unsigned short level=0)=0
ParticleBConds< Position_t, Dimension > & getBConds()
double dh_m
Mesh enlargement.
bool interpolationCacheSet_m
Definition: PartBunch.h:115
BConds< Vector_t, 3, Mesh_t, Center_t > vbc_m
Definition: PartBunch.h:112
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
const Mesh_t & getMesh() const
Definition: PartBunch.h:138
T ParticlePeriodicBCond(const T t, const T minval, const T maxval)
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
std::pair< Vector_t, Vector_t > VectorPair_t
Definition: PartBunchBase.h:57
virtual void resizeMesh(Vector_t &, Vector_t &, const Vector_t &, const Vector_t &, double)
Definition: PoissonSolver.h:68
BConds< double, 3, Mesh_t, Center_t > bc_m
for defining the boundary conditions
Definition: PartBunch.h:111
std::shared_ptr< AbstractParticle< double, Dim > > pbase_m
virtual void create(size_t)
VectorPair_t getEExtrema()
Definition: PartBunch.cpp:838
PoissonSolver * solver_m
the actual solver, should be a base object
Definition: FieldSolver.h:124
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
Vector_t rmin_m
minimal extend of particles
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
virtual double getYRangeMax(unsigned short level=0)=0
Inform * gmsg
Definition: Main.cpp:70
T ParticleNoBCond(const T t, const T, const T)
Vector_t rmax_m
maximal extend of particles
void updateFields(const Vector_t &hr, const Vector_t &origin)
Definition: PartBunch.cpp:824