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,634 @@
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
+ ! SUBROUTINE hwscyl(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, bdd,
35
+ ! elmbda, f, idimf, pertrb, ierror)
36
+ !
37
+ !
38
+ ! DIMENSION OF bda(n), bdb(n), bdc(m), bdd(m), f(idimf, n+1)
39
+ ! ARGUMENTS
40
+ !
41
+ ! PURPOSE Solves a finite difference approximation
42
+ ! to the helmholtz equation in cylindrical
43
+ ! coordinates. this modified helmholtz equation
44
+ !
45
+ ! (1/r)(d/dr)(r(du/dr)) + (d/dz)(du/dz)
46
+ !
47
+ ! + (lambda/r**2)u = f(r, z)
48
+ !
49
+ ! results from the fourier transform of the
50
+ ! three-dimensional poisson equation.
51
+ !
52
+ ! USAGE call hwscyl(a, b, m, mbdcnd, bda, bdb, c, d, n,
53
+ ! nbdcnd, bdc, bdd, elmbda, f, idimf,
54
+ ! pertrb, ierror, w)
55
+ !
56
+ ! ARGUMENTS
57
+ ! ON INPUT a, b
58
+ ! the range of r, i.e., a <= r <= b.
59
+ ! a must be less than b and a must be
60
+ ! non-negative.
61
+ !
62
+ ! m
63
+ ! the number of panels into which the
64
+ ! interval (a, b) is subdivided. hence,
65
+ ! there will be m+1 grid points in the
66
+ ! r-direction given by r(i) = a+(i-1)dr,
67
+ ! for i = 1, 2, ..., m+1, where dr = (b-a)/m
68
+ ! is the panel width. m must be greater
69
+ ! than 3.
70
+ !
71
+ ! mbdcnd
72
+ ! indicates the type of boundary conditions
73
+ ! at r = a and r = b.
74
+ !
75
+ ! = 1 if the solution is specified at
76
+ ! r = a and r = b.
77
+ ! = 2 if the solution is specified at
78
+ ! r = a and the derivative of the
79
+ ! solution with respect to r is
80
+ ! specified at r = b.
81
+ ! = 3 if the derivative of the solution
82
+ ! with respect to r is specified at
83
+ ! r = a (see note below) and r = b.
84
+ ! = 4 if the derivative of the solution
85
+ ! with respect to r is specified at
86
+ ! r = a (see note below) and the
87
+ ! solution is specified at r = b.
88
+ ! = 5 if the solution is unspecified at
89
+ ! r = a = 0 and the solution is
90
+ ! specified at r = b.
91
+ ! = 6 if the solution is unspecified at
92
+ ! r = a = 0 and the derivative of the
93
+ ! solution with respect to r is specified
94
+ ! at r = b.
95
+ !
96
+ ! if a = 0, do not use mbdcnd = 3 or 4,
97
+ ! but instead use mbdcnd = 1, 2, 5, or 6 .
98
+ !
99
+ ! bda
100
+ ! a one-dimensional array of length n+1 that
101
+ ! specifies the values of the derivative of
102
+ ! the solution with respect to r at r = a.
103
+ !
104
+ ! when mbdcnd = 3 or 4,
105
+ ! bda(j) = (d/dr)u(a, z(j)), j = 1, 2, ..., n+1.
106
+ !
107
+ ! when mbdcnd has any other value, bda is
108
+ ! a dummy variable.
109
+ !
110
+ ! bdb
111
+ ! a one-dimensional array of length n+1 that
112
+ ! specifies the values of the derivative
113
+ ! of the solution with respect to r at r = b.
114
+ !
115
+ ! when mbdcnd = 2, 3, or 6,
116
+ ! bdb(j) = (d/dr)u(b, z(j)), j = 1, 2, ..., n+1.
117
+ !
118
+ ! when mbdcnd has any other value, bdb is
119
+ ! a dummy variable.
120
+ !
121
+ ! c, d
122
+ ! the range of z, i.e., c <= z <= d.
123
+ ! c must be less than d.
124
+ !
125
+ ! n
126
+ ! the number of panels into which the
127
+ ! interval (c, d) is subdivided. hence,
128
+ ! there will be n+1 grid points in the
129
+ ! z-direction given by z(j) = c+(j-1)dz,
130
+ ! for j = 1, 2, ..., n+1,
131
+ ! where dz = (d-c)/n is the panel width.
132
+ ! n must be greater than 3.
133
+ !
134
+ ! nbdcnd
135
+ ! indicates the type of boundary conditions
136
+ ! at z = c and z = d.
137
+ !
138
+ ! = 0 if the solution is periodic in z,
139
+ ! i.e., u(i, 1) = u(i, n+1).
140
+ ! = 1 if the solution is specified at
141
+ ! z = c and z = d.
142
+ ! = 2 if the solution is specified at
143
+ ! z = c and the derivative of
144
+ ! the solution with respect to z is
145
+ ! specified at z = d.
146
+ ! = 3 if the derivative of the solution
147
+ ! with respect to z is
148
+ ! specified at z = c and z = d.
149
+ ! = 4 if the derivative of the solution
150
+ ! with respect to z is specified at
151
+ ! z = c and the solution is specified
152
+ ! at z = d.
153
+ !
154
+ ! bdc
155
+ ! a one-dimensional array of length m+1 that
156
+ ! specifies the values of the derivative
157
+ ! of the solution with respect to z at z = c.
158
+ !
159
+ ! when nbdcnd = 3 or 4,
160
+ ! bdc(i) = (d/dz)u(r(i), c), i = 1, 2, ..., m+1.
161
+ !
162
+ ! when nbdcnd has any other value, bdc is
163
+ ! a dummy variable.
164
+ !
165
+ ! bdd
166
+ ! a one-dimensional array of length m+1 that
167
+ ! specifies the values of the derivative of
168
+ ! the solution with respect to z at z = d.
169
+ !
170
+ ! when nbdcnd = 2 or 3,
171
+ ! bdd(i) = (d/dz)u(r(i), d), i = 1, 2, ..., m+1
172
+ !
173
+ ! when nbdcnd has any other value, bdd is
174
+ ! a dummy variable.
175
+ !
176
+ ! elmbda
177
+ ! the constant lambda in the helmholtz
178
+ ! equation. if lambda > 0, a solution
179
+ ! may not exist. however, hwscyl will
180
+ ! attempt to find a solution. lambda must
181
+ ! be zero when mbdcnd = 5 or 6 .
182
+ !
183
+ ! f
184
+ ! a two-dimensional array, of dimension at
185
+ ! least (m+1)*(n+1), specifying values
186
+ ! of the right side of the helmholtz
187
+ ! equation and boundary data (if any).
188
+ !
189
+ ! on the interior, f is defined as follows:
190
+ ! for i = 2, 3, ..., m and j = 2, 3, ..., n
191
+ ! f(i, j) = f(r(i), z(j)).
192
+ !
193
+ ! on the boundaries f is defined as follows:
194
+ ! for j = 1, 2, ..., n+1 and i = 1, 2, ..., m+1
195
+ !
196
+ ! mbdcnd f(1, j) f(m+1, j)
197
+ ! ------ --------- ---------
198
+ !
199
+ ! 1 u(a, z(j)) u(b, z(j))
200
+ ! 2 u(a, z(j)) f(b, z(j))
201
+ ! 3 f(a, z(j)) f(b, z(j))
202
+ ! 4 f(a, z(j)) u(b, z(j))
203
+ ! 5 f(0, z(j)) u(b, z(j))
204
+ ! 6 f(0, z(j)) f(b, z(j))
205
+ !
206
+ ! nbdcnd f(i, 1) f(i, n+1)
207
+ ! ------ --------- ---------
208
+ !
209
+ ! 0 f(r(i), c) f(r(i), c)
210
+ ! 1 u(r(i), c) u(r(i), d)
211
+ ! 2 u(r(i), c) f(r(i), d)
212
+ ! 3 f(r(i), c) f(r(i), d)
213
+ ! 4 f(r(i), c) u(r(i), d)
214
+ !
215
+ ! note:
216
+ ! if the table calls for both the solution
217
+ ! u and the right side f at a corner then
218
+ ! the solution must be specified.
219
+ !
220
+ ! idimf
221
+ ! the row (or first) dimension of the array
222
+ ! f as it appears in the program calling
223
+ ! hwscyl. this parameter is used to specify
224
+ ! the variable dimension of f. idimf must
225
+ ! be at least m+1 .
226
+ !
227
+ !
228
+ ! ON OUTPUT f
229
+ ! contains the solution u(i, j) of the finite
230
+ ! difference approximation for the grid point
231
+ ! (r(i), z(j)), i =1, 2, ..., m+1, j =1, 2, ..., n+1.
232
+ !
233
+ ! pertrb
234
+ ! if one specifies a combination of periodic,
235
+ ! derivative, and unspecified boundary
236
+ ! conditions for a poisson equation
237
+ ! (lambda = 0), a solution may not exist.
238
+ ! pertrb is a constant, calculated and
239
+ ! subtracted from f, which ensures that a
240
+ ! solution exists. hwscyl then computes
241
+ ! this solution, which is a least squares
242
+ ! solution to the original approximation.
243
+ ! this solution plus any constant is also
244
+ ! a solution. hence, the solution is not
245
+ ! unique. the value of pertrb should be
246
+ ! small compared to the right side f.
247
+ ! otherwise, a solution is obtained to an
248
+ ! essentially different problem. this
249
+ ! comparison should always be made to insure
250
+ ! that a meaningful solution has been obtained.
251
+ !
252
+ ! ierror
253
+ ! an error flag which indicates invalid input
254
+ ! parameters. except for numbers 0 and 11,
255
+ ! a solution is not attempted.
256
+ !
257
+ ! = 0 no error.
258
+ ! = 1 a < 0 .
259
+ ! = 2 a >= b.
260
+ ! = 3 mbdcnd < 1 or mbdcnd > 6 .
261
+ ! = 4 c >= d.
262
+ ! = 5 n <= 3
263
+ ! = 6 nbdcnd < 0 or nbdcnd > 4 .
264
+ ! = 7 a = 0, mbdcnd = 3 or 4 .
265
+ ! = 8 a > 0, mbdcnd >= 5 .
266
+ ! = 9 a = 0, lambda /= 0, mbdcnd >= 5 .
267
+ ! = 10 idimf < m+1 .
268
+ ! = 11 lambda > 0 .
269
+ ! = 12 m <= 3
270
+ ! = 20 if the dynamic allocation of real and
271
+ ! complex workspace required for solution
272
+ ! fails (for example if n, m are too large
273
+ ! for your computer)
274
+ !
275
+ ! since this is the only means of indicating
276
+ ! a possibly incorrect call to hwscyl, the
277
+ ! user should test ierror after the call.
278
+ !
279
+ !
280
+ ! HISTORY Written by Roland Sweet at NCAR in the late
281
+ ! 1970's. Released on NCAR's public software
282
+ ! libraries in January 1980.
283
+ ! Revised in June 2004 by John Adams using
284
+ ! Fortran 90 dynamically allocated workspace.
285
+ !
286
+ !
287
+ !
288
+ ! ALGORITHM The routine defines the finite difference
289
+ ! equations, incorporates boundary data, and
290
+ ! adjusts the right side of singular systems
291
+ ! and then calls genbun to solve the system.
292
+ !
293
+ ! TIMING For large m and n, the operation count
294
+ ! is roughly proportional to
295
+ !
296
+ ! m*n*(log2(n)
297
+ !
298
+ ! but also depends on input parameters nbdcnd
299
+ ! and mbdcnd.
300
+ !
301
+ ! ACCURACY The solution process employed results in a loss
302
+ ! of no more than three significant digits for n
303
+ ! and m as large as 64. more details about
304
+ ! accuracy can be found in the documentation for
305
+ ! subroutine genbun which is the routine that
306
+ ! solves the finite difference equations.
307
+ !
308
+ ! REFERENCES Swarztrauber, P. and R. Sweet, "Efficient
309
+ ! FORTRAN subprograms for the solution of
310
+ ! elliptic equations"
311
+ ! NCAR TN/IA-109, July, 1975, 138 pp.
312
+ !
313
+ submodule(centered_helmholtz_solvers) centered_cylindrical_solver
314
+
315
+ contains
316
+
317
+ module subroutine hwscyl(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, &
318
+ bdd, elmbda, f, idimf, pertrb, ierror)
319
+
320
+ ! Dummy arguments
321
+ integer(ip), intent(in) :: m
322
+ integer(ip), intent(in) :: mbdcnd
323
+ integer(ip), intent(in) :: n
324
+ integer(ip), intent(in) :: nbdcnd
325
+ integer(ip), intent(in) :: idimf
326
+ integer(ip), intent(out) :: ierror
327
+ real(wp), intent(in) :: a
328
+ real(wp), intent(in) :: b
329
+ real(wp), intent(in) :: c
330
+ real(wp), intent(in) :: d
331
+ real(wp), intent(in) :: elmbda
332
+ real(wp), intent(out) :: pertrb
333
+ real(wp), intent(in) :: bda(:)
334
+ real(wp), intent(in) :: bdb(:)
335
+ real(wp), intent(in) :: bdc(:)
336
+ real(wp), intent(in) :: bdd(:)
337
+ real(wp), intent(inout) :: f(:,:)
338
+
339
+ ! Local variables
340
+ type(FishpackWorkspace) :: workspace
341
+
342
+ ! Check input arguments
343
+ call hwscyl_check_input_arguments(a, b, m, mbdcnd, c, d, n, &
344
+ nbdcnd, elmbda, idimf, ierror)
345
+
346
+ ! Check error flag
347
+ if (ierror /= 0) return
348
+
349
+ ! Allocate memory
350
+ call workspace%initialize_staggered_workspace(n, m)
351
+
352
+ ! Solve system
353
+ associate( rew => workspace%real_workspace )
354
+ call hwscyl_lower_routine(a, b, m, mbdcnd, bda, bdb, c, d, n, &
355
+ nbdcnd, bdc, bdd, elmbda, f, idimf, pertrb, ierror, rew)
356
+ end associate
357
+
358
+ ! Release memory
359
+ call workspace%destroy()
360
+
361
+ end subroutine hwscyl
362
+
363
+ subroutine hwscyl_check_input_arguments(a, b, m, mbdcnd, c, d, n, &
364
+ nbdcnd, elmbda, idimf, ierror)
365
+
366
+ ! Dummy arguments
367
+ integer(ip), intent(in) :: m
368
+ integer(ip), intent(in) :: mbdcnd
369
+ integer(ip), intent(in) :: n
370
+ integer(ip), intent(in) :: nbdcnd
371
+ integer(ip), intent(in) :: idimf
372
+ integer(ip), intent(out) :: ierror
373
+ real(wp), intent(in) :: a
374
+ real(wp), intent(in) :: b
375
+ real(wp), intent(in) :: c
376
+ real(wp), intent(in) :: d
377
+ real(wp), intent(in) :: elmbda
378
+
379
+ if (a < ZERO) then
380
+ ierror = 1
381
+ else if (a >= b) then
382
+ ierror = 2
383
+ else if (mbdcnd <= 0 .or. mbdcnd >= 7) then
384
+ ierror = 3
385
+ else if (c >= d) then
386
+ ierror = 4
387
+ else if (n <= 3) then
388
+ ierror = 5
389
+ else if (nbdcnd <= (-1) .or. nbdcnd >= 5) then
390
+ ierror = 6
391
+ else if (a == ZERO .and. (mbdcnd == 3 .or. mbdcnd == 4)) then
392
+ ierror = 7
393
+ else if (a > ZERO .and. mbdcnd >= 5) then
394
+ ierror = 8
395
+ else if (a == ZERO .and. elmbda /= ZERO .and. mbdcnd >= 5) then
396
+ ierror = 9
397
+ else if (idimf < m + 1) then
398
+ ierror = 10
399
+ else if (m <= 3) then
400
+ ierror = 12
401
+ else
402
+ ierror = 0
403
+ end if
404
+
405
+ end subroutine hwscyl_check_input_arguments
406
+
407
+ subroutine hwscyl_lower_routine(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, &
408
+ bdd, elmbda, f, idimf, pertrb, ierror, w)
409
+
410
+ ! Dummy arguments
411
+
412
+ integer(ip), intent(in) :: m
413
+ integer(ip), intent(in) :: mbdcnd
414
+ integer(ip), intent(in) :: n
415
+ integer(ip), intent(in) :: nbdcnd
416
+ integer(ip), intent(in) :: idimf
417
+ integer(ip), intent(out) :: ierror
418
+ real(wp), intent(in) :: a
419
+ real(wp), intent(in) :: b
420
+ real(wp), intent(in) :: c
421
+ real(wp), intent(in) :: d
422
+ real(wp), intent(in) :: elmbda
423
+ real(wp), intent(out) :: pertrb
424
+ real(wp), intent(in) :: bda(:)
425
+ real(wp), intent(in) :: bdb(:)
426
+ real(wp), intent(in) :: bdc(:)
427
+ real(wp), intent(in) :: bdd(:)
428
+ real(wp), intent(inout) :: f(:,:)
429
+ real(wp), intent(inout) :: w(:)
430
+
431
+ ! Local variables
432
+ integer(ip) :: mp1, np1, np, mstart, mstop, munk, nstart, nstop, nunk
433
+ integer(ip) :: id2, id3, id4, id5, id6, istart
434
+ integer(ip) :: ij, i, j, k, l, nsp1, nstm1
435
+ integer(ip) :: local_error_flag, i1
436
+ real(wp) :: dr, half_dr, dr2, dth, dth2
437
+ real(wp) :: a1, r, a2, s, s1, s2
438
+ type(CenteredCyclicReductionUtility) :: util
439
+
440
+ mp1 = m + 1
441
+ dr = (b - a)/m
442
+ half_dr = dr/2
443
+ dr2 = dr**2
444
+ np1 = n + 1
445
+ dth = (d - c)/n
446
+ dth2 = dth**2
447
+ np = nbdcnd + 1
448
+
449
+ ! Define range of indices i and j for unknowns u(i, j).
450
+ mstart = 2
451
+ mstop = m
452
+ select case (mbdcnd)
453
+ case (2)
454
+ mstop = mp1
455
+ case (3, 6)
456
+ mstart = 1
457
+ mstop = mp1
458
+ case (4:5)
459
+ mstart = 1
460
+ end select
461
+
462
+ munk = mstop - mstart + 1
463
+ nstart = 1
464
+ nstop = n
465
+ select case (np)
466
+ case (2)
467
+ nstart = 2
468
+ case (3)
469
+ nstart = 2
470
+ nstop = np1
471
+ case (4)
472
+ nstop = np1
473
+ end select
474
+
475
+ nunk = nstop - nstart + 1
476
+
477
+ ! Define a, b, c coefficients in w-array.
478
+ id2 = munk
479
+ id3 = id2 + munk
480
+ id4 = id3 + munk
481
+ id5 = id4 + munk
482
+ id6 = id5 + munk
483
+ istart = 1
484
+ a1 = TWO/dr2
485
+ ij = 0
486
+
487
+ if (mbdcnd==3 .or. mbdcnd==4) ij = 1
488
+
489
+ if (mbdcnd > 4) then
490
+ w(1) = 0.
491
+ w(id2+1) = -TWO*a1
492
+ w(id3+1) = TWO*a1
493
+ istart = 2
494
+ ij = 1
495
+ end if
496
+
497
+ do i = istart, munk
498
+ r = a + real(i - ij, kind=wp)*dr
499
+ j = id5 + i
500
+ w(j) = r
501
+ j = id6 + i
502
+ w(j) = ONE/r**2
503
+ w(i) = (r - half_dr)/(r*dr2)
504
+ j = id3 + i
505
+ w(j) = (r + half_dr)/(r*dr2)
506
+ k = id6 + i
507
+ j = id2 + i
508
+ w(j) = (-a1) + elmbda*w(k)
509
+ end do
510
+
511
+ select case (mbdcnd)
512
+ case (2)
513
+ w(id2) = a1
514
+ case (3, 6)
515
+ w(id2) = a1
516
+ w(id3+1) = a1*real(istart, kind=wp)
517
+ case (4)
518
+ w(id3+1) = a1*real(istart, kind=wp)
519
+ end select
520
+
521
+ select case (mbdcnd)
522
+ case (1:2)
523
+ a1 = w(1)
524
+ f(2, nstart:nstop) = f(2, nstart:nstop) - a1*f(1, nstart:nstop)
525
+ case (3:4)
526
+ a1 = TWO*dr*w(1)
527
+ f(1, nstart:nstop) = f(1, nstart:nstop) + a1*bda(nstart:nstop)
528
+ end select
529
+
530
+ select case (mbdcnd)
531
+ case (1, 4:5)
532
+ a1 = w(id4)
533
+ f(m, nstart:nstop) = f(m, nstart:nstop) - a1*f(mp1, nstart:nstop)
534
+ case (2:3, 6)
535
+ a1 = TWO*dr*w(id4)
536
+ f(mp1, nstart:nstop) = f(mp1, nstart:nstop) - a1*bdb(nstart:nstop)
537
+ end select
538
+
539
+ ! Enter boundary data for z-boundaries.
540
+ a1 = ONE/dth2
541
+ l = id5 - mstart + 1
542
+
543
+ if (np /= 1) then
544
+ select case (np)
545
+ case (2:3)
546
+ f(mstart:mstop, 2) = f(mstart:mstop, 2) - a1*f(mstart:mstop, 1)
547
+ case (4:5)
548
+ a1 = 2./dth
549
+ f(mstart:mstop, 1) = f(mstart:mstop, 1) + a1*bdc(mstart:mstop)
550
+ end select
551
+
552
+ a1 = ONE/dth2
553
+ select case (np)
554
+ case (2, 5)
555
+ f(mstart:mstop, n) = f(mstart:mstop, n) - a1*f(mstart:mstop, np1)
556
+ case (3:4)
557
+ a1 = 2./dth
558
+ f(mstart:mstop, np1) = f(mstart:mstop, np1) - a1*bdd(mstart:mstop)
559
+ end select
560
+ end if
561
+
562
+ if_block: block
563
+ pertrb = ZERO
564
+ if (elmbda >= ZERO) then
565
+ if (elmbda /= ZERO) then
566
+ ierror = 11
567
+ return
568
+ else
569
+ w(id5+1) = HALF*(w(id5+2)-half_dr)
570
+
571
+ select case (mbdcnd)
572
+ case (1:2, 4:5)
573
+ exit if_block
574
+ case (6)
575
+ w(id5+1) = HALF*w(id5+1)
576
+ end select
577
+
578
+ select case (np)
579
+ case (1)
580
+ a2 = ONE
581
+ case (2:3, 5)
582
+ exit if_block
583
+ case (4)
584
+ a2 = TWO
585
+ end select
586
+
587
+ k = id5 + munk
588
+ w(k) = HALF*(w(k-1)+half_dr)
589
+ s = ZERO
590
+
591
+ do i = mstart, mstop
592
+ s1 = ZERO
593
+ nsp1 = nstart + 1
594
+ nstm1 = nstop - 1
595
+ s1 = sum(f(i, nsp1:nstm1))
596
+ k = i + l
597
+ s = s + (a2*s1 + f(i, nstart)+f(i, nstop))*w(k)
598
+ end do
599
+
600
+ s2 = real(m, kind=wp)*a + (0.75_wp + real((m - 1)*(m + 1), kind=wp))*half_dr
601
+
602
+ if (mbdcnd == 3) s2 = s2 + 0.25_wp*half_dr
603
+
604
+ s1 = (TWO + a2*real(nunk-2, kind=wp))*s2
605
+
606
+ pertrb = s/s1
607
+ f(mstart:mstop, nstart:nstop) = &
608
+ f(mstart:mstop, nstart:nstop) - pertrb
609
+ end if
610
+ end if
611
+ end block if_block
612
+
613
+ w(:mstop-mstart+1) = w(:mstop-mstart+1)*dth2
614
+ w(id2+1:mstop-mstart+1+id2) = w(id2+1:mstop-mstart+1+id2)*dth2
615
+ w(id3+1:mstop-mstart+1+id3) = w(id3+1:mstop-mstart+1+id3)*dth2
616
+ f(mstart:mstop, nstart:nstop) = f(mstart:mstop, nstart:nstop)*dth2
617
+ w(1) = ZERO
618
+ w(id4) = ZERO
619
+
620
+ ! Solve the system of equations.
621
+ local_error_flag = 0
622
+ i1 = 1
623
+ call util%genbun_lower_routine(nbdcnd, nunk, i1, munk, w(1:), w(id2+1:), w(id3+1:), &
624
+ idimf, f(mstart:, nstart:), local_error_flag, w(id4+1:))
625
+
626
+ if (local_error_flag /= 0) then
627
+ error stop 'fishpack library: genbun_lower_routine call failed in hwscyl_lower_routine'
628
+ end if
629
+
630
+ if (nbdcnd == 0) f(mstart:mstop, np1) = f(mstart:mstop, 1)
631
+
632
+ end subroutine hwscyl_lower_routine
633
+
634
+ end submodule centered_cylindrical_solver