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,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
|