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.
Files changed (81) hide show
  1. PyFishPack/__init__.py +86 -0
  2. PyFishPack/__pycache__/__init__.cpython-313.pyc +0 -0
  3. PyFishPack/__pycache__/apps.cpython-313.pyc +0 -0
  4. PyFishPack/_dummy.c +23 -0
  5. PyFishPack/_dummy.cp313-win_amd64.pyd +0 -0
  6. PyFishPack/apps.py +3640 -0
  7. PyFishPack/fishpack.cp313-win_amd64.dll.a +0 -0
  8. PyFishPack/fishpack.cp313-win_amd64.pyd +0 -0
  9. PyFishPack/meson.build +213 -0
  10. PyFishPack/src/archive/f77/Makefile +19 -0
  11. PyFishPack/src/archive/f77/blktri.f +1404 -0
  12. PyFishPack/src/archive/f77/cblktri.f +1414 -0
  13. PyFishPack/src/archive/f77/cmgnbn.f +1592 -0
  14. PyFishPack/src/archive/f77/comf.f +186 -0
  15. PyFishPack/src/archive/f77/fftpack.f +2968 -0
  16. PyFishPack/src/archive/f77/genbun.f +1335 -0
  17. PyFishPack/src/archive/f77/gnbnaux.f +314 -0
  18. PyFishPack/src/archive/f77/hstcrt.f +443 -0
  19. PyFishPack/src/archive/f77/hstcsp.f +683 -0
  20. PyFishPack/src/archive/f77/hstcyl.f +485 -0
  21. PyFishPack/src/archive/f77/hstplr.f +538 -0
  22. PyFishPack/src/archive/f77/hstssp.f +634 -0
  23. PyFishPack/src/archive/f77/hw3crt.f +687 -0
  24. PyFishPack/src/archive/f77/hwscrt.f +512 -0
  25. PyFishPack/src/archive/f77/hwscsp.f +728 -0
  26. PyFishPack/src/archive/f77/hwscyl.f +538 -0
  27. PyFishPack/src/archive/f77/hwsplr.f +602 -0
  28. PyFishPack/src/archive/f77/hwsssp.f +780 -0
  29. PyFishPack/src/archive/f77/pois3d.f +550 -0
  30. PyFishPack/src/archive/f77/poistg.f +875 -0
  31. PyFishPack/src/archive/f77/sepaux.f +361 -0
  32. PyFishPack/src/archive/f77/sepeli.f +1029 -0
  33. PyFishPack/src/archive/f77/sepx4.f +958 -0
  34. PyFishPack/src/centered_axisymmetric_spherical_solver.f90 +1002 -0
  35. PyFishPack/src/centered_cartesian_helmholtz_solver_3d.f90 +819 -0
  36. PyFishPack/src/centered_cartesian_solver.f90 +583 -0
  37. PyFishPack/src/centered_cylindrical_solver.f90 +634 -0
  38. PyFishPack/src/centered_helmholtz_solvers.f90 +156 -0
  39. PyFishPack/src/centered_polar_solver.f90 +746 -0
  40. PyFishPack/src/centered_real_linear_systems_solver.f90 +280 -0
  41. PyFishPack/src/centered_spherical_solver.f90 +928 -0
  42. PyFishPack/src/complex_block_tridiagonal_linear_systems_solver.f90 +1947 -0
  43. PyFishPack/src/complex_linear_systems_solver.f90 +1787 -0
  44. PyFishPack/src/fftpack_c_api.f90 +86 -0
  45. PyFishPack/src/fishpack.f90 +191 -0
  46. PyFishPack/src/fishpack.pyf +504 -0
  47. PyFishPack/src/fishpack_c_api.f90 +365 -0
  48. PyFishPack/src/fishpack_original.pyf +2119 -0
  49. PyFishPack/src/fishpack_precision.f90 +53 -0
  50. PyFishPack/src/general_linear_systems_solver_3d.f90 +296 -0
  51. PyFishPack/src/iterative_solvers.f90 +969 -0
  52. PyFishPack/src/main.f90 +10 -0
  53. PyFishPack/src/pyfishpack_module.c +1302 -0
  54. PyFishPack/src/real_block_tridiagonal_linear_systems_solver.f90 +319 -0
  55. PyFishPack/src/sepeli.f90 +1454 -0
  56. PyFishPack/src/sepx4.f90 +1338 -0
  57. PyFishPack/src/staggered_axisymmetric_spherical_solver.f90 +908 -0
  58. PyFishPack/src/staggered_cartesian_solver.f90 +553 -0
  59. PyFishPack/src/staggered_cylindrical_solver.f90 +630 -0
  60. PyFishPack/src/staggered_helmholtz_solvers.f90 +172 -0
  61. PyFishPack/src/staggered_polar_solver.f90 +651 -0
  62. PyFishPack/src/staggered_real_linear_systems_solver.f90 +258 -0
  63. PyFishPack/src/staggered_spherical_solver.f90 +758 -0
  64. PyFishPack/src/three_dimensional_solvers.f90 +602 -0
  65. PyFishPack/src/type_CenteredCyclicReductionUtility.f90 +1714 -0
  66. PyFishPack/src/type_CyclicReductionUtility.f90 +472 -0
  67. PyFishPack/src/type_FishpackWorkspace.f90 +290 -0
  68. PyFishPack/src/type_GeneralizedCyclicReductionUtility.f90 +1980 -0
  69. PyFishPack/src/type_PeriodicFastFourierTransform.f90 +3789 -0
  70. PyFishPack/src/type_SepAux.f90 +586 -0
  71. PyFishPack/src/type_StaggeredCyclicReductionUtility.f90 +893 -0
  72. pyfishpack-0.1.0.dist-info/DELVEWHEEL +2 -0
  73. pyfishpack-0.1.0.dist-info/METADATA +81 -0
  74. pyfishpack-0.1.0.dist-info/RECORD +81 -0
  75. pyfishpack-0.1.0.dist-info/WHEEL +5 -0
  76. pyfishpack-0.1.0.dist-info/licenses/LICENSE +21 -0
  77. pyfishpack-0.1.0.dist-info/top_level.txt +1 -0
  78. pyfishpack.libs/libgcc_s_seh-1-25d59ccffa1a9009644065b069829e07.dll +0 -0
  79. pyfishpack.libs/libgfortran-5-08f2195cfa0d823e13371c5c3186a82a.dll +0 -0
  80. pyfishpack.libs/libquadmath-0-c5abb9113f1ee64b87a889958e4b7418.dll +0 -0
  81. 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