PyFishPack 0.1.0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PyFishPack/__init__.py +86 -0
- PyFishPack/__pycache__/__init__.cpython-313.pyc +0 -0
- PyFishPack/__pycache__/apps.cpython-313.pyc +0 -0
- PyFishPack/_dummy.c +23 -0
- PyFishPack/_dummy.cp313-win_amd64.pyd +0 -0
- PyFishPack/apps.py +3640 -0
- PyFishPack/fishpack.cp313-win_amd64.dll.a +0 -0
- PyFishPack/fishpack.cp313-win_amd64.pyd +0 -0
- PyFishPack/meson.build +213 -0
- PyFishPack/src/archive/f77/Makefile +19 -0
- PyFishPack/src/archive/f77/blktri.f +1404 -0
- PyFishPack/src/archive/f77/cblktri.f +1414 -0
- PyFishPack/src/archive/f77/cmgnbn.f +1592 -0
- PyFishPack/src/archive/f77/comf.f +186 -0
- PyFishPack/src/archive/f77/fftpack.f +2968 -0
- PyFishPack/src/archive/f77/genbun.f +1335 -0
- PyFishPack/src/archive/f77/gnbnaux.f +314 -0
- PyFishPack/src/archive/f77/hstcrt.f +443 -0
- PyFishPack/src/archive/f77/hstcsp.f +683 -0
- PyFishPack/src/archive/f77/hstcyl.f +485 -0
- PyFishPack/src/archive/f77/hstplr.f +538 -0
- PyFishPack/src/archive/f77/hstssp.f +634 -0
- PyFishPack/src/archive/f77/hw3crt.f +687 -0
- PyFishPack/src/archive/f77/hwscrt.f +512 -0
- PyFishPack/src/archive/f77/hwscsp.f +728 -0
- PyFishPack/src/archive/f77/hwscyl.f +538 -0
- PyFishPack/src/archive/f77/hwsplr.f +602 -0
- PyFishPack/src/archive/f77/hwsssp.f +780 -0
- PyFishPack/src/archive/f77/pois3d.f +550 -0
- PyFishPack/src/archive/f77/poistg.f +875 -0
- PyFishPack/src/archive/f77/sepaux.f +361 -0
- PyFishPack/src/archive/f77/sepeli.f +1029 -0
- PyFishPack/src/archive/f77/sepx4.f +958 -0
- PyFishPack/src/centered_axisymmetric_spherical_solver.f90 +1002 -0
- PyFishPack/src/centered_cartesian_helmholtz_solver_3d.f90 +819 -0
- PyFishPack/src/centered_cartesian_solver.f90 +583 -0
- PyFishPack/src/centered_cylindrical_solver.f90 +634 -0
- PyFishPack/src/centered_helmholtz_solvers.f90 +156 -0
- PyFishPack/src/centered_polar_solver.f90 +746 -0
- PyFishPack/src/centered_real_linear_systems_solver.f90 +280 -0
- PyFishPack/src/centered_spherical_solver.f90 +928 -0
- PyFishPack/src/complex_block_tridiagonal_linear_systems_solver.f90 +1947 -0
- PyFishPack/src/complex_linear_systems_solver.f90 +1787 -0
- PyFishPack/src/fftpack_c_api.f90 +86 -0
- PyFishPack/src/fishpack.f90 +191 -0
- PyFishPack/src/fishpack.pyf +504 -0
- PyFishPack/src/fishpack_c_api.f90 +365 -0
- PyFishPack/src/fishpack_original.pyf +2119 -0
- PyFishPack/src/fishpack_precision.f90 +53 -0
- PyFishPack/src/general_linear_systems_solver_3d.f90 +296 -0
- PyFishPack/src/iterative_solvers.f90 +969 -0
- PyFishPack/src/main.f90 +10 -0
- PyFishPack/src/pyfishpack_module.c +1302 -0
- PyFishPack/src/real_block_tridiagonal_linear_systems_solver.f90 +319 -0
- PyFishPack/src/sepeli.f90 +1454 -0
- PyFishPack/src/sepx4.f90 +1338 -0
- PyFishPack/src/staggered_axisymmetric_spherical_solver.f90 +908 -0
- PyFishPack/src/staggered_cartesian_solver.f90 +553 -0
- PyFishPack/src/staggered_cylindrical_solver.f90 +630 -0
- PyFishPack/src/staggered_helmholtz_solvers.f90 +172 -0
- PyFishPack/src/staggered_polar_solver.f90 +651 -0
- PyFishPack/src/staggered_real_linear_systems_solver.f90 +258 -0
- PyFishPack/src/staggered_spherical_solver.f90 +758 -0
- PyFishPack/src/three_dimensional_solvers.f90 +602 -0
- PyFishPack/src/type_CenteredCyclicReductionUtility.f90 +1714 -0
- PyFishPack/src/type_CyclicReductionUtility.f90 +472 -0
- PyFishPack/src/type_FishpackWorkspace.f90 +290 -0
- PyFishPack/src/type_GeneralizedCyclicReductionUtility.f90 +1980 -0
- PyFishPack/src/type_PeriodicFastFourierTransform.f90 +3789 -0
- PyFishPack/src/type_SepAux.f90 +586 -0
- PyFishPack/src/type_StaggeredCyclicReductionUtility.f90 +893 -0
- pyfishpack-0.1.0.dist-info/DELVEWHEEL +2 -0
- pyfishpack-0.1.0.dist-info/METADATA +81 -0
- pyfishpack-0.1.0.dist-info/RECORD +81 -0
- pyfishpack-0.1.0.dist-info/WHEEL +5 -0
- pyfishpack-0.1.0.dist-info/licenses/LICENSE +21 -0
- pyfishpack-0.1.0.dist-info/top_level.txt +1 -0
- pyfishpack.libs/libgcc_s_seh-1-25d59ccffa1a9009644065b069829e07.dll +0 -0
- pyfishpack.libs/libgfortran-5-08f2195cfa0d823e13371c5c3186a82a.dll +0 -0
- pyfishpack.libs/libquadmath-0-c5abb9113f1ee64b87a889958e4b7418.dll +0 -0
- pyfishpack.libs/libwinpthread-1-83908d14abfafb8b3bfa38cf51ecee56.dll +0 -0
|
@@ -0,0 +1,893 @@
|
|
|
1
|
+
!
|
|
2
|
+
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
3
|
+
! * *
|
|
4
|
+
! * copyright (c) 2005 by UCAR *
|
|
5
|
+
! * *
|
|
6
|
+
! * University Corporation for Atmospheric Research *
|
|
7
|
+
! * *
|
|
8
|
+
! * all rights reserved *
|
|
9
|
+
! * *
|
|
10
|
+
! * Fishpack *
|
|
11
|
+
! * *
|
|
12
|
+
! * A Package of Fortran *
|
|
13
|
+
! * *
|
|
14
|
+
! * Subroutines and Example Programs *
|
|
15
|
+
! * *
|
|
16
|
+
! * for Modeling Geophysical Processes *
|
|
17
|
+
! * *
|
|
18
|
+
! * by *
|
|
19
|
+
! * *
|
|
20
|
+
! * John Adams, Paul Swarztrauber and Roland Sweet *
|
|
21
|
+
! * *
|
|
22
|
+
! * of *
|
|
23
|
+
! * *
|
|
24
|
+
! * the National Center for Atmospheric Research *
|
|
25
|
+
! * *
|
|
26
|
+
! * Boulder, Colorado (80307) U.S.A. *
|
|
27
|
+
! * *
|
|
28
|
+
! * which is sponsored by *
|
|
29
|
+
! * *
|
|
30
|
+
! * the National Science Foundation *
|
|
31
|
+
! * *
|
|
32
|
+
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
33
|
+
!
|
|
34
|
+
module type_StaggeredCyclicReductionUtility
|
|
35
|
+
|
|
36
|
+
use fishpack_precision, only: &
|
|
37
|
+
wp, & ! Working precision
|
|
38
|
+
ip ! Integer precision
|
|
39
|
+
|
|
40
|
+
use type_FishpackWorkspace, only: &
|
|
41
|
+
FishpackWorkspace
|
|
42
|
+
|
|
43
|
+
use type_CyclicReductionUtility, only: &
|
|
44
|
+
CyclicReductionUtility
|
|
45
|
+
|
|
46
|
+
! Explicit typing only
|
|
47
|
+
implicit none
|
|
48
|
+
|
|
49
|
+
! Everything is private unless stated otherwise
|
|
50
|
+
private
|
|
51
|
+
public :: CyclicReductionUtility
|
|
52
|
+
|
|
53
|
+
! Parameters confined to the module
|
|
54
|
+
real(wp), parameter :: ZERO = 0.0_wp
|
|
55
|
+
real(wp), parameter :: HALF = 0.5_wp
|
|
56
|
+
real(wp), parameter :: ONE = 1.0_wp
|
|
57
|
+
real(wp), parameter :: TWO = 2.0_wp
|
|
58
|
+
integer(ip), parameter :: SIZE_OF_WORKSPACE_INDICES = 11
|
|
59
|
+
|
|
60
|
+
type, public, extends(CyclicReductionUtility) :: StaggeredCyclicReductionUtility
|
|
61
|
+
contains
|
|
62
|
+
! Public type-bound procedures
|
|
63
|
+
procedure, public :: poistg_lower_routine
|
|
64
|
+
! Private type-bound procedures
|
|
65
|
+
procedure, private :: poistg_solve_poisson_on_staggered_grid
|
|
66
|
+
end type
|
|
67
|
+
|
|
68
|
+
contains
|
|
69
|
+
|
|
70
|
+
subroutine poistg_lower_routine(self, nperod, n, mperod, m, a, b, c, idimy, y, ierror, w)
|
|
71
|
+
|
|
72
|
+
! Local variables
|
|
73
|
+
class(StaggeredCyclicReductionUtility), intent(inout) :: self
|
|
74
|
+
integer(ip), intent(in) :: nperod
|
|
75
|
+
integer(ip), intent(in) :: n
|
|
76
|
+
integer(ip), intent(in) :: mperod
|
|
77
|
+
integer(ip), intent(in) :: m
|
|
78
|
+
integer(ip), intent(in) :: idimy
|
|
79
|
+
integer(ip), intent(out) :: ierror
|
|
80
|
+
real(wp), intent(in) :: a(m)
|
|
81
|
+
real(wp), intent(in) :: b(m)
|
|
82
|
+
real(wp), intent(in) :: c(m)
|
|
83
|
+
real(wp), intent(inout) :: y(idimy,n)
|
|
84
|
+
real(wp), intent(inout) :: w(:)
|
|
85
|
+
|
|
86
|
+
! Local variables
|
|
87
|
+
integer(ip) :: workspace_indices(SIZE_OF_WORKSPACE_INDICES)
|
|
88
|
+
integer(ip) :: i, k, j, np, mp
|
|
89
|
+
integer(ip) :: nby2, mskip, ipstor, irev, mh, mhm1, m_odd
|
|
90
|
+
real(wp) :: temp
|
|
91
|
+
|
|
92
|
+
! Check validity of calling arguments
|
|
93
|
+
call poistg_check_input_arguments(nperod, n, mperod, m, idimy, ierror, a, b, c)
|
|
94
|
+
|
|
95
|
+
! Check error flag
|
|
96
|
+
if (ierror /= 0) return
|
|
97
|
+
|
|
98
|
+
! Compute workspace indices
|
|
99
|
+
workspace_indices = poistg_get_workspace_indices(n,m)
|
|
100
|
+
|
|
101
|
+
associate( &
|
|
102
|
+
iwba => workspace_indices(1), &
|
|
103
|
+
iwbb => workspace_indices(2), &
|
|
104
|
+
iwbc => workspace_indices(3), &
|
|
105
|
+
iwb2 => workspace_indices(4), &
|
|
106
|
+
iwb3 => workspace_indices(5), &
|
|
107
|
+
iww1 => workspace_indices(6), &
|
|
108
|
+
iww2 => workspace_indices(7), &
|
|
109
|
+
iww3 => workspace_indices(8), &
|
|
110
|
+
iwd => workspace_indices(9), &
|
|
111
|
+
iwtcos => workspace_indices(10), &
|
|
112
|
+
iwp => workspace_indices(11) &
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
do i = 1, m
|
|
116
|
+
k = iwba + i - 1
|
|
117
|
+
w(k) = -a(i)
|
|
118
|
+
k = iwbc + i - 1
|
|
119
|
+
w(k) = -c(i)
|
|
120
|
+
k = iwbb + i - 1
|
|
121
|
+
w(k) = TWO - b(i)
|
|
122
|
+
y(i, :n) = -y(i, :n)
|
|
123
|
+
end do
|
|
124
|
+
|
|
125
|
+
np = nperod
|
|
126
|
+
mp = mperod + 1
|
|
127
|
+
|
|
128
|
+
if (mp == 1) then
|
|
129
|
+
mh = (m + 1)/2
|
|
130
|
+
mhm1 = mh - 1
|
|
131
|
+
|
|
132
|
+
if (mh*2 == m) then
|
|
133
|
+
m_odd = 2
|
|
134
|
+
else
|
|
135
|
+
m_odd = 1
|
|
136
|
+
end if
|
|
137
|
+
|
|
138
|
+
do j = 1, n
|
|
139
|
+
do i = 1, mhm1
|
|
140
|
+
w(i) = y(mh-i, j) - y(i+mh, j)
|
|
141
|
+
w(i+mh) = y(mh-i, j) + y(i+mh, j)
|
|
142
|
+
end do
|
|
143
|
+
w(mh) = TWO * y(mh, j)
|
|
144
|
+
select case (m_odd)
|
|
145
|
+
case (1)
|
|
146
|
+
y(:m, j) = w(:m)
|
|
147
|
+
case (2)
|
|
148
|
+
w(m) = TWO * y(m, j)
|
|
149
|
+
y(:m, j) = w(:m)
|
|
150
|
+
end select
|
|
151
|
+
end do
|
|
152
|
+
|
|
153
|
+
k = iwbc + mhm1 - 1
|
|
154
|
+
i = iwba + mhm1
|
|
155
|
+
w(k) = ZERO
|
|
156
|
+
w(i) = ZERO
|
|
157
|
+
w(k+1) = TWO * w(k+1)
|
|
158
|
+
|
|
159
|
+
select case (m_odd)
|
|
160
|
+
case (2)
|
|
161
|
+
w(iwbb-1) = w(k+1)
|
|
162
|
+
case default
|
|
163
|
+
k = iwbb + mhm1 - 1
|
|
164
|
+
w(k) = w(k) - w(i-1)
|
|
165
|
+
w(iwbc-1) = w(iwbc-1) + w(iwbb-1)
|
|
166
|
+
end select
|
|
167
|
+
end if
|
|
168
|
+
|
|
169
|
+
loop_107: do
|
|
170
|
+
loop_108: do
|
|
171
|
+
if (nperod /= 4) then
|
|
172
|
+
|
|
173
|
+
call self%poistg_solve_poisson_on_staggered_grid(np, n, m, w(iwba:), w(iwbb:), w(iwbc:), idimy, y, &
|
|
174
|
+
w, w(iwb2:), w(iwb3:), w(iww1:), w(iww2:), w(iww3:), &
|
|
175
|
+
w(iwd:), w(iwtcos:), w(iwp:))
|
|
176
|
+
|
|
177
|
+
ipstor = int(w(iww1), kind=ip)
|
|
178
|
+
irev = 2
|
|
179
|
+
select case (mp)
|
|
180
|
+
case (1)
|
|
181
|
+
exit loop_107
|
|
182
|
+
case (2)
|
|
183
|
+
w(1) = real(ipstor + iwp - 1, kind=wp)
|
|
184
|
+
return
|
|
185
|
+
end select
|
|
186
|
+
cycle loop_107
|
|
187
|
+
end if
|
|
188
|
+
|
|
189
|
+
irev = 1
|
|
190
|
+
nby2 = n/2
|
|
191
|
+
np = 2
|
|
192
|
+
|
|
193
|
+
do j = 1, nby2
|
|
194
|
+
mskip = n + 1 - j
|
|
195
|
+
do i = 1, m
|
|
196
|
+
temp = y(i, j)
|
|
197
|
+
y(i, j) = y(i, mskip)
|
|
198
|
+
y(i, mskip) = temp
|
|
199
|
+
end do
|
|
200
|
+
end do
|
|
201
|
+
|
|
202
|
+
select case (irev)
|
|
203
|
+
case (1)
|
|
204
|
+
cycle loop_108
|
|
205
|
+
case (2)
|
|
206
|
+
select case (mp)
|
|
207
|
+
case (1)
|
|
208
|
+
exit loop_107
|
|
209
|
+
case (2)
|
|
210
|
+
w(1) = real(ipstor + iwp - 1, kind=wp)
|
|
211
|
+
return
|
|
212
|
+
end select
|
|
213
|
+
cycle loop_107
|
|
214
|
+
end select
|
|
215
|
+
|
|
216
|
+
exit loop_108
|
|
217
|
+
end do loop_108
|
|
218
|
+
exit loop_107
|
|
219
|
+
end do loop_107
|
|
220
|
+
|
|
221
|
+
do j = 1, n
|
|
222
|
+
w(mh-1:mh-mhm1:(-1)) = HALF * (y(mh+1:mhm1+mh, j)+y(:mhm1, j))
|
|
223
|
+
w(mh+1:mhm1+mh) = HALF * (y(mh+1:mhm1+mh, j)-y(:mhm1, j))
|
|
224
|
+
w(mh) = HALF * y(mh, j)
|
|
225
|
+
select case (m_odd)
|
|
226
|
+
case (1)
|
|
227
|
+
y(:m, j) = w(:m)
|
|
228
|
+
case (2)
|
|
229
|
+
w(m) = HALF * y(m, j)
|
|
230
|
+
y(:m, j) = w(:m)
|
|
231
|
+
end select
|
|
232
|
+
end do
|
|
233
|
+
|
|
234
|
+
w(1) = real(ipstor + iwp - 1, kind=wp)
|
|
235
|
+
|
|
236
|
+
end associate
|
|
237
|
+
|
|
238
|
+
end subroutine poistg_lower_routine
|
|
239
|
+
|
|
240
|
+
pure subroutine poistg_check_input_arguments(nperod, n, mperod, m, idimy, ierror, a, b, c)
|
|
241
|
+
|
|
242
|
+
! Dummy arguments
|
|
243
|
+
integer(ip), intent(in) :: nperod
|
|
244
|
+
integer(ip), intent(in) :: n
|
|
245
|
+
integer(ip), intent(in) :: mperod
|
|
246
|
+
integer(ip), intent(in) :: m
|
|
247
|
+
integer(ip), intent(in) :: idimy
|
|
248
|
+
integer(ip), intent(out) :: ierror
|
|
249
|
+
real(wp), intent(in) :: a(m)
|
|
250
|
+
real(wp), intent(in) :: b(m)
|
|
251
|
+
real(wp), intent(in) :: c(m)
|
|
252
|
+
|
|
253
|
+
if (3 > m) then
|
|
254
|
+
ierror = 1
|
|
255
|
+
else if (3 > n) then
|
|
256
|
+
ierror = 2
|
|
257
|
+
else if (idimy < m) then
|
|
258
|
+
ierror = 3
|
|
259
|
+
else if (nperod < 1 .or. nperod > 4) then
|
|
260
|
+
ierror = 4
|
|
261
|
+
else if (mperod < 0 .or. mperod > 1) then
|
|
262
|
+
ierror = 5
|
|
263
|
+
else if (mperod /= 1) then
|
|
264
|
+
if (any(a /= c(1)) .or. any(c /= c(1)) .or. any(b /= b(1))) then
|
|
265
|
+
ierror = 6
|
|
266
|
+
end if
|
|
267
|
+
else if (a(1) /= ZERO .or. c(m) /= ZERO) then
|
|
268
|
+
ierror = 7
|
|
269
|
+
else
|
|
270
|
+
ierror = 0
|
|
271
|
+
end if
|
|
272
|
+
|
|
273
|
+
end subroutine poistg_check_input_arguments
|
|
274
|
+
|
|
275
|
+
function poistg_get_workspace_indices(n, m) &
|
|
276
|
+
result (return_value)
|
|
277
|
+
|
|
278
|
+
! Dummy arguments
|
|
279
|
+
integer(ip), intent(in) :: n
|
|
280
|
+
integer(ip), intent(in) :: m
|
|
281
|
+
integer(ip) :: return_value(SIZE_OF_WORKSPACE_INDICES)
|
|
282
|
+
|
|
283
|
+
integer(ip) :: j !! Counter
|
|
284
|
+
|
|
285
|
+
associate( i => return_value)
|
|
286
|
+
i(1) = m + 1
|
|
287
|
+
do j = 2, SIZE_OF_WORKSPACE_INDICES - 1
|
|
288
|
+
i(j) = i(j-1) + m
|
|
289
|
+
end do
|
|
290
|
+
i(SIZE_OF_WORKSPACE_INDICES) = i(SIZE_OF_WORKSPACE_INDICES - 1) + 4 * n
|
|
291
|
+
end associate
|
|
292
|
+
|
|
293
|
+
end function poistg_get_workspace_indices
|
|
294
|
+
|
|
295
|
+
subroutine poistg_solve_poisson_on_staggered_grid(self, &
|
|
296
|
+
nperod, n, m, a, bb, c, idimq, q, b, b2, b3, w, w2, w3, d, tcos, p)
|
|
297
|
+
|
|
298
|
+
! Dummy arguments
|
|
299
|
+
class(StaggeredCyclicReductionUtility), intent(inout) :: self
|
|
300
|
+
integer(ip), intent(in) :: nperod
|
|
301
|
+
integer(ip), intent(in) :: n
|
|
302
|
+
integer(ip), intent(in) :: m
|
|
303
|
+
integer(ip), intent(in) :: idimq
|
|
304
|
+
real(wp), intent(in) :: a(m)
|
|
305
|
+
real(wp), intent(in) :: bb(m)
|
|
306
|
+
real(wp), intent(in) :: c(m)
|
|
307
|
+
real(wp), intent(inout) :: q(idimq, n)
|
|
308
|
+
real(wp), intent(inout) :: b(m)
|
|
309
|
+
real(wp), intent(inout) :: b2(m)
|
|
310
|
+
real(wp), intent(inout) :: b3(m)
|
|
311
|
+
real(wp), intent(inout) :: w(m)
|
|
312
|
+
real(wp), intent(inout) :: w2(m)
|
|
313
|
+
real(wp), intent(inout) :: w3(m)
|
|
314
|
+
real(wp), intent(inout) :: d(m)
|
|
315
|
+
real(wp), intent(inout) :: tcos(m)
|
|
316
|
+
real(wp), intent(inout) :: p(4*n)
|
|
317
|
+
|
|
318
|
+
! Local variables
|
|
319
|
+
integer(ip) :: k(4)
|
|
320
|
+
integer(ip) :: np, mr, ipp, ipstor, i2r, jr, nr, nlast
|
|
321
|
+
integer(ip) :: kr, lr, nrod, jstart, jstop, i2rby2
|
|
322
|
+
integer(ip) :: j, ijump, jp1, jp2, jp3
|
|
323
|
+
integer(ip) :: jm1, jm2, jm3, i, nrodpr, ii, nlastp, jstep
|
|
324
|
+
real(wp) :: fnum, fnum2, fi, t
|
|
325
|
+
|
|
326
|
+
associate( &
|
|
327
|
+
k1 => k(1), &
|
|
328
|
+
k2 => k(2), &
|
|
329
|
+
k3 => k(3), &
|
|
330
|
+
k4 => k(4) &
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
np = nperod
|
|
334
|
+
fnum = HALF * real(np/3, kind=wp)
|
|
335
|
+
fnum2 = HALF * real(np/2, kind=wp)
|
|
336
|
+
mr = m
|
|
337
|
+
ipp = -mr
|
|
338
|
+
ipstor = 0
|
|
339
|
+
i2r = 1
|
|
340
|
+
jr = 2
|
|
341
|
+
nr = n
|
|
342
|
+
nlast = n
|
|
343
|
+
kr = 1
|
|
344
|
+
lr = 0
|
|
345
|
+
|
|
346
|
+
if (nr > 3) then
|
|
347
|
+
|
|
348
|
+
loop_101: do
|
|
349
|
+
|
|
350
|
+
jr = 2*i2r
|
|
351
|
+
|
|
352
|
+
if ((nr/2)*2 == nr) then
|
|
353
|
+
nrod = 0
|
|
354
|
+
else
|
|
355
|
+
nrod = 1
|
|
356
|
+
end if
|
|
357
|
+
|
|
358
|
+
jstart = 1
|
|
359
|
+
jstop = nlast - jr
|
|
360
|
+
|
|
361
|
+
if (nrod == 0) jstop = jstop - i2r
|
|
362
|
+
|
|
363
|
+
i2rby2 = i2r/2
|
|
364
|
+
|
|
365
|
+
if (jstop < jstart) then
|
|
366
|
+
j = jr
|
|
367
|
+
else
|
|
368
|
+
ijump = 1
|
|
369
|
+
do j = jstart, jstop, jr
|
|
370
|
+
jp1 = j + i2rby2
|
|
371
|
+
jp2 = j + i2r
|
|
372
|
+
jp3 = jp2 + i2rby2
|
|
373
|
+
jm1 = j - i2rby2
|
|
374
|
+
jm2 = j - i2r
|
|
375
|
+
jm3 = jm2 - i2rby2
|
|
376
|
+
|
|
377
|
+
if (j == 1) then
|
|
378
|
+
call self%generate_cosines(i2r, 1, fnum, HALF, tcos)
|
|
379
|
+
select case (i2r)
|
|
380
|
+
case (1)
|
|
381
|
+
b(:mr) = q(:mr, 1)
|
|
382
|
+
q(:mr, 1) = q(:mr, 2)
|
|
383
|
+
case default
|
|
384
|
+
b(:mr) = q(:mr, 1) + HALF * (q(:mr, jp2)-q(:mr, jp1)-q(:mr, &
|
|
385
|
+
jp3))
|
|
386
|
+
q(:mr, 1) = q(:mr, jp2) + q(:mr, 1) - q(:mr, jp1)
|
|
387
|
+
end select
|
|
388
|
+
else
|
|
389
|
+
if (ijump == 1) then
|
|
390
|
+
ijump = 2
|
|
391
|
+
call self%generate_cosines(i2r, 1, HALF, ZERO, tcos)
|
|
392
|
+
end if
|
|
393
|
+
|
|
394
|
+
select case (i2r)
|
|
395
|
+
case (1)
|
|
396
|
+
b(:mr) = TWO*q(:mr, j)
|
|
397
|
+
q(:mr, j) = q(:mr, jm2) + q(:mr, jp2)
|
|
398
|
+
case default
|
|
399
|
+
do i = 1, mr
|
|
400
|
+
fi = q(i, j)
|
|
401
|
+
q(i, j)=q(i, j)-q(i, jm1)-q(i, jp1)+q(i, jm2)+q(i, jp2)
|
|
402
|
+
b(i) = fi + q(i, j) - q(i, jm3) - q(i, jp3)
|
|
403
|
+
end do
|
|
404
|
+
end select
|
|
405
|
+
end if
|
|
406
|
+
|
|
407
|
+
call self%solve_tridiag(i2r, 0, mr, a, bb, c, b, tcos, d, w)
|
|
408
|
+
|
|
409
|
+
q(:mr, j) = q(:mr, j) + b(:mr)
|
|
410
|
+
!
|
|
411
|
+
! End of reduction for regular unknowns.
|
|
412
|
+
!
|
|
413
|
+
end do
|
|
414
|
+
!
|
|
415
|
+
! Begin special reduction for last unknown.
|
|
416
|
+
!
|
|
417
|
+
j = jstop + jr
|
|
418
|
+
end if
|
|
419
|
+
|
|
420
|
+
nlast = j
|
|
421
|
+
jm1 = j - i2rby2
|
|
422
|
+
jm2 = j - i2r
|
|
423
|
+
jm3 = jm2 - i2rby2
|
|
424
|
+
|
|
425
|
+
if (nrod /= 0) then
|
|
426
|
+
!
|
|
427
|
+
! Odd number of unknowns
|
|
428
|
+
!
|
|
429
|
+
select case (i2r)
|
|
430
|
+
case (1)
|
|
431
|
+
b(:mr) = q(:mr, j)
|
|
432
|
+
q(:mr, j) = q(:mr, jm2)
|
|
433
|
+
case default
|
|
434
|
+
b(:mr)=q(:mr, j)+HALF * (q(:mr, jm2)-q(:mr, jm1)-q(:mr, jm3))
|
|
435
|
+
|
|
436
|
+
select case (nrodpr)
|
|
437
|
+
case (0)
|
|
438
|
+
q(:mr, j) = q(:mr, jm2) + p(ipp+1:mr+ipp)
|
|
439
|
+
ipp = ipp - mr
|
|
440
|
+
case default
|
|
441
|
+
q(:mr, j) = q(:mr, j) - q(:mr, jm1) + q(:mr, jm2)
|
|
442
|
+
end select
|
|
443
|
+
|
|
444
|
+
if (lr /= 0) call self%generate_cosines(lr, 1, fnum2, HALF, tcos(kr+1:))
|
|
445
|
+
|
|
446
|
+
end select
|
|
447
|
+
|
|
448
|
+
call self%generate_cosines(kr, 1, fnum2, HALF, tcos)
|
|
449
|
+
call self%solve_tridiag(kr, lr, mr, a, bb, c, b, tcos, d, w)
|
|
450
|
+
|
|
451
|
+
q(:mr, j) = q(:mr, j) + b(:mr)
|
|
452
|
+
kr = kr + i2r
|
|
453
|
+
else
|
|
454
|
+
jp1 = j + i2rby2
|
|
455
|
+
jp2 = j + i2r
|
|
456
|
+
|
|
457
|
+
select case (i2r)
|
|
458
|
+
case (1)
|
|
459
|
+
b(:mr) = q(:mr, j)
|
|
460
|
+
tcos(1) = ZERO
|
|
461
|
+
|
|
462
|
+
call self%solve_tridiag(1, 0, mr, a, bb, c, b, tcos, d, w)
|
|
463
|
+
|
|
464
|
+
ipp = 0
|
|
465
|
+
ipstor = mr
|
|
466
|
+
p(:mr) = b(:mr)
|
|
467
|
+
b(:mr) = b(:mr) + q(:mr, n)
|
|
468
|
+
tcos(1) = -ONE + TWO*real(np/2, kind=wp)
|
|
469
|
+
tcos(2) = ZERO
|
|
470
|
+
|
|
471
|
+
call self%solve_tridiag(1, 1, mr, a, bb, c, b, tcos, d, w)
|
|
472
|
+
|
|
473
|
+
q(:mr, j) = q(:mr, jm2) + p(:mr) + b(:mr)
|
|
474
|
+
|
|
475
|
+
case default
|
|
476
|
+
|
|
477
|
+
b(:mr) = q(:mr, j) + HALF * (q(:mr, jm2)-q(:mr, jm1)-q(:mr, jm3))
|
|
478
|
+
|
|
479
|
+
select case (nrodpr)
|
|
480
|
+
case (0)
|
|
481
|
+
b(:mr) = b(:mr) + p(ipp+1:mr+ipp)
|
|
482
|
+
case default
|
|
483
|
+
b(:mr) = b(:mr) + q(:mr, jp2) - q(:mr, jp1)
|
|
484
|
+
end select
|
|
485
|
+
|
|
486
|
+
call self%generate_cosines(i2r, 1, HALF, ZERO, tcos)
|
|
487
|
+
call self%solve_tridiag(i2r, 0, mr, a, bb, c, b, tcos, d, w)
|
|
488
|
+
|
|
489
|
+
ipp = ipp + mr
|
|
490
|
+
ipstor = max(ipstor, ipp + mr)
|
|
491
|
+
p(ipp+1:mr+ipp) = b(:mr) + HALF * (q(:mr, j)-q(:mr, jm1)-q(:mr, jp1))
|
|
492
|
+
b(:mr) = p(ipp+1:mr+ipp) + q(:mr, jp2)
|
|
493
|
+
|
|
494
|
+
if (lr /= 0) then
|
|
495
|
+
call self%generate_cosines(lr, 1, fnum2, HALF, tcos(i2r+1:))
|
|
496
|
+
call self%merge_cosines(tcos, 0, i2r, i2r, lr, kr)
|
|
497
|
+
else
|
|
498
|
+
do i = 1, i2r
|
|
499
|
+
ii = kr + i
|
|
500
|
+
tcos(ii) = tcos(i)
|
|
501
|
+
end do
|
|
502
|
+
end if
|
|
503
|
+
|
|
504
|
+
call self%generate_cosines(kr, 1, fnum2, HALF, tcos)
|
|
505
|
+
call self%solve_tridiag(kr, kr, mr, a, bb, c, b, tcos, d, w)
|
|
506
|
+
|
|
507
|
+
q(:mr, j) = q(:mr, jm2) + p(ipp+1:mr+ipp) + b(:mr)
|
|
508
|
+
|
|
509
|
+
end select
|
|
510
|
+
lr = kr
|
|
511
|
+
kr = kr + jr
|
|
512
|
+
end if
|
|
513
|
+
|
|
514
|
+
nr = (nlast - 1)/jr + 1
|
|
515
|
+
|
|
516
|
+
if (nr <= 3) exit loop_101
|
|
517
|
+
|
|
518
|
+
i2r = jr
|
|
519
|
+
nrodpr = nrod
|
|
520
|
+
|
|
521
|
+
end do loop_101
|
|
522
|
+
end if
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
j = 1 + jr
|
|
526
|
+
jm1 = j - i2r
|
|
527
|
+
jp1 = j + i2r
|
|
528
|
+
jm2 = nlast - i2r
|
|
529
|
+
|
|
530
|
+
block_construct: block
|
|
531
|
+
if_nr: if (nr /= 2) then
|
|
532
|
+
if_lr: if (lr == 0) then
|
|
533
|
+
if_n: if (n == 3) then
|
|
534
|
+
!
|
|
535
|
+
! case n = 3.
|
|
536
|
+
!
|
|
537
|
+
select case (np)
|
|
538
|
+
case (1,3)
|
|
539
|
+
b(:mr) = q(:mr, 2)
|
|
540
|
+
b2(:mr) = q(:mr, 1) + q(:mr, 3)
|
|
541
|
+
b3(:mr) = ZERO
|
|
542
|
+
|
|
543
|
+
select case (np)
|
|
544
|
+
case (1:2)
|
|
545
|
+
tcos(1) = -TWO
|
|
546
|
+
tcos(2) = ONE
|
|
547
|
+
tcos(3) = -ONE
|
|
548
|
+
k1 = 2
|
|
549
|
+
case default
|
|
550
|
+
tcos(1) = -ONE
|
|
551
|
+
tcos(2) = ONE
|
|
552
|
+
k1 = 1
|
|
553
|
+
end select
|
|
554
|
+
|
|
555
|
+
k2 = 1
|
|
556
|
+
k3 = 0
|
|
557
|
+
k4 = 0
|
|
558
|
+
case (2)
|
|
559
|
+
b(:mr) = q(:mr, 2)
|
|
560
|
+
b2(:mr) = q(:mr, 3)
|
|
561
|
+
b3(:mr) = q(:mr, 1)
|
|
562
|
+
|
|
563
|
+
call self%generate_cosines(3, 1, HALF, ZERO, tcos)
|
|
564
|
+
|
|
565
|
+
tcos(4) = -ONE
|
|
566
|
+
tcos(5) = ONE
|
|
567
|
+
tcos(6) = -ONE
|
|
568
|
+
tcos(7) = ONE
|
|
569
|
+
|
|
570
|
+
k1 = 3
|
|
571
|
+
k2 = 2
|
|
572
|
+
k3 = 1
|
|
573
|
+
k4 = 1
|
|
574
|
+
end select
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
call self%solve_tridiag3(mr, a, bb, c, k, b, b2, b3, tcos, d, w, w2, w3)
|
|
578
|
+
|
|
579
|
+
b(:mr) = b(:mr) + b2(:mr) + b3(:mr)
|
|
580
|
+
|
|
581
|
+
if (np == 3) then
|
|
582
|
+
tcos(1) = TWO
|
|
583
|
+
call self%solve_tridiag(1, 0, mr, a, bb, c, b, tcos, d, w)
|
|
584
|
+
end if
|
|
585
|
+
|
|
586
|
+
q(:mr, 2) = b(:mr)
|
|
587
|
+
b(:mr) = q(:mr, 1) + b(:mr)
|
|
588
|
+
tcos(1) = -ONE + 4.0_wp*fnum
|
|
589
|
+
|
|
590
|
+
call self%solve_tridiag(1, 0, mr, a, bb, c, b, tcos, d, w)
|
|
591
|
+
|
|
592
|
+
q(:mr, 1) = b(:mr)
|
|
593
|
+
jr = 1
|
|
594
|
+
i2r = 0
|
|
595
|
+
exit block_construct
|
|
596
|
+
end if if_n
|
|
597
|
+
!
|
|
598
|
+
! case n = 2**p+1
|
|
599
|
+
!
|
|
600
|
+
b(:mr)=q(:mr, j)+q(:mr, 1)-q(:mr, jm1)+q(:mr, nlast)-q(:mr, jm2)
|
|
601
|
+
|
|
602
|
+
select case (np)
|
|
603
|
+
case (1, 3)
|
|
604
|
+
b2(:mr) = q(:mr, 1) + q(:mr, nlast) &
|
|
605
|
+
+ q(:mr, j) - q(:mr, jm1) - q(:mr, jp1)
|
|
606
|
+
b3(:mr) = ZERO
|
|
607
|
+
k1 = nlast - 1
|
|
608
|
+
k2 = nlast + jr - 1
|
|
609
|
+
|
|
610
|
+
call self%generate_cosines(jr - 1, 1, ZERO, ONE, tcos(nlast:))
|
|
611
|
+
|
|
612
|
+
tcos(k2) = TWO*real(np - 2, kind=wp)
|
|
613
|
+
|
|
614
|
+
call self%generate_cosines(jr, 1, HALF - fnum, HALF, tcos(k2+1:))
|
|
615
|
+
|
|
616
|
+
k3 = (3 - np)/2
|
|
617
|
+
|
|
618
|
+
call self%merge_cosines(tcos, k1, jr - k3, k2 - k3, jr + k3, 0)
|
|
619
|
+
|
|
620
|
+
k1 = k1 - 1 + k3
|
|
621
|
+
|
|
622
|
+
call self%generate_cosines(jr, 1, fnum, HALF, tcos(k1+1:))
|
|
623
|
+
|
|
624
|
+
k2 = jr
|
|
625
|
+
k3 = 0
|
|
626
|
+
k4 = 0
|
|
627
|
+
case (2)
|
|
628
|
+
do i = 1, mr
|
|
629
|
+
fi = (q(i, j)-q(i, jm1)-q(i, jp1))/2
|
|
630
|
+
b2(i) = q(i, 1) + fi
|
|
631
|
+
b3(i) = q(i, nlast) + fi
|
|
632
|
+
end do
|
|
633
|
+
|
|
634
|
+
k1 = nlast + jr - 1
|
|
635
|
+
k2 = k1 + jr - 1
|
|
636
|
+
|
|
637
|
+
call self%generate_cosines(jr - 1, 1, ZERO, ONE, tcos(k1+1:))
|
|
638
|
+
call self%generate_cosines(nlast, 1, HALF, ZERO, tcos(k2+1:))
|
|
639
|
+
call self%merge_cosines(tcos, k1, jr - 1, k2, nlast, 0)
|
|
640
|
+
|
|
641
|
+
k3 = k1 + nlast - 1
|
|
642
|
+
k4 = k3 + jr
|
|
643
|
+
|
|
644
|
+
call self%generate_cosines(jr, 1, HALF, HALF, tcos(k3+1:))
|
|
645
|
+
call self%generate_cosines(jr, 1, ZERO, HALF, tcos(k4+1:))
|
|
646
|
+
call self%merge_cosines(tcos, k3, jr, k4, jr, k1)
|
|
647
|
+
|
|
648
|
+
k2 = nlast - 1
|
|
649
|
+
k3 = jr
|
|
650
|
+
k4 = jr
|
|
651
|
+
end select
|
|
652
|
+
|
|
653
|
+
call self%solve_tridiag3(mr, a, bb, c, k, b, b2, b3, tcos, d, w, w2, w3)
|
|
654
|
+
b(:mr) = b(:mr) + b2(:mr) + b3(:mr)
|
|
655
|
+
|
|
656
|
+
if (np == 3) then
|
|
657
|
+
tcos(1) = TWO
|
|
658
|
+
call self%solve_tridiag(1, 0, mr, a, bb, c, b, tcos, d, w)
|
|
659
|
+
end if
|
|
660
|
+
|
|
661
|
+
q(:mr, j) = b(:mr) + HALF * (q(:mr, j)-q(:mr, jm1)-q(:mr, jp1))
|
|
662
|
+
b(:mr) = q(:mr, j) + q(:mr, 1)
|
|
663
|
+
|
|
664
|
+
call self%generate_cosines(jr, 1, fnum, HALF, tcos)
|
|
665
|
+
call self%solve_tridiag(jr, 0, mr, a, bb, c, b, tcos, d, w)
|
|
666
|
+
|
|
667
|
+
q(:mr, 1) = q(:mr, 1) - q(:mr, jm1) + b(:mr)
|
|
668
|
+
|
|
669
|
+
exit block_construct
|
|
670
|
+
end if if_lr
|
|
671
|
+
!
|
|
672
|
+
! case of general n with nr = 3 .
|
|
673
|
+
!
|
|
674
|
+
b(:mr) = q(:mr, 1) - q(:mr, jm1) + q(:mr, j)
|
|
675
|
+
|
|
676
|
+
if (nrod == 0) then
|
|
677
|
+
b(:mr) = b(:mr) + p(ipp+1:mr+ipp)
|
|
678
|
+
else
|
|
679
|
+
b(:mr) = b(:mr) + q(:mr, nlast) - q(:mr, jm2)
|
|
680
|
+
end if
|
|
681
|
+
|
|
682
|
+
do i = 1, mr
|
|
683
|
+
t = HALF * (q(i, j)-q(i, jm1)-q(i, jp1))
|
|
684
|
+
q(i, j) = t
|
|
685
|
+
b2(i) = q(i, nlast) + t
|
|
686
|
+
b3(i) = q(i, 1) + t
|
|
687
|
+
end do
|
|
688
|
+
|
|
689
|
+
k1 = kr + 2*jr
|
|
690
|
+
|
|
691
|
+
call self%generate_cosines(jr - 1, 1, ZERO, ONE, tcos(k1+1:))
|
|
692
|
+
|
|
693
|
+
k2 = k1 + jr
|
|
694
|
+
tcos(k2) = TWO*real(np - 2, kind=wp)
|
|
695
|
+
k4 = (np - 1)*(3 - np)
|
|
696
|
+
k3 = k2 + 1 - k4
|
|
697
|
+
|
|
698
|
+
!generate_cosines(n, ijump, fnum, fden, a)
|
|
699
|
+
associate( &
|
|
700
|
+
n_arg => kr+jr+k4, &
|
|
701
|
+
fnum_arg => real(k4, kind=wp)/2, &
|
|
702
|
+
fden_arg => ONE-real(k4, kind=wp) &
|
|
703
|
+
)
|
|
704
|
+
call self%generate_cosines(n_arg, 1, fnum_arg , fden_arg, tcos(k3:))
|
|
705
|
+
end associate
|
|
706
|
+
|
|
707
|
+
k4 = 1 - np/3
|
|
708
|
+
|
|
709
|
+
call self%merge_cosines(tcos, k1, jr - k4, k2 - k4, kr + jr + k4, 0)
|
|
710
|
+
|
|
711
|
+
if (np == 3) k1 = k1 - 1
|
|
712
|
+
|
|
713
|
+
k2 = kr + jr
|
|
714
|
+
k4 = k1 + k2
|
|
715
|
+
|
|
716
|
+
call self%generate_cosines(kr, 1, fnum2, HALF, tcos(k4+1:))
|
|
717
|
+
|
|
718
|
+
k3 = k4 + kr
|
|
719
|
+
|
|
720
|
+
call self%generate_cosines(jr, 1, fnum, HALF, tcos(k3+1:))
|
|
721
|
+
call self%merge_cosines(tcos, k4, kr, k3, jr, k1)
|
|
722
|
+
|
|
723
|
+
k4 = k3 + jr
|
|
724
|
+
|
|
725
|
+
call self%generate_cosines(lr, 1, fnum2, HALF, tcos(k4+1:))
|
|
726
|
+
call self%merge_cosines(tcos, k3, jr, k4, lr, k1 + k2)
|
|
727
|
+
call self%generate_cosines(kr, 1, fnum2, HALF, tcos(k3+1:))
|
|
728
|
+
|
|
729
|
+
k3 = kr
|
|
730
|
+
k4 = kr
|
|
731
|
+
|
|
732
|
+
call self%solve_tridiag3(mr, a, bb, c, k, b, b2, b3, tcos, d, w, w2, w3)
|
|
733
|
+
|
|
734
|
+
b(:mr) = b(:mr) + b2(:mr) + b3(:mr)
|
|
735
|
+
|
|
736
|
+
if (np == 3) then
|
|
737
|
+
tcos(1) = TWO
|
|
738
|
+
call self%solve_tridiag(1, 0, mr, a, bb, c, b, tcos, d, w)
|
|
739
|
+
end if
|
|
740
|
+
|
|
741
|
+
q(:mr, j) = q(:mr, j) + b(:mr)
|
|
742
|
+
b(:mr) = q(:mr, 1) + q(:mr, j)
|
|
743
|
+
|
|
744
|
+
call self%generate_cosines(jr, 1, fnum, HALF, tcos)
|
|
745
|
+
call self%solve_tridiag(jr, 0, mr, a, bb, c, b, tcos, d, w)
|
|
746
|
+
|
|
747
|
+
if (jr == 1) then
|
|
748
|
+
q(:mr, 1) = b(:mr)
|
|
749
|
+
exit block_construct
|
|
750
|
+
end if
|
|
751
|
+
|
|
752
|
+
q(:mr, 1) = q(:mr, 1) - q(:mr, jm1) + b(:mr)
|
|
753
|
+
|
|
754
|
+
exit block_construct
|
|
755
|
+
end if if_nr
|
|
756
|
+
|
|
757
|
+
b3(:mr) = ZERO
|
|
758
|
+
b(:mr) = q(:mr, 1) + p(ipp+1:mr+ipp)
|
|
759
|
+
q(:mr, 1) = q(:mr, 1) - q(:mr, jm1)
|
|
760
|
+
b2(:mr) = q(:mr, 1) + q(:mr, nlast)
|
|
761
|
+
k1 = kr + jr
|
|
762
|
+
k2 = k1 + jr
|
|
763
|
+
|
|
764
|
+
call self%generate_cosines(jr - 1, 1, ZERO, ONE, tcos(k1+1:))
|
|
765
|
+
|
|
766
|
+
select case (np)
|
|
767
|
+
case (1, 3)
|
|
768
|
+
tcos(k2) = TWO*real(np - 2, kind=wp)
|
|
769
|
+
call self%generate_cosines(kr, 1, ZERO, ONE, tcos(k2+1:))
|
|
770
|
+
case (2)
|
|
771
|
+
call self%generate_cosines(kr + 1, 1, HALF, ZERO, tcos(k2:))
|
|
772
|
+
end select
|
|
773
|
+
|
|
774
|
+
k4 = 1 - np/3
|
|
775
|
+
|
|
776
|
+
call self%merge_cosines(tcos, k1, jr - k4, k2 - k4, kr + k4, 0)
|
|
777
|
+
|
|
778
|
+
if (np == 3) k1 = k1 - 1
|
|
779
|
+
|
|
780
|
+
k2 = kr
|
|
781
|
+
|
|
782
|
+
call self%generate_cosines(kr, 1, fnum2, HALF, tcos(k1+1:))
|
|
783
|
+
|
|
784
|
+
k4 = k1 + kr
|
|
785
|
+
|
|
786
|
+
call self%generate_cosines(lr, 1, fnum2, HALF, tcos(k4+1:))
|
|
787
|
+
|
|
788
|
+
k3 = lr
|
|
789
|
+
k4 = 0
|
|
790
|
+
|
|
791
|
+
call self%solve_tridiag3(mr, a, bb, c, k, b, b2, b3, tcos, d, w, w2, w3)
|
|
792
|
+
|
|
793
|
+
b(:mr) = b(:mr) + b2(:mr)
|
|
794
|
+
|
|
795
|
+
if (np == 3) then
|
|
796
|
+
tcos(1) = TWO
|
|
797
|
+
call self%solve_tridiag(1, 0, mr, a, bb, c, b, tcos, d, w)
|
|
798
|
+
end if
|
|
799
|
+
|
|
800
|
+
q(:mr, 1) = q(:mr, 1) + b(:mr)
|
|
801
|
+
|
|
802
|
+
end block block_construct
|
|
803
|
+
|
|
804
|
+
loop_188: do
|
|
805
|
+
|
|
806
|
+
j = nlast - jr
|
|
807
|
+
b(:mr) = q(:mr, nlast) + q(:mr, j)
|
|
808
|
+
jm2 = nlast - i2r
|
|
809
|
+
|
|
810
|
+
if (jr == 1) then
|
|
811
|
+
q(:mr, nlast) = ZERO
|
|
812
|
+
else
|
|
813
|
+
select case (nrod)
|
|
814
|
+
case (0)
|
|
815
|
+
q(:mr, nlast) = p(ipp+1:mr+ipp)
|
|
816
|
+
ipp = ipp - mr
|
|
817
|
+
case default
|
|
818
|
+
q(:mr, nlast) = q(:mr, nlast) - q(:mr, jm2)
|
|
819
|
+
end select
|
|
820
|
+
end if
|
|
821
|
+
|
|
822
|
+
call self%generate_cosines(kr, 1, fnum2, HALF, tcos)
|
|
823
|
+
call self%generate_cosines(lr, 1, fnum2, HALF, tcos(kr+1:))
|
|
824
|
+
call self%solve_tridiag(kr, lr, mr, a, bb, c, b, tcos, d, w)
|
|
825
|
+
|
|
826
|
+
q(:mr, nlast) = q(:mr, nlast) + b(:mr)
|
|
827
|
+
nlastp = nlast
|
|
828
|
+
|
|
829
|
+
loop_197: do
|
|
830
|
+
|
|
831
|
+
jstep = jr
|
|
832
|
+
jr = i2r
|
|
833
|
+
i2r = i2r/2
|
|
834
|
+
|
|
835
|
+
if (jr == 0) then
|
|
836
|
+
w(1) = real(ipstor, kind=wp)
|
|
837
|
+
return
|
|
838
|
+
end if
|
|
839
|
+
|
|
840
|
+
jstart = 1 + jr
|
|
841
|
+
kr = kr - jr
|
|
842
|
+
|
|
843
|
+
if (nlast + jr <= n) then
|
|
844
|
+
kr = kr - jr
|
|
845
|
+
nlast = nlast + jr
|
|
846
|
+
jstop = nlast - jstep
|
|
847
|
+
else
|
|
848
|
+
jstop = nlast - jr
|
|
849
|
+
end if
|
|
850
|
+
|
|
851
|
+
lr = kr - jr
|
|
852
|
+
|
|
853
|
+
call self%generate_cosines(jr, 1, HALF, ZERO, tcos)
|
|
854
|
+
|
|
855
|
+
do j = jstart, jstop, jstep
|
|
856
|
+
jm2 = j - jr
|
|
857
|
+
jp2 = j + jr
|
|
858
|
+
|
|
859
|
+
if (j == jr) then
|
|
860
|
+
b(:mr) = q(:mr, j) + q(:mr, jp2)
|
|
861
|
+
else
|
|
862
|
+
b(:mr) = q(:mr, j) + q(:mr, jm2) + q(:mr, jp2)
|
|
863
|
+
end if
|
|
864
|
+
|
|
865
|
+
if (jr == 1) then
|
|
866
|
+
q(:mr, j) = ZERO
|
|
867
|
+
else
|
|
868
|
+
jm1 = j - i2r
|
|
869
|
+
jp1 = j + i2r
|
|
870
|
+
q(:mr, j) = HALF * (q(:mr, j)-q(:mr, jm1)-q(:mr, jp1))
|
|
871
|
+
end if
|
|
872
|
+
|
|
873
|
+
call self%solve_tridiag(jr, 0, mr, a, bb, c, b, tcos, d, w)
|
|
874
|
+
|
|
875
|
+
q(:mr, j) = q(:mr, j) + b(:mr)
|
|
876
|
+
end do
|
|
877
|
+
|
|
878
|
+
if (nlast + i2r <= n) then
|
|
879
|
+
nrod = 0
|
|
880
|
+
else
|
|
881
|
+
nrod = 1
|
|
882
|
+
end if
|
|
883
|
+
|
|
884
|
+
if (nlastp /= nlast) cycle loop_188
|
|
885
|
+
|
|
886
|
+
end do loop_197
|
|
887
|
+
end do loop_188
|
|
888
|
+
|
|
889
|
+
end associate
|
|
890
|
+
|
|
891
|
+
end subroutine poistg_solve_poisson_on_staggered_grid
|
|
892
|
+
|
|
893
|
+
end module type_StaggeredCyclicReductionUtility
|