XGC1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
electric_field.hpp
Go to the documentation of this file.
1 #ifndef ELECTRIC_FIELD_HPP
2 #define ELECTRIC_FIELD_HPP
3 #include "space_settings.hpp"
4 #include "NamelistReader.hpp"
5 #include "grid.hpp"
6 #include "grid_field_pack.hpp"
7 #include "timer_macro.hpp"
8 #include "smoothing.hpp"
9 #include "get_potential_grad.hpp"
10 #include "plane_field_gatherer.hpp"
12 #ifdef SONIC_GK
13 #include "get_sonic_fields.hpp"
14 #endif
15 #ifdef EXPLICIT_EM
16 #include "globals.hpp"
17 #endif
18 #include "bias_potential.hpp"
19 #include "simple00_solver.hpp"
20 
21 template<KinType KT, PhiInterpType PIT, MarkerType MT, MagneticFieldMode MFM>
23 
24 template<KinType KT> struct getGyroVecFldType;
25 template<> struct getGyroVecFldType<KinType::DriftKin>{ using t = EfieldType; };
26 template<> struct getGyroVecFldType<KinType::GyroKin>{ using t = EfieldGyroType; };
27 
28 template<KinType KT> struct getGyroScaFldType;
29 template<> struct getGyroScaFldType<KinType::DriftKin>{ using t = PotType; };
30 template<> struct getGyroScaFldType<KinType::GyroKin>{ using t = PotGyroType; };
31 
32 // XGC1
33 
35 template<KinType KT, MarkerType MT>
37  using t = Pack<Labeled<typename getGyroVecFldType<KT>::t, Label::E>,
43 };
44 
46 template<KinType KT, MarkerType MT>
48  using t = Pack<Labeled<typename getGyroVecFldType<KT>::t, Label::E>>;
49 };
50 
52 template<KinType KT>
54  using t = Pack<Labeled<typename getGyroVecFldType<KT>::t, Label::E>,
57 };
58 
59 // XGCA
60 template<KinType KT, MarkerType MT>
62 # ifdef SONIC_GK
63  using t = Pack<Labeled<Efield2DGyroType, Label::E>,
67 # else
68  using t = Pack<Labeled<Efield2DGyroType, Label::E>>;
69 # endif
70 };
71 
72 
73 // Fortran calls
74 #ifdef XGC1
75 # ifdef EXPLICIT_EM
78 # else
80 # endif
81 #else
82 extern "C" void set_rho_pointers(int n, Field<VarType::Scalar,PhiInterpType::None>* dpot);
83 #endif
84 
85 // Electric field class
86 template<class Device>
87 struct ElectricField {
88 
89  // Dimensions
90  int nnode;
91  int nphi;
92 
93  // Gyromatrix info (to be moved soon)
94  int nrho;
95 
96  // Optimization options
98 
99  // Field variables
100  bool turb_efield;
101  bool E00_efield;
103 
104  // Host Views
107 
108  //For EM
120 
123 //#ifdef XGC1
125 //#else
126 //# ifdef SONIC_GK
130 //# endif
131 //#endif
135  View<double***,CLayout, HostType> save_dpot0; // Used for adiabatic response
136  View<double***,CLayout, HostType> save_dpot; // Used for adiabatic response
137  View<double***,CLayout, HostType> dpotsave; // Used for split-weight scheme
138  View<double*,CLayout, HostType> dpot_es; // Used for a diagnostic
139 
140  View<double*,CLayout, HostType> pot0m;
141  View<double*,CLayout, HostType> pot00_1d;
142 
144 
145  // Host View for the adjustable loop voltage current drive
149 
150  // Bias potential
152 
153  // Solver boundaries; These are lists of nodes that are EXCLUDED
160 
161  // Default constructor
163 
164  // Makes sense to use the Grid in the constructor here, but the Grid still copies from fortran so until that changes,
165  // it's simpler to not use it here so that ElectricField can be defined before the restart, which uses psn%As
166  ElectricField(NLReader::NamelistReader& nlr, const Grid<DeviceType>& grid, int nrho_in, bool es_reduced_deltaf_setup=false, double dt=1.0, double psi_norm=1.0) : //Grid<HostTypeType>& grid) :
167  nnode(grid.nnode),
168  nphi(grid.nplanes),
169  nrho(nrho_in),
170  // Host Views
171 #ifdef XGC1
172  pot("pot",nphi,nrho,nnode),
173  E("E",nphi,nrho,nnode),
174  save_dpot("save_dpot", 2, 2, nnode), // View. dims: RK2, ff, nnode
175  save_dpot0("save_dpot0", 2, 2, nnode), // View. dims: RK2, ff, nnode
176 # ifdef EXPLICIT_EM
177  dpot_es("dpot_es", nnode),
178  dAh("dAh",nphi,nrho,nnode),
179  Ah("Ah",nphi,nrho,nnode),
180  Ah_h("Ah_h",4,nnode), // -1:2 in fortran
181  Ah_h_backup("Ah_h_backup",nnode), // -1:2 in fortran
182  As_h("As_h",4,nnode), // -1:2 in fortran
183  As_h_backup("As_h_backup",4,nnode), // -1:2 in fortran
184 # endif
185  dpot_h("dpot_h",4,nnode), // -1:2 in fortran
186  dpot_ff_h("dpot_ff_h",nnode),
187  dpot_n0_h("dpot_n0_h",nnode),
188 #else
189  E("E",nrho, nnode),
190  dpot_h("dpot_h",1,nnode),
191 # ifdef SONIC_GK
192  dEr_B2("dEr_B2",nrho, nnode),
193  dEz_B2("dEz_B2",nrho, nnode),
194  du2_E("du2_E",nrho, nnode),
195 # endif
196  dpot_n0_h("dpot_n0_h",nnode),
197 #endif
198  pot0m("pot0m", nnode),
199  pot00_1d("pot00_1d", grid.psi00.n),
200  pot0_h("pot0_h",nnode),
201  loop_voltage_h("loop_voltage_h",nnode),
202  jpara_diff_previous_h("jpara_diff_previous_h",nnode),
203  jpara_diff_integral_h("jpara_diff_integral_h",nnode),
204  bias_potential(nlr, dt, psi_norm)
205  {
206  if(es_reduced_deltaf_setup){
209  dpotsave = View<double***,CLayout, HostType>("dpotsave", 2, 2, nnode); // View. dims: RK2, ff, nnode
210  }
211 
212  nlr.use_namelist("sml_param");
213  turb_efield = nlr.get<bool>("sml_turb_efield",true); // E-field calculated only with \f$<\phi>\f$ if .false.
214  // psn%dpot will still contain all (n=0,|m|>0) and (|n|>0,m) modes
215  E00_efield = nlr.get<bool>("sml_00_efield",true); // Flux-surface averaged potential not used for calculating the electric field if .false.
216  n0_m_efield = nlr.get<bool>("sml_0m_efield",true); // The axisymmetric potential variation \f$\langle \phi-\langle\phi\rangle\rangle_T\f$ is
217  // set to zero if .false.
218 
219 #ifdef EXPLICIT_EM
220  // Pass these (or sml) as arguments
221  bool em_mixed_variable = nlr.get<bool>("sml_em_mixed_variable",true);
222  bool em_control_variate = nlr.get<bool>("sml_em_control_variate",false);
223  int em_pullback_mode = nlr.get<int>("sml_em_pullback_mode",3);
224 
225  if (!em_mixed_variable)
226  exit_XGC("\nError: sml_em_mixed_variable is explicitly set to .false. which is incompatible with EXPLICIT_EM\n");
227 #endif
228 
229  if(nlr.namelist_present("performance_param")){
230  nlr.use_namelist("performance_param");
231  calculate_phi_ff_on_device = nlr.get<bool>("calculate_phi_ff_on_device", false); // With this option, potential is communicated and the electric field is calculated on every MPI process. This means additional computation, but less communication. This tradeoff is probably beneficial on all current flagship platforms, but this has not been verified.
232  }else{
234  }
235 
236 #ifdef EXPLICIT_EM
237  if (em_control_variate){
240  }
241 
242  if (em_mixed_variable){
245  if (em_pullback_mode==4){
247  }
248  }
249 #endif
250 
251  // Set pointers in Fortran to rho arrays
252 #ifdef XGC1
253 # ifdef EXPLICIT_EM
254  set_rho_ff_pointers(nnode, dpot_h.data(), dpot_ff_h.data(), Ah_h.data(), As_h.data(), As_h_backup.data());
255 # else
256  set_rho_ff_pointers(nnode, dpot_h.data(), dpot_ff_h.data());
257 # endif
258 #else
259  set_rho_pointers(nnode, dpot_h.data());
260 #endif
261  // Initialize loop voltage
262  nlr.use_namelist("src_param");
263  const double initial_loop_vol = nlr.get<double>("src_loop_voltage",0.0);
264  //
265  for (int inode=0; inode<nnode; inode++){
266  loop_voltage_h(inode) = initial_loop_vol;
267  }
268  }
269 
270 
271  /**************************************************/
272  /************ Copy to GridFieldPack *************/
273  /**************************************************/
274  template<MarkerType MT>
276 
277  // Set push type here for now
279  gfp_push_type gfpack(turb_efield);
280 
281  GPTLstart("GAT_FIELD_INFO");
282  if(pol_decomp.decompose_fields){
283  if(near_field){
284  // Gathering the "near field", defined as the field decomposition region that contains this rank's
285  // global domain decomposition
286  int local_pid = pol_decomp.field_decomp.find_domain_owner(pol_decomp.plane_index, grid.nplanes, pol_decomp.node_offset, grid.nnode);
287  gfpack.phi_offset = pol_decomp.field_decomp.all_first_plane(local_pid);
288  gfpack.node_offset = pol_decomp.field_decomp.all_first_node(local_pid);
289  }else{
290  gfpack.phi_offset = pol_decomp.field_decomp.first_plane;
291  gfpack.node_offset = pol_decomp.field_decomp.first_node;
292  }
293  }
294  PlaneFieldGatherer pfg(pol_decomp, grid, near_field);
295 
296 #ifndef EXPLICIT_EM
297  if constexpr(MT==MarkerType::ReducedDeltaF){
298  if(ddpotdt.f.size()>0) pfg.gather_phi_ff_on_device(ddpotdt.f, gfpack.template get<Label::ddpotdt>().f);
299  grid_field_copy(gfpack.template get<Label::E00>(), E00_ff_h); // No gather_phi needed due to axisymmetry
300  }
301 #endif
302 
304  // Allocate temporary views
305  GPTLstart("GET_POT_GRAD_ALLOC_VIEWS");
306  int n_input_field_planes = pot0_h.nphi();
307  bool gradient_requested = true;
308  bool gyroaverage_requested = false;
309  GetPotentialGradTemp<DeviceType, DeviceType> gpg_tmp(sml, grid, pol_decomp, magnetic_field, pbd0, n_input_field_planes, gradient_requested, gyroaverage_requested);
310  GPTLstop("GET_POT_GRAD_ALLOC_VIEWS");
311 
312  // Whether to ignore dpot
313  bool ignore_poloidal_dpot = !(turb_efield);
314  bool use_field00 = E00_efield;
315  bool potential_is_requested = false; // Not used in push
317  pfg.calculate_phi_ff_on_device(sml,grid, magnetic_field, smoothing, gpg_tmp, my_subview(dpot_h.f, 2), pot0_h, gfpack.template get<Label::E>(), unused_pot, potential_is_requested, use_field00, ignore_poloidal_dpot);
318 # ifdef EXPLICIT_EM
320  pfg.calculate_phi_ff_on_device(sml,grid, magnetic_field, smoothing, gpg_tmp, my_subview(Ah_h.f, 2), pot0_em_h, gfpack.template get<Label::dAh>(), gfpack.template get<Label::Ah>());
321  if(As.f.size()>0) pfg.calculate_phi_ff_on_device(sml,grid, magnetic_field, smoothing, gpg_tmp, my_subview(As_h.f, 2), pot0_em_h, gfpack.template get<Label::dAs>(), gfpack.template get<Label::As>());
322 # endif
323  }else{
324  pfg.gather_phi_ff_on_device(E.f, gfpack.template get<Label::E>().f);
325 # ifdef EXPLICIT_EM
326  pfg.gather_phi_ff_on_device(dAh.f, gfpack.template get<Label::dAh>().f);
327  pfg.gather_phi_ff_on_device(Ah.f, gfpack.template get<Label::Ah>().f);
328  if(dAs.f.size()>0) pfg.gather_phi_ff_on_device(dAs.f, gfpack.template get<Label::dAs>().f);
329  if(As.f.size()>0) pfg.gather_phi_ff_on_device(As.f, gfpack.template get<Label::As>().f);
330 # endif
331  }
332 # ifdef EXPLICIT_EM
333  if(Epar_em.f.size()>0) pfg.gather_phi_ff_on_device(Epar_em.f, gfpack.template get<Label::Epar_em>().f);
334 # endif
335  GPTLstop("GAT_FIELD_INFO");
336 
338  // Copy axisymmetric loop voltage to temporary device-view
339  ScalarGridField loop_voltage("loop_voltage",loop_voltage_h.nnode());
340  Kokkos::deep_copy(loop_voltage.f,loop_voltage_h.f);
342  ff.cnvt_grid_real2ff(grid,loop_voltage,gfpack.loop_voltage);
343 
344  return std::make_unique<gfp_push_type>(gfpack);
345  }
346 
347  template<MarkerType MT>
350  gfp_push_type gfpack(turb_efield);
351 
352  GPTLstart("Copy_rho_ff_fields_to_device");
353  grid_field_copy(gfpack.template get<Label::E>(), E);
354 # ifdef EXPLICIT_EM
355  grid_field_copy(gfpack.template get<Label::dAs>(), dAs);
356  grid_field_copy(gfpack.template get<Label::dAh>(), dAh);
357  grid_field_copy(gfpack.template get<Label::As>(), As);
358  grid_field_copy(gfpack.template get<Label::Ah>(), Ah);
359  grid_field_copy(gfpack.template get<Label::Epar_em>(), Epar_em);
360 # endif
361  GPTLstop("Copy_rho_ff_fields_to_device");
362 
363  // Loop voltage is identical for gyrokinetic and drift-kinetic species,
364  // but different between XGC1 and XGCa
366  // Copy axisymmetric loop voltage to temporary device-view
367  ScalarGridField loop_voltage("loop_voltage",loop_voltage_h.nnode());
368  Kokkos::deep_copy(loop_voltage.f,loop_voltage_h.f);
370  ff.cnvt_grid_real2ff(grid,loop_voltage,gfpack.loop_voltage);
371 
372  return std::make_unique<gfp_push_type>(gfpack);
373  }
374 
375 #ifdef XGC1
376  // Resizes allocations for large arrays that have a phi dimension (i.e used for electron push)
377  GridFieldPackPtr copy_push_fields_to_device(KinType kintype_in, MarkerType markertype_in, const Simulation<DeviceType>& sml, const DomainDecomposition<DeviceType>& pol_decomp, const MagneticField<DeviceType>& magnetic_field, const Grid<DeviceType>& grid, Smoothing& smoothing, bool near_field=false) const{
378  if(markertype_in==MarkerType::ReducedDeltaF){
379  if(kintype_in==DriftKin){
380  return copy_push_fields_to_device_drift_kin_XGC1<MarkerType::ReducedDeltaF>(sml, pol_decomp, magnetic_field, grid, smoothing, near_field);
381  }else{
382  return copy_push_fields_to_device_gyro_kin_XGC1<MarkerType::ReducedDeltaF>(sml, pol_decomp, magnetic_field, grid, smoothing, near_field);
383  }
384  }else{
385  if(kintype_in==DriftKin){
386  return copy_push_fields_to_device_drift_kin_XGC1<MarkerType::TotalF>(sml, pol_decomp, magnetic_field, grid, smoothing, near_field);
387  }else{
388  return copy_push_fields_to_device_gyro_kin_XGC1<MarkerType::TotalF>(sml, pol_decomp, magnetic_field, grid, smoothing, near_field);
389  }
390  }
391  }
392 #else
393  // Resizes allocations for large arrays that have a phi dimension (i.e used for electron push)
394  GridFieldPackPtr copy_push_fields_to_device(KinType kintype_in, MarkerType markertype_in, const Simulation<DeviceType>& sml, const DomainDecomposition<DeviceType>& pol_decomp, const MagneticField<DeviceType>& magnetic_field, const Grid<DeviceType>& grid, Smoothing& smoothing, bool near_field=false) const{
395  // Re-initialize new gridpack - deallocates whatever Views were already allocated
397  gfp_push_type gfpack(turb_efield);
398 
399  grid_field_copy(gfpack.template get<Label::E>(), E);
400 # ifdef SONIC_GK
401  grid_field_copy(gfpack.template get<Label::dEr_B2>, dEr_B2);
402  grid_field_copy(gfpack.template get<Label::dEz_B2>, dEz_B2);
403  grid_field_copy(gfpack.template get<Label::du2_E>, du2_E);
404 # endif
405  // Copy axisymmetric loop voltage to temporary device-view
406  ScalarGridField loop_voltage("loop_voltage",loop_voltage_h.nnode());
407  Kokkos::deep_copy(loop_voltage.f,loop_voltage_h.f);
408  grid_field_copy(gfpack.loop_voltage,loop_voltage);
409 
410  //grid_field_copy(gfpack.loop_voltage,loop_voltage_h);
411  return std::make_unique<gfp_push_type>(gfpack);
412  }
413 #endif
414 
424  void get_Ah_rho_ff(const Simulation<DeviceType>& sml, const Grid<DeviceType>& grid, const DomainDecomposition<DeviceType>& pol_decomp, const MagneticField<DeviceType>& magnetic_field, Smoothing& smoothing, Species<DeviceType>& species){
425  GPTLstart("GET_AH_RHO_FF_EXCL_DESTR"); // Timer excludes the destructors which are non-negligible
426 
427  // Allocate temporary views
428  GPTLstart("GET_AH_RHO_FF_ALLOC_VIEWS");
429  int n_input_field_planes = Ah_h.nphi();
430  bool gradient_requested = false;
431  bool gyroaverage_requested = true;
433  GetPotentialGradTemp<DeviceType, HostType> tmp(sml, grid, pol_decomp, magnetic_field, pbd0, n_input_field_planes, gradient_requested, gyroaverage_requested, species.gyro_avg_matrices);
434  GPTLstop("GET_AH_RHO_FF_ALLOC_VIEWS");
435 
436  /****************************************/
437  // Calculation of the Hamiltonian vector potential A_h
438  /****************************************/
440  FieldArgs gpg_field_args(Ah_h.unmanaged());
441  gpg_field_args.request_potential(Ah);
442  get_field_grad(sml, grid, pol_decomp, magnetic_field, smoothing, gpg_field_args, tmp);
443 
444  GPTLstop("GET_AH_RHO_FF_EXCL_DESTR");
445 
447  }
448 
459  void get_potential_grad(const Simulation<DeviceType>& sml, const Grid<DeviceType>& grid, const DomainDecomposition<DeviceType>& pol_decomp, const MagneticField<DeviceType>& magnetic_field, Smoothing& smoothing, const View<double*, CLayout, HostType>& spitzer_resistivity, Species<DeviceType>& species){
460  GPTLstart("GET_POT_GRAD_EXCL_DESTR"); // Timer excludes the destructors which are non-negligible
461 
462  // Allocate temporary views
463  GPTLstart("GET_POT_GRAD_ALLOC_VIEWS");
464  int n_input_field_planes = dpot_h.nphi();
465  bool gradient_requested = true;
466  bool gyroaverage_requested = true;
467 #ifdef MULTI_RATE
468  gyroaverage_requested = false; // This is a hack. This variable controls the size of the tmp arrays for get_pot_grad,
469  // but the rho_ff arrays will still exist and the rho=0 values will be correct
470 #endif
471  if(gyroaverage_requested) species.gyro_avg_matrices.copy_to_device_if_not_resident();
472  GetPotentialGradTemp<DeviceType, HostType> tmp(sml, grid, pol_decomp, magnetic_field, pbd0, n_input_field_planes, gradient_requested, gyroaverage_requested, species.gyro_avg_matrices);
473  GPTLstop("GET_POT_GRAD_ALLOC_VIEWS");
474 
475  /****************************************/
476  // Calculation of the electric potential E
477  /****************************************/
478  GPTLstart("GET_POT_GRAD_PHI");
479 
481  FieldArgs gpg_field_args(dpot_h.unmanaged(), !(turb_efield));
482 
483  // Set up E00
484  if(E00_efield){
485  gpg_field_args.field00 = Field00<DeviceType>(pot0_h, sml.grad_psitheta);
486  gpg_field_args.field00.calculate_gradient(grid, tmp.grad_matrices);
487  }
488  // Write results of E00
489  if(sml.reduced_deltaf && sml.electron_on) gpg_field_args.field00.set_field(grid, tmp.ff, E00_ff_h.f);
490 
491  // Set up EMPar
492  if(sml.explicit_electromagnetic && (sml.em_mixed_variable && sml.em_pullback_mode==4)) gpg_field_args.request_para_em(Epar_em, sml.em_pullback_dampfac, spitzer_resistivity, AbdH, gyroaverage_requested);
493 
494  // Request potential and/or gradient outputs
495  // XGC1 algorithm uses potential but XGCa doesnt
496  if(!sml.is_XGCa) gpg_field_args.request_potential(pot);
497  gpg_field_args.request_gradient(E);
498 
499  // Get potentials
500  get_field_grad(sml, grid, pol_decomp, magnetic_field, smoothing, gpg_field_args, tmp);
501 
502  GPTLstop("GET_POT_GRAD_PHI");
503 
504  if(sml.explicit_electromagnetic){
505  GPTLstart("GET_POT_GRAD_APAR");
506 
507  /****************************************/
508  // Calculation of the Hamiltonian vector potential A_h
509  /****************************************/
510  gpg_field_args = FieldArgs(Ah_h.unmanaged());
511  gpg_field_args.request_potential(Ah);
512 #ifndef MULTI_RATE
513  gpg_field_args.request_gradient(dAh);
514 #endif
515  get_field_grad(sml, grid, pol_decomp, magnetic_field, smoothing, gpg_field_args, tmp);
516 
517  /****************************************/
518  // Calculation of the symplectic vector potential A_s
519  /****************************************/
520  if (sml.em_mixed_variable){
521  gpg_field_args = FieldArgs(As_h.unmanaged());
522  gpg_field_args.request_potential(As);
523 #ifndef MULTI_RATE
524  gpg_field_args.request_gradient(dAs);
525 #endif
526  get_field_grad(sml, grid, pol_decomp, magnetic_field, smoothing, gpg_field_args, tmp);
527  }
528 
529  /****************************************/
530  // Calculation of the Hamiltonian vector potential A_h for the control-variate method
531  /****************************************/
532  if (sml.em_control_variate){
533  TIMER("GET_POT_APAR_CV",
534  get_field_Ah_cv_ff(grid, pol_decomp, Ah_cv_h, Ah_cv) );
535  }
536  GPTLstop("GET_POT_GRAD_APAR");
537  }
538 
539 #ifdef SONIC_GK
540  GPTLstart("GET_POT_GRAD_SONIC");
541  View<double*,CLayout,HostType> Er_B2_h("Er_B2_h",grid.nnode);
542  View<double*,CLayout,HostType> Ez_B2_h("Ez_B2_h",grid.nnode);
543  View<double*,CLayout,HostType> u2_E_h("u2_E_h",grid.nnode);
544 
545  TIMER("GET_POT_SONIC",
546  get_sonic_fields(grid, E, Er_B2_h, Ez_B2_h, u2_E_h) );
547 
548  gpg_field_args = FieldArgs(Er_B2_h);
549  gpg_field_args.request_gradient(dEr_B2);
550  get_field_grad(sml, grid, pol_decomp, magnetic_field, smoothing, gpg_field_args, tmp);
551 
552  gpg_field_args = FieldArgs(Ez_B2_h);
553  gpg_field_args.request_gradient(dEz_B2);
554  get_field_grad(sml, grid, pol_decomp, magnetic_field, smoothing, gpg_field_args, tmp);
555 
556  gpg_field_args = FieldArgs(u2_E_h);
557  gpg_field_args.request_gradient(du2_E);
558  get_field_grad(sml, grid, pol_decomp, magnetic_field, smoothing, gpg_field_args, tmp);
559 
560  GPTLstop("GET_POT_GRAD_SONIC");
561 #endif
562 
564 
565  GPTLstop("GET_POT_GRAD_EXCL_DESTR");
566  }
567 
569  nlr.use_namelist("sml_param");
570  int field_n_rho = nlr.get<int>("sml_grid_nrho", 6);
571 
572 #ifdef EXPLICIT_EM
573  int n_fields = 3 + 1; // E, dAs, dAh, + scalars As,Ah
574 #else
575  int n_fields = 1;
576 #endif
577  double host_field_GB_per_vertex = (53 + 8*grid.nplanes + 11*(field_n_rho + 1))*8*BYTES_TO_GB;
578  double cpu_memory_usage = grid.nnode*host_field_GB_per_vertex;
579 
580  double device_field_GB_per_vertex = std::max(n_fields*8*grid.nplanes, n_fields*8*(field_n_rho+1))*8*BYTES_TO_GB;
581  double gpu_memory_usage = grid.nnode*device_field_GB_per_vertex;
582 
583  MemoryPrediction memory_prediction{"Collisions", cpu_memory_usage, gpu_memory_usage};
584 
585  return memory_prediction;
586  }
587 };
588 
589 #endif
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::OnePlane, KinType::DriftKin > Ah_h_backup
Definition: electric_field.hpp:110
GridField< HostType, VarType::Scalar, PhiInterpType::Planes, TorType::OnePlane, KinType::DriftKin > ddpotdt
Time derivative of - Not field-following?
Definition: electric_field.hpp:106
Boundary pbdH
Definition: electric_field.hpp:159
bool decompose_fields
Whether to decompose fields.
Definition: domain_decomposition.hpp:85
GridField< HostType, VarType::Scalar, PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > pot
Definition: electric_field.hpp:121
Definition: field_following_coordinates.hpp:9
static int GPTLstart(const char *name)
Definition: timer_macro.hpp:9
BiasPotential bias_potential
Definition: electric_field.hpp:151
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::OnePlane, KinType::DriftKin > jpara_diff_integral_h
Definition: electric_field.hpp:148
Definition: bias_potential.hpp:7
Definition: electric_field.hpp:22
std::unique_ptr< GridFieldPackGeneric > GridFieldPackPtr
Definition: grid_field_pack.hpp:21
GridFieldPackPtr copy_push_fields_to_device(KinType kintype_in, MarkerType markertype_in, const Simulation< DeviceType > &sml, const DomainDecomposition< DeviceType > &pol_decomp, const MagneticField< DeviceType > &magnetic_field, const Grid< DeviceType > &grid, Smoothing &smoothing, bool near_field=false) const
Definition: electric_field.hpp:377
int first_plane
First plane belonging to this rank, including ghost planes.
Definition: field_decomposition.hpp:35
MarkerType
Definition: globals.hpp:110
void set_rho_ff_pointers(int n, Field< VarType::Scalar, PhiInterpType::None > *dpot, Field< VarType::Scalar, PhiInterpType::Planes > *dpot_ff)
GridField< DeviceType, VarType::Scalar, PIT_GLOBAL, TorType::MultiplePlanes, KinType::DriftKin > PotType
Definition: grid_field.hpp:486
void get_potential_grad(const Simulation< DeviceType > &sml, const Grid< DeviceType > &grid, const DomainDecomposition< DeviceType > &pol_decomp, const MagneticField< DeviceType > &magnetic_field, Smoothing &smoothing, const View< double *, CLayout, HostType > &spitzer_resistivity, Species< DeviceType > &species)
Definition: electric_field.hpp:459
GridField< HostType, vec2d_if_axisym< PIT_GLOBAL >), PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > dAh
Definition: electric_field.hpp:111
T get(const string &param, const T default_val, int val_ind=0)
Definition: NamelistReader.hpp:373
constexpr double BYTES_TO_GB
Definition: constants.hpp:12
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::OnePlane, KinType::DriftKin > loop_voltage_h
Definition: electric_field.hpp:146
GridField< HostType, VarType::Scalar, PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > Ah
Definition: electric_field.hpp:112
bool em_mixed_variable
Switch for use of mixed-variable formulation.
Definition: sml.hpp:66
GridField< HostType, VarType::Vector2D, PIT_GLOBAL, TorType::OnePlane, KinType::DriftKin > E00_ff_h
Radial electric field from in field-following format.
Definition: electric_field.hpp:105
View< double *, CLayout, HostType > dpot_es
Definition: electric_field.hpp:138
GridField< HostType, VarType::Scalar, PhiInterpType::Planes, TorType::OnePlane, KinType::DriftKin > dpot_ff_h
Definition: electric_field.hpp:124
Definition: sml.hpp:8
void request_para_em(const GridField< DeviceOut, VarType::Scalar, PhiInterpType::Planes, TorType::OnePlane, KinType::GyroKin > &output_field, double em_pullback_dampfac_in, const View< double *, CLayout, HostType > &spitzer_resistivity, const Boundary &boundary, bool gyroaverage_requested)
Definition: get_potential_grad.hpp:312
static constexpr bool is_XGCa
Equivalent to the preprocessor flag for now.
Definition: sml.hpp:19
bool reduced_deltaf
True if any species is reduced_deltaf. Will be removed.
Definition: sml.hpp:36
static constexpr bool explicit_electromagnetic
Equivalent to the preprocessor flag for now.
Definition: sml.hpp:25
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::MultiplePlanes, KinType::DriftKin > As_h
Definition: electric_field.hpp:113
void copy_to_device_if_not_resident()
Definition: gyro_avg_mat.hpp:50
int plane_index
Offset of local plane.
Definition: domain_decomposition.hpp:82
Definition: globals.hpp:89
Definition: plane_field_gatherer.hpp:9
FieldFollowingCoordinates ff
Definition: get_potential_grad.hpp:68
KOKKOS_INLINE_FUNCTION int find_domain_owner(int global_plane_index, int nplanes_total, int global_node_index, int nnodes_total) const
Definition: field_decomposition.hpp:136
int nrho
Definition: electric_field.hpp:94
void get_Ah_rho_ff(const Simulation< DeviceType > &sml, const Grid< DeviceType > &grid, const DomainDecomposition< DeviceType > &pol_decomp, const MagneticField< DeviceType > &magnetic_field, Smoothing &smoothing, Species< DeviceType > &species)
Definition: electric_field.hpp:424
Definition: NamelistReader.hpp:193
Definition: magnetic_field.hpp:12
static MemoryPrediction estimate_memory_usage(NLReader::NamelistReader &nlr, const Grid< DeviceType > &grid)
Definition: electric_field.hpp:568
Definition: get_potential_grad.hpp:276
Simple00Solver simple00
Definition: electric_field.hpp:143
void cnvt_grid_real2ff(const Grid< DeviceType > &grid, const View< double **, CLayout, DeviceType > &input, const View< double **, Kokkos::LayoutRight, DeviceType > &output) const
Definition: field_following_coordinates.hpp:169
Definition: electric_field.hpp:87
void get_field_grad(const Simulation< DeviceType > &sml, const Grid< DeviceType > &grid, const DomainDecomposition< DeviceType > &pol_decomp, const MagneticField< DeviceType > &magnetic_field, Smoothing &smoothing, GetPotGradFieldArgs< DeviceIn, DeviceOut, VT, PIT, TT, KT > &args, GetPotentialGradTemp< DeviceType, DeviceOut > &tmp)
Definition: get_potential_grad.cpp:395
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::OnePlane, KinType::DriftKin > pot0_h
Definition: electric_field.hpp:133
int nplanes
Number of planes.
Definition: grid.hpp:169
GridField< DeviceType, VarType::Vector, PhiInterpType::Planes, TorType::MultiplePlanes, KinType::DriftKin > EfieldType
Definition: grid_field.hpp:484
Definition: grid_field_pack.hpp:24
int node_offset
Offset of first mesh node belonging to this MPI rank.
Definition: domain_decomposition.hpp:89
GradientMatrices< DeviceType > grad_matrices
Definition: get_potential_grad.hpp:67
Projection< HostType > half_plane_ff
Definition: grid.hpp:188
void deallocate_device_matrices_if_not_resident()
Definition: gyro_avg_mat.hpp:56
Boundary pbd0
Definition: electric_field.hpp:157
Definition: grid_field.hpp:22
Definition: boundary.hpp:81
View< double ***, CLayout, HostType > save_dpot
Definition: electric_field.hpp:136
int em_pullback_mode
Definition: sml.hpp:68
bool grad_psitheta
Definition: sml.hpp:89
GridFieldPackPtr copy_push_fields_to_device_gyro_kin_XGC1(const Simulation< DeviceType > &sml, const DomainDecomposition< DeviceType > &pol_decomp, const MagneticField< DeviceType > &magnetic_field, const Grid< DeviceType > &grid, Smoothing &smoothing, bool near_field=false) const
Definition: electric_field.hpp:348
GridField< HostType, VarType::Scalar, PhiInterpType::Planes, TorType::OnePlane, KinType::DriftKin > Ah_cv
Definition: electric_field.hpp:118
ElectricField()
Definition: electric_field.hpp:162
PhiInterpType
Definition: globals.hpp:95
#define TIMER(N, F)
Definition: timer_macro.hpp:24
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::MultiplePlanes, KinType::DriftKin > Ah_cv_h
Definition: electric_field.hpp:117
void use_namelist(const string &namelist)
Definition: NamelistReader.hpp:355
constexpr PhiInterpType PIT_GLOBAL
Definition: globals.hpp:103
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::MultiplePlanes, KinType::DriftKin > As_h_backup
Definition: electric_field.hpp:114
Definition: memory_prediction.hpp:4
Boundary AbdH
Definition: electric_field.hpp:155
Boundary jbdH
Definition: electric_field.hpp:154
void grid_field_copy(T &dest, const T &src)
Definition: grid_field.hpp:496
Definition: smoothing.hpp:9
GridField< HostType, VarType::Vector2D, PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > dEz_B2
Gradient of Ez/B^2.
Definition: electric_field.hpp:128
void gather_phi_ff_on_device(View< FT **, CLayout, HostType > &tmp, View< FT *, CLayout, HostType > &tmp_full, const T_h &rho_ff_h, View< FT **, CLayout, DeviceType > &phi_ff)
Definition: plane_field_gatherer.hpp:197
Field00< DeviceType > field00
Definition: get_potential_grad.hpp:283
Definition: globals.hpp:90
GridField< HostType, vec2d_if_axisym< PIT_GLOBAL >), PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > dAs
Definition: electric_field.hpp:115
Pack< Labeled< typename getGyroVecFldType< KT >::t, Label::E >> t
Definition: electric_field.hpp:48
void request_potential(const GridField< DeviceOut, VarType::Scalar, PIT, TT, KT > &potential_in)
Definition: get_potential_grad.hpp:302
Pack< Labeled< Efield2DGyroType, Label::E >> t
Definition: electric_field.hpp:68
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::MultiplePlanes, KinType::DriftKin > Ah_h
Definition: electric_field.hpp:109
bool E00_efield
Flux-surface averaged potential not used for calculating the electric field if .false.
Definition: electric_field.hpp:101
Definition: label.hpp:44
Definition: simple00_solver.hpp:7
GridField< HostType, VarType::Vector2D, PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > dEr_B2
Gradient of Er/B^2.
Definition: electric_field.hpp:127
View< double *, CLayout, HostType > pot00_1d
1D flux-surface averaged potential
Definition: electric_field.hpp:141
GridField< HostType, VarType::Vector2D, PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > du2_E
Gradient of the square (dot product) of the E x B drift.
Definition: electric_field.hpp:129
KinType
Definition: globals.hpp:88
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::OnePlane, KinType::DriftKin > jpara_diff_previous_h
Definition: electric_field.hpp:147
View< int *, CLayout, HostType > all_first_plane
First plane of each rank.
Definition: field_decomposition.hpp:43
bool namelist_present(const string &namelist)
Definition: NamelistReader.hpp:351
bool electron_on
Use kinetic electrons.
Definition: sml.hpp:54
GridField< HostType, VarType::Scalar, PhiInterpType::Planes, TorType::OnePlane, KinType::GyroKin > Epar_em
Definition: electric_field.hpp:119
Definition: electric_field.hpp:28
void get_sonic_fields(const Grid< DeviceType > &grid, const GridField< HostType, vec2d_if_axisym< PIT_GLOBAL >(), PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > &E, View< double *, CLayout, HostType > &Er_B2_h, View< double *, CLayout, HostType > &Ez_B2_h, View< double *, CLayout, HostType > &u2_E_h)
bool calculate_phi_ff_on_device
Definition: electric_field.hpp:97
void exit_XGC(std::string msg)
Definition: globals.hpp:37
Kokkos::View< T *, Kokkos::LayoutRight, Device > my_subview(const Kokkos::View< T ****, Kokkos::LayoutRight, Device > &view, int i, int j, int k)
Definition: my_subview.hpp:8
GridField< DeviceType, VarType::Scalar, PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > PotGyroType
Definition: grid_field.hpp:490
Definition: magnetic_field.F90:1
Definition: electric_field.hpp:24
bool turb_efield
E-field calculated only with if .false., psndpot will still contain all (n=0,|m|&gt;0) and (|n|&gt;0...
Definition: electric_field.hpp:100
Pack< Labeled< typename getGyroVecFldType< KT >::t, Label::E >, Labeled< E00Type, Label::E00 >, Labeled< PotType, Label::ddpotdt >> t
Definition: electric_field.hpp:56
View< double *, CLayout, HostType > pot0m
n=0 component of the electrostatic potential before smoothing
Definition: electric_field.hpp:140
View< double ***, CLayout, HostType > save_dpot0
Definition: electric_field.hpp:135
int nphi
Definition: electric_field.hpp:91
Boundary cbdH
Definition: electric_field.hpp:158
GridField< HostType, VarType::Scalar, PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > As
Definition: electric_field.hpp:116
int nnode
Definition: electric_field.hpp:90
FieldDecomposition< Device > field_decomp
Definition: domain_decomposition.hpp:86
Definition: species.hpp:75
void request_gradient(const GridField< DeviceOut, VT, PIT, TT, KT > &gradient_in)
Definition: get_potential_grad.hpp:307
void get_field_Ah_cv_ff(const Grid< DeviceType > &grid, const DomainDecomposition< DeviceType > &pol_decomp, const GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::MultiplePlanes, KinType::DriftKin > &Ah_cv_h, const GridField< HostType, VarType::Scalar, PhiInterpType::Planes, TorType::OnePlane, KinType::DriftKin > &Ah_cv_ff)
Definition: get_potential_grad.cpp:7
void calculate_gradient(const Grid< DeviceType > &grid, const GradientMatrices< DeviceType > &grad_matrices)
Definition: get_potential_grad.hpp:142
GyroAverageMatrices< Device > gyro_avg_matrices
Definition: species.hpp:147
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::MultiplePlanes, KinType::DriftKin > dpot_h
Definition: electric_field.hpp:132
int nnode
Number of grid nodes.
Definition: grid.hpp:168
GridField< DeviceType, VarType::Vector, PhiInterpType::Planes, TorType::OnePlane, KinType::GyroKin > EfieldGyroType
Definition: grid_field.hpp:488
double em_pullback_dampfac
Damping term gamma on -b.grad(phi) in pullback mode 4.
Definition: sml.hpp:74
GridField< HostType, VarType::Scalar, PhiInterpType::None, TorType::OnePlane, KinType::DriftKin > dpot_n0_h
Definition: electric_field.hpp:134
bool n0_m_efield
Definition: electric_field.hpp:102
View< int *, CLayout, HostType > all_first_node
First node of each rank.
Definition: field_decomposition.hpp:41
bool em_control_variate
Switch for use of control variate method.
Definition: sml.hpp:67
int first_node
First mesh node belonging to this rank, including ghost nodes.
Definition: field_decomposition.hpp:32
GridField< HostType, vec2d_if_axisym< PIT_GLOBAL >), PIT_GLOBAL, TorType::OnePlane, KinType::GyroKin > E
Definition: electric_field.hpp:122
void set_field(const Grid< DeviceType > &grid, const FieldFollowingCoordinates &ff, View< Field< VarType::Vector2D, PIT > *, CLayout, DeviceOut > &field00_ff_h)
Definition: get_potential_grad.hpp:158
View< double ***, CLayout, HostType > dpotsave
Definition: electric_field.hpp:137
void calculate_phi_ff_on_device(const Simulation< DeviceType > &sml, const Grid< DeviceType > &grid, const MagneticField< DeviceType > &magnetic_field, Smoothing &smoothing, GetPotentialGradTemp< DeviceType, DeviceType > &tmp, const View< Field< VarType::Scalar, PhiInterpType::None > *, CLayout, HostType > &dpot_h, const GT0 &pot0_h, GT &phi_ff, GT2 &pot_phi_ff, bool potential_is_requested=true, bool use_field00=false, bool ignore_poloidal_dpot=false)
Definition: plane_field_gatherer.hpp:117
Boundary cbd0
Definition: electric_field.hpp:156
ElectricField(NLReader::NamelistReader &nlr, const Grid< DeviceType > &grid, int nrho_in, bool es_reduced_deltaf_setup=false, double dt=1.0, double psi_norm=1.0)
Definition: electric_field.hpp:166
GridFieldPackPtr copy_push_fields_to_device_drift_kin_XGC1(const Simulation< DeviceType > &sml, const DomainDecomposition< DeviceType > &pol_decomp, const MagneticField< DeviceType > &magnetic_field, const Grid< DeviceType > &grid, Smoothing &smoothing, bool near_field=false) const
Definition: electric_field.hpp:275
Pack< Labeled< typename getGyroVecFldType< KT >::t, Label::E >, Labeled< typename getGyroVecFldType< KT >::t, Label::dAh >, Labeled< typename getGyroVecFldType< KT >::t, Label::dAs >, Labeled< typename getGyroScaFldType< KT >::t, Label::Ah >, Labeled< typename getGyroScaFldType< KT >::t, Label::As >, Labeled< typename getGyroScaFldType< KT >::t, Label::Epar_em >> t
Definition: electric_field.hpp:42
static int GPTLstop(const char *name)
Definition: timer_macro.hpp:10
Definition: get_potential_grad.hpp:46