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.
- PyFishPack/__init__.py +86 -0
- PyFishPack/__pycache__/__init__.cpython-313.pyc +0 -0
- PyFishPack/__pycache__/apps.cpython-313.pyc +0 -0
- PyFishPack/_dummy.c +23 -0
- PyFishPack/_dummy.cp313-win_amd64.pyd +0 -0
- PyFishPack/apps.py +3640 -0
- PyFishPack/fishpack.cp313-win_amd64.dll.a +0 -0
- PyFishPack/fishpack.cp313-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 +81 -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/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,1002 @@
|
|
|
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
|
+
|
|
35
|
+
submodule(centered_helmholtz_solvers) centered_axisymmetric_spherical_solver
|
|
36
|
+
|
|
37
|
+
! Parameters confined to the submodule
|
|
38
|
+
integer(ip), parameter :: SIZE_OF_WORKSPACE_INDICES = 10
|
|
39
|
+
|
|
40
|
+
contains
|
|
41
|
+
|
|
42
|
+
! SUBROUTINE hwscsp(intl, ts, tf, m, mbdcnd, bdts, bdtf, rs, rf, n, nbdcnd, &
|
|
43
|
+
! bdrs, bdrf, elmbda, f, idimf, pertrb, ierror, w)
|
|
44
|
+
!
|
|
45
|
+
!
|
|
46
|
+
! DIMENSION OF bdts(n+1), bdtf(n+1), bdrs(m+1), bdrf(m+1),
|
|
47
|
+
! ARGUMENTS f(idimf, n+1)
|
|
48
|
+
!
|
|
49
|
+
!
|
|
50
|
+
! PURPOSE Solves a finite difference approximation
|
|
51
|
+
! to the modified helmholtz equation in
|
|
52
|
+
! spherical coordinates assuming axisymmetry
|
|
53
|
+
! (no dependence on longitude). the equation
|
|
54
|
+
! is
|
|
55
|
+
!
|
|
56
|
+
! (1/r**2)(d/dr)((r**2)(d/dr)u) +
|
|
57
|
+
!
|
|
58
|
+
! (1/(r**2)sin(theta))(d/dtheta)
|
|
59
|
+
!
|
|
60
|
+
! (sin(theta)(d/dtheta)u) +
|
|
61
|
+
!
|
|
62
|
+
! (lambda/(rsin(theta))**2)u = f(theta, r).
|
|
63
|
+
!
|
|
64
|
+
! this two dimensional modified helmholtz
|
|
65
|
+
! equation results from the fourier transform
|
|
66
|
+
! of the three dimensional poisson equation.
|
|
67
|
+
!
|
|
68
|
+
! USAGE call hwscsp(intl, ts, tf, m, mbdcnd, bdts, bdtf,
|
|
69
|
+
! rs, rf, n, nbdcnd, bdrs, bdrf, elmbda,
|
|
70
|
+
! f, idimf, pertrb, ierror, w)
|
|
71
|
+
!
|
|
72
|
+
! ARGUMENTS
|
|
73
|
+
! ON INPUT intl
|
|
74
|
+
! = 0 on initial entry to hwscsp or if any
|
|
75
|
+
! of the arguments rs, rf, n, nbdcnd
|
|
76
|
+
! are changed from a previous call.
|
|
77
|
+
! = 1 if rs, rf, n, nbdcnd are all unchanged
|
|
78
|
+
! from previous call to hwscsp.
|
|
79
|
+
!
|
|
80
|
+
! note:
|
|
81
|
+
! a call with intl=0 takes approximately
|
|
82
|
+
! 1.5 times as much time as a call with
|
|
83
|
+
! intl = 1 . once a call with intl = 0
|
|
84
|
+
! has been made then subsequent solutions
|
|
85
|
+
! corresponding to different f, bdts, bdtf,
|
|
86
|
+
! bdrs, bdrf can be obtained faster with
|
|
87
|
+
! intl = 1 since initialization is not
|
|
88
|
+
! repeated.
|
|
89
|
+
!
|
|
90
|
+
! ts, tf
|
|
91
|
+
! the range of theta (colatitude), i.e.,
|
|
92
|
+
! ts <= theta <= tf. ts must be less
|
|
93
|
+
! than tf. ts and tf are in radians. a ts of
|
|
94
|
+
! zero corresponds to the north pole and a
|
|
95
|
+
! tf of pi corresponds to the south pole.
|
|
96
|
+
!
|
|
97
|
+
! **** important ****
|
|
98
|
+
!
|
|
99
|
+
! if tf is equal to pi then it must be
|
|
100
|
+
! computed using the statement
|
|
101
|
+
! tf = pi_mach(dum). this insures that tf
|
|
102
|
+
! in the user's program is equal to pi in
|
|
103
|
+
! this program which permits several tests
|
|
104
|
+
! of the input parameters that otherwise
|
|
105
|
+
! would not be possible.
|
|
106
|
+
!
|
|
107
|
+
! m
|
|
108
|
+
! the number of panels into which the
|
|
109
|
+
! interval (ts, tf) is subdivided.
|
|
110
|
+
! hence, there will be m+1 grid points
|
|
111
|
+
! in the theta-direction given by
|
|
112
|
+
! theta(k) = (i-1)dtheta+ts for
|
|
113
|
+
! i = 1, 2, ..., m+1, where dtheta = (tf-ts)/m
|
|
114
|
+
! is the panel width.
|
|
115
|
+
!
|
|
116
|
+
! mbdcnd
|
|
117
|
+
! indicates the type of boundary condition
|
|
118
|
+
! at theta = ts and theta = tf.
|
|
119
|
+
!
|
|
120
|
+
! = 1 if the solution is specified at
|
|
121
|
+
! theta = ts and theta = tf.
|
|
122
|
+
! = 2 if the solution is specified at
|
|
123
|
+
! theta = ts and the derivative of the
|
|
124
|
+
! solution with respect to theta is
|
|
125
|
+
! specified at theta = tf
|
|
126
|
+
! (see note 2 below).
|
|
127
|
+
! = 3 if the derivative of the solution
|
|
128
|
+
! with respect to theta is specified
|
|
129
|
+
! at theta = ts and theta = tf
|
|
130
|
+
! (see notes 1, 2 below).
|
|
131
|
+
! = 4 if the derivative of the solution
|
|
132
|
+
! with respect to theta is specified
|
|
133
|
+
! at theta = ts (see note 1 below) and
|
|
134
|
+
! solution is specified at theta = tf.
|
|
135
|
+
! = 5 if the solution is unspecified at
|
|
136
|
+
! theta = ts = 0 and the solution is
|
|
137
|
+
! specified at theta = tf.
|
|
138
|
+
! = 6 if the solution is unspecified at
|
|
139
|
+
! theta = ts = 0 and the derivative
|
|
140
|
+
! of the solution with respect to theta
|
|
141
|
+
! is specified at theta = tf
|
|
142
|
+
! (see note 2 below).
|
|
143
|
+
! = 7 if the solution is specified at
|
|
144
|
+
! theta = ts and the solution is
|
|
145
|
+
! unspecified at theta = tf = pi.
|
|
146
|
+
! = 8 if the derivative of the solution
|
|
147
|
+
! with respect to theta is specified
|
|
148
|
+
! at theta = ts (see note 1 below)
|
|
149
|
+
! and the solution is unspecified at
|
|
150
|
+
! theta = tf = pi.
|
|
151
|
+
! = 9 if the solution is unspecified at
|
|
152
|
+
! theta = ts = 0 and theta = tf = pi.
|
|
153
|
+
!
|
|
154
|
+
! note 1:
|
|
155
|
+
! if ts = 0, do not use mbdcnd = 3, 4, or 8,
|
|
156
|
+
! but instead use mbdcnd = 5, 6, or 9 .
|
|
157
|
+
!
|
|
158
|
+
! note 2:
|
|
159
|
+
! if tf = pi, do not use mbdcnd = 2, 3, or 6,
|
|
160
|
+
! but instead use mbdcnd = 7, 8, or 9 .
|
|
161
|
+
!
|
|
162
|
+
! bdts
|
|
163
|
+
! a one-dimensional array of length n+1 that
|
|
164
|
+
! specifies the values of the derivative of
|
|
165
|
+
! the solution with respect to theta at
|
|
166
|
+
! theta = ts. when mbdcnd = 3, 4, or 8,
|
|
167
|
+
!
|
|
168
|
+
! bdts(j) = (d/dtheta)u(ts, r(j)),
|
|
169
|
+
! j = 1, 2, ..., n+1 .
|
|
170
|
+
!
|
|
171
|
+
! when mbdcnd has any other value, bdts is
|
|
172
|
+
! a dummy variable.
|
|
173
|
+
!
|
|
174
|
+
! bdtf
|
|
175
|
+
! a one-dimensional array of length n+1 that
|
|
176
|
+
! specifies the values of the derivative of
|
|
177
|
+
! the solution with respect to theta at
|
|
178
|
+
! theta = tf. when mbdcnd = 2, 3, or 6,
|
|
179
|
+
!
|
|
180
|
+
! bdtf(j) = (d/dtheta)u(tf, r(j)),
|
|
181
|
+
! j = 1, 2, ..., n+1 .
|
|
182
|
+
!
|
|
183
|
+
! when mbdcnd has any other value, bdtf is
|
|
184
|
+
! a dummy variable.
|
|
185
|
+
!
|
|
186
|
+
! rs, rf
|
|
187
|
+
! the range of r, i.e., rs <= r < rf.
|
|
188
|
+
! rs must be less than rf. rs must be
|
|
189
|
+
! non-negative.
|
|
190
|
+
!
|
|
191
|
+
! n
|
|
192
|
+
! the number of panels into which the
|
|
193
|
+
! interval (rs, rf) is subdivided.
|
|
194
|
+
! hence, there will be n+1 grid points in the
|
|
195
|
+
! r-direction given by r(j) = (j-1)dr+rs
|
|
196
|
+
! for j = 1, 2, ..., n+1, where dr = (rf-rs)/n
|
|
197
|
+
! is the panel width.
|
|
198
|
+
! n must be greater than 2
|
|
199
|
+
!
|
|
200
|
+
! nbdcnd
|
|
201
|
+
! indicates the type of boundary condition
|
|
202
|
+
! at r = rs and r = rf.
|
|
203
|
+
!
|
|
204
|
+
! = 1 if the solution is specified at
|
|
205
|
+
! r = rs and r = rf.
|
|
206
|
+
! = 2 if the solution is specified at
|
|
207
|
+
! r = rs and the derivative
|
|
208
|
+
! of the solution with respect to r
|
|
209
|
+
! is specified at r = rf.
|
|
210
|
+
! = 3 if the derivative of the solution
|
|
211
|
+
! with respect to r is specified at
|
|
212
|
+
! r = rs and r = rf.
|
|
213
|
+
! = 4 if the derivative of the solution
|
|
214
|
+
! with respect to r is specified at
|
|
215
|
+
! rs and the solution is specified at
|
|
216
|
+
! r = rf.
|
|
217
|
+
! = 5 if the solution is unspecified at
|
|
218
|
+
! r = rs = 0 (see note below) and the
|
|
219
|
+
! solution is specified at r = rf.
|
|
220
|
+
! = 6 if the solution is unspecified at
|
|
221
|
+
! r = rs = 0 (see note below) and the
|
|
222
|
+
! derivative of the solution with
|
|
223
|
+
! respect to r is specified at r = rf.
|
|
224
|
+
!
|
|
225
|
+
! note:
|
|
226
|
+
! nbdcnd = 5 or 6 cannot be used with
|
|
227
|
+
! mbdcnd = 1, 2, 4, 5, or 7. the former
|
|
228
|
+
! indicates that the solution is unspecified
|
|
229
|
+
! at r = 0, the latter indicates that the
|
|
230
|
+
! solution is specified).
|
|
231
|
+
! use instead nbdcnd = 1 or 2 .
|
|
232
|
+
!
|
|
233
|
+
! bdrs
|
|
234
|
+
! a one-dimensional array of length m+1 that
|
|
235
|
+
! specifies the values of the derivative of
|
|
236
|
+
! the solution with respect to r at r = rs.
|
|
237
|
+
!
|
|
238
|
+
! when nbdcnd = 3 or 4,
|
|
239
|
+
! bdrs(i) = (d/dr)u(theta(i), rs),
|
|
240
|
+
! i = 1, 2, ..., m+1 .
|
|
241
|
+
!
|
|
242
|
+
! when nbdcnd has any other value, bdrs is
|
|
243
|
+
! a dummy variable.
|
|
244
|
+
!
|
|
245
|
+
! bdrf
|
|
246
|
+
! a one-dimensional array of length m+1
|
|
247
|
+
! that specifies the values of the
|
|
248
|
+
! derivative of the solution with respect
|
|
249
|
+
! to r at r = rf.
|
|
250
|
+
!
|
|
251
|
+
! when nbdcnd = 2, 3, or 6,
|
|
252
|
+
! bdrf(i) = (d/dr)u(theta(i), rf),
|
|
253
|
+
! i = 1, 2, ..., m+1 .
|
|
254
|
+
!
|
|
255
|
+
! when nbdcnd has any other value, bdrf is
|
|
256
|
+
! a dummy variable.
|
|
257
|
+
!
|
|
258
|
+
! elmbda
|
|
259
|
+
! the constant lambda in the helmholtz
|
|
260
|
+
! equation. if lambda > 0, a solution
|
|
261
|
+
! may not exist. however, hwscsp will
|
|
262
|
+
! attempt to find a solution. if nbdcnd = 5
|
|
263
|
+
! or 6 or mbdcnd = 5, 6, 7, 8, or 9, elmbda
|
|
264
|
+
! must be zero.
|
|
265
|
+
!
|
|
266
|
+
! f
|
|
267
|
+
! a two-dimensional array, of dimension at
|
|
268
|
+
! least (m+1)*(n+1), specifying values of the
|
|
269
|
+
! right side of the helmholtz equation and
|
|
270
|
+
! boundary values (if any).
|
|
271
|
+
!
|
|
272
|
+
! on the interior, f is defined as follows:
|
|
273
|
+
! for i = 2, 3, ..., m and j = 2, 3, ..., n
|
|
274
|
+
! f(i, j) = f(theta(i), r(j)).
|
|
275
|
+
!
|
|
276
|
+
! on the boundaries, f is defined as follows:
|
|
277
|
+
! for j=1, 2, ..., n+1, i=1, 2, ..., m+1,
|
|
278
|
+
!
|
|
279
|
+
! mbdcnd f(1, j) f(m+1, j)
|
|
280
|
+
! ------ ---------- ----------
|
|
281
|
+
!
|
|
282
|
+
! 1 u(ts, r(j)) u(tf, r(j))
|
|
283
|
+
! 2 u(ts, r(j)) f(tf, r(j))
|
|
284
|
+
! 3 f(ts, r(j)) f(tf, r(j))
|
|
285
|
+
! 4 f(ts, r(j)) u(tf, r(j))
|
|
286
|
+
! 5 f(0, r(j)) u(tf, r(j))
|
|
287
|
+
! 6 f(0, r(j)) f(tf, r(j))
|
|
288
|
+
! 7 u(ts, r(j)) f(pi, r(j))
|
|
289
|
+
! 8 f(ts, r(j)) f(pi, r(j))
|
|
290
|
+
! 9 f(0, r(j)) f(pi, r(j))
|
|
291
|
+
!
|
|
292
|
+
! nbdcnd f(i, 1) f(i, n+1)
|
|
293
|
+
! ------ -------------- --------------
|
|
294
|
+
!
|
|
295
|
+
! 1 u(theta(i), rs) u(theta(i), rf)
|
|
296
|
+
! 2 u(theta(i), rs) f(theta(i), rf)
|
|
297
|
+
! 3 f(theta(i), rs) f(theta(i), rf)
|
|
298
|
+
! 4 f(theta(i), rs) u(theta(i), rf)
|
|
299
|
+
! 5 f(ts, 0) u(theta(i), rf)
|
|
300
|
+
! 6 f(ts, 0) f(theta(i), rf)
|
|
301
|
+
!
|
|
302
|
+
! note:
|
|
303
|
+
! if the table calls for both the solution
|
|
304
|
+
! u and the right side f at a corner then
|
|
305
|
+
! the solution must be specified.
|
|
306
|
+
!
|
|
307
|
+
! idimf
|
|
308
|
+
! the row (or first) dimension of the array
|
|
309
|
+
! f as it appears in the program calling
|
|
310
|
+
! hwscsp. this parameter is used to specify
|
|
311
|
+
! the variable dimension of f. idimf must
|
|
312
|
+
! be at least m+1 .
|
|
313
|
+
!
|
|
314
|
+
! w
|
|
315
|
+
! A FishpackWorkspace derived data type variable
|
|
316
|
+
! that must be declared by the user. the first
|
|
317
|
+
! two declarative statements in the user program
|
|
318
|
+
! calling sepeli must be:
|
|
319
|
+
!
|
|
320
|
+
! use type_fishpackworkspace
|
|
321
|
+
! type(fishpackworkspace) :: w
|
|
322
|
+
!
|
|
323
|
+
! The first statement makes the fishpack module
|
|
324
|
+
! defined in the file "type_FishpackWorkspace.f90" available to the
|
|
325
|
+
! user program calling hwscsp. The second statement
|
|
326
|
+
! declares a derived type variable (defined in
|
|
327
|
+
! the module "type_FishpackWorkspace.f90") which is used internally
|
|
328
|
+
! in hwscsp to dynamically allocate real and complex
|
|
329
|
+
! workspace used in solution. an error flag
|
|
330
|
+
! (ierror = 20) is set if the required workspace
|
|
331
|
+
! allocation fails (for example if n, m are too large)
|
|
332
|
+
! real and complex values are set in the components
|
|
333
|
+
! of w on a initial (intl=0) call to hwscsp. these
|
|
334
|
+
! must be preserved on non-initial calls (intl=1)
|
|
335
|
+
! to hwscsp. this eliminates redundant calculations
|
|
336
|
+
! and saves compute time.
|
|
337
|
+
! **** IMPORTANT! The user program calling hwscsp should
|
|
338
|
+
! include the statement:
|
|
339
|
+
!
|
|
340
|
+
! call w%destroy()
|
|
341
|
+
!
|
|
342
|
+
! after the final approximation is generated by
|
|
343
|
+
! hwscsp. The will deallocate the real and complex
|
|
344
|
+
! workspace of W. Failure to include this statement
|
|
345
|
+
! could result in serious memory leakage.
|
|
346
|
+
!
|
|
347
|
+
!
|
|
348
|
+
! ON OUTPUT f
|
|
349
|
+
! contains the solution u(i, j) of the finite
|
|
350
|
+
! difference approximation for the grid point
|
|
351
|
+
! (theta(i), r(j)), i = 1, 2, ..., m+1,
|
|
352
|
+
! j = 1, 2, ..., n+1 .
|
|
353
|
+
!
|
|
354
|
+
! pertrb
|
|
355
|
+
! if a combination of periodic or derivative
|
|
356
|
+
! boundary conditions is specified for a
|
|
357
|
+
! poisson equation (lambda = 0), a solution
|
|
358
|
+
! may not exist. pertrb is a constant,
|
|
359
|
+
! calculated and subtracted from f, which
|
|
360
|
+
! ensures that a solution exists. hwscsp
|
|
361
|
+
! then computes this solution, which is a
|
|
362
|
+
! least squares solution to the original
|
|
363
|
+
! approximation. this solution is not unique
|
|
364
|
+
! and is unnormalized. the value of pertrb
|
|
365
|
+
! should be small compared to the right side
|
|
366
|
+
! f. otherwise , a solution is obtained to
|
|
367
|
+
! an essentially different problem. this
|
|
368
|
+
! comparison should always be made to insure
|
|
369
|
+
! that a meaningful solution has been obtained.
|
|
370
|
+
!
|
|
371
|
+
! ierror
|
|
372
|
+
! an error flag that indicates invalid input
|
|
373
|
+
! parameters. except for numbers 0 and 10,
|
|
374
|
+
! a solution is not attempted.
|
|
375
|
+
!
|
|
376
|
+
! = 1 ts<0. or tf>pi
|
|
377
|
+
! = 2 ts>=tf
|
|
378
|
+
! = 3 m<5
|
|
379
|
+
! = 4 mbdcnd<1 or mbdcnd>9
|
|
380
|
+
! = 5 rs<0
|
|
381
|
+
! = 6 rs>=rf
|
|
382
|
+
! = 7 n<5
|
|
383
|
+
! = 8 nbdcnd<1 or nbdcnd>6
|
|
384
|
+
! = 9 elmbda>0
|
|
385
|
+
! = 10 idimf<m+1
|
|
386
|
+
! = 11 elmbda/=0 and mbdcnd>=5
|
|
387
|
+
! = 12 elmbda/=0 and nbdcnd equals 5 or 6
|
|
388
|
+
! = 13 mbdcnd equals 5, 6 or 9 and ts/=0
|
|
389
|
+
! = 14 mbdcnd>=7 and tf/=pi
|
|
390
|
+
! = 15 ts.eq.0 and mbdcnd equals 3, 4 or 8
|
|
391
|
+
! = 16 tf.eq.pi and mbdcnd equals 2, 3 or 6
|
|
392
|
+
! = 17 nbdcnd>=5 and rs/=0
|
|
393
|
+
! = 18 nbdcnd>=5 and mbdcnd equals 1, 2, 4, 5 or
|
|
394
|
+
! = 20 if the dynamic allocation of real and
|
|
395
|
+
! complex workspace in the derived type
|
|
396
|
+
! (fishpackworkspace) variable w fails (e.g.,
|
|
397
|
+
! if n, m are too large for the platform used)
|
|
398
|
+
!
|
|
399
|
+
! since this is the only means of indicating
|
|
400
|
+
! a possliby incorrect call to hwscsp, the
|
|
401
|
+
! user should test ierror after a call.
|
|
402
|
+
!
|
|
403
|
+
! w
|
|
404
|
+
! the derived type(fishpackworkspace) variable w
|
|
405
|
+
! contains real and complex values that must not
|
|
406
|
+
! be destroyed if hwscsp is called again with
|
|
407
|
+
! intl=1.
|
|
408
|
+
!
|
|
409
|
+
!
|
|
410
|
+
! HISTORY Written by Roland Sweet AT NCAR in the late
|
|
411
|
+
! 1970'S. Released on NCAR's public software
|
|
412
|
+
! libraries in January 1980. Revised by John
|
|
413
|
+
! Adams in June 2004 using Fortran 90 dynamically
|
|
414
|
+
! allocated workspace and derived datat types
|
|
415
|
+
! to eliminate mixed mode conflicts in the earlier
|
|
416
|
+
! versions.
|
|
417
|
+
!
|
|
418
|
+
!
|
|
419
|
+
! ALGORITHM The routine defines the finite difference
|
|
420
|
+
! equations, incorporates boundary data, and
|
|
421
|
+
! adjusts the right side of singular systems
|
|
422
|
+
! and then calls blktri to solve the system.
|
|
423
|
+
!
|
|
424
|
+
! REFERENCES Swarztrauber, P. and R. Sweet, "Efficient
|
|
425
|
+
! FORTRAN subprograms for the solution of
|
|
426
|
+
! elliptic equations"
|
|
427
|
+
! NCAR TN/IA-109, July, 1975, 138 pp.
|
|
428
|
+
!
|
|
429
|
+
module subroutine hwscsp(intl, ts, tf, m, mbdcnd, bdts, bdtf, rs, rf, n, &
|
|
430
|
+
nbdcnd, bdrs, bdrf, elmbda, f, idimf, pertrb, ierror, workspace)
|
|
431
|
+
|
|
432
|
+
! Dummy arguments
|
|
433
|
+
integer(ip), intent(in) :: intl
|
|
434
|
+
integer(ip), intent(in) :: m
|
|
435
|
+
integer(ip), intent(in) :: mbdcnd
|
|
436
|
+
integer(ip), intent(in) :: n
|
|
437
|
+
integer(ip), intent(in) :: nbdcnd
|
|
438
|
+
integer(ip), intent(in) :: idimf
|
|
439
|
+
integer(ip), intent(out) :: ierror
|
|
440
|
+
real(wp), intent(in) :: ts
|
|
441
|
+
real(wp), intent(in) :: tf
|
|
442
|
+
real(wp), intent(in) :: rs
|
|
443
|
+
real(wp), intent(in) :: rf
|
|
444
|
+
real(wp), intent(in) :: elmbda
|
|
445
|
+
real(wp), intent(out) :: pertrb
|
|
446
|
+
real(wp), intent(in) :: bdts(:)
|
|
447
|
+
real(wp), intent(in) :: bdtf(:)
|
|
448
|
+
real(wp), intent(in) :: bdrs(:)
|
|
449
|
+
real(wp), intent(in) :: bdrf(:)
|
|
450
|
+
real(wp), intent(inout) :: f(:,:)
|
|
451
|
+
class(FishpackWorkspace), intent(inout) :: workspace
|
|
452
|
+
|
|
453
|
+
! Check input arguments
|
|
454
|
+
call hwscsp_check_input_arguments(ts, tf, m, mbdcnd, rs, rf, &
|
|
455
|
+
n, nbdcnd, elmbda, idimf, ierror)
|
|
456
|
+
|
|
457
|
+
! Check error flag
|
|
458
|
+
if (ierror /= 0) return
|
|
459
|
+
|
|
460
|
+
! Set up workspace on initial call only
|
|
461
|
+
if (intl == 0) call hwscsp_initialize_workspace(n, m, nbdcnd, workspace)
|
|
462
|
+
|
|
463
|
+
! Solve system
|
|
464
|
+
associate( &
|
|
465
|
+
indx => workspace%workspace_indices, &
|
|
466
|
+
rew => workspace%real_workspace, &
|
|
467
|
+
cxw => workspace%complex_workspace &
|
|
468
|
+
)
|
|
469
|
+
associate( &
|
|
470
|
+
w => rew, &
|
|
471
|
+
wc => cxw, &
|
|
472
|
+
s => rew(indx(1):), &
|
|
473
|
+
an => rew(indx(2):), &
|
|
474
|
+
bn => rew(indx(3):), &
|
|
475
|
+
cn => rew(indx(4):), &
|
|
476
|
+
r => rew(indx(5):), &
|
|
477
|
+
am => rew(indx(6):), &
|
|
478
|
+
bm => rew(indx(7):), &
|
|
479
|
+
cm => rew(indx(8):), &
|
|
480
|
+
sint => rew(indx(9):), &
|
|
481
|
+
bmh => rew(indx(10):) &
|
|
482
|
+
)
|
|
483
|
+
call hwscsp_lower_routine(intl, ts, tf, m, mbdcnd, bdts, bdtf, rs, rf, n, &
|
|
484
|
+
nbdcnd, bdrs, bdrf, elmbda, f, idimf, pertrb, w, wc, s, an, bn, &
|
|
485
|
+
cn, r, am, bm, cm, sint, bmh, ierror)
|
|
486
|
+
end associate
|
|
487
|
+
end associate
|
|
488
|
+
|
|
489
|
+
end subroutine hwscsp
|
|
490
|
+
|
|
491
|
+
subroutine hwscsp_initialize_workspace(n, m, nbdcnd, workspace)
|
|
492
|
+
|
|
493
|
+
! Dummy arguments
|
|
494
|
+
integer(ip), intent(in) :: nbdcnd
|
|
495
|
+
integer(ip), intent(in) :: n
|
|
496
|
+
integer(ip), intent(in) :: m
|
|
497
|
+
class(FishpackWorkspace), intent(out) :: workspace
|
|
498
|
+
|
|
499
|
+
! Local variables
|
|
500
|
+
integer(ip) :: irwk, icwk, indx(SIZE_OF_WORKSPACE_INDICES)
|
|
501
|
+
|
|
502
|
+
! Compute workspace indices
|
|
503
|
+
indx = hwscsp_get_workspace_indices(n, m, nbdcnd)
|
|
504
|
+
|
|
505
|
+
! Compute required blktri workspace lengths
|
|
506
|
+
call workspace%compute_blktri_workspace_lengths(n, m, irwk, icwk)
|
|
507
|
+
|
|
508
|
+
! Adjust workspace requirements for hwscsp
|
|
509
|
+
irwk = indx(10) + m + 1
|
|
510
|
+
icwk = icwk + 3 * m
|
|
511
|
+
|
|
512
|
+
! Allocate memory
|
|
513
|
+
call workspace%create(irwk, icwk, SIZE_OF_WORKSPACE_INDICES)
|
|
514
|
+
|
|
515
|
+
! Set workspace indices
|
|
516
|
+
workspace%workspace_indices = indx
|
|
517
|
+
|
|
518
|
+
end subroutine hwscsp_initialize_workspace
|
|
519
|
+
|
|
520
|
+
pure function hwscsp_get_workspace_indices(n, m, nbdcnd) result (return_value)
|
|
521
|
+
|
|
522
|
+
! Dummy arguments
|
|
523
|
+
integer(ip), intent(in) :: n, m, nbdcnd
|
|
524
|
+
integer(ip) :: return_value(SIZE_OF_WORKSPACE_INDICES)
|
|
525
|
+
|
|
526
|
+
! Local variables
|
|
527
|
+
integer(ip) :: j, nck, l, k
|
|
528
|
+
|
|
529
|
+
nck = n
|
|
530
|
+
|
|
531
|
+
select case (nbdcnd)
|
|
532
|
+
case (1, 5)
|
|
533
|
+
nck = nck - 1
|
|
534
|
+
case (3)
|
|
535
|
+
nck = nck + 1
|
|
536
|
+
end select
|
|
537
|
+
|
|
538
|
+
k = 1
|
|
539
|
+
l = 4
|
|
540
|
+
k = k + 1
|
|
541
|
+
|
|
542
|
+
do
|
|
543
|
+
if (nck <= l) exit
|
|
544
|
+
l = 2*l
|
|
545
|
+
k = k + 1
|
|
546
|
+
end do
|
|
547
|
+
|
|
548
|
+
l = 2*l
|
|
549
|
+
|
|
550
|
+
associate( indx => return_value)
|
|
551
|
+
|
|
552
|
+
indx(1) = (k - 2)*l + k + max(2*n, 6*m) + 13
|
|
553
|
+
|
|
554
|
+
do j = 1, 5
|
|
555
|
+
indx(j+1) = indx(j) + n + 1
|
|
556
|
+
end do
|
|
557
|
+
|
|
558
|
+
do j = 6, 9
|
|
559
|
+
indx(j+1) = indx(j) + m + 1
|
|
560
|
+
end do
|
|
561
|
+
|
|
562
|
+
end associate
|
|
563
|
+
|
|
564
|
+
end function hwscsp_get_workspace_indices
|
|
565
|
+
|
|
566
|
+
subroutine hwscsp_check_input_arguments(ts, tf, m, mbdcnd, rs, rf, &
|
|
567
|
+
n, nbdcnd, elmbda, idimf, ierror)
|
|
568
|
+
|
|
569
|
+
! Dummy arguments
|
|
570
|
+
integer(ip), intent(in) :: m
|
|
571
|
+
integer(ip), intent(in) :: mbdcnd
|
|
572
|
+
integer(ip), intent(in) :: n
|
|
573
|
+
integer(ip), intent(in) :: nbdcnd
|
|
574
|
+
integer(ip), intent(in) :: idimf
|
|
575
|
+
integer(ip), intent(out) :: ierror
|
|
576
|
+
real(wp), intent(in) :: ts
|
|
577
|
+
real(wp), intent(in) :: tf
|
|
578
|
+
real(wp), intent(in) :: rs
|
|
579
|
+
real(wp), intent(in) :: rf
|
|
580
|
+
real(wp), intent(in) :: elmbda
|
|
581
|
+
|
|
582
|
+
if (ts < ZERO .or. tf > PI) then
|
|
583
|
+
ierror = 1
|
|
584
|
+
return
|
|
585
|
+
else if (ts >= tf) then
|
|
586
|
+
ierror = 2
|
|
587
|
+
return
|
|
588
|
+
else if (m < 5) then
|
|
589
|
+
ierror = 3
|
|
590
|
+
return
|
|
591
|
+
else if (mbdcnd < 1 .or. mbdcnd > 9) then
|
|
592
|
+
ierror = 4
|
|
593
|
+
return
|
|
594
|
+
else if (rs < ZERO) then
|
|
595
|
+
ierror = 5
|
|
596
|
+
return
|
|
597
|
+
else if (rs >= rf) then
|
|
598
|
+
ierror = 6
|
|
599
|
+
return
|
|
600
|
+
else if (n < 5) then
|
|
601
|
+
ierror = 7
|
|
602
|
+
return
|
|
603
|
+
else if (nbdcnd < 1 .or. nbdcnd > 6) then
|
|
604
|
+
ierror = 8
|
|
605
|
+
return
|
|
606
|
+
else if (elmbda > ZERO) then
|
|
607
|
+
ierror = 9
|
|
608
|
+
return
|
|
609
|
+
else if (idimf < m + 1) then
|
|
610
|
+
ierror = 10
|
|
611
|
+
return
|
|
612
|
+
else if (elmbda /= ZERO .and. mbdcnd >= 5) then
|
|
613
|
+
ierror = 11
|
|
614
|
+
return
|
|
615
|
+
else if (elmbda /= ZERO) then
|
|
616
|
+
select case (nbdcnd)
|
|
617
|
+
case (5, 6)
|
|
618
|
+
ierror = 12
|
|
619
|
+
return
|
|
620
|
+
end select
|
|
621
|
+
else if (ts /= ZERO) then
|
|
622
|
+
select case (mbdcnd)
|
|
623
|
+
case (5, 6, 9)
|
|
624
|
+
ierror = 13
|
|
625
|
+
return
|
|
626
|
+
end select
|
|
627
|
+
else if (mbdcnd >= 7 .and. tf /= PI) then
|
|
628
|
+
ierror = 14
|
|
629
|
+
return
|
|
630
|
+
else if (ts == ZERO) then
|
|
631
|
+
select case (mbdcnd)
|
|
632
|
+
case (3:4, 8)
|
|
633
|
+
ierror = 15
|
|
634
|
+
return
|
|
635
|
+
end select
|
|
636
|
+
else if (tf == PI) then
|
|
637
|
+
select case (mbdcnd)
|
|
638
|
+
case (2, 3, 6)
|
|
639
|
+
ierror = 16
|
|
640
|
+
return
|
|
641
|
+
end select
|
|
642
|
+
else if (nbdcnd >= 5 .and. rs /= ZERO) then
|
|
643
|
+
ierror = 17
|
|
644
|
+
return
|
|
645
|
+
else if (5 <= nbdcnd) then
|
|
646
|
+
select case (mbdcnd)
|
|
647
|
+
case (1:2, 5, 7)
|
|
648
|
+
ierror = 18
|
|
649
|
+
return
|
|
650
|
+
end select
|
|
651
|
+
else
|
|
652
|
+
ierror = 0
|
|
653
|
+
end if
|
|
654
|
+
|
|
655
|
+
end subroutine hwscsp_check_input_arguments
|
|
656
|
+
|
|
657
|
+
subroutine hwscsp_lower_routine(intl, ts, tf, m, mbdcnd, bdts, bdtf, rs, rf, n, &
|
|
658
|
+
nbdcnd, bdrs, bdrf, elmbda, f, idimf, pertrb, w, wc, s, an, bn &
|
|
659
|
+
, cn, r, am, bm, cm, sint, bmh, ierror)
|
|
660
|
+
|
|
661
|
+
! Dummy arguments
|
|
662
|
+
|
|
663
|
+
integer(ip), intent(in) :: intl
|
|
664
|
+
integer(ip), intent(in) :: m
|
|
665
|
+
integer(ip), intent(in) :: mbdcnd
|
|
666
|
+
integer(ip), intent(in) :: n
|
|
667
|
+
integer(ip), intent(in) :: nbdcnd
|
|
668
|
+
integer(ip), intent(in) :: idimf
|
|
669
|
+
integer(ip), intent(out) :: ierror
|
|
670
|
+
real(wp), intent(in) :: ts
|
|
671
|
+
real(wp), intent(in) :: tf
|
|
672
|
+
real(wp), intent(in) :: rs
|
|
673
|
+
real(wp), intent(in) :: rf
|
|
674
|
+
real(wp), intent(in) :: elmbda
|
|
675
|
+
real(wp), intent(out) :: pertrb
|
|
676
|
+
real(wp), intent(in) :: bdts(:)
|
|
677
|
+
real(wp), intent(in) :: bdtf(:)
|
|
678
|
+
real(wp), intent(in) :: bdrs(:)
|
|
679
|
+
real(wp), intent(in) :: bdrf(:)
|
|
680
|
+
real(wp), intent(inout) :: f(idimf,n + 1)
|
|
681
|
+
real(wp), intent(out) :: w(:)
|
|
682
|
+
real(wp), intent(out) :: s(:)
|
|
683
|
+
real(wp), intent(out) :: an(:)
|
|
684
|
+
real(wp), intent(out) :: bn(:)
|
|
685
|
+
real(wp), intent(out) :: cn(:)
|
|
686
|
+
real(wp), intent(out) :: r(:)
|
|
687
|
+
real(wp), intent(out) :: am(:)
|
|
688
|
+
real(wp), intent(out) :: bm(:)
|
|
689
|
+
real(wp), intent(out) :: cm(:)
|
|
690
|
+
real(wp), intent(out) :: sint(:)
|
|
691
|
+
real(wp), intent(out) :: bmh(:)
|
|
692
|
+
complex(wp), intent(out) :: wc(:)
|
|
693
|
+
|
|
694
|
+
! Local variables
|
|
695
|
+
integer(ip) :: mp1, i, np1, j, mp, np
|
|
696
|
+
integer(ip) :: its, itf, itsp, itfm, ictr, jrs
|
|
697
|
+
integer(ip) :: l, jrf, jrsp, jrfm, munk, nunk, ising, iflg
|
|
698
|
+
real(wp) :: dth, tdt, hdth, sdts
|
|
699
|
+
real(wp) :: theta, t1, dr, hdr
|
|
700
|
+
real(wp) :: tdr, dr2, czr, at, ct, wts, wtf
|
|
701
|
+
real(wp) :: ar, wtnm, yps, cr, wrs, wrf
|
|
702
|
+
real(wp) :: wrz, summation, r2, hne, yhld
|
|
703
|
+
real(wp) :: rs2, rf2, rsq, xp, yph, xps
|
|
704
|
+
real(wp), parameter :: FOUR = 4.0_wp
|
|
705
|
+
real(wp), parameter :: SIX = 6.0_wp
|
|
706
|
+
type(GeneralizedCyclicReductionUtility) :: util
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
mp1 = m + 1
|
|
710
|
+
dth = (tf - ts)/m
|
|
711
|
+
tdt = dth + dth
|
|
712
|
+
hdth = dth/2
|
|
713
|
+
sdts = ONE/(dth**2)
|
|
714
|
+
|
|
715
|
+
do i = 1, mp1
|
|
716
|
+
theta = ts + real(i - 1, kind=wp)*dth
|
|
717
|
+
sint(i) = sin(theta)
|
|
718
|
+
if (sint(i) == ZERO) cycle
|
|
719
|
+
t1 = sdts/sint(i)
|
|
720
|
+
am(i) = t1*sin(theta - hdth)
|
|
721
|
+
cm(i) = t1*sin(theta + hdth)
|
|
722
|
+
bm(i) = -(am(i)+cm(i))
|
|
723
|
+
end do
|
|
724
|
+
|
|
725
|
+
np1 = n + 1
|
|
726
|
+
dr = (rf - rs)/n
|
|
727
|
+
hdr = dr/2
|
|
728
|
+
tdr = dr + dr
|
|
729
|
+
dr2 = dr**2
|
|
730
|
+
czr = SIX*dth/(dr2*(cos(ts) - cos(tf)))
|
|
731
|
+
|
|
732
|
+
do j = 1, np1
|
|
733
|
+
r(j) = rs + real(j - 1, kind=wp)*dr
|
|
734
|
+
an(j) = (r(j)-hdr)**2/dr2
|
|
735
|
+
cn(j) = (r(j)+hdr)**2/dr2
|
|
736
|
+
bn(j) = -(an(j)+cn(j))
|
|
737
|
+
end do
|
|
738
|
+
|
|
739
|
+
mp = 1
|
|
740
|
+
np = 1
|
|
741
|
+
|
|
742
|
+
!
|
|
743
|
+
! Boundary condition at phi=ps
|
|
744
|
+
!
|
|
745
|
+
select case (mbdcnd)
|
|
746
|
+
case (1:2,7)
|
|
747
|
+
at = am(2)
|
|
748
|
+
its = 2
|
|
749
|
+
case (3:4,8)
|
|
750
|
+
at = am(1)
|
|
751
|
+
its = 1
|
|
752
|
+
cm(1) = cm(1) + am(1)
|
|
753
|
+
case (5:6,9)
|
|
754
|
+
its = 1
|
|
755
|
+
bm(1) = -FOUR*sdts
|
|
756
|
+
cm(1) = -bm(1)
|
|
757
|
+
end select
|
|
758
|
+
|
|
759
|
+
!
|
|
760
|
+
! Boundary condition at phi=pf
|
|
761
|
+
!
|
|
762
|
+
select case (mbdcnd)
|
|
763
|
+
case (1,4:5)
|
|
764
|
+
ct = cm(m)
|
|
765
|
+
itf = m
|
|
766
|
+
case (2:3,6)
|
|
767
|
+
ct = cm(m+1)
|
|
768
|
+
am(m+1) = am(m+1) + cm(m+1)
|
|
769
|
+
itf = m + 1
|
|
770
|
+
case (7:9)
|
|
771
|
+
itf = m + 1
|
|
772
|
+
am(m+1) = FOUR*sdts
|
|
773
|
+
bm(m+1) = -am(m+1)
|
|
774
|
+
end select
|
|
775
|
+
|
|
776
|
+
wts = sint(its+1)*am(its+1)/cm(its)
|
|
777
|
+
wtf = sint(itf-1)*cm(itf-1)/am(itf)
|
|
778
|
+
itsp = its + 1
|
|
779
|
+
itfm = itf - 1
|
|
780
|
+
!
|
|
781
|
+
! Boundary condition at r=rs
|
|
782
|
+
!
|
|
783
|
+
ictr = 0
|
|
784
|
+
select case (nbdcnd)
|
|
785
|
+
case default
|
|
786
|
+
ar = an(2)
|
|
787
|
+
jrs = 2
|
|
788
|
+
case (3:4)
|
|
789
|
+
ar = an(1)
|
|
790
|
+
jrs = 1
|
|
791
|
+
cn(1) = cn(1) + an(1)
|
|
792
|
+
case (5:6)
|
|
793
|
+
jrs = 2
|
|
794
|
+
ictr = 1
|
|
795
|
+
s(n) = an(n)/bn(n)
|
|
796
|
+
do j = 3, n
|
|
797
|
+
l = n - j + 2
|
|
798
|
+
s(l) = an(l)/(bn(l)-cn(l)*s(l+1))
|
|
799
|
+
end do
|
|
800
|
+
s(2) = -s(2)
|
|
801
|
+
do j = 3, n
|
|
802
|
+
s(j) = -s(j)*s(j-1)
|
|
803
|
+
end do
|
|
804
|
+
wtnm = wts + wtf
|
|
805
|
+
do i = itsp, itfm
|
|
806
|
+
wtnm = wtnm + sint(i)
|
|
807
|
+
end do
|
|
808
|
+
yps = czr*wtnm*(s(2)-ONE)
|
|
809
|
+
end select
|
|
810
|
+
|
|
811
|
+
!
|
|
812
|
+
! Boundary condition at r=rf
|
|
813
|
+
!
|
|
814
|
+
select case (nbdcnd)
|
|
815
|
+
case (1,4:5)
|
|
816
|
+
cr = cn(n)
|
|
817
|
+
jrf = n
|
|
818
|
+
case (2:3,6)
|
|
819
|
+
cr = cn(n+1)
|
|
820
|
+
an(n+1) = an(n+1) + cn(n+1)
|
|
821
|
+
jrf = n + 1
|
|
822
|
+
end select
|
|
823
|
+
|
|
824
|
+
wrs = an(jrs+1)*r(jrs)**2/cn(jrs)
|
|
825
|
+
wrf = cn(jrf-1)*r(jrf)**2/an(jrf)
|
|
826
|
+
wrz = an(jrs)/czr
|
|
827
|
+
jrsp = jrs + 1
|
|
828
|
+
jrfm = jrf - 1
|
|
829
|
+
munk = itf - its + 1
|
|
830
|
+
nunk = jrf - jrs + 1
|
|
831
|
+
bmh(its:itf) = bm(its:itf)
|
|
832
|
+
ising = 0
|
|
833
|
+
|
|
834
|
+
if (nbdcnd == 3 .or. nbdcnd == 6 ) then
|
|
835
|
+
select case (mbdcnd)
|
|
836
|
+
case (3,6,8:9)
|
|
837
|
+
if (elmbda >= ZERO) then
|
|
838
|
+
ising = 1
|
|
839
|
+
summation = wts*wrs + wts*wrf + wtf*wrs + wtf*wrf
|
|
840
|
+
if (ictr /= 0) then
|
|
841
|
+
summation = summation + wrz
|
|
842
|
+
end if
|
|
843
|
+
do j = jrsp, jrfm
|
|
844
|
+
r2 = r(j)**2
|
|
845
|
+
do i = itsp, itfm
|
|
846
|
+
summation = summation + r2*sint(i)
|
|
847
|
+
end do
|
|
848
|
+
end do
|
|
849
|
+
do j = jrsp, jrfm
|
|
850
|
+
summation = summation + (wts + wtf)*r(j)**2
|
|
851
|
+
end do
|
|
852
|
+
do i = itsp, itfm
|
|
853
|
+
summation = summation + (wrs + wrf)*sint(i)
|
|
854
|
+
end do
|
|
855
|
+
hne = summation
|
|
856
|
+
end if
|
|
857
|
+
end select
|
|
858
|
+
end if
|
|
859
|
+
|
|
860
|
+
select case (mbdcnd)
|
|
861
|
+
case (1:4, 7:8)
|
|
862
|
+
bm(its) = bmh(its) + elmbda/sint(its)**2
|
|
863
|
+
end select
|
|
864
|
+
|
|
865
|
+
select case (mbdcnd)
|
|
866
|
+
case (1:6)
|
|
867
|
+
bm(itf) = bmh(itf) + elmbda/sint(itf)**2
|
|
868
|
+
end select
|
|
869
|
+
|
|
870
|
+
bm(itsp:itfm) = bmh(itsp:itfm) + elmbda/sint(itsp:itfm)**2
|
|
871
|
+
|
|
872
|
+
select case (mbdcnd)
|
|
873
|
+
case (1:2, 7)
|
|
874
|
+
f(2, jrs:jrf) = f(2, jrs:jrf) - at*f(1, jrs:jrf)/r(jrs:jrf)**2
|
|
875
|
+
case (3:4, 8)
|
|
876
|
+
f(1, jrs:jrf) = f(1, jrs:jrf) + tdt*bdts(jrs:jrf)*at/r(jrs:jrf)**2
|
|
877
|
+
end select
|
|
878
|
+
|
|
879
|
+
select case (mbdcnd)
|
|
880
|
+
case (1, 4:5)
|
|
881
|
+
f(m, jrs:jrf) = f(m, jrs:jrf) - ct*f(m+1, jrs:jrf)/r(jrs:jrf)**2
|
|
882
|
+
case (2:3, 6)
|
|
883
|
+
f(m+1, jrs:jrf)=f(m+1, jrs:jrf)-tdt*bdtf(jrs:jrf)*ct/r(jrs:jrf)**2
|
|
884
|
+
end select
|
|
885
|
+
|
|
886
|
+
case_block: block
|
|
887
|
+
select case (nbdcnd)
|
|
888
|
+
case default
|
|
889
|
+
if (mbdcnd /= 3) exit case_block
|
|
890
|
+
yhld = f(its, 1) - czr/tdt*(sin(tf)*bdtf(2)-sin(ts)*bdts(2))
|
|
891
|
+
f(:mp1, 1) = yhld
|
|
892
|
+
case (1:2)
|
|
893
|
+
rs2 = (rs + dr)**2
|
|
894
|
+
f(its:itf, 2) = f(its:itf, 2) - ar*f(its:itf, 1)/rs2
|
|
895
|
+
case (3:4)
|
|
896
|
+
f(its:itf, 1) = f(its:itf, 1) + tdr*bdrs(its:itf)*ar/rs**2
|
|
897
|
+
end select
|
|
898
|
+
end block case_block
|
|
899
|
+
|
|
900
|
+
select case (nbdcnd)
|
|
901
|
+
case (1, 4:5)
|
|
902
|
+
rf2 = (rf - dr)**2
|
|
903
|
+
f(its:itf, n) = f(its:itf, n) - cr*f(its:itf, n+1)/rf2
|
|
904
|
+
case (2:3, 6)
|
|
905
|
+
f(its:itf, n+1) = f(its:itf, n+1) - tdr*bdrf(its:itf)*cr/rf**2
|
|
906
|
+
end select
|
|
907
|
+
|
|
908
|
+
pertrb = ZERO
|
|
909
|
+
|
|
910
|
+
if (ising /= 0) then
|
|
911
|
+
summation = wts*wrs*f(its, jrs) + wts*wrf*f(its, jrf) + wtf*wrs*f(itf, &
|
|
912
|
+
jrs) + wtf*wrf*f(itf, jrf)
|
|
913
|
+
|
|
914
|
+
if (ictr /= 0) summation = summation + wrz*f(its, 1)
|
|
915
|
+
|
|
916
|
+
do j = jrsp, jrfm
|
|
917
|
+
r2 = r(j)**2
|
|
918
|
+
do i = itsp, itfm
|
|
919
|
+
summation = summation + r2*sint(i)*f(i, j)
|
|
920
|
+
end do
|
|
921
|
+
end do
|
|
922
|
+
|
|
923
|
+
summation = summation &
|
|
924
|
+
+ dot_product(r(jrsp:jrfm)**2, wts*f(its, jrsp:jrfm)+ &
|
|
925
|
+
wtf*f(itf, jrsp:jrfm))
|
|
926
|
+
|
|
927
|
+
summation = summation &
|
|
928
|
+
+ dot_product(sint(itsp:itfm), wrs*f(itsp:itfm, jrs)+ &
|
|
929
|
+
wrf*f(itsp:itfm, jrf))
|
|
930
|
+
|
|
931
|
+
pertrb = summation/hne
|
|
932
|
+
|
|
933
|
+
f(:mp1, :np1) = f(:mp1, :np1) - pertrb
|
|
934
|
+
|
|
935
|
+
end if
|
|
936
|
+
|
|
937
|
+
do j = jrs, jrf
|
|
938
|
+
rsq = r(j)**2
|
|
939
|
+
f(its:itf, j) = rsq*f(its:itf, j)
|
|
940
|
+
end do
|
|
941
|
+
|
|
942
|
+
iflg = intl
|
|
943
|
+
|
|
944
|
+
call util%blktrii(iflg, np, nunk, an(jrs:), bn(jrs:), cn(jrs:), mp, munk, &
|
|
945
|
+
am(its:), bm(its:), cm(its:), idimf, f(its:, jrs:), ierror, w, wc)
|
|
946
|
+
|
|
947
|
+
if (ierror /= 0) then
|
|
948
|
+
error stop 'fishpack library: blktrii call failed in hwscsp_lower_routine'
|
|
949
|
+
end if
|
|
950
|
+
|
|
951
|
+
iflg = iflg + 1
|
|
952
|
+
|
|
953
|
+
do while(iflg == 1)
|
|
954
|
+
!
|
|
955
|
+
! Iterate solver
|
|
956
|
+
!
|
|
957
|
+
call util%blktrii(iflg, np, nunk, an(jrs:), bn(jrs:), cn(jrs:), mp, &
|
|
958
|
+
munk, am(its:), bm(its:), cm(its:), idimf, f(its:, jrs:), ierror, w, wc)
|
|
959
|
+
|
|
960
|
+
if (ierror /= 0) then
|
|
961
|
+
error stop 'fishpack library: blktrii call failed in hwscsp_lower_routine'
|
|
962
|
+
end if
|
|
963
|
+
!
|
|
964
|
+
! Increment solver flag
|
|
965
|
+
!
|
|
966
|
+
iflg = iflg + 1
|
|
967
|
+
end do
|
|
968
|
+
|
|
969
|
+
if (nbdcnd == 0) f(:mp1, jrf+1) = f(:mp1, jrs)
|
|
970
|
+
|
|
971
|
+
if (mbdcnd == 0) f(itf+1, :np1) = f(its, :np1)
|
|
972
|
+
|
|
973
|
+
xp = ZERO
|
|
974
|
+
|
|
975
|
+
if (ictr /= 0) then
|
|
976
|
+
if (ising == 0) then
|
|
977
|
+
summation = wts*f(its, 2) + wtf*f(itf, 2)
|
|
978
|
+
summation = summation + dot_product(sint(itsp:itfm), f(itsp:itfm, 2))
|
|
979
|
+
yph = czr*summation
|
|
980
|
+
xp = (f(its, 1)-yph)/yps
|
|
981
|
+
do j = jrs, jrf
|
|
982
|
+
xps = xp*s(j)
|
|
983
|
+
f(its:itf, j) = f(its:itf, j) + xps
|
|
984
|
+
end do
|
|
985
|
+
end if
|
|
986
|
+
f(:mp1, 1) = xp
|
|
987
|
+
end if
|
|
988
|
+
|
|
989
|
+
end subroutine hwscsp_lower_routine
|
|
990
|
+
|
|
991
|
+
end submodule centered_axisymmetric_spherical_solver
|
|
992
|
+
!
|
|
993
|
+
! REVISION HISTORY
|
|
994
|
+
!
|
|
995
|
+
! September 1973 Version 1
|
|
996
|
+
! April 1976 Version 2
|
|
997
|
+
! January 1978 Version 3
|
|
998
|
+
! December 1979 Version 3.1
|
|
999
|
+
! February 1985 Documentation upgrade
|
|
1000
|
+
! November 1988 Version 3.2, FORTRAN 77 changes
|
|
1001
|
+
! June 2004 Version 5.0, Fortran 90 changes
|
|
1002
|
+
!
|