PyFishPack 0.1.0__cp39-cp39-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 (82) hide show
  1. PyFishPack/__init__.py +105 -0
  2. PyFishPack/__pycache__/__init__.cpython-39.pyc +0 -0
  3. PyFishPack/__pycache__/apps.cpython-39.pyc +0 -0
  4. PyFishPack/_dummy.c +23 -0
  5. PyFishPack/_dummy.cp39-win_amd64.pyd +0 -0
  6. PyFishPack/apps.py +3640 -0
  7. PyFishPack/fishpack.cp39-win_amd64.dll.a +0 -0
  8. PyFishPack/fishpack.cp39-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 +82 -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/.load-order-pyfishpack-0.1.0 +4 -0
  79. pyfishpack.libs/libgcc_s_seh-1-25d59ccffa1a9009644065b069829e07.dll +0 -0
  80. pyfishpack.libs/libgfortran-5-08f2195cfa0d823e13371c5c3186a82a.dll +0 -0
  81. pyfishpack.libs/libquadmath-0-c5abb9113f1ee64b87a889958e4b7418.dll +0 -0
  82. pyfishpack.libs/libwinpthread-1-83908d14abfafb8b3bfa38cf51ecee56.dll +0 -0
@@ -0,0 +1,746 @@
1
+ !
2
+ ! file hwsplr.f90
3
+ !
4
+ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5
+ ! * *
6
+ ! * copyright (c) 2005 by UCAR *
7
+ ! * *
8
+ ! * University Corporation for Atmospheric Research *
9
+ ! * *
10
+ ! * all rights reserved *
11
+ ! * *
12
+ ! * Fishpack *
13
+ ! * *
14
+ ! * A Package of Fortran *
15
+ ! * *
16
+ ! * Subroutines and Example Programs *
17
+ ! * *
18
+ ! * for Modeling Geophysical Processes *
19
+ ! * *
20
+ ! * by *
21
+ ! * *
22
+ ! * John Adams, Paul Swarztrauber and Roland Sweet *
23
+ ! * *
24
+ ! * of *
25
+ ! * *
26
+ ! * the National Center for Atmospheric Research *
27
+ ! * *
28
+ ! * Boulder, Colorado (80307) U.S.A. *
29
+ ! * *
30
+ ! * which is sponsored by *
31
+ ! * *
32
+ ! * the National Science Foundation *
33
+ ! * *
34
+ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
35
+ !
36
+ ! SUBROUTINE hwsplr(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, bdd,
37
+ ! elmbda, f, idimf, pertrb, ierror)
38
+ !
39
+ !
40
+ ! DIMENSION OF bda(n), bdb(n), bdc(m), bdd(m), f(idimf, n+1)
41
+ ! ARGUMENTS
42
+ !
43
+ ! LATEST REVISION May 2016
44
+ !
45
+ ! PURPOSE Solves a finite difference approximation to
46
+ ! the helmholtz equation in polar coordinates.
47
+ ! the equation is
48
+ !
49
+ ! (1/r)(d/dr)(r(du/dr)) +
50
+ ! (1/r**2)(d/dtheta)(du/dtheta) +
51
+ ! lambda*u = f(r, theta).
52
+ !
53
+ ! USAGE call hwsplr(a, b, m, mbdcnd, bda, bdb, c, d, n,
54
+ ! nbdcnd, bdc, bdd, elmbda, f, idimf,
55
+ ! pertrb, ierror, w)
56
+ !
57
+ ! ARGUMENTS
58
+ ! ON INPUT a, b
59
+ ! the range of r, i.e., a <= r <= b.
60
+ ! a must be less than b and a must be
61
+ ! non-negative.
62
+ !
63
+ ! m
64
+ ! the number of panels into which the
65
+ ! interval (a, b) is subdivided. hence,
66
+ ! there will be m+1 grid points in the
67
+ ! r-direction given by r(i) = a+(i-1)dr,
68
+ ! for i = 1, 2, ..., m+1,
69
+ ! where dr = (b-a)/m is the panel width.
70
+ ! m must be greater than 3.
71
+ !
72
+ ! mbdcnd
73
+ ! indicates the type of boundary condition
74
+ ! at r = a and r = b.
75
+ !
76
+ ! = 1 if the solution is specified at
77
+ ! r = a and r = b.
78
+ ! = 2 if the solution is specified at
79
+ ! r = a and the derivative of
80
+ ! the solution with respect to r is
81
+ ! specified at r = b.
82
+ ! = 3 if the derivative of the solution
83
+ ! with respect to r is specified at
84
+ ! r = a (see note below) and r = b.
85
+ ! = 4 if the derivative of the solution
86
+ ! with respect to r is specified at
87
+ ! r = a (see note below) and the
88
+ ! solution is specified at r = b.
89
+ ! = 5 if the solution is unspecified at
90
+ ! r = a = 0 and the solution is
91
+ ! specified at r = b.
92
+ ! = 6 if the solution is unspecified at
93
+ ! r = a = 0 and the derivative of the
94
+ ! solution with respect to r is specified
95
+ ! at r = b.
96
+ !
97
+ ! note:
98
+ ! if a = 0, do not use mbdcnd = 3 or 4, but
99
+ ! instead use mbdcnd = 1, 2, 5, or 6 .
100
+ !
101
+ ! bda
102
+ ! a one-dimensional array of length n+1 that
103
+ ! specifies the values of the derivative of
104
+ ! the solution with respect to r at r = a.
105
+ !
106
+ ! when mbdcnd = 3 or 4,
107
+ ! bda(j) = (d/dr)u(a, theta(j)),
108
+ ! j = 1, 2, ..., n+1 .
109
+ !
110
+ ! when mbdcnd has any other value, bda is
111
+ ! a dummy variable.
112
+ !
113
+ ! bdb
114
+ ! a one-dimensional array of length n+1 that
115
+ ! specifies the values of the derivative of
116
+ ! the solution with respect to r at r = b.
117
+ !
118
+ ! when mbdcnd = 2, 3, or 6,
119
+ ! bdb(j) = (d/dr)u(b, theta(j)),
120
+ ! j = 1, 2, ..., n+1 .
121
+ !
122
+ ! when mbdcnd has any other value, bdb is
123
+ ! a dummy variable.
124
+ !
125
+ ! c, d
126
+ ! the range of theta, i.e., c <=
127
+ ! theta <= d. c must be less than d.
128
+ !
129
+ ! n
130
+ ! the number of panels into which the
131
+ ! interval (c, d) is subdivided. hence,
132
+ ! there will be n+1 grid points in the
133
+ ! theta-direction given by
134
+ ! theta(j) = c+(j-1)dtheta for
135
+ ! j = 1, 2, ..., n+1, where
136
+ ! dtheta = (d-c)/n is the panel width.
137
+ ! n must be greater than 3.
138
+ !
139
+ ! nbdcnd
140
+ ! indicates the type of boundary conditions
141
+ ! at theta = c and at theta = d.
142
+ !
143
+ ! = 0 if the solution is periodic in theta,
144
+ ! i.e., u(i, j) = u(i, n+j).
145
+ ! = 1 if the solution is specified at
146
+ ! theta = c and theta = d
147
+ ! (see note below).
148
+ ! = 2 if the solution is specified at
149
+ ! theta = c and the derivative of the
150
+ ! solution with respect to theta is
151
+ ! specified at theta = d
152
+ ! (see note below).
153
+ ! = 4 if the derivative of the solution
154
+ ! with respect to theta is specified
155
+ ! at theta = c and the solution is
156
+ ! specified at theta = d
157
+ ! (see note below).
158
+ !
159
+ ! note:
160
+ ! when nbdcnd = 1, 2, or 4, do not use
161
+ ! mbdcnd = 5 or 6
162
+ ! (the former indicates that the solution
163
+ ! is specified at r = 0, the latter indicates
164
+ ! the solution is unspecified at r = 0).
165
+ ! use instead mbdcnd = 1 or 2 .
166
+ !
167
+ ! bdc
168
+ ! a one-dimensional array of length m+1 that
169
+ ! specifies the values of the derivative
170
+ ! of the solution with respect to theta at
171
+ ! theta = c. when nbdcnd = 3 or 4,
172
+ !
173
+ ! bdc(i) = (d/dtheta)u(r(i), c),
174
+ ! i = 1, 2, ..., m+1 .
175
+ !
176
+ ! when nbdcnd has any other value, bdc is
177
+ ! a dummy variable.
178
+ !
179
+ ! bdd
180
+ ! a one-dimensional array of length m+1 that
181
+ ! specifies the values of the derivative
182
+ ! of the solution with respect to theta at
183
+ ! theta = d. when nbdcnd = 2 or 3,
184
+ !
185
+ ! bdd(i) = (d/dtheta)u(r(i), d),
186
+ ! i = 1, 2, ..., m+1 .
187
+ !
188
+ ! when nbdcnd has any other value, bdd is
189
+ ! a dummy variable.
190
+ !
191
+ ! elmbda
192
+ ! the constant lambda in the helmholtz
193
+ ! equation. if lambda < 0, a solution
194
+ ! may not exist. however, hwsplr will
195
+ ! attempt to find a solution.
196
+ !
197
+ ! f
198
+ ! a two-dimensional array, of dimension at
199
+ ! least (m+1)*(n+1), specifying values
200
+ ! of the right side of the helmholtz
201
+ ! equation and boundary data (if any).
202
+ !
203
+ ! on the interior, f is defined as follows:
204
+ ! for i = 2, 3, ..., m and j = 2, 3, ..., n
205
+ ! f(i, j) = f(r(i), theta(j)).
206
+ !
207
+ ! on the boundaries f is defined as follows:
208
+ ! for j = 1, 2, ..., n+1 and i = 1, 2, ..., m+1
209
+ !
210
+ ! mbdcnd f(1, j) f(m+1, j)
211
+ ! ------ ------------- -------------
212
+ !
213
+ ! 1 u(a, theta(j)) u(b, theta(j))
214
+ ! 2 u(a, theta(j)) f(b, theta(j))
215
+ ! 3 f(a, theta(j)) f(b, theta(j))
216
+ ! 4 f(a, theta(j)) u(b, theta(j))
217
+ ! 5 f(0, 0) u(b, theta(j))
218
+ ! 6 f(0, 0) f(b, theta(j))
219
+ !
220
+ ! nbdcnd f(i, 1) f(i, n+1)
221
+ ! ------ --------- ---------
222
+ !
223
+ ! 0 f(r(i), c) f(r(i), c)
224
+ ! 1 u(r(i), c) u(r(i), d)
225
+ ! 2 u(r(i), c) f(r(i), d)
226
+ ! 3 f(r(i), c) f(r(i), d)
227
+ ! 4 f(r(i), c) u(r(i), d)
228
+ !
229
+ ! note:
230
+ ! if the table calls for both the solution
231
+ ! u and the right side f at a corner then
232
+ ! then the solution must be specified.
233
+ !
234
+ ! idimf
235
+ ! the row (or first) dimension of the array
236
+ ! f as it appears in the program calling
237
+ ! hwsplr. this parameter is used to specify
238
+ ! the variable dimension of f. idimf must
239
+ ! be at least m+1.
240
+ !
241
+ ! ON OUTPUT f
242
+ ! contains the solution u(i, j) of the finite
243
+ ! difference approximation for the grid point
244
+ ! (r(i), theta(j)),
245
+ ! i = 1, 2, ..., m+1, j = 1, 2, ..., n+1 .
246
+ !
247
+ ! pertrb
248
+ ! if a combination of periodic, derivative,
249
+ ! or unspecified boundary conditions is
250
+ ! specified for a poisson equation
251
+ ! (lambda = 0), a solution may not exist.
252
+ ! pertrb is a constant, calculated and
253
+ ! subtracted from f, which ensures that a
254
+ ! solution exists. hwsplr then computes
255
+ ! this solution, which is a least squares
256
+ ! solution to the original approximation.
257
+ ! this solution plus any constant is also
258
+ ! a solution. hence, the solution is not
259
+ ! unique. pertrb should be small compared
260
+ ! to the right side. otherwise, a solution
261
+ ! is obtained to an essentially different
262
+ ! problem. this comparison should always
263
+ ! be made to insure that a meaningful
264
+ ! solution has been obtained.
265
+ !
266
+ ! ierror
267
+ ! An error flag that indicates invalid input
268
+ ! parameters. Except for numbers 0 and 11,
269
+ ! a solution is not attempted.
270
+ !
271
+ ! = 0 no error.
272
+ ! = 1 a < 0 .
273
+ ! = 2 a >= b.
274
+ ! = 3 mbdcnd < 1 or mbdcnd > 6 .
275
+ ! = 4 c >= d.
276
+ ! = 5 n <= 3
277
+ ! = 6 nbdcnd < 0 or > 4 .
278
+ ! = 7 a = 0, mbdcnd = 3 or 4 .
279
+ ! = 8 a > 0, mbdcnd >= 5 .
280
+ ! = 9 mbdcnd >= 5, nbdcnd /= 0
281
+ ! and nbdcnd /= 3 .
282
+ ! = 10 idimf < m+1 .
283
+ ! = 11 lambda > 0 .
284
+ ! = 12 m <= 3
285
+ ! = 20 If the dynamic allocation of real and
286
+ ! complex workspace required for solution
287
+ ! fails (for example if n, m are too large
288
+ ! for your computer)
289
+ !
290
+ ! Since this is the only means of indicating
291
+ ! a possibly incorrect call to hwsplr, the
292
+ ! user should test ierror after the call.
293
+ !
294
+ ! SPECIAL CONDITIONS None
295
+ !
296
+ ! I/O None
297
+ !
298
+ ! PRECISION 64-bit double precision
299
+ !
300
+ ! REQUIRED files type_FishpackWorkspace.f90, genbun.f90, type_CyclicReductionUtility.f9090
301
+ !
302
+ ! STANDARD Fortran 2008
303
+ !
304
+ ! HISTORY * Written by Roland Sweet at NCAR in the late
305
+ ! 1970's. Released on NCAR's public software
306
+ ! libraries in January 1980.
307
+ ! * Revised in June 2004 by John Adams using
308
+ ! Fortran 90 dynamically allocated workspace.
309
+ !
310
+ ! ALGORITHM The routine defines the finite difference
311
+ ! equations, incorporates boundary data, and
312
+ ! adjusts the right side of singular systems
313
+ ! and then calls genbun to solve the system.
314
+ !
315
+ ! TIMING For large m and n, the operation count
316
+ ! is roughly proportional to
317
+ !
318
+ ! m*n*log2(n)
319
+ !
320
+ ! but also depends on input parameters nbdcnd
321
+ ! and mbdcnd.
322
+ !
323
+ ! ACCURACY The solution process employed results in a loss
324
+ ! of no more than three significant digits for n
325
+ ! and m as large as 64. More details about
326
+ ! accuracy can be found in the documentation for
327
+ ! subroutine genbun which is the routine that
328
+ ! solves the finite difference equations.
329
+ !
330
+ ! REFERENCES Swarztrauber, P. and R. Sweet, "Efficient
331
+ ! FORTRAN subprograms for the solution of
332
+ ! elliptic equations"
333
+ ! NCAR TN/IA-109, July, 1975, 138 pp.
334
+ !
335
+ submodule (centered_helmholtz_solvers) centered_polar_solver
336
+
337
+ contains
338
+
339
+ module subroutine hwsplr(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, &
340
+ bdd, elmbda, f, idimf, pertrb, ierror)
341
+
342
+ ! Dummy arguments
343
+ integer(ip), intent(in) :: m
344
+ integer(ip), intent(in) :: mbdcnd
345
+ integer(ip), intent(in) :: n
346
+ integer(ip), intent(in) :: nbdcnd
347
+ integer(ip), intent(in) :: idimf
348
+ integer(ip), intent(out) :: ierror
349
+ real(wp), intent(in) :: a
350
+ real(wp), intent(in) :: b
351
+ real(wp), intent(in) :: c
352
+ real(wp), intent(in) :: d
353
+ real(wp), intent(in) :: elmbda
354
+ real(wp), intent(out) :: pertrb
355
+ real(wp), intent(in) :: bda(:)
356
+ real(wp), intent(in) :: bdb(:)
357
+ real(wp), intent(in) :: bdc(:)
358
+ real(wp), intent(in) :: bdd(:)
359
+ real(wp), intent(inout) :: f(:,:)
360
+
361
+ ! Local variables
362
+ type(FishpackWorkspace) workspace
363
+
364
+ ! Check input arguments
365
+ call hwsplr_check_input_arguments(a, b, m, mbdcnd, c, d, n, nbdcnd, idimf, ierror)
366
+
367
+ ! Check error flag
368
+ if (ierror /= 0) return
369
+
370
+ ! Allocate memory
371
+ call workspace%initialize_centered_workspace(n, m)
372
+
373
+ ! Solve system
374
+ associate( rew => workspace%real_workspace )
375
+ call hwsplr_lower_routine(a, b, m, mbdcnd, bda, bdb, c, d, n, &
376
+ nbdcnd, bdc, bdd, elmbda, f, idimf, pertrb, ierror, rew)
377
+ end associate
378
+
379
+ ! Release memory
380
+ call workspace%destroy()
381
+
382
+ end subroutine hwsplr
383
+
384
+ pure subroutine hwsplr_check_input_arguments(a, b, m, mbdcnd, c, d, n, nbdcnd, idimf, ierror)
385
+
386
+ ! Dummy arguments
387
+ integer(ip), intent(in) :: m
388
+ integer(ip), intent(in) :: mbdcnd
389
+ integer(ip), intent(in) :: n
390
+ integer(ip), intent(in) :: nbdcnd
391
+ integer(ip), intent(in) :: idimf
392
+ integer(ip), intent(out) :: ierror
393
+ real(wp), intent(in) :: a
394
+ real(wp), intent(in) :: b
395
+ real(wp), intent(in) :: c
396
+ real(wp), intent(in) :: d
397
+
398
+ if (a < ZERO) then
399
+ ierror = 1
400
+ else if (a >= b) then
401
+ ierror = 2
402
+ else if (mbdcnd <= 0 .or. mbdcnd >= 7) then
403
+ ierror = 3
404
+ else if (d <= c) then
405
+ ierror = 4
406
+ else if (n <= 3) then
407
+ ierror = 5
408
+ else if (nbdcnd <= -1 .or. 5 <= nbdcnd) then
409
+ ierror = 6
410
+ else if (a == ZERO .and. (mbdcnd==3 .or. mbdcnd==4)) then
411
+ ierror = 7
412
+ else if (a > ZERO .and. 5 <= mbdcnd) then
413
+ ierror = 8
414
+ else if (5 <= mbdcnd .and. nbdcnd /= 0 .and. nbdcnd /= 3) then
415
+ ierror = 9
416
+ else if (idimf < m + 1) then
417
+ ierror = 10
418
+ else if (m <= 3) then
419
+ ierror = 12
420
+ else
421
+ ierror = 0
422
+ end if
423
+
424
+ end subroutine hwsplr_check_input_arguments
425
+
426
+ subroutine hwsplr_lower_routine(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, &
427
+ bdd, elmbda, f, idimf, pertrb, ierror, w)
428
+
429
+ ! Dummy arguments
430
+ integer(ip), intent(in) :: m
431
+ integer(ip), intent(in) :: mbdcnd
432
+ integer(ip), intent(in) :: n
433
+ integer(ip), intent(in) :: nbdcnd
434
+ integer(ip), intent(in) :: idimf
435
+ integer(ip), intent(out) :: ierror
436
+ real(wp), intent(in) :: a
437
+ real(wp), intent(in) :: b
438
+ real(wp), intent(in) :: c
439
+ real(wp), intent(in) :: d
440
+ real(wp), intent(in) :: elmbda
441
+ real(wp), intent(out) :: pertrb
442
+ real(wp), intent(in) :: bda(:)
443
+ real(wp), intent(in) :: bdb(:)
444
+ real(wp), intent(in) :: bdc(:)
445
+ real(wp), intent(in) :: bdd(:)
446
+ real(wp), intent(inout) :: f(:,:)
447
+ real(wp), intent(inout) :: w(:)
448
+
449
+ ! Local variables
450
+ integer(ip) :: mp1, np1, np, mstart, mstop, munk, nstart, nstop, nunk
451
+ integer(ip) :: id2, id3, id4, id5, id6, ij, i
452
+ integer(ip) :: j, l, lp, k, i1, local_error_flag, iip
453
+ real(wp) :: dr, half_dr, dr2, dt, dt2
454
+ real(wp) :: a1, r, s2, a2, s, s1, ypole
455
+ type(CenteredCyclicReductionUtility) :: util
456
+
457
+ mp1 = m + 1
458
+ dr = (b - a)/m
459
+ half_dr = dr/2
460
+ dr2 = dr**2
461
+ np1 = n + 1
462
+ dt = (d - c)/n
463
+ dt2 = dt**2
464
+ np = nbdcnd + 1
465
+ !
466
+ ! Define range of indices i and j for unknowns u(i, j).
467
+ !
468
+ mstart = 2
469
+ mstop = mp1
470
+
471
+ select case (mbdcnd)
472
+ case (1)
473
+ mstop = m
474
+ case (3)
475
+ mstart = 1
476
+ case (4)
477
+ mstart = 1
478
+ mstop = m
479
+ case (5)
480
+ mstop = m
481
+ end select
482
+
483
+ munk = mstop - mstart + 1
484
+ nstart = 1
485
+ nstop = n
486
+
487
+ select case (np)
488
+ case (2)
489
+ nstart = 2
490
+ case (3)
491
+ nstart = 2
492
+ nstop = np1
493
+ case (4)
494
+ nstop = np1
495
+ end select
496
+
497
+ nunk = nstop - nstart + 1
498
+ !
499
+ ! Define a, b, c coefficients in w-array.
500
+ !
501
+ id2 = munk
502
+ id3 = id2 + munk
503
+ id4 = id3 + munk
504
+ id5 = id4 + munk
505
+ id6 = id5 + munk
506
+ a1 = TWO/dr2
507
+ ij = 0
508
+
509
+ if (mbdcnd == 3 .or. mbdcnd == 4) ij = 1
510
+
511
+ do i = 1, munk
512
+ r = a + real(i - ij, kind=wp)*dr
513
+ j = id5 + i
514
+ w(j) = r
515
+ j = id6 + i
516
+ w(j) = ONE/r**2
517
+ w(i) = (r - half_dr)/(r*dr2)
518
+ j = id3 + i
519
+ w(j) = (r + half_dr)/(r*dr2)
520
+ j = id2 + i
521
+ w(j) = (-a1) + elmbda
522
+ end do
523
+
524
+ select case (mbdcnd)
525
+ case (2, 6)
526
+ w(id2) = a1
527
+ case (3)
528
+ w(id2) = a1
529
+ w(id3+1) = a1
530
+ case (4)
531
+ w(id3+1) = a1
532
+ end select
533
+
534
+ select case (mbdcnd)
535
+ case (1:2)
536
+ a1 = w(1)
537
+ f(2, nstart:nstop) = f(2, nstart:nstop) - a1*f(1, nstart:nstop)
538
+ case (3:4)
539
+ a1 = TWO * dr*w(1)
540
+ f(1, nstart:nstop) = f(1, nstart:nstop) + a1*bda(nstart:nstop)
541
+ end select
542
+
543
+ select case (mbdcnd)
544
+ case (1, 4:5)
545
+ a1 = w(id4)
546
+ f(m, nstart:nstop) = f(m, nstart:nstop) - a1*f(mp1, nstart:nstop)
547
+ case (2:3, 6)
548
+ a1 = TWO * dr*w(id4)
549
+ f(mp1, nstart:nstop) = f(mp1, nstart:nstop) - a1*bdb(nstart:nstop)
550
+ end select
551
+
552
+ !
553
+ ! Enter boundary data for theta-boundaries.
554
+ !
555
+ a1 = ONE/dt2
556
+ l = id5 - mstart + 1
557
+ lp = id6 - mstart + 1
558
+
559
+ if (np /= 1) then
560
+ select case (np)
561
+ case (2:3)
562
+ f(mstart:mstop, 2) = f(mstart:mstop, 2) - a1*w(mstart+lp:mstop+lp)*f &
563
+ (mstart:mstop, 1)
564
+ case (4:5)
565
+ a1 = TWO/dt
566
+ f(mstart:mstop, 1) = f(mstart:mstop, 1) + a1*w(mstart+lp:mstop+lp)* &
567
+ bdc(mstart:mstop)
568
+ end select
569
+
570
+ a1 = ONE/dt2
571
+
572
+ select case (np)
573
+ case (2, 5)
574
+ f(mstart:mstop, n) = f(mstart:mstop, n) &
575
+ - a1*w(mstart+lp:mstop+lp) * f(mstart:mstop, np1)
576
+ case (3:4)
577
+ a1 = TWO/dt
578
+ f(mstart:mstop, np1) = f(mstart:mstop, np1) &
579
+ - a1 * w(mstart+lp:mstop+lp) * bdd(mstart:mstop)
580
+ end select
581
+ end if
582
+
583
+ if ((mbdcnd >= 5) .and. (nbdcnd == 3)) then
584
+ f(1, 1) = f(1, 1) - (bdd(2)-bdc(2))* 4.0_wp/(real(n, kind=wp)*dt*dr2)
585
+ end if
586
+ !
587
+ ! adjust right side of singular problems to insure existence of a
588
+ ! solution.
589
+ !
590
+ pertrb = ZERO
591
+
592
+ if_construct: if (elmbda >= ZERO) then
593
+ if (elmbda /= ZERO) then
594
+ ierror = 11
595
+ return
596
+ else
597
+ if (nbdcnd == 0 .or. nbdcnd == 3) then
598
+ s2 = ZERO
599
+ select case (mbdcnd)
600
+ case (1:2, 4:5)
601
+ exit if_construct
602
+ case (3)
603
+ w(id5+1) = HALF * (w(id5+2)-half_dr)
604
+ s2 = 0.25_wp * dr
605
+ end select
606
+
607
+ if (nbdcnd == 0) then
608
+ a2 = ONE
609
+ else
610
+ a2 = TWO
611
+ end if
612
+
613
+ j = id5 + munk
614
+ w(j) = HALF * (w(j-1)+half_dr)
615
+ s = ZERO
616
+
617
+ do i = mstart, mstop
618
+ s1 = ZERO
619
+ ij = nstart + 1
620
+ k = nstop - 1
621
+ s1 = sum(f(i, ij:k))
622
+ j = i + l
623
+ s = s + (a2*s1 + f(i, nstart)+f(i, nstop))*w(j)
624
+ end do
625
+
626
+ s2=real(m, kind=wp)*a+dr*(real((m-1)*(m+1), kind=wp)*HALF+0.25_wp)+s2
627
+ s1 = (TWO + a2*real(nunk - 2, kind=wp))*s2
628
+
629
+ if (mbdcnd /= 3) then
630
+ s2 = (real(n, kind=wp)*a2*dr)/8
631
+ s = s + f(1, 1)*s2
632
+ s1 = s1 + s2
633
+ end if
634
+
635
+ pertrb = s/s1
636
+ f(mstart:mstop, nstart:nstop) = &
637
+ f(mstart:mstop, nstart:nstop) - pertrb
638
+ end if
639
+ end if
640
+ end if if_construct
641
+
642
+
643
+ do i = mstart, mstop
644
+ k = i - mstart + 1
645
+ j = i + lp
646
+ a1 = dt2/w(j)
647
+ w(k) = a1*w(k)
648
+ j = id2 + k
649
+ w(j) = a1*w(j)
650
+ j = id3 + k
651
+ w(j) = a1*w(j)
652
+ f(i, nstart:nstop) = a1*f(i, nstart:nstop)
653
+ end do
654
+
655
+ w(1) = ZERO
656
+ w(id4) = ZERO
657
+ !
658
+ ! Solve the system of equations.
659
+ !
660
+ i1 = 1
661
+ local_error_flag = 0
662
+ associate( &
663
+ a_arg => w(1:munk), &
664
+ b_arg => w(id2+1:id2+1+munk), &
665
+ c_arg => w(id3+1:id3+1+munk), &
666
+ y_arg => f(mstart:,nstart:nstart+nunk), &
667
+ w_arg => w(id4+1:) &
668
+ )
669
+ call util%genbun_lower_routine(nbdcnd, nunk, i1, munk, a_arg, b_arg, c_arg, &
670
+ idimf, y_arg, local_error_flag, w_arg)
671
+ end associate
672
+
673
+ ! Check error flag
674
+ if (local_error_flag /= 0) then
675
+ error stop 'fishpack library: genbun_lower_routine call failed in hwsplr_lower_routine'
676
+ end if
677
+
678
+
679
+ select case (mbdcnd)
680
+ case (1:4)
681
+ if (nbdcnd == 0) f(mstart:mstop, np1) = f(mstart:mstop, 1)
682
+ case (5)
683
+ j = id5 + munk
684
+ w(j) = w(id2)/w(id3)
685
+
686
+ do iip = 3, munk
687
+ i = munk - iip + 2
688
+ j = id5 + i
689
+ lp = id2 + i
690
+ k = id3 + i
691
+ w(j) = w(i)/(w(lp)-w(k)*w(j+1))
692
+ end do
693
+
694
+ w(id5+1) = -HALF * dt2/(w(id2+1)-w(id3+1)*w(id5+2))
695
+
696
+ do i = 2, munk
697
+ j = id5 + i
698
+ w(j) = -w(j)*w(j-1)
699
+ end do
700
+
701
+ s = ZERO
702
+ s = sum(f(2, nstart:nstop))
703
+ a2 = nunk
704
+
705
+ if (nbdcnd /= 0) then
706
+ s = s - HALF * (f(2, nstart)+f(2, nstop))
707
+ a2 = a2 - ONE
708
+ end if
709
+
710
+ ypole = (0.25_wp *dr2*f(1, 1)-s/a2)/(w(id5+1)-ONE + elmbda*dr2* 0.25_wp)
711
+
712
+ do i = mstart, mstop
713
+ k = l + i
714
+ f(i, nstart:nstop) = f(i, nstart:nstop) + ypole*w(k)
715
+ end do
716
+
717
+ f(1, :np1) = ypole
718
+
719
+ if (nbdcnd == 0) f(mstart:mstop, np1) = f(mstart:mstop, 1)
720
+
721
+ case (6)
722
+ !
723
+ ! Adjust the solution as necessary for the problems where a = 0.
724
+ !
725
+ if (elmbda == ZERO) then
726
+ ypole = ZERO
727
+ f(1, :np1) = ypole
728
+ if (nbdcnd == 0) f(mstart:mstop, np1) = f(mstart:mstop, 1)
729
+ end if
730
+ end select
731
+
732
+ end subroutine hwsplr_lower_routine
733
+
734
+ end submodule centered_polar_solver
735
+ !
736
+ ! REVISION HISTORY
737
+ !
738
+ ! September 1973 Version 1
739
+ ! April 1976 Version 2
740
+ ! January 1978 Version 3
741
+ ! December 1979 Version 3.1
742
+ ! February 1985 Documentation upgrade
743
+ ! November 1988 Version 3.2, FORTRAN 77 changes
744
+ ! June 2004 Version 5.0, Fortran 90 changes
745
+ ! May 2016 Fortran 2008 changes
746
+ !