PB3D [2.47]
Ideal linear high-n MHD stability in 3-D
Loading...
Searching...
No Matches
PB3D_utilities.f90
Go to the documentation of this file.
1!------------------------------------------------------------------------------!
2!> Numerical utilities related to PB3D operations.
3!------------------------------------------------------------------------------!
5#include <PB3D_macros.h>
7 use messages
9 use hdf5_vars, only: var_1d_type
10
11 implicit none
12 private
14
15 ! interfaces
16
17 !> \public Converts 1-D to n-D variables.
18 !!
19 !! The 1-D variables are used for internal storage in HDF5, whereas the n_D
20 !! variables correspond to the ones in PB3D.
21 interface conv_1d2nd
22 !> \public
23 module procedure conv_1d2nd_1d
24 !> \public
25 module procedure conv_1d2nd_2d
26 !> \public
27 module procedure conv_1d2nd_3d
28 !> \public
29 module procedure conv_1d2nd_4d
30 !> \public
31 module procedure conv_1d2nd_6d
32 !> \public
33 module procedure conv_1d2nd_7d
34 end interface
35
36contains
37 !> \private 1-D version
38 subroutine conv_1d2nd_1d(var_in,var_out)
39 ! input / output
40 type(var_1d_type), intent(in) :: var_in !< 1D variable
41 real(dp), intent(inout), allocatable :: var_out(:) !< output variable
42
43 ! allocate and copy variable
44 if (allocated(var_out)) deallocate(var_out)
45 allocate(var_out(var_in%tot_i_min(1):var_in%tot_i_max(1)))
46 var_out = reshape(var_in%p,shape(var_out))
47 end subroutine conv_1d2nd_1d
48 !> \private 2-D version
49 subroutine conv_1d2nd_2d(var_in,var_out)
50 ! input / output
51 type(var_1d_type), intent(in) :: var_in !< 1D variable
52 real(dp), intent(inout), allocatable :: var_out(:,:) !< output variable
53
54 ! allocate and copy variable
55 if (allocated(var_out)) deallocate(var_out)
56 allocate(var_out(&
57 &var_in%tot_i_min(1):var_in%tot_i_max(1),&
58 &var_in%tot_i_min(2):var_in%tot_i_max(2)))
59 var_out = reshape(var_in%p,[&
60 &var_in%tot_i_max(1)-var_in%tot_i_min(1)+1,&
61 &var_in%tot_i_max(2)-var_in%tot_i_min(2)+1])
62 end subroutine conv_1d2nd_2d
63 !> \private 3-D version
64 subroutine conv_1d2nd_3d(var_in,var_out)
65 ! input / output
66 type(var_1d_type), intent(in) :: var_in !< 1D variable
67 real(dp), intent(inout), allocatable :: var_out(:,:,:) !< output variable
68
69 ! allocate and copy variable
70 if (allocated(var_out)) deallocate(var_out)
71 allocate(var_out(&
72 &var_in%tot_i_min(1):var_in%tot_i_max(1),&
73 &var_in%tot_i_min(2):var_in%tot_i_max(2),&
74 &var_in%tot_i_min(3):var_in%tot_i_max(3)))
75 var_out = reshape(var_in%p,shape(var_out))
76 end subroutine conv_1d2nd_3d
77 !> \private 4-D version
78 subroutine conv_1d2nd_4d(var_in,var_out)
79 ! input / output
80 type(var_1d_type), intent(in) :: var_in !< 1D variable
81 real(dp), intent(inout), allocatable :: var_out(:,:,:,:) !< output variable
82
83 ! allocate and copy variable
84 if (allocated(var_out)) deallocate(var_out)
85 allocate(var_out(&
86 &var_in%tot_i_min(1):var_in%tot_i_max(1),&
87 &var_in%tot_i_min(2):var_in%tot_i_max(2),&
88 &var_in%tot_i_min(3):var_in%tot_i_max(3),&
89 &var_in%tot_i_min(4):var_in%tot_i_max(4)))
90 var_out = reshape(var_in%p,shape(var_out))
91 end subroutine conv_1d2nd_4d
92 !> \private 6-D version
93 subroutine conv_1d2nd_6d(var_in,var_out)
94 ! input / output
95 type(var_1d_type), intent(in) :: var_in !< 1D variable
96 real(dp), intent(inout), allocatable :: var_out(:,:,:,:,:,:) !< output variable
97
98 ! allocate and copy variable
99 if (allocated(var_out)) deallocate(var_out)
100 allocate(var_out(&
101 &var_in%tot_i_min(1):var_in%tot_i_max(1),&
102 &var_in%tot_i_min(2):var_in%tot_i_max(2),&
103 &var_in%tot_i_min(3):var_in%tot_i_max(3),&
104 &var_in%tot_i_min(4):var_in%tot_i_max(4),&
105 &var_in%tot_i_min(5):var_in%tot_i_max(5),&
106 &var_in%tot_i_min(6):var_in%tot_i_max(6)))
107 var_out = reshape(var_in%p,shape(var_out))
108 end subroutine conv_1d2nd_6d
109 !> \private 7-D version
110 subroutine conv_1d2nd_7d(var_in,var_out)
111 ! input / output
112 type(var_1d_type), intent(in) :: var_in !< 1D variable
113 real(dp), intent(inout), allocatable :: var_out(:,:,:,:,:,:,:) !< output variable
114
115 ! allocate and copy variable
116 if (allocated(var_out)) deallocate(var_out)
117 allocate(var_out(&
118 &var_in%tot_i_min(1):var_in%tot_i_max(1),&
119 &var_in%tot_i_min(2):var_in%tot_i_max(2),&
120 &var_in%tot_i_min(3):var_in%tot_i_max(3),&
121 &var_in%tot_i_min(4):var_in%tot_i_max(4),&
122 &var_in%tot_i_min(5):var_in%tot_i_max(5),&
123 &var_in%tot_i_min(6):var_in%tot_i_max(6),&
124 &var_in%tot_i_min(7):var_in%tot_i_max(7)))
125 var_out = reshape(var_in%p,shape(var_out))
126 end subroutine conv_1d2nd_7d
127
128 !> Setup parallel id.
129 !!
130 !! The parallel id consists of:
131 !! - \c par_id(1): start index
132 !! - \c par_id(2): end index
133 !! - \c par_id(3): stride
134 !!
135 !! These are set up by considering the transformation between a point \f$r
136 !! \in (1\ldots n)\f$ in the local variable, with corresponding indices
137 !! \f$(a\ldots b)\f$ indicated by \c par_lim in the HDF5 variable in memory,
138 !! so that \f$n = b-a+1\f$:
139 !! \f[p + k s = a + r - 1,\f]
140 !! where \f$k\f$ is an integer, \f$s\f$ is the stride for Richardson level
141 !! \f$i\f$ (with max. level \f$I\f$):
142 !! \f[\begin{aligned}
143 !! s &= 2^{I-1} \ \text{for} \ i = 1 \\
144 !! &= 2^{I-i+1} \ \text{for} \ i > 1
145 !! \end{aligned}\f]
146 !! and where \f$p\f$ is the starting point in the HDF5 variables:
147 !! \f[\begin{aligned}
148 !! p &= 1 \ \text{for} \ i = 1 \\
149 !! &= 1 + s/2 \ \text{for} \ i > 1
150 !! \end{aligned}\f]
151 !!
152 !! Therefore, the minimum possible \f$r\f$ lies in \f$(0..s-1)\f$:
153 !! \f[\mod(r-1,s) = r_\text{min}-1, \f]
154 !! which leads to
155 !! \f[r_\text{min} = 1 + \mod(p-a,s). \f]
156 !!
157 !! The maximum possible \f$r\f$, then, lies in \f$(n-s+1..n)\f$, which leads
158 !! to:
159 !! \f[ r_\text{max} = n - s + 1 + \mod(p-b-1,s). \f]
160 !!
161 !! These limits and the strides are saved in \c par_id = \f$\vec{r} =
162 !! \begin{pmatrix}r_\text{min}\\ r_\text{max}\end{pmatrix}\f$.
163 !!
164 !! If the optional indices \f$a\f$ and \f$b\f$ are not given they are
165 !! assumed to be 1 and \f$n\f$, with \f$n = 1+ks\f$, which simplifies the
166 !! equations to:
167 !! \f[\begin{aligned}
168 !! r_\text{min} &= p \\
169 !! r_\text{max} &= n-p+1 .
170 !! \end{aligned}\f]
171 !!
172 !! Optionally, the indices in the HDF5 arrays can also be
173 !! returned in \c par_id_mem = \f$\begin{pmatrix}R_\text{min}\\
174 !! R_\text{max}\end{pmatrix}\f$. These are equal to \f$k-1\f$, where \f$k\f$
175 !! is the integer refered to above:
176 !! \f[\vec{R} = 1 + \frac{a-1-p+\vec{r}}{s}, \f]
177 !! where the addition between a vector and a scalar should be seen as the
178 !! element-wise operation.
179 function setup_par_id(grid,rich_lvl_max,rich_lvl_loc,tot_rich,par_lim,&
180 &par_id_mem) result(par_id)
181 use grid_vars, only: grid_type
182
183 ! input / output
184 type(grid_type), intent(in) :: grid !< grid
185 integer, intent(in) :: rich_lvl_max !< maximum Richardson level
186 integer, intent(in) :: rich_lvl_loc !< local Richardson level
187 logical, intent(in), optional :: tot_rich !< whether to combine with previous Richardson levels
188 integer, intent(in), optional :: par_lim(2) !< limits (a..b) of variable requested
189 integer, intent(inout), optional :: par_id_mem(2) !< parallel id in memory
190 integer :: par_id(3) !< parallel id
191
192 ! local variables
193 integer :: s ! stride
194 integer :: p ! lower limit in memory
195 integer :: n ! b-a+1
196 logical :: tot_rich_loc ! local tot_rich
197 integer :: par_lim_loc(2) ! local par_lim
198
199 ! set up local tot_rich and par_lim
200 tot_rich_loc = .false.
201 if (present(tot_rich) .and. rich_lvl_max.gt.1) tot_rich_loc = tot_rich ! only for higher Richardson levels
202 par_lim_loc = [1,grid%n(1)]
203 if (present(par_lim)) par_lim_loc = par_lim
204
205 ! set up parallel indices
206 n = par_lim_loc(2)-par_lim_loc(1)+1
207 if (tot_rich_loc) then
208 if (rich_lvl_loc.eq.1) then
209 s = 2**(rich_lvl_max-1)
210 p = 1
211 else
212 s = 2**(rich_lvl_max+1-rich_lvl_loc)
213 p = 1 + s/2
214 end if
215 else
216 s = 1
217 p = 1
218 end if
219 par_id(1) = 1 + modulo(p-par_lim_loc(1),s)
220 par_id(2) = n - s + 1 + modulo(p-par_lim_loc(2)-1,s)
221 par_id(3) = s
222
223 ! set par_id in memory if requested
224 if (present(par_id_mem)) par_id_mem = &
225 &1 + (par_lim_loc(1)-1-p+par_id(1:2))/s
226 end function setup_par_id
227
228 !> Returns richardson id.
229 !!
230 !! \c rich_id has the following structure:
231 !! - \c rich_id(1): start Richardson level
232 !! - \c rich_id(2): end Richardson level
233 function setup_rich_id(rich_lvl_max,tot_rich) result(rich_id)
234 ! input / output
235 integer, intent(in) :: rich_lvl_max !< maximum Richardson level
236 logical, intent(in), optional :: tot_rich !< whether to combine with previous Richardson levels
237 integer :: rich_id(2) !< Richardson id
238
239 ! set up rich_id
240 rich_id = [rich_lvl_max,rich_lvl_max]
241 if (present(tot_rich) .and. rich_lvl_max.gt.1) then ! only for higher Richardson levels
242 if (tot_rich) rich_id = [1,rich_lvl_max]
243 end if
244 end function setup_rich_id
245end module pb3d_utilities
Converts 1-D to n-D variables.
Variables pertaining to the different grids used.
Definition grid_vars.f90:4
Variables pertaining to HDF5 and XDMF.
Definition HDF5_vars.f90:4
Numerical utilities related to giving output.
Definition messages.f90:4
Numerical variables used by most other modules.
Definition num_vars.f90:4
integer, parameter, public dp
double precision
Definition num_vars.f90:46
integer, parameter, public max_name_ln
maximum length of filenames
Definition num_vars.f90:51
real(dp), parameter, public pi
Definition num_vars.f90:83
integer, parameter, public max_str_ln
maximum length of strings
Definition num_vars.f90:50
Numerical utilities related to PB3D operations.
integer function, dimension(2), public setup_rich_id(rich_lvl_max, tot_rich)
Returns richardson id.
integer function, dimension(3), public setup_par_id(grid, rich_lvl_max, rich_lvl_loc, tot_rich, par_lim, par_id_mem)
Setup parallel id.
Operations on strings.
Type for grids.
Definition grid_vars.f90:59
1D equivalent of multidimensional variables, used for internal HDF5 storage.
Definition HDF5_vars.f90:48