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.
- PyFishPack/__init__.py +105 -0
- PyFishPack/__pycache__/__init__.cpython-39.pyc +0 -0
- PyFishPack/__pycache__/apps.cpython-39.pyc +0 -0
- PyFishPack/_dummy.c +23 -0
- PyFishPack/_dummy.cp39-win_amd64.pyd +0 -0
- PyFishPack/apps.py +3640 -0
- PyFishPack/fishpack.cp39-win_amd64.dll.a +0 -0
- PyFishPack/fishpack.cp39-win_amd64.pyd +0 -0
- PyFishPack/meson.build +213 -0
- PyFishPack/src/archive/f77/Makefile +19 -0
- PyFishPack/src/archive/f77/blktri.f +1404 -0
- PyFishPack/src/archive/f77/cblktri.f +1414 -0
- PyFishPack/src/archive/f77/cmgnbn.f +1592 -0
- PyFishPack/src/archive/f77/comf.f +186 -0
- PyFishPack/src/archive/f77/fftpack.f +2968 -0
- PyFishPack/src/archive/f77/genbun.f +1335 -0
- PyFishPack/src/archive/f77/gnbnaux.f +314 -0
- PyFishPack/src/archive/f77/hstcrt.f +443 -0
- PyFishPack/src/archive/f77/hstcsp.f +683 -0
- PyFishPack/src/archive/f77/hstcyl.f +485 -0
- PyFishPack/src/archive/f77/hstplr.f +538 -0
- PyFishPack/src/archive/f77/hstssp.f +634 -0
- PyFishPack/src/archive/f77/hw3crt.f +687 -0
- PyFishPack/src/archive/f77/hwscrt.f +512 -0
- PyFishPack/src/archive/f77/hwscsp.f +728 -0
- PyFishPack/src/archive/f77/hwscyl.f +538 -0
- PyFishPack/src/archive/f77/hwsplr.f +602 -0
- PyFishPack/src/archive/f77/hwsssp.f +780 -0
- PyFishPack/src/archive/f77/pois3d.f +550 -0
- PyFishPack/src/archive/f77/poistg.f +875 -0
- PyFishPack/src/archive/f77/sepaux.f +361 -0
- PyFishPack/src/archive/f77/sepeli.f +1029 -0
- PyFishPack/src/archive/f77/sepx4.f +958 -0
- PyFishPack/src/centered_axisymmetric_spherical_solver.f90 +1002 -0
- PyFishPack/src/centered_cartesian_helmholtz_solver_3d.f90 +819 -0
- PyFishPack/src/centered_cartesian_solver.f90 +583 -0
- PyFishPack/src/centered_cylindrical_solver.f90 +634 -0
- PyFishPack/src/centered_helmholtz_solvers.f90 +156 -0
- PyFishPack/src/centered_polar_solver.f90 +746 -0
- PyFishPack/src/centered_real_linear_systems_solver.f90 +280 -0
- PyFishPack/src/centered_spherical_solver.f90 +928 -0
- PyFishPack/src/complex_block_tridiagonal_linear_systems_solver.f90 +1947 -0
- PyFishPack/src/complex_linear_systems_solver.f90 +1787 -0
- PyFishPack/src/fftpack_c_api.f90 +86 -0
- PyFishPack/src/fishpack.f90 +191 -0
- PyFishPack/src/fishpack.pyf +504 -0
- PyFishPack/src/fishpack_c_api.f90 +365 -0
- PyFishPack/src/fishpack_original.pyf +2119 -0
- PyFishPack/src/fishpack_precision.f90 +53 -0
- PyFishPack/src/general_linear_systems_solver_3d.f90 +296 -0
- PyFishPack/src/iterative_solvers.f90 +969 -0
- PyFishPack/src/main.f90 +10 -0
- PyFishPack/src/pyfishpack_module.c +1302 -0
- PyFishPack/src/real_block_tridiagonal_linear_systems_solver.f90 +319 -0
- PyFishPack/src/sepeli.f90 +1454 -0
- PyFishPack/src/sepx4.f90 +1338 -0
- PyFishPack/src/staggered_axisymmetric_spherical_solver.f90 +908 -0
- PyFishPack/src/staggered_cartesian_solver.f90 +553 -0
- PyFishPack/src/staggered_cylindrical_solver.f90 +630 -0
- PyFishPack/src/staggered_helmholtz_solvers.f90 +172 -0
- PyFishPack/src/staggered_polar_solver.f90 +651 -0
- PyFishPack/src/staggered_real_linear_systems_solver.f90 +258 -0
- PyFishPack/src/staggered_spherical_solver.f90 +758 -0
- PyFishPack/src/three_dimensional_solvers.f90 +602 -0
- PyFishPack/src/type_CenteredCyclicReductionUtility.f90 +1714 -0
- PyFishPack/src/type_CyclicReductionUtility.f90 +472 -0
- PyFishPack/src/type_FishpackWorkspace.f90 +290 -0
- PyFishPack/src/type_GeneralizedCyclicReductionUtility.f90 +1980 -0
- PyFishPack/src/type_PeriodicFastFourierTransform.f90 +3789 -0
- PyFishPack/src/type_SepAux.f90 +586 -0
- PyFishPack/src/type_StaggeredCyclicReductionUtility.f90 +893 -0
- pyfishpack-0.1.0.dist-info/DELVEWHEEL +2 -0
- pyfishpack-0.1.0.dist-info/METADATA +81 -0
- pyfishpack-0.1.0.dist-info/RECORD +82 -0
- pyfishpack-0.1.0.dist-info/WHEEL +5 -0
- pyfishpack-0.1.0.dist-info/licenses/LICENSE +21 -0
- pyfishpack-0.1.0.dist-info/top_level.txt +1 -0
- pyfishpack.libs/.load-order-pyfishpack-0.1.0 +4 -0
- pyfishpack.libs/libgcc_s_seh-1-25d59ccffa1a9009644065b069829e07.dll +0 -0
- pyfishpack.libs/libgfortran-5-08f2195cfa0d823e13371c5c3186a82a.dll +0 -0
- pyfishpack.libs/libquadmath-0-c5abb9113f1ee64b87a889958e4b7418.dll +0 -0
- pyfishpack.libs/libwinpthread-1-83908d14abfafb8b3bfa38cf51ecee56.dll +0 -0
|
@@ -0,0 +1,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
|
+
!
|