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,928 @@
1
+ !
2
+ ! file hwsssp.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 hwssp(ts, tf, m, mbdcnd, bdts, bdtf, ps, pf, n, nbdcnd, bdps,
37
+ ! bdpf, elmbda, f, idimf, pertrb, ierror)
38
+ !
39
+ ! DIMENSION OF bdts(n+1), bdtf(n+1), bdps(m+1), bdpf(m+1),
40
+ ! ARGUMENTS f(idimf, n+1)
41
+ !
42
+ ! LATEST REVISION May 2016
43
+ !
44
+ ! PURPOSE Solves a finite difference approximation to
45
+ ! the helmholtz equation in spherical
46
+ ! coordinates and on the surface of the unit
47
+ ! sphere (radius of 1). the equation is
48
+ !
49
+ ! (1/sin(theta))(d/dtheta)(sin(theta)
50
+ ! (du/dtheta)) + (1/sin(theta)**2)(d/dphi)
51
+ ! (du/dphi) + lambda*u = f(theta, phi)
52
+ !
53
+ ! where theta is colatitude and phi is
54
+ ! longitude.
55
+ !
56
+ ! USAGE call hwsssp(ts, tf, m, mbdcnd, bdts, bdtf, ps, pf,
57
+ ! n, nbdcnd, bdps, bdpf, elmbda, f,
58
+ ! idimf, pertrb, ierror, w)
59
+ !
60
+ ! ARGUMENTS
61
+ ! ON INPUT ts, tf
62
+ !
63
+ ! the range of theta (colatitude), i.e.,
64
+ ! ts <= theta <= tf. ts must be less
65
+ ! than tf. ts and tf are in radians.
66
+ ! a ts of zero corresponds to the north
67
+ ! pole and a tf of pi corresponds to
68
+ ! the south pole.
69
+ !
70
+ ! * * * important * * *
71
+ !
72
+ ! if tf is equal to pi then it must be
73
+ ! computed using the statement
74
+ ! tf = pi_mach(dum). this insures that tf
75
+ ! in the user's program is equal to pi in
76
+ ! this program which permits several tests
77
+ ! of the input parameters that otherwise
78
+ ! would not be possible.
79
+ !
80
+ !
81
+ ! m
82
+ ! the number of panels into which the
83
+ ! interval (ts, tf) is subdivided.
84
+ ! hence, there will be m+1 grid points in the
85
+ ! theta-direction given by
86
+ ! theta(i) = (i-1)dtheta+ts for
87
+ ! i = 1, 2, ..., m+1, where
88
+ ! dtheta = (tf-ts)/m is the panel width.
89
+ ! m must be greater than 5
90
+ !
91
+ ! mbdcnd
92
+ ! indicates the type of boundary condition
93
+ ! at theta = ts and theta = tf.
94
+ !
95
+ ! = 1 if the solution is specified at
96
+ ! theta = ts and theta = tf.
97
+ ! = 2 if the solution is specified at
98
+ ! theta = ts and the derivative of
99
+ ! the solution with respect to theta is
100
+ ! specified at theta = tf
101
+ ! (see note 2 below).
102
+ ! = 3 if the derivative of the solution
103
+ ! with respect to theta is specified
104
+ ! specified at theta = ts and
105
+ ! theta = tf (see notes 1, 2 below).
106
+ ! = 4 if the derivative of the solution
107
+ ! with respect to theta is specified
108
+ ! at theta = ts (see note 1 below)
109
+ ! and the solution is specified at
110
+ ! theta = tf.
111
+ ! = 5 if the solution is unspecified at
112
+ ! theta = ts = 0 and the solution
113
+ ! is specified at theta = tf.
114
+ ! = 6 if the solution is unspecified at
115
+ ! theta = ts = 0 and the derivative
116
+ ! of the solution with respect to theta
117
+ ! is specified at theta = tf
118
+ ! (see note 2 below).
119
+ ! = 7 if the solution is specified at
120
+ ! theta = ts and the solution is
121
+ ! is unspecified at theta = tf = pi.
122
+ ! = 8 if the derivative of the solution
123
+ ! with respect to theta is specified
124
+ ! at theta = ts (see note 1 below) and
125
+ ! the solution is unspecified at
126
+ ! theta = tf = pi.
127
+ ! = 9 if the solution is unspecified at
128
+ ! theta = ts = 0 and theta = tf = pi.
129
+ !
130
+ ! notes:
131
+ ! if ts = 0, do not use mbdcnd = 3, 4, or 8,
132
+ ! but instead use mbdcnd = 5, 6, or 9 .
133
+ !
134
+ ! if tf = pi, do not use mbdcnd = 2, 3, or 6,
135
+ ! but instead use mbdcnd = 7, 8, or 9 .
136
+ !
137
+ ! bdts
138
+ ! a one-dimensional array of length n+1 that
139
+ ! specifies the values of the derivative of
140
+ ! the solution with respect to theta at
141
+ ! theta = ts. when mbdcnd = 3, 4, or 8,
142
+ !
143
+ ! bdts(j) = (d/dtheta)u(ts, phi(j)),
144
+ ! j = 1, 2, ..., n+1 .
145
+ !
146
+ ! when mbdcnd has any other value, bdts is
147
+ ! a dummy variable.
148
+ !
149
+ ! bdtf
150
+ ! a one-dimensional array of length n+1
151
+ ! that specifies the values of the derivative
152
+ ! of the solution with respect to theta at
153
+ ! theta = tf. when mbdcnd = 2, 3, or 6,
154
+ !
155
+ ! bdtf(j) = (d/dtheta)u(tf, phi(j)),
156
+ ! j = 1, 2, ..., n+1 .
157
+ !
158
+ ! when mbdcnd has any other value, bdtf is
159
+ ! a dummy variable.
160
+ !
161
+ ! ps, pf
162
+ ! the range of phi (longitude), i.e.,
163
+ ! ps <= phi <= pf. ps must be less
164
+ ! than pf. ps and pf are in radians.
165
+ ! if ps = 0 and pf = 2*pi, periodic
166
+ ! boundary conditions are usually prescribed.
167
+ !
168
+ ! * * * IMPORTANT * * *
169
+ !
170
+ ! if pf is equal to 2*pi then it must be
171
+ ! computed using the statement
172
+ ! pf = TWO *pi_mach(dum). this insures that
173
+ ! pf in the users program is equal to
174
+ ! 2*pi in this program which permits tests
175
+ ! of the input parameters that otherwise
176
+ ! would not be possible.
177
+ !
178
+ ! n
179
+ ! the number of panels into which the
180
+ ! interval (ps, pf) is subdivided.
181
+ ! hence, there will be n+1 grid points
182
+ ! in the phi-direction given by
183
+ ! phi(j) = (j-1)dphi+ps for
184
+ ! j = 1, 2, ..., n+1, where
185
+ ! dphi = (pf-ps)/n is the panel width.
186
+ ! n must be greater than 4
187
+ !
188
+ ! nbdcnd
189
+ ! indicates the type of boundary condition
190
+ ! at phi = ps and phi = pf.
191
+ !
192
+ ! = 0 if the solution is periodic in phi,
193
+ ! i.u., u(i, j) = u(i, n+j).
194
+ ! = 1 if the solution is specified at
195
+ ! phi = ps and phi = pf
196
+ ! (see note below).
197
+ ! = 2 if the solution is specified at
198
+ ! phi = ps (see note below)
199
+ ! and the derivative of the solution
200
+ ! with respect to phi is specified
201
+ ! at phi = pf.
202
+ ! = 3 if the derivative of the solution
203
+ ! with respect to phi is specified
204
+ ! at phi = ps and phi = pf.
205
+ ! = 4 if the derivative of the solution
206
+ ! with respect to phi is specified
207
+ ! at ps and the solution is specified
208
+ ! at phi = pf
209
+ !
210
+ ! note:
211
+ ! nbdcnd = 1, 2, or 4 cannot be used with
212
+ ! mbdcnd = 5, 6, 7, 8, or 9. the former indicates
213
+ ! that the solution is specified at a pole, the
214
+ ! latter indicates that the solution is not
215
+ ! specified. use instead mbdcnd = 1 or 2.
216
+ !
217
+ ! bdps
218
+ ! a one-dimensional array of length m+1 that
219
+ ! specifies the values of the derivative
220
+ ! of the solution with respect to phi at
221
+ ! phi = ps. when nbdcnd = 3 or 4,
222
+ !
223
+ ! bdps(i) = (d/dphi)u(theta(i), ps),
224
+ ! i = 1, 2, ..., m+1 .
225
+ !
226
+ ! when nbdcnd has any other value, bdps is
227
+ ! a dummy variable.
228
+ !
229
+ ! bdpf
230
+ ! a one-dimensional array of length m+1 that
231
+ ! specifies the values of the derivative
232
+ ! of the solution with respect to phi at
233
+ ! phi = pf. when nbdcnd = 2 or 3,
234
+ !
235
+ ! bdpf(i) = (d/dphi)u(theta(i), pf),
236
+ ! i = 1, 2, ..., m+1 .
237
+ !
238
+ ! when nbdcnd has any other value, bdpf is
239
+ ! a dummy variable.
240
+ !
241
+ ! elmbda
242
+ ! the constant lambda in the helmholtz
243
+ ! equation. if lambda > 0, a solution
244
+ ! may not exist. however, hwsssp will
245
+ ! attempt to find a solution.
246
+ !
247
+ ! f
248
+ ! a two-dimensional array that specifies the
249
+ ! value of the right side of the helmholtz
250
+ ! equation and boundary values (if any).
251
+ ! f must be dimensioned at least (m+1)*(n+1).
252
+ !
253
+ ! on the interior, f is defined as follows:
254
+ ! for i = 2, 3, ..., m and j = 2, 3, ..., n
255
+ ! f(i, j) = f(theta(i), phi(j)).
256
+ !
257
+ ! on the boundaries f is defined as follows:
258
+ ! for j = 1, 2, ..., n+1 and i = 1, 2, ..., m+1
259
+ !
260
+ ! mbdcnd f(1, j) f(m+1, j)
261
+ ! ------ ------------ ------------
262
+ !
263
+ ! 1 u(ts, phi(j)) u(tf, phi(j))
264
+ ! 2 u(ts, phi(j)) f(tf, phi(j))
265
+ ! 3 f(ts, phi(j)) f(tf, phi(j))
266
+ ! 4 f(ts, phi(j)) u(tf, phi(j))
267
+ ! 5 f(0, ps) u(tf, phi(j))
268
+ ! 6 f(0, ps) f(tf, phi(j))
269
+ ! 7 u(ts, phi(j)) f(pi, ps)
270
+ ! 8 f(ts, phi(j)) f(pi, ps)
271
+ ! 9 f(0, ps) f(pi, ps)
272
+ !
273
+ ! nbdcnd f(i, 1) f(i, n+1)
274
+ ! ------ -------------- --------------
275
+ !
276
+ ! 0 f(theta(i), ps) f(theta(i), ps)
277
+ ! 1 u(theta(i), ps) u(theta(i), pf)
278
+ ! 2 u(theta(i), ps) f(theta(i), pf)
279
+ ! 3 f(theta(i), ps) f(theta(i), pf)
280
+ ! 4 f(theta(i), ps) u(theta(i), pf)
281
+ !
282
+ ! note:
283
+ ! if the table calls for both the solution u
284
+ ! and the right side f at a corner then the
285
+ ! solution must be specified.
286
+ !
287
+ ! idimf
288
+ ! the row (or first) dimension of the array
289
+ ! f as it appears in the program calling
290
+ ! hwsssp. this parameter is used to specify
291
+ ! the variable dimension of f. idimf must be
292
+ ! at least m+1 .
293
+ !
294
+ !
295
+ ! ON OUTPUT f
296
+ ! contains the solution u(i, j) of the finite
297
+ ! difference approximation for the grid point
298
+ ! (theta(i), phi(j)), i = 1, 2, ..., m+1 and
299
+ ! j = 1, 2, ..., n+1 .
300
+ !
301
+ ! pertrb
302
+ ! if one specifies a combination of periodic,
303
+ ! derivative or unspecified boundary
304
+ ! conditions for a poisson equation
305
+ ! (lambda = 0), a solution may not exist.
306
+ ! pertrb is a constant, calculated and
307
+ ! subtracted from f, which ensures that a
308
+ ! solution exists. hwsssp then computes
309
+ ! this solution, which is a least squares
310
+ ! solution to the original approximation.
311
+ ! this solution is not unique and is
312
+ ! unnormalized. the value of pertrb should
313
+ ! be small compared to the right side f.
314
+ ! otherwise , a solution is obtained to an
315
+ ! essentially different problem. this
316
+ ! comparison should always be made to insure
317
+ ! that a meaningful solution has been
318
+ ! obtained
319
+ !
320
+ ! ierror
321
+ ! an error flag that indicates invalid input
322
+ ! parameters. except for numbers 0 and 8,
323
+ ! a solution is not attempted.
324
+ !
325
+ ! = 0 no error
326
+ ! = 1 ts<0 or tf>pi
327
+ ! = 2 ts>=tf
328
+ ! = 3 mbdcnd<1 or mbdcnd>9
329
+ ! = 4 ps<0 or ps>pi+pi
330
+ ! = 5 ps>=pf
331
+ ! = 6 n<5
332
+ ! = 7 m<5
333
+ ! = 8 nbdcnd<0 or nbdcnd>4
334
+ ! = 9 elmbda>0
335
+ ! = 10 idimf<m+1
336
+ ! = 11 nbdcnd equals 1, 2 or 4 and mbdcnd>=5
337
+ ! = 12 ts==0 and mbdcnd equals 3, 4 or 8
338
+ ! = 13 tf==pi and mbdcnd equals 2, 3 or 6
339
+ ! = 14 mbdcnd equals 5, 6 or 9 and ts/=0
340
+ ! = 15 mbdcnd>=7 and tf/=pi
341
+ ! = 20 if the dynamic allocation of real and
342
+ ! complex workspace required for solution
343
+ ! fails (for example if n, m are too large
344
+ ! for your computer)
345
+ !
346
+ !
347
+ ! SPECIAL CONDITIONS None
348
+ !
349
+ ! I/O None
350
+ !
351
+ ! PRECISION 64-bit double precision
352
+ !
353
+ ! REQUIRED files type_FishpackWorkspace.f90, genbun.f90, type_CyclicReductionUtility.f9090
354
+ !
355
+ ! HISTORY * Written by Roland Sweet at NCAR in the late
356
+ ! 1970's. released on NCAR's public software
357
+ ! libraries in January 1980.
358
+ ! * Revised in June 2004 by John Adams using
359
+ ! Fortran 90 dynamically allocated workspace.
360
+ !
361
+ ! PORTABILITY Fortran 2008
362
+ !
363
+ ! ALGORITHM The routine defines the finite difference
364
+ ! equations, incorporates boundary data, and
365
+ ! adjusts the right side of singular systems
366
+ ! and then calls genbun to solve the system.
367
+ !
368
+ ! TIMING For large m and n, the operation count
369
+ ! is roughly proportional to
370
+ !
371
+ ! m*n*(log2(n)
372
+ !
373
+ ! but also depends on input parameters nbdcnd
374
+ ! and mbdcnd.
375
+ !
376
+ ! ACCURACY The solution process employed results in a loss
377
+ ! of no more than three significant digits for n
378
+ ! and m as large as 64. more details about
379
+ ! accuracy can be found in the documentation for
380
+ ! subroutine genbun which is the routine that
381
+ ! solves the finite difference equations.
382
+ !
383
+ ! REFERENCES P. N. Swarztrauber, "The direct solution of
384
+ ! the discrete poisson equation on the surface of
385
+ ! a sphere", S.I.A.M. J. Numer. Anal., 15(1974),
386
+ ! pp 212-215.
387
+ !
388
+ ! Swarztrauber, P. and R. Sweet, "Efficient
389
+ ! FORTRAN subprograms for the solution of
390
+ ! elliptic equations", NCAR TN/IA-109, July,
391
+ ! 1975, 138 pp.
392
+ !
393
+ submodule(centered_helmholtz_solvers) centered_spherical_solver
394
+
395
+
396
+ ! Parameters confined to the submodule
397
+
398
+ integer(ip), parameter :: IIWK = 7 ! Size for workspace_indices
399
+
400
+
401
+ contains
402
+
403
+ module subroutine hwsssp(ts, tf, m, mbdcnd, bdts, bdtf, ps, pf, n, nbdcnd, &
404
+ bdps, bdpf, elmbda, f, idimf, pertrb, ierror)
405
+
406
+ ! Dummy arguments
407
+
408
+ integer(ip), intent(in) :: m
409
+ integer(ip), intent(in) :: mbdcnd
410
+ integer(ip), intent(in) :: n
411
+ integer(ip), intent(in) :: nbdcnd
412
+ integer(ip), intent(in) :: idimf
413
+ integer(ip), intent(out) :: ierror
414
+ real(wp), intent(in) :: ts
415
+ real(wp), intent(in) :: tf
416
+ real(wp), intent(in) :: ps
417
+ real(wp), intent(in) :: pf
418
+ real(wp), intent(in) :: elmbda
419
+ real(wp), intent(out) :: pertrb
420
+ real(wp), intent(in) :: bdts(:)
421
+ real(wp), intent(in) :: bdtf(:)
422
+ real(wp), intent(in) :: bdps(:)
423
+ real(wp), intent(in) :: bdpf(:)
424
+ real(wp), intent(inout) :: f(:,:)
425
+
426
+ ! Local variables
427
+ type(FishpackWorkspace) :: workspace
428
+
429
+ ! Check input arguments
430
+ call hwsssp_check_input_arguments(ts, tf, m, mbdcnd, ps, pf, n, &
431
+ nbdcnd, elmbda, idimf, ierror)
432
+
433
+ ! Check error flag
434
+ if (ierror /= 0) return
435
+
436
+ ! Allocate memory
437
+ call hwsssp_initialize_workspace(n, m, workspace)
438
+
439
+ ! Solve system
440
+ associate( &
441
+ indx => workspace%workspace_indices, &
442
+ rew => workspace%real_workspace &
443
+ )
444
+ associate( &
445
+ am => rew(indx(1):), &
446
+ bm => rew(indx(2):), &
447
+ cm => rew(indx(3):), &
448
+ sn => rew(indx(4):), &
449
+ ss => rew(indx(5):), &
450
+ sint => rew(indx(6):), &
451
+ d => rew(indx(7):) &
452
+ )
453
+ call hwsssp_lower_routine(ts, tf, m, mbdcnd, bdts, bdtf, ps, pf, n, nbdcnd, &
454
+ bdps, bdpf, elmbda, f, idimf, pertrb, am, bm, cm, sn, ss, &
455
+ sint, d, ierror)
456
+ end associate
457
+ end associate
458
+
459
+ ! Release memory
460
+ call workspace%destroy()
461
+
462
+ end subroutine hwsssp
463
+
464
+ subroutine hwsssp_check_input_arguments(ts, tf, m, mbdcnd, ps, pf, n, &
465
+ nbdcnd, elmbda, idimf, ierror)
466
+
467
+ ! Dummy arguments
468
+ integer(ip), intent(in) :: m
469
+ integer(ip), intent(in) :: mbdcnd
470
+ integer(ip), intent(in) :: n
471
+ integer(ip), intent(in) :: nbdcnd
472
+ integer(ip), intent(in) :: idimf
473
+ integer(ip), intent(out) :: ierror
474
+ real(wp), intent(in) :: elmbda
475
+ real(wp), intent(in) :: ts
476
+ real(wp), intent(in) :: tf
477
+ real(wp), intent(in) :: ps
478
+ real(wp), intent(in) :: pf
479
+
480
+ if (ts < ZERO .or. tf > PI) then
481
+ ierror = 1
482
+ else if (ts >= tf) then
483
+ ierror = 2
484
+ else if (mbdcnd < 1 .or. mbdcnd > 9) then
485
+ ierror = 3
486
+ else if (ps < ZERO .or. pf > TWO_PI) then
487
+ ierror = 4
488
+ else if (ps >= pf) then
489
+ ierror = 5
490
+ else if (n < 5) then
491
+ ierror = 6
492
+ else if (m < 5) then
493
+ ierror = 7
494
+ else if (nbdcnd < 0 .or. nbdcnd > 4) then
495
+ ierror = 8
496
+ else if (elmbda > ZERO) then
497
+ ierror = 9
498
+ else if (idimf < m + 1) then
499
+ ierror = 10
500
+ else if ((nbdcnd == 1 .or. nbdcnd == 2 .or. nbdcnd == 4) .and. mbdcnd >= 5) then
501
+ ierror = 11
502
+ else if (ts == ZERO .and. (mbdcnd==3.or. mbdcnd==4 .or. mbdcnd == 8)) then
503
+ ierror = 12
504
+ else if (tf == PI .and. (mbdcnd==2.or. mbdcnd == 3 .or. mbdcnd == 6)) then
505
+ ierror = 13
506
+ else if ((mbdcnd == 5.or.mbdcnd == 6.or.mbdcnd == 9) .and. ts /= ZERO) then
507
+ ierror = 14
508
+ else if (mbdcnd >= 7 .and. tf /= PI) then
509
+ ierror = 15
510
+ else
511
+ ierror = 0
512
+ end if
513
+
514
+ end subroutine hwsssp_check_input_arguments
515
+
516
+ subroutine hwsssp_initialize_workspace(n, m, workspace)
517
+
518
+ ! Dummy arguments
519
+ integer(ip), intent(in) :: n
520
+ integer(ip), intent(in) :: m
521
+ class(FishpackWorkspace), intent(out) :: workspace
522
+
523
+ ! Local variables
524
+ integer(ip) :: irwk, icwk
525
+
526
+ ! Compute workspace lengths for hwsssp
527
+ irwk = 4 * (n + 1) &
528
+ + (16 + int(log(real(n+1,kind=wp))/log(TWO), kind=ip)) &
529
+ * (m + 1)
530
+ icwk = 0
531
+
532
+ ! Allocate memory
533
+ call workspace%create(irwk, icwk, IIWK)
534
+
535
+ ! Set workspace indices
536
+ workspace%workspace_indices = hwsssp_get_workspace_indices(m)
537
+
538
+ end subroutine hwsssp_initialize_workspace
539
+
540
+ pure function hwsssp_get_workspace_indices(m) &
541
+ result (return_value)
542
+
543
+ ! Dummy arguments
544
+ integer(ip), intent(in) :: m
545
+ integer(ip) :: return_value(IIWK)
546
+
547
+ associate( indx => return_value)
548
+ indx(1) = 1
549
+ indx(2) = m+2
550
+ indx(3) = 2*m+3
551
+ indx(4) = 3*m+4
552
+ indx(5) = 4*m+5
553
+ indx(6) = 5*m+6
554
+ indx(7) = 6*m+7
555
+ end associate
556
+
557
+ end function hwsssp_get_workspace_indices
558
+
559
+ subroutine hwsssp_lower_routine(ts, tf, m, mbdcnd, bdts, bdtf, ps, pf, n, nbdcnd, &
560
+ bdps, bdpf, elmbda, f, idimf, pertrb, am, bm, cm, sn, ss, &
561
+ sint, d, error_flag)
562
+
563
+ ! Dummy arguments
564
+ integer(ip), intent(in) :: m
565
+ integer(ip), intent(in) :: mbdcnd
566
+ integer(ip), intent(in) :: n
567
+ integer(ip), intent(in) :: nbdcnd
568
+ integer(ip), intent(in) :: idimf
569
+ real(wp), intent(in) :: ts
570
+ real(wp), intent(in) :: tf
571
+ real(wp), intent(in) :: ps
572
+ real(wp), intent(in) :: pf
573
+ real(wp), intent(in) :: elmbda
574
+ real(wp), intent(out) :: pertrb
575
+ real(wp), intent(in) :: bdts(:)
576
+ real(wp), intent(in) :: bdtf(:)
577
+ real(wp), intent(in) :: bdps(:)
578
+ real(wp), intent(in) :: bdpf(:)
579
+ real(wp), intent(inout) :: f(:,:)
580
+ real(wp), intent(out) :: am(:)
581
+ real(wp), intent(out) :: bm(:)
582
+ real(wp), intent(out) :: cm(:)
583
+ real(wp), intent(out) :: sn(:)
584
+ real(wp), intent(out) :: ss(:)
585
+ real(wp), intent(out) :: sint(:)
586
+ real(wp), intent(out) :: d(:)
587
+ integer(ip), intent(out) :: error_flag
588
+
589
+ ! Local variables
590
+ integer(ip) :: mp1, np1, i, inp, isp, mbr, its, itf, itsp, itfm, munk
591
+ integer(ip) :: iid, ii, nbr, jps, jpf, jpsp, jpfm, nunk, ising
592
+ real(wp) :: fn, fm, dth, half_dth, two_dth, dphi, two_dphi
593
+ real(wp) :: dphi2, edp2, dth2, cp, wpp, fim1, theta, t1, at, ct, wts, wtf
594
+ real(wp) :: wps, wpf, fjj, cf, summation, sum1, hne, yhld, sum2, dfn, dnn, dsn
595
+ real(wp) :: cnp, hld, dfs, dss, dns, csp, rtn, rts, den
596
+ type(CenteredCyclicReductionUtility) :: util
597
+
598
+ mp1 = m + 1
599
+ np1 = n + 1
600
+ fn = n
601
+ fm = m
602
+ dth = (tf - ts)/fm
603
+ half_dth = dth/2
604
+ two_dth = TWO * dth
605
+ dphi = (pf - ps)/fn
606
+ two_dphi = TWO * dphi
607
+ dphi2 = dphi**2
608
+ edp2 = elmbda*dphi2
609
+ dth2 = dth**2
610
+ cp = 4.0_wp/(fn*dth2)
611
+ wpp = fn*sin(half_dth)/4
612
+
613
+ ! Initialize constants
614
+ dfn = ZERO
615
+ dnn = ZERO
616
+ dsn = ZERO
617
+
618
+ do i = 1, mp1
619
+ fim1 = i - 1
620
+ theta = fim1*dth + ts
621
+ sint(i) = sin(theta)
622
+
623
+ if (sint(i) == ZERO) cycle
624
+
625
+ t1 = ONE/(dth2*sint(i))
626
+ am(i) = t1*sin(theta - half_dth)
627
+ cm(i) = t1*sin(theta + half_dth)
628
+ bm(i) = (-am(i)) - cm(i) + elmbda
629
+ end do
630
+ inp = 0
631
+ isp = 0
632
+ !
633
+ ! boundary condition at theta=ts
634
+ !
635
+ mbr = mbdcnd + 1
636
+ select case (mbr)
637
+ case (1)
638
+ its = 1
639
+ case (2:3, 8)
640
+ at = am(2)
641
+ its = 2
642
+ case (4:5, 9)
643
+ at = am(1)
644
+ its = 1
645
+ cm(1) = am(1) + cm(1)
646
+ case (6:7, 10)
647
+ at = am(2)
648
+ inp = 1
649
+ its = 2
650
+ end select
651
+
652
+ !
653
+ ! boundary condition theta=tf
654
+ !
655
+ select case (mbr)
656
+ case (1)
657
+ itf = m
658
+ case (2, 5:6)
659
+ ct = cm(m)
660
+ itf = m
661
+ case (3:4, 7)
662
+ ct = cm(m+1)
663
+ am(m+1) = am(m+1) + cm(m+1)
664
+ itf = m + 1
665
+ case (8:10)
666
+ itf = m
667
+ isp = 1
668
+ ct = cm(m)
669
+ end select
670
+
671
+ !
672
+ ! compute homogeneous solution with solution at pole equal to one
673
+ !
674
+ itsp = its + 1
675
+ itfm = itf - 1
676
+ wts = sint(its+1)*am(its+1)/cm(its)
677
+ wtf = sint(itf-1)*cm(itf-1)/am(itf)
678
+ munk = itf - its + 1
679
+
680
+ if (isp > 0) then
681
+ d(its) = cm(its)/bm(its)
682
+ do i = itsp, m
683
+ d(i) = cm(i)/(bm(i)-am(i)*d(i-1))
684
+ end do
685
+ ss(m) = -d(m)
686
+ iid = m - its
687
+ do ii = 1, iid
688
+ i = m - ii
689
+ ss(i) = -d(i)*ss(i+1)
690
+ end do
691
+ ss(m+1) = ONE
692
+ end if
693
+
694
+ if (inp > 0) then
695
+ sn(1) = ONE
696
+ d(itf) = am(itf)/bm(itf)
697
+ iid = itf - 2
698
+ do ii = 1, iid
699
+ i = itf - ii
700
+ d(i) = am(i)/(bm(i)-cm(i)*d(i+1))
701
+ end do
702
+ sn(2) = -d(2)
703
+ do i = 3, itf
704
+ sn(i) = -d(i)*sn(i-1)
705
+ end do
706
+ end if
707
+ !
708
+ ! boundary conditions at phi=ps
709
+ !
710
+ nbr = nbdcnd + 1
711
+ wps = ONE
712
+ wpf = ONE
713
+ select case (nbr)
714
+ case default
715
+ jps = 1
716
+ case (2:3)
717
+ jps = 2
718
+ case (4:5)
719
+ jps = 1
720
+ wps = HALF
721
+ end select
722
+ !
723
+ ! boundary condition at phi=pf
724
+ !
725
+ select case (nbr)
726
+ case (1)
727
+ jpf = n
728
+ case (2, 5)
729
+ jpf = n
730
+ case (3:4)
731
+ wpf = HALF
732
+ jpf = n + 1
733
+ end select
734
+
735
+ jpsp = jps + 1
736
+ jpfm = jpf - 1
737
+ nunk = jpf - jps + 1
738
+ fjj = jpfm - jpsp + 1
739
+ !
740
+ ! scale coefficients for subroutine genbun
741
+ !
742
+ do i = its, itf
743
+ cf = dphi2*sint(i)*sint(i)
744
+ am(i) = cf*am(i)
745
+ bm(i) = cf*bm(i)
746
+ cm(i) = cf*cm(i)
747
+ end do
748
+
749
+ am(its) = ZERO
750
+ cm(itf) = ZERO
751
+ ising = 0
752
+
753
+ select case (mbr)
754
+ case (1, 4, 7, 9:10)
755
+ select case (nbr)
756
+ case (1, 4)
757
+ if (elmbda >= ZERO) then
758
+ ising = 1
759
+ summation = wts*wps + wts*wpf + wtf*wps + wtf*wpf
760
+
761
+ if (inp > 0) summation = summation + wpp
762
+
763
+ if (isp > 0) summation = summation + wpp
764
+
765
+ sum1 = sum(sint(itsp:itfm))
766
+ summation = summation + fjj*(sum1 + wts + wtf)
767
+ summation = summation + (wps + wpf)*sum1
768
+ hne = summation
769
+ end if
770
+ end select
771
+ end select
772
+
773
+ select case (mbr)
774
+ case (2:3, 8)
775
+ f(2,jps:jpf) = f(2,jps:jpf) - at*f(1,jps:jpf)
776
+ case (4:5, 9)
777
+ f(1,jps:jpf) = f(1,jps:jpf) + two_dth*bdts(jps:jpf)*at
778
+ case (6:7, 10)
779
+ if (nbdcnd == 3) then
780
+ yhld = f(1,jps) - 4.0_wp/(fn*dphi*dth2)*(bdpf(2)-bdps(2))
781
+ f(1,:np1) = yhld
782
+ end if
783
+ end select
784
+
785
+ select case (mbr)
786
+ case (2, 5:6)
787
+ f(m,jps:jpf) = f(m,jps:jpf) - ct*f(m+1,jps:jpf)
788
+ case (3:4, 7)
789
+ f(m+1,jps:jpf) = f(m+1,jps:jpf) - two_dth*bdtf(jps:jpf)*ct
790
+ case (8:10)
791
+ if (nbdcnd == 3) then
792
+ yhld = f(m+1,jps) - 4.0_wp/(fn*dphi*dth2)*(bdpf(m)-bdps(m))
793
+ f(m+1,:np1) = yhld
794
+ end if
795
+ end select
796
+
797
+ select case (nbr)
798
+ case (2:3)
799
+ f(its:itf,2) = f(its:itf,2) &
800
+ - f(its:itf,1)/(dphi2*sint(its:itf)*sint(its:itf))
801
+ case (4:5)
802
+ f(its:itf,1) = f(its:itf,1) &
803
+ + two_dphi*bdps(its:itf)/(dphi2*sint(its:itf)*sint(its:itf))
804
+ end select
805
+
806
+ select case (nbr)
807
+ case (2, 5)
808
+ f(its:itf,n) = f(its:itf,n) &
809
+ - f(its:itf,n+1)/(dphi2*sint(its:itf)*sint(its:itf))
810
+ case (3:4)
811
+ f(its:itf,n+1) = f(its:itf,n+1) &
812
+ - two_dphi*bdpf(its:itf)/(dphi2*sint(its:itf)*sint(its:itf))
813
+ end select
814
+
815
+ pertrb = ZERO
816
+
817
+ if (ising /= 0) then
818
+ summation = &
819
+ wts*wps*f(its,jps) + wts*wpf*f(its,jpf) &
820
+ + wtf*wps*f(itf,jps) + wtf*wpf*f(itf,jpf)
821
+
822
+ if (inp > 0) summation = summation + wpp*f(1,jps)
823
+ if (isp > 0) summation = summation + wpp*f(m+1,jps)
824
+
825
+ do i = itsp, itfm
826
+ summation = summation + sint(i)*sum(f(i,jpsp:jpfm))
827
+ end do
828
+
829
+ sum1 = sum(f(its,jpsp:jpfm))
830
+ sum2 = sum(f(itf,jpsp:jpfm))
831
+ summation = summation + wts*sum1 + wtf*sum2
832
+ sum1 = ZERO
833
+ sum2 = ZERO
834
+ sum1 = dot_product(sint(itsp:itfm),f(itsp:itfm,jps))
835
+ sum2 = dot_product(sint(itsp:itfm),f(itsp:itfm,jpf))
836
+ summation = summation + wps*sum1 + wpf*sum2
837
+ pertrb = summation/hne
838
+ f(:mp1,:np1) = f(:mp1,:np1) - pertrb
839
+ end if
840
+
841
+ ! scale right side for subroutine genbun_lower_routine
842
+ do i = its, itf
843
+ cf = dphi2*sint(i)*sint(i)
844
+ f(i,jps:jpf) = cf*f(i,jps:jpf)
845
+ end do
846
+
847
+ call_arguments: associate( &
848
+ a_arg => am(its:), &
849
+ b_arg => bm(its:), &
850
+ c_arg => cm(its:), &
851
+ y_arg => f(its:,jps:) &
852
+ )
853
+
854
+ ! Invoke genbun_lower_routine solver
855
+ call util%genbun_lower_routine(nbdcnd, nunk, 1, munk, a_arg, b_arg, c_arg, &
856
+ idimf, y_arg, error_flag, d)
857
+ end associate call_arguments
858
+
859
+ ! Check error flag
860
+ if (error_flag /= 0) then
861
+ error stop 'fishpack library: genbun_lower_routine call failed in hwsssp_lower_routine'
862
+ end if
863
+
864
+ if (ising > 0 .and. inp > 0 .and. isp <= 0) then
865
+ f(1,:np1) = ZERO
866
+ else if (isp > 0) then
867
+ f(m+1,:np1) = ZERO
868
+ else if (inp > 0) then
869
+
870
+ summation = wps*f(its,jps) + wpf*f(its,jpf) + sum(f(its,jpsp:jpfm))
871
+ dfn = cp*summation
872
+ dnn = cp*((wps + wpf + fjj)*(sn(2)-ONE)) + elmbda
873
+ dsn = cp*(wps + wpf + fjj)*sn(m)
874
+
875
+ if (isp > 0) then
876
+ cnp = (f(1,1)-dfn)/dnn
877
+ do i = its, itf
878
+ hld = cnp*sn(i)
879
+ f(i,jps:jpf) = f(i,jps:jpf) + hld
880
+ end do
881
+ f(1,:np1) = cnp
882
+ end if
883
+ else
884
+ summation = wps*f(itf,jps) + wpf*f(itf,jpf) + sum(f(itf,jpsp:jpfm))
885
+ dfs = cp*summation
886
+ dss = cp*((wps + wpf + fjj)*(ss(m)-ONE)) + elmbda
887
+ dns = cp*(wps + wpf + fjj)*ss(2)
888
+
889
+ if (inp <= 0) then
890
+ csp = (f(m+1,1)-dfs)/dss
891
+ do i = its, itf
892
+ hld = csp*ss(i)
893
+ f(i,jps:jpf) = f(i,jps:jpf) + hld
894
+ end do
895
+ f(m+1,:np1) = csp
896
+ else
897
+ rtn = f(1,1) - dfn
898
+ rts = f(m+1,1) - dfs
899
+ if (ising > 0) then
900
+ csp = ZERO
901
+ cnp = rtn/dnn
902
+ else
903
+ if (abs(dnn) - abs(dsn) > ZERO) then
904
+ den = dss - dns*dsn/dnn
905
+ rts = rts - rtn*dsn/dnn
906
+ csp = rts/den
907
+ cnp = (rtn - csp*dns)/dnn
908
+ else
909
+ den = dns - dss*dnn/dsn
910
+ rtn = rtn - rts*dnn/dsn
911
+ csp = rtn/den
912
+ cnp = (rts - dss*csp)/dsn
913
+ end if
914
+ end if
915
+ do i = its, itf
916
+ hld = cnp*sn(i) + csp*ss(i)
917
+ f(i,jps:jpf) = f(i,jps:jpf) + hld
918
+ end do
919
+ f(1,:np1) = cnp
920
+ f(m+1,:np1) = csp
921
+ end if
922
+ end if
923
+
924
+ if (nbdcnd == 0) f(:mp1,jpf+1) = f(:mp1,jps)
925
+
926
+ end subroutine hwsssp_lower_routine
927
+
928
+ end submodule centered_spherical_solver