PB3D  [2.45]
Ideal linear high-n MHD stability in 3-D
grid_vars.f90
Go to the documentation of this file.
1 !------------------------------------------------------------------------------!
3 !------------------------------------------------------------------------------!
4 module grid_vars
5 #include <PB3D_macros.h>
6  use str_utilities
7  use messages
8  use num_vars, only: dp, pi, max_str_ln, weight_dp
9 
10  implicit none
11  private
14 #if ldebug
16 #endif
17 
18  ! global variables
19  integer :: n_r_in
20  integer :: n_r_eq
21  integer :: n_r_x
22  integer :: n_r_sol
23  integer :: n_alpha
24  real(dp) :: min_par_x
25  real(dp) :: max_par_x
26  real(dp) :: min_alpha
27  real(dp) :: max_alpha
28  real(dp), allocatable :: alpha(:)
29 #if ldebug
30  integer :: n_alloc_grids
31  integer :: n_alloc_discs
32 #endif
33 
59  type, public :: grid_type
60  integer :: n(3)
61  integer :: loc_n_r
62  integer :: i_min
63  integer :: i_max
64  logical :: divided
65  real(dp), pointer :: r_e(:) => null()
66  real(dp), pointer :: r_f(:) => null()
67  real(dp), pointer :: loc_r_e(:) => null()
68  real(dp), pointer :: loc_r_f(:) => null()
69  real(dp), pointer :: theta_e(:,:,:) => null()
70  real(dp), pointer :: theta_f(:,:,:) => null()
71  real(dp), pointer :: zeta_e(:,:,:) => null()
72  real(dp), pointer :: zeta_f(:,:,:) => null()
73  real(dp), allocatable :: trigon_factors(:,:,:,:,:)
74 #if ldebug
75  real(dp) :: estim_mem_usage
76 #endif
77  contains
79  procedure :: init => init_grid
81  procedure :: copy => copy_grid
83  procedure :: dealloc => dealloc_grid
84  end type
85 
86 contains
101  integer function init_grid(grid,n,i_lim,divided) result(ierr)
102 #if ldebug
103  use num_vars, only: print_mem_usage, rank
104 #endif
105  character(*), parameter :: rout_name = 'init_grid'
106 
107  ! input / output
108  class(grid_type), intent(inout) :: grid
109  integer, intent(in) :: n(3)
110  integer, intent(in), optional :: i_lim(2)
111  logical, intent(in), optional :: divided
112 
113  ! local variables
114  character(len=max_str_ln) :: err_msg ! error message
115  logical :: divided_loc ! local divided
116 
117  ! initialize ierr
118  ierr = 0
119 
120  ! tests
121  if (present(i_lim)) then
122  if (i_lim(2)-i_lim(1)+1.gt.n(3)) then
123  ierr = 1
124  err_msg = 'The local nr. of normal points cannot be higher &
125  &than the total nr. of normal points'
126  chckerr(err_msg)
127  end if
128  end if
129 
130 #if ldebug
131  ! initialize memory usage
132  if (print_mem_usage) grid%estim_mem_usage = 0._dp
133 #endif
134 
135  ! set local divided and loc_n_r
136  divided_loc = .false.
137  if (present(i_lim)) then ! might be divided grid
138  if (i_lim(2).lt.i_lim(1)) then
139  ierr = 1
140  write(*,*) 'i_lim = ', i_lim
141  err_msg = 'faulty i_lim'
142  chckerr(err_msg)
143  end if
144  grid%i_min = i_lim(1)
145  grid%i_max = i_lim(2)
146  grid%loc_n_r = i_lim(2)-i_lim(1)+1
147  if (i_lim(2)-i_lim(1)+1.lt.n(3)) divided_loc = .true. ! only divided if difference between local and total
148  else ! certainly not divided grid
149  grid%i_min = 1
150  grid%i_max = n(3)
151  grid%loc_n_r = n(3)
152  end if
153  if (present(divided)) divided_loc = divided
154 
155  grid%divided = divided_loc
156 
157  ! allocate normal variables
158  grid%n = n
159  allocate(grid%r_E(n(3)))
160  allocate(grid%r_F(n(3)))
161  if (divided_loc) then
162  allocate(grid%loc_r_E(grid%loc_n_r))
163  allocate(grid%loc_r_F(grid%loc_n_r))
164  else
165  grid%loc_r_E => grid%r_E
166  grid%loc_r_F => grid%r_F
167  end if
168 
169 #if ldebug
170  ! set estimated memory usage
171  if (print_mem_usage) grid%estim_mem_usage = grid%estim_mem_usage + &
172  &grid%n(3)*2
173 #endif
174 
175  ! allocate angular variables
176  if (n(1).ne.0 .and. n(2).ne.0) then
177  allocate(grid%theta_E(n(1),n(2),grid%loc_n_r))
178  allocate(grid%zeta_E(n(1),n(2),grid%loc_n_r))
179  allocate(grid%theta_F(n(1),n(2),grid%loc_n_r))
180  allocate(grid%zeta_F(n(1),n(2),grid%loc_n_r))
181 
182 #if ldebug
183  ! set estimated memory usage
184  if (print_mem_usage) grid%estim_mem_usage = grid%estim_mem_usage + &
185  &grid%loc_n_r*n(1)*n(2)*4
186 #endif
187  end if
188 
189 #if ldebug
190  ! increment n_alloc_grids
192 
193  ! print memory usage
194  if (print_mem_usage) call writo('[rank '//trim(i2str(rank))//&
195  &' - Expected memory usage of grid: '//&
196  &trim(r2strt(grid%estim_mem_usage*weight_dp))//' kB]',&
197  &alert=.true.)
198 #endif
199  end function init_grid
200 
202  subroutine dealloc_grid(grid)
203 #if ldebug
204  use num_vars, only: rank, print_mem_usage
205 #endif
206  ! input / output
207  class(grid_type), intent(inout) :: grid
208 
209  ! local variables
210 #if ldebug
211  integer :: mem_diff ! difference in memory
212  real(dp) :: estim_mem_usage ! estimated memory usage
213 
214  ! memory usage before deallocation
215  if (print_mem_usage) then
216  mem_diff = get_mem_usage()
217  estim_mem_usage = grid%estim_mem_usage
218  end if
219 #endif
220 
221  ! deallocate allocated pointers
222  deallocate(grid%r_E,grid%r_F)
223  if (grid%n(1).ne.0 .and. grid%n(2).ne.0) then ! 3D grid
224  deallocate(grid%theta_E,grid%zeta_E)
225  deallocate(grid%theta_F,grid%zeta_F)
226  end if
227  if (grid%divided) deallocate(grid%loc_r_E,grid%loc_r_F)
228 
229  ! nullify pointers
230  nullify(grid%r_E,grid%r_F)
231  nullify(grid%theta_E,grid%zeta_E)
232  nullify(grid%theta_F,grid%zeta_F)
233  nullify(grid%loc_r_E,grid%loc_r_F)
234 
235  ! deallocate allocatable variables
236  call dealloc_grid_final(grid)
237 
238 #if ldebug
239  ! decrement n_alloc_grids
241 
242  ! memory usage difference after deallocation
243  if (print_mem_usage) then
244  mem_diff = mem_diff - get_mem_usage()
245  call writo('[Rank '//trim(i2str(rank))//' - liberated '//&
246  &trim(i2str(mem_diff))//'kB deallocating grid ('//&
247  &trim(i2str(nint(100*mem_diff/&
248  &(estim_mem_usage*weight_dp))))//&
249  &'% of estimated)]',alert=.true.)
250  end if
251 #endif
252  contains
253  ! Note: intent(out) automatically deallocates the variable
255  subroutine dealloc_grid_final(grid)
256  ! input / output
257  type(grid_type), intent(out) :: grid ! grid to be deallocated
258  end subroutine dealloc_grid_final
259  end subroutine dealloc_grid
260 
266  integer function copy_grid(grid_i,grid_o) result(ierr)
267  character(*), parameter :: rout_name = 'copy_grid'
268 
269  ! input / output
270  class(grid_type), intent(in) :: grid_i
271  type(grid_type), intent(inout) :: grid_o
272 
273  ! initialize ierr
274  ierr = 0
275 
276  ierr = init_grid(grid_o,grid_i%n,i_lim=[grid_i%i_min,grid_i%i_max],&
277  &divided=grid_i%divided)
278  chckerr('')
279  grid_o%r_E = grid_i%r_E
280  grid_o%r_F = grid_i%r_F
281  grid_o%loc_r_E = grid_i%loc_r_E
282  grid_o%loc_r_F = grid_i%loc_r_F
283  if (associated(grid_i%theta_E)) grid_o%theta_E = grid_i%theta_E
284  if (associated(grid_i%theta_F)) grid_o%theta_F = grid_i%theta_F
285  if (associated(grid_i%zeta_E)) grid_o%zeta_E = grid_i%zeta_E
286  if (associated(grid_i%zeta_F)) grid_o%zeta_F = grid_i%zeta_F
287  if (allocated(grid_i%trigon_factors)) then
288  allocate(grid_o%trigon_factors(size(grid_i%trigon_factors,1),&
289  &size(grid_i%trigon_factors,2),size(grid_i%trigon_factors,3),&
290  &size(grid_i%trigon_factors,4),size(grid_i%trigon_factors,5)))
291  grid_o%trigon_factors = grid_i%trigon_factors
292  end if
293  end function copy_grid
294 end module grid_vars
num_vars::dp
integer, parameter, public dp
double precision
Definition: num_vars.f90:46
num_vars
Numerical variables used by most other modules.
Definition: num_vars.f90:4
num_vars::max_str_ln
integer, parameter, public max_str_ln
maximum length of strings
Definition: num_vars.f90:50
str_utilities::i2str
elemental character(len=max_str_ln) function, public i2str(k)
Convert an integer to string.
Definition: str_utilities.f90:18
grid_vars::max_par_x
real(dp), public max_par_x
max. of parallel coordinate [ ] in field-aligned grid
Definition: grid_vars.f90:25
messages::get_mem_usage
integer function, public get_mem_usage()
Returns the memory usage in kilobytes.
Definition: messages.f90:554
grid_vars::n_r_eq
integer, public n_r_eq
nr. of normal points in equilibrium grid
Definition: grid_vars.f90:20
str_utilities
Operations on strings.
Definition: str_utilities.f90:4
grid_vars::grid_type
Type for grids.
Definition: grid_vars.f90:59
str_utilities::r2strt
elemental character(len=max_str_ln) function, public r2strt(k)
Convert a real (double) to string.
Definition: str_utilities.f90:54
grid_vars::n_r_x
integer, public n_r_x
nr. of normal points in perturbation grid
Definition: grid_vars.f90:21
grid_vars::alpha
real(dp), dimension(:), allocatable, public alpha
field line label alpha
Definition: grid_vars.f90:28
grid_vars::n_r_sol
integer, public n_r_sol
nr. of normal points in solution grid
Definition: grid_vars.f90:22
num_vars::weight_dp
real(dp), parameter, public weight_dp
size of double precision in kB
Definition: num_vars.f90:49
grid_vars::min_par_x
real(dp), public min_par_x
min. of parallel coordinate [ ] in field-aligned grid
Definition: grid_vars.f90:24
grid_vars::n_r_in
integer, public n_r_in
nr. of normal points in input grid
Definition: grid_vars.f90:19
grid_vars::n_alloc_discs
integer, public n_alloc_discs
nr. of allocated discretizations
Definition: grid_vars.f90:31
num_vars::print_mem_usage
logical, public print_mem_usage
print memory usage is printed
Definition: num_vars.f90:149
grid_vars::dealloc_grid
subroutine dealloc_grid(grid)
Deallocates a grid.
Definition: grid_vars.f90:203
grid_vars::copy_grid
integer function copy_grid(grid_i, grid_o)
Deep copy of a grid.
Definition: grid_vars.f90:267
messages::writo
subroutine, public writo(input_str, persistent, error, warning, alert)
Write output to file identified by output_i.
Definition: messages.f90:275
messages
Numerical utilities related to giving output.
Definition: messages.f90:4
num_vars::pi
real(dp), parameter, public pi
Definition: num_vars.f90:83
grid_vars::max_alpha
real(dp), public max_alpha
max. of field-line label [ ] in field-aligned grid
Definition: grid_vars.f90:27
grid_vars
Variables pertaining to the different grids used.
Definition: grid_vars.f90:4
grid_vars::init_grid
integer function init_grid(grid, n, i_lim, divided)
Initializes a new grid.
Definition: grid_vars.f90:102
grid_vars::min_alpha
real(dp), public min_alpha
min. of field-line label [ ] in field-aligned grid
Definition: grid_vars.f90:26
grid_vars::n_alloc_grids
integer, public n_alloc_grids
nr. of allocated grids
Definition: grid_vars.f90:30
grid_vars::n_alpha
integer, public n_alpha
nr. of field-lines
Definition: grid_vars.f90:23
num_vars::rank
integer, public rank
MPI rank.
Definition: num_vars.f90:68