XGC1
DM_wrapper.hpp
Go to the documentation of this file.
1 #ifndef DM_WRAPPER_HPP
2 #define DM_WRAPPER_HPP
3 
4 #define VELOCITY_SPACE_DIMENSION 2
5 
6 #ifndef NO_PETSC
7 
8 #include <string>
9 #include <Kokkos_Core.hpp>
10 #include "space_settings.hpp"
11 #include <petscdm.h>
12 #include <petscversion.h>
13 #include <petscsys.h>
14 #include <petscdmplex.h>
15 #include <petscds.h>
16 #include "petscdmswarm.h"
17 #include "petscksp.h"
18 
19 // For older PETSc versions
20 #if !defined(PETSC_USE_STRICT_PETSCERRORCODE) && !defined(PETSC_SUCCESS)
21 #define PETSC_SUCCESS 0
22 #endif
23 
24 // For some reason Kokkos cannot handle Views of PETSc objects, but it works when putting them in a wrapper
25 // Pseudo-inverse mesh PETSc objects
26 struct DMObjects{
27  DM dm;
28  Mat MM;
29 };
30 
31 #endif
32 
33 // Wrapper for PETSc DM object to facilitate cleanup in destructor
34 struct DMWrapper{
35 
36 #ifdef NO_PETSC
37  DMWrapper(){}
38 #else
39  bool is_owner;
40  int dm_len;
41  Kokkos::View<DMObjects*, Kokkos::LayoutRight, HostType> obj;
42 
44  : is_owner(false),
45  dm_len(0){
46  Kokkos::resize(obj, 0);
47  }
48 
49  ~DMWrapper(){ // destructor
50  if(is_owner){
51  for (int id = 0; id < dm_len; id++){
52  DMDestroy(&obj(id).dm);
53  MatDestroy(&obj(id).MM);
54  }
55  }
56  }
57 
58  DMWrapper(const DMWrapper& original) // copy constructor
59  : is_owner(false),
60  dm_len(original.dm_len){
61  Kokkos::resize(obj, dm_len);
62  for (int id = 0; id < dm_len; id++){
63  obj(id).dm = original.obj(id).dm;
64  obj(id).MM = original.obj(id).MM;
65  }
66  }
67 
68  DMWrapper& operator=(const DMWrapper& original) { // copy assignment
69  if (this == &original){
70  return *this;
71  }
72  is_owner = false;
73  dm_len = original.dm_len;
74  Kokkos::resize(obj, dm_len);
75  for (int id = 0; id < dm_len; id++){
76  obj(id).dm = original.obj(id).dm;
77  obj(id).MM = original.obj(id).MM;
78  }
79  return *this;
80  }
81 
99  PetscErrorCode initialize_pseudo_inverse_interpolation_petsc(int nthreads,
100  PetscInt order, const PetscInt Nspecies,
101  const PetscReal vPara_min, const PetscReal vPara_max,
102  const PetscInt nvp, const PetscReal vPerp_min,
103  const PetscReal vPerp_max, const PetscInt nmu)
104  {
105  int element_order_shift = (order > 0) ? order : 1;
106  const PetscInt num_vPara = 2*nvp/element_order_shift + 1;
107  const PetscInt num_vPerp = nmu/element_order_shift + 1;
108 
109  is_owner = true;
110  dm_len = nthreads;
111  Kokkos::resize(obj, dm_len);
112 
113  PetscErrorCode ierr;
114 
115  PetscInt cells[2];
116  PetscReal lo[2], hi[2];
117  cells[0] = num_vPara - 1; //2 grid points give 1 cell, etc
118  cells[1] = num_vPerp - 1;
119  lo[0] = vPara_min;
120  lo[1] = vPerp_min;
121  hi[0] = vPara_max;
122  hi[1] = vPerp_max;
123 
124  PetscFunctionBeginUser;
125 
126  std::string order_str = std::to_string(order);
127  ierr = PetscOptionsSetValue(NULL, "-petscspace_degree", order_str.c_str());CHKERRQ(ierr);
128 
129  /* create mesh */
130  PetscFE fe;
131  PetscInt field = 0, dim = VELOCITY_SPACE_DIMENSION;
132  DMBoundaryType periodicity[2] = {DM_BOUNDARY_NONE, DM_BOUNDARY_NONE};
133  PetscBool interpolate = PETSC_TRUE;
134 
135  for (int id = 0; id < dm_len; id++){
136  PetscInt petsc_zero=0.0;
137  ierr = DMPlexCreateBoxMesh(PETSC_COMM_SELF, dim, PETSC_FALSE, cells, lo, hi, periodicity, interpolate, petsc_zero, PETSC_FALSE, &obj(id).dm);CHKERRQ(ierr);
138  ierr = PetscObjectSetName((PetscObject)obj(id).dm, "Potential Grid");CHKERRQ(ierr);
139  if (id == dm_len - 1) {ierr = DMViewFromOptions(obj(id).dm, NULL, "-dm_view");CHKERRQ(ierr);}
140  ierr = DMSetFromOptions(obj(id).dm);CHKERRQ(ierr);
141  ierr = PetscFECreateDefault(PETSC_COMM_SELF, dim, Nspecies, PETSC_FALSE, "", PETSC_DECIDE, &fe);CHKERRQ(ierr);
142  ierr = PetscFESetFromOptions(fe);CHKERRQ(ierr);
143  ierr = PetscObjectSetName((PetscObject)fe, "fe");CHKERRQ(ierr);
144  ierr = DMSetField(obj(id).dm, field, NULL, (PetscObject)fe);CHKERRQ(ierr);
145  ierr = DMCreateDS(obj(id).dm);CHKERRQ(ierr);
146  ierr = PetscFEDestroy(&fe);CHKERRQ(ierr);
147 
148  ierr = DMCreateMassMatrix(obj(id).dm, obj(id).dm, &obj(id).MM);CHKERRQ(ierr);
149  }
150 
151  PetscFunctionReturn(PETSC_SUCCESS);
152  } //end initialize_pseudo_inverse_interpolation()
153 
160  PetscErrorCode destroy_DM_petsc(){
161  PetscErrorCode ierr;
162  PetscFunctionBeginUser;
163  if(is_owner){
164  for (int id = 0; id < dm_len; id++){
165  if(obj(id).dm != NULL){
166  ierr = DMDestroy(&obj(id).dm);CHKERRQ(ierr);
167  obj(id).dm = NULL;
168  }
169  if(obj(id).MM != NULL){
170  ierr = MatDestroy(&obj(id).MM);CHKERRQ(ierr);
171  obj(id).MM = NULL;
172  }
173  }
174  }
175  PetscFunctionReturn(PETSC_SUCCESS);
176  }
177 #endif
178 
180  int order, const int Nspecies,
181  const double vPara_min, const double vPara_max,
182  const int nvp, const double vPerp_min,
183  const double vPerp_max, const int nmu){
184 #ifndef NO_PETSC
185  int ierr = initialize_pseudo_inverse_interpolation_petsc(nthreads, order, Nspecies, vPara_min, vPara_max, nvp, vPerp_min, vPerp_max, nmu);
186  CHKERRABORT(PETSC_COMM_SELF,ierr);
187 #endif
188  }
189 
190  void destroy_DM(){
191 #ifndef NO_PETSC
192  int ierr = destroy_DM_petsc();
193  CHKERRABORT(PETSC_COMM_SELF,ierr);
194 #endif
195  }
196 };
197 
198 #endif
#define VELOCITY_SPACE_DIMENSION
Definition: DM_wrapper.hpp:4
#define PETSC_SUCCESS
Definition: DM_wrapper.hpp:21
subroutine field(fld, t, rz_outside)
Calculate field of a given point using interpolation funtions This is for the equilibrium and RMP mag...
Definition: magnetic_field.F90:24
logical false
Definition: module.F90:102
Definition: DM_wrapper.hpp:26
Mat MM
PETSc mass matrix object for the velocity grid when pseudo-inverse is used.
Definition: DM_wrapper.hpp:28
DM dm
PETSc DM mesh object representing the velocity grid when pseudo-inverse is used.
Definition: DM_wrapper.hpp:27
Definition: DM_wrapper.hpp:34
PetscErrorCode initialize_pseudo_inverse_interpolation_petsc(int nthreads, PetscInt order, const PetscInt Nspecies, const PetscReal vPara_min, const PetscReal vPara_max, const PetscInt nvp, const PetscReal vPerp_min, const PetscReal vPerp_max, const PetscInt nmu)
Definition: DM_wrapper.hpp:99
int dm_len
Number of PETSc mesh objects to store.
Definition: DM_wrapper.hpp:40
DMWrapper()
Definition: DM_wrapper.hpp:43
bool is_owner
Definition: DM_wrapper.hpp:39
~DMWrapper()
Definition: DM_wrapper.hpp:49
void destroy_DM()
Definition: DM_wrapper.hpp:190
DMWrapper(const DMWrapper &original)
Definition: DM_wrapper.hpp:58
Kokkos::View< DMObjects *, Kokkos::LayoutRight, HostType > obj
Stores number of threads DMObjects.
Definition: DM_wrapper.hpp:41
PetscErrorCode destroy_DM_petsc()
Definition: DM_wrapper.hpp:160
void initialize_pseudo_inverse_interpolation(int nthreads, int order, const int Nspecies, const double vPara_min, const double vPara_max, const int nvp, const double vPerp_min, const double vPerp_max, const int nmu)
Definition: DM_wrapper.hpp:179
DMWrapper & operator=(const DMWrapper &original)
Definition: DM_wrapper.hpp:68