PyFishPack 0.1.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. PyFishPack/__init__.py +86 -0
  2. PyFishPack/__pycache__/__init__.cpython-313.pyc +0 -0
  3. PyFishPack/__pycache__/apps.cpython-313.pyc +0 -0
  4. PyFishPack/_dummy.c +23 -0
  5. PyFishPack/_dummy.cp313-win_amd64.pyd +0 -0
  6. PyFishPack/apps.py +3640 -0
  7. PyFishPack/fishpack.cp313-win_amd64.dll.a +0 -0
  8. PyFishPack/fishpack.cp313-win_amd64.pyd +0 -0
  9. PyFishPack/meson.build +213 -0
  10. PyFishPack/src/archive/f77/Makefile +19 -0
  11. PyFishPack/src/archive/f77/blktri.f +1404 -0
  12. PyFishPack/src/archive/f77/cblktri.f +1414 -0
  13. PyFishPack/src/archive/f77/cmgnbn.f +1592 -0
  14. PyFishPack/src/archive/f77/comf.f +186 -0
  15. PyFishPack/src/archive/f77/fftpack.f +2968 -0
  16. PyFishPack/src/archive/f77/genbun.f +1335 -0
  17. PyFishPack/src/archive/f77/gnbnaux.f +314 -0
  18. PyFishPack/src/archive/f77/hstcrt.f +443 -0
  19. PyFishPack/src/archive/f77/hstcsp.f +683 -0
  20. PyFishPack/src/archive/f77/hstcyl.f +485 -0
  21. PyFishPack/src/archive/f77/hstplr.f +538 -0
  22. PyFishPack/src/archive/f77/hstssp.f +634 -0
  23. PyFishPack/src/archive/f77/hw3crt.f +687 -0
  24. PyFishPack/src/archive/f77/hwscrt.f +512 -0
  25. PyFishPack/src/archive/f77/hwscsp.f +728 -0
  26. PyFishPack/src/archive/f77/hwscyl.f +538 -0
  27. PyFishPack/src/archive/f77/hwsplr.f +602 -0
  28. PyFishPack/src/archive/f77/hwsssp.f +780 -0
  29. PyFishPack/src/archive/f77/pois3d.f +550 -0
  30. PyFishPack/src/archive/f77/poistg.f +875 -0
  31. PyFishPack/src/archive/f77/sepaux.f +361 -0
  32. PyFishPack/src/archive/f77/sepeli.f +1029 -0
  33. PyFishPack/src/archive/f77/sepx4.f +958 -0
  34. PyFishPack/src/centered_axisymmetric_spherical_solver.f90 +1002 -0
  35. PyFishPack/src/centered_cartesian_helmholtz_solver_3d.f90 +819 -0
  36. PyFishPack/src/centered_cartesian_solver.f90 +583 -0
  37. PyFishPack/src/centered_cylindrical_solver.f90 +634 -0
  38. PyFishPack/src/centered_helmholtz_solvers.f90 +156 -0
  39. PyFishPack/src/centered_polar_solver.f90 +746 -0
  40. PyFishPack/src/centered_real_linear_systems_solver.f90 +280 -0
  41. PyFishPack/src/centered_spherical_solver.f90 +928 -0
  42. PyFishPack/src/complex_block_tridiagonal_linear_systems_solver.f90 +1947 -0
  43. PyFishPack/src/complex_linear_systems_solver.f90 +1787 -0
  44. PyFishPack/src/fftpack_c_api.f90 +86 -0
  45. PyFishPack/src/fishpack.f90 +191 -0
  46. PyFishPack/src/fishpack.pyf +504 -0
  47. PyFishPack/src/fishpack_c_api.f90 +365 -0
  48. PyFishPack/src/fishpack_original.pyf +2119 -0
  49. PyFishPack/src/fishpack_precision.f90 +53 -0
  50. PyFishPack/src/general_linear_systems_solver_3d.f90 +296 -0
  51. PyFishPack/src/iterative_solvers.f90 +969 -0
  52. PyFishPack/src/main.f90 +10 -0
  53. PyFishPack/src/pyfishpack_module.c +1302 -0
  54. PyFishPack/src/real_block_tridiagonal_linear_systems_solver.f90 +319 -0
  55. PyFishPack/src/sepeli.f90 +1454 -0
  56. PyFishPack/src/sepx4.f90 +1338 -0
  57. PyFishPack/src/staggered_axisymmetric_spherical_solver.f90 +908 -0
  58. PyFishPack/src/staggered_cartesian_solver.f90 +553 -0
  59. PyFishPack/src/staggered_cylindrical_solver.f90 +630 -0
  60. PyFishPack/src/staggered_helmholtz_solvers.f90 +172 -0
  61. PyFishPack/src/staggered_polar_solver.f90 +651 -0
  62. PyFishPack/src/staggered_real_linear_systems_solver.f90 +258 -0
  63. PyFishPack/src/staggered_spherical_solver.f90 +758 -0
  64. PyFishPack/src/three_dimensional_solvers.f90 +602 -0
  65. PyFishPack/src/type_CenteredCyclicReductionUtility.f90 +1714 -0
  66. PyFishPack/src/type_CyclicReductionUtility.f90 +472 -0
  67. PyFishPack/src/type_FishpackWorkspace.f90 +290 -0
  68. PyFishPack/src/type_GeneralizedCyclicReductionUtility.f90 +1980 -0
  69. PyFishPack/src/type_PeriodicFastFourierTransform.f90 +3789 -0
  70. PyFishPack/src/type_SepAux.f90 +586 -0
  71. PyFishPack/src/type_StaggeredCyclicReductionUtility.f90 +893 -0
  72. pyfishpack-0.1.0.dist-info/DELVEWHEEL +2 -0
  73. pyfishpack-0.1.0.dist-info/METADATA +81 -0
  74. pyfishpack-0.1.0.dist-info/RECORD +81 -0
  75. pyfishpack-0.1.0.dist-info/WHEEL +5 -0
  76. pyfishpack-0.1.0.dist-info/licenses/LICENSE +21 -0
  77. pyfishpack-0.1.0.dist-info/top_level.txt +1 -0
  78. pyfishpack.libs/libgcc_s_seh-1-25d59ccffa1a9009644065b069829e07.dll +0 -0
  79. pyfishpack.libs/libgfortran-5-08f2195cfa0d823e13371c5c3186a82a.dll +0 -0
  80. pyfishpack.libs/libquadmath-0-c5abb9113f1ee64b87a889958e4b7418.dll +0 -0
  81. pyfishpack.libs/libwinpthread-1-83908d14abfafb8b3bfa38cf51ecee56.dll +0 -0
@@ -0,0 +1,651 @@
1
+ !
2
+ ! file hstplr.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 hstplr(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, bdd,
37
+ ! elmbda, f, idimf, pertrb, ierror)
38
+ !
39
+ ! DIMENSION OF bda(n), bdb(n), bdc(m), bdd(m), f(idimf, n)
40
+ ! ARGUMENTS
41
+ !
42
+ ! LATEST REVISION May 2016
43
+ !
44
+ ! PURPOSE Solves the standard five-point finite
45
+ ! difference approximation on a staggered
46
+ ! grid to the helmholtz equation in polar
47
+ ! coordinates. 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 hstplr(a, b, m, mbdcnd, bda, bdb, c, d, n,
54
+ ! nbdcnd, bdc, bdd, elmbda, f,
55
+ ! idimf, pertrb, ierror)
56
+ !
57
+ ! ARGUMENTS
58
+ ! ON INPUT a, b
59
+ !
60
+ ! the range of r, i.e. a <= r <= b.
61
+ ! a must be less than b and a must be
62
+ ! non-negative.
63
+ !
64
+ ! m
65
+ ! the number of grid points in the interval
66
+ ! (a, b). the grid points in the r-direction
67
+ ! are given by r(i) = a + (i-0.5)dr for
68
+ ! i=1, 2, ..., m where dr =(b-a)/m.
69
+ ! m must be greater than 2.
70
+ !
71
+ ! mbdcnd
72
+ ! indicates the type of boundary conditions
73
+ ! at r = a and r = b.
74
+ !
75
+ ! = 1 if the solution is specified at r = a
76
+ ! and r = b.
77
+ !
78
+ ! = 2 if the solution is specified at r = a
79
+ ! and the derivative of the solution
80
+ ! with respect to r is specified at r = b.
81
+ ! (see note 1 below)
82
+ !
83
+ ! = 3 if the derivative of the solution
84
+ ! with respect to r is specified at
85
+ ! r = a (see note 2 below) and r = b.
86
+ !
87
+ ! = 4 if the derivative of the solution
88
+ ! with respect to r is specified at
89
+ ! specified at r = a (see note 2 below)
90
+ ! and the solution is specified at r = b.
91
+ !
92
+ !
93
+ ! = 5 if the solution is unspecified at
94
+ ! r = a = 0 and the solution is
95
+ ! specified at r = b.
96
+ !
97
+ ! = 6 if the solution is unspecified at
98
+ ! r = a = 0 and the derivative of the
99
+ ! solution with respect to r is specified
100
+ ! at r = b.
101
+ !
102
+ ! note 1:
103
+ ! if a = 0, mbdcnd = 2, and nbdcnd = 0 or 3,
104
+ ! the system of equations to be solved is
105
+ ! singular. the unique solution is
106
+ ! is determined by extrapolation to the
107
+ ! specification of u(0, theta(1)).
108
+ ! but in this case the right side of the
109
+ ! system will be perturbed by the constant
110
+ ! pertrb.
111
+ !
112
+ ! note 2:
113
+ ! if a = 0, do not use mbdcnd = 3 or 4,
114
+ ! but instead use mbdcnd = 1, 2, 5, or 6.
115
+ !
116
+ ! bda
117
+ ! a one-dimensional array of length n that
118
+ ! specifies the boundary values (if any) of
119
+ ! the solution at r = a.
120
+ !
121
+ ! when mbdcnd = 1 or 2,
122
+ ! bda(j) = u(a, theta(j)) , j=1, 2, ..., n.
123
+ !
124
+ ! when mbdcnd = 3 or 4,
125
+ ! bda(j) = (d/dr)u(a, theta(j)) ,
126
+ ! j=1, 2, ..., n.
127
+ !
128
+ ! when mbdcnd = 5 or 6, bda is a dummy
129
+ ! variable.
130
+ !
131
+ ! bdb
132
+ ! a one-dimensional array of length n that
133
+ ! specifies the boundary values of the
134
+ ! solution at r = b.
135
+ !
136
+ ! when mbdcnd = 1, 4, or 5,
137
+ ! bdb(j) = u(b, theta(j)) , j=1, 2, ..., n.
138
+ !
139
+ ! when mbdcnd = 2, 3, or 6,
140
+ ! bdb(j) = (d/dr)u(b, theta(j)) ,
141
+ ! j=1, 2, ..., n.
142
+ !
143
+ ! c, d
144
+ ! the range of theta, i.e. c <= theta <= d.
145
+ ! c must be less than d.
146
+ !
147
+ ! n
148
+ ! the number of unknowns in the interval
149
+ ! (c, d). the unknowns in the theta-
150
+ ! direction are given by theta(j) = c +
151
+ ! (j-0.5)dt, j=1, 2, ..., n, where
152
+ ! dt = (d-c)/n. n must be greater than 2.
153
+ !
154
+ ! nbdcnd
155
+ ! indicates the type of boundary conditions
156
+ ! at theta = c and theta = d.
157
+ !
158
+ ! = 0 if the solution is periodic in theta,
159
+ ! i.e. u(i, j) = u(i, n+j).
160
+ !
161
+ ! = 1 if the solution is specified at
162
+ ! theta = c and theta = d
163
+ ! (see note below).
164
+ !
165
+ ! = 2 if the solution is specified at
166
+ ! theta = c and the derivative of the
167
+ ! solution with respect to theta is
168
+ ! specified at theta = d
169
+ ! (see note below).
170
+ !
171
+ ! = 3 if the derivative of the solution
172
+ ! with respect to theta is specified
173
+ ! at theta = c and theta = d.
174
+ !
175
+ ! = 4 if the derivative of the solution
176
+ ! with respect to theta is specified
177
+ ! at theta = c and the solution is
178
+ ! specified at theta = d
179
+ ! (see note below).
180
+ !
181
+ ! note:
182
+ ! when nbdcnd = 1, 2, or 4, do not use
183
+ ! mbdcnd = 5 or 6 (the former indicates that
184
+ ! the solution is specified at r = 0; the
185
+ ! latter indicates the solution is unspecified
186
+ ! at r = 0). use instead mbdcnd = 1 or 2.
187
+ !
188
+ ! bdc
189
+ ! a one dimensional array of length m that
190
+ ! specifies the boundary values of the
191
+ ! solution at theta = c.
192
+ !
193
+ ! when nbdcnd = 1 or 2,
194
+ ! bdc(i) = u(r(i), c) , i=1, 2, ..., m.
195
+ !
196
+ ! when nbdcnd = 3 or 4,
197
+ ! bdc(i) = (d/dtheta)u(r(i), c),
198
+ ! i=1, 2, ..., m.
199
+ !
200
+ ! when nbdcnd = 0, bdc is a dummy variable.
201
+ !
202
+ ! bdd
203
+ ! a one-dimensional array of length m that
204
+ ! specifies the boundary values of the
205
+ ! solution at theta = d.
206
+ !
207
+ ! when nbdcnd = 1 or 4,
208
+ ! bdd(i) = u(r(i), d) , i=1, 2, ..., m.
209
+ !
210
+ ! when nbdcnd = 2 or 3,
211
+ ! bdd(i) =(d/dtheta)u(r(i), d), i=1, 2, ..., m.
212
+ !
213
+ ! when nbdcnd = 0, bdd is a dummy variable.
214
+ !
215
+ ! elmbda
216
+ ! the constant lambda in the helmholtz
217
+ ! equation. if lambda is greater than 0,
218
+ ! a solution may not exist. however, hstplr
219
+ ! will attempt to find a solution.
220
+ !
221
+ ! f
222
+ ! a two-dimensional array that specifies the
223
+ ! values of the right side of the helmholtz
224
+ ! equation.
225
+ !
226
+ ! for i=1, 2, ..., m and j=1, 2, ..., n
227
+ ! f(i, j) = f(r(i), theta(j)) .
228
+ !
229
+ ! f must be dimensioned at least m x n.
230
+ !
231
+ ! idimf
232
+ ! the row (or first) dimension of the array
233
+ ! f as it appears in the program calling
234
+ ! hstplr. this parameter is used to specify
235
+ ! the variable dimension of f.
236
+ ! idimf must be at least m.
237
+ !
238
+ !
239
+ ! ON OUTPUT
240
+ !
241
+ ! f
242
+ ! contains the solution u(i, j) of the finite
243
+ ! difference approximation for the grid point
244
+ ! (r(i), theta(j)) for i=1, 2, ..., m,
245
+ ! j=1, 2, ..., n.
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. hstplr then computes this
255
+ ! solution, which is a least squares solution
256
+ ! to the original approximation.
257
+ ! this solution plus any constant is also
258
+ ! a solution; hence, the solution is not
259
+ ! unique. the value of pertrb should be
260
+ ! small compared to the right side f.
261
+ ! otherwise, a solution is obtained to an
262
+ ! essentially different problem.
263
+ ! this comparison should always be made to
264
+ ! insure that a meaningful solution has been
265
+ ! obtained.
266
+ !
267
+ ! ierror
268
+ ! an error flag that indicates invalid input
269
+ ! parameters. except to numbers 0 and 11,
270
+ ! a solution is not attempted.
271
+ !
272
+ ! = 0 no error
273
+ !
274
+ ! = 1 a < 0
275
+ !
276
+ ! = 2 a >= b
277
+ !
278
+ ! = 3 mbdcnd < 1 or mbdcnd > 6
279
+ !
280
+ ! = 4 c >= d
281
+ !
282
+ ! = 5 n <= 2
283
+ !
284
+ ! = 6 nbdcnd < 0 or nbdcnd > 4
285
+ !
286
+ ! = 7 a = 0 and mbdcnd = 3 or 4
287
+ !
288
+ ! = 8 a > 0 and mbdcnd >= 5
289
+ !
290
+ ! = 9 mbdcnd >= 5 and nbdcnd /= 0 or 3
291
+ !
292
+ ! = 10 idimf < m
293
+ !
294
+ ! = 11 lambda > 0
295
+ !
296
+ ! = 12 m <= 2
297
+ !
298
+ ! = 20 if the dynamic allocation of real and
299
+ ! complex workspace required for solution
300
+ ! fails (for example if n, m are too large
301
+ ! for your computer)
302
+ !
303
+ ! since this is the only means of indicating
304
+ ! a possibly incorrect call to hstplr, the
305
+ ! user should test ierror after the call.
306
+ !
307
+ !
308
+ ! I/O None
309
+ !
310
+ ! PRECISION 64-bit double precision
311
+ !
312
+ ! REQUIRED FILES type_FishpackWorkspace.f90, genbun.f90, type_CyclicReductionUtility.f9090, poistg.f90
313
+ !
314
+ ! STANDARD Fortran 2008
315
+ !
316
+ ! HISTORY Written by Roland Sweet at NCAR in 1977.
317
+ ! released on NCAR's public software libraries
318
+ ! IN January 1980.
319
+ ! Revised in June 2004 by John Adams using
320
+ ! Fortran 90 dynamically allocated workspace.
321
+ !
322
+ ! PORTABILITY FORTRAN 90
323
+ !
324
+ ! ALGORITHM This subroutine defines the finite-
325
+ ! difference equations, incorporates boundary
326
+ ! data, adjusts the right side when the system
327
+ ! is singular and calls either poistg or genbun
328
+ ! which solves the linear system of equations.
329
+ !
330
+ ! TIMING For large m and n, the operation count
331
+ ! is roughly proportional to m*n*log2(n).
332
+ !
333
+ ! ACCURACY The solution process employed results in
334
+ ! a loss of no more than four significant
335
+ ! digits for n and m as large as 64.
336
+ ! more detailed information about accuracy
337
+ ! can be found in the documentation for
338
+ ! routine poistg which is the routine that
339
+ ! actually solves the finite difference
340
+ ! equations.
341
+ !
342
+ ! REFERENCES U. Schumann and R. Sweet, "A direct method
343
+ ! for the solution of poisson's equation with
344
+ ! neumann boundary conditions on a staggered
345
+ ! grid of arbitrary size, " J. Comp. Phys.
346
+ ! 20(1976), pp. 171-182.
347
+ !
348
+ submodule(staggered_helmholtz_solvers) staggered_polar_solver
349
+
350
+ contains
351
+
352
+ module subroutine hstplr(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, &
353
+ bdd, elmbda, f, idimf, pertrb, ierror)
354
+ !-----------------------------------------------
355
+ ! Dummy arguments
356
+ !-----------------------------------------------
357
+ integer(ip), intent(in) :: m
358
+ integer(ip), intent(in) :: mbdcnd
359
+ integer(ip), intent(in) :: n
360
+ integer(ip), intent(in) :: nbdcnd
361
+ integer(ip), intent(in) :: idimf
362
+ integer(ip), intent(out) :: ierror
363
+ real(wp), intent(in) :: a
364
+ real(wp), intent(in) :: b
365
+ real(wp), intent(in) :: c
366
+ real(wp), intent(in) :: d
367
+ real(wp), intent(in) :: elmbda
368
+ real(wp), intent(out) :: pertrb
369
+ real(wp), intent(in) :: bda(:)
370
+ real(wp), intent(in) :: bdb(:)
371
+ real(wp), intent(in) :: bdc(:)
372
+ real(wp), intent(in) :: bdd(:)
373
+ real(wp), intent(inout) :: f(:,:)
374
+ !-----------------------------------------------
375
+ ! Local variables
376
+ !-----------------------------------------------
377
+ type(FishpackWorkspace) :: workspace
378
+ !-----------------------------------------------
379
+
380
+ ! Check input arguments
381
+ call hstplr_check_input_arguments(a, b, m, mbdcnd, c, d, n, &
382
+ nbdcnd, idimf, ierror)
383
+
384
+ ! Check error flag
385
+ if (ierror /= 0) return
386
+
387
+ ! Allocate memory
388
+ call workspace%initialize_staggered_workspace(n, m)
389
+
390
+ ! Solve system
391
+ associate( rew => workspace%real_workspace )
392
+ call hstplr_lower_routine(a, b, m, mbdcnd, &
393
+ bda, bdb, c, d, n, nbdcnd, bdc, bdd, &
394
+ elmbda, f, idimf, pertrb, ierror, rew)
395
+ end associate
396
+
397
+ ! Release memory
398
+ call workspace%destroy()
399
+
400
+ end subroutine hstplr
401
+
402
+ pure subroutine hstplr_check_input_arguments(a, b, m, mbdcnd, c, d, n, &
403
+ nbdcnd, idimf, ierror)
404
+ !-----------------------------------------------
405
+ ! Dummy arguments
406
+ !-----------------------------------------------
407
+ integer(ip), intent(in) :: m
408
+ integer(ip), intent(in) :: mbdcnd
409
+ integer(ip), intent(in) :: n
410
+ integer(ip), intent(in) :: nbdcnd
411
+ integer(ip), intent(in) :: idimf
412
+ integer(ip), intent(out) :: ierror
413
+ real(wp), intent(in) :: a
414
+ real(wp), intent(in) :: b
415
+ real(wp), intent(in) :: c
416
+ real(wp), intent(in) :: d
417
+ !-----------------------------------------------
418
+
419
+ ! Check validity of calling arguments
420
+ if (a < ZERO) then
421
+ ierror = 1
422
+ return
423
+ else if (a >= b) then
424
+ ierror = 2
425
+ return
426
+ else if (mbdcnd <= 0 .or. mbdcnd >= 7) then
427
+ ierror = 3
428
+ return
429
+ else if (c >= d) then
430
+ ierror = 4
431
+ return
432
+ else if (3 > n) then
433
+ ierror = 5
434
+ return
435
+ else if (nbdcnd < 0 .or. nbdcnd >= 5) then
436
+ ierror = 6
437
+ return
438
+ else if (a == ZERO .and. (mbdcnd == 3 .or. mbdcnd == 4)) then
439
+ ierror = 7
440
+ return
441
+ else if (a > ZERO .and. mbdcnd >= 5) then
442
+ ierror = 8
443
+ return
444
+ else if (mbdcnd >= 5 .and. nbdcnd /= 0 .and. nbdcnd /= 3) then
445
+ ierror = 9
446
+ return
447
+ else if (idimf < m) then
448
+ ierror = 10
449
+ return
450
+ else if (3 > m) then
451
+ ierror = 12
452
+ return
453
+ else
454
+ ierror = 0
455
+ end if
456
+
457
+ end subroutine hstplr_check_input_arguments
458
+
459
+ subroutine hstplr_lower_routine(a, b, m, mbdcnd, bda, bdb, c, d, n, nbdcnd, bdc, &
460
+ bdd, elmbda, f, idimf, pertrb, ierror, w)
461
+ !-----------------------------------------------
462
+ ! Dummy arguments
463
+ !-----------------------------------------------
464
+ integer(ip), intent(in) :: m
465
+ integer(ip), intent(in) :: mbdcnd
466
+ integer(ip), intent(in) :: n
467
+ integer(ip), intent(in) :: nbdcnd
468
+ integer(ip), intent(in) :: idimf
469
+ integer(ip), intent(out) :: ierror
470
+ real(wp), intent(in) :: a
471
+ real(wp), intent(in) :: b
472
+ real(wp), intent(in) :: c
473
+ real(wp), intent(in) :: d
474
+ real(wp), intent(in) :: elmbda
475
+ real(wp), intent(out) :: pertrb
476
+ real(wp), intent(in) :: bda(:)
477
+ real(wp), intent(in) :: bdb(:)
478
+ real(wp), intent(in) :: bdc(:)
479
+ real(wp), intent(in) :: bdd(:)
480
+ real(wp), intent(inout) :: f(:,:)
481
+ real(wp), intent(inout) :: w(:)
482
+ !-----------------------------------------------
483
+ ! Local variables
484
+ !-----------------------------------------------
485
+ integer(ip) :: np, isw, mb, iwb, iwc, iwr
486
+ integer(ip) :: i, j, k, lp, local_error_flag
487
+ real(wp) :: dr, dr2, dth, dth2, a1, a2
488
+ type(CenteredCyclicReductionUtility) :: centered_util
489
+ type(StaggeredCyclicReductionUtility) :: staggered_util
490
+
491
+ dr = (b - a)/m
492
+ dr2 = dr**2
493
+ dth = (d - c)/n
494
+ dth2 = dth**2
495
+ np = nbdcnd + 1
496
+ isw = 1
497
+ mb = mbdcnd
498
+
499
+ if (a == ZERO .and. mbdcnd == 2) mb = 6
500
+ !
501
+ ! define a, b, c coefficients in w-array.
502
+ !
503
+ iwb = m
504
+ iwc = iwb + m
505
+ iwr = iwc + m
506
+
507
+ do i = 1, m
508
+ j = iwr + i
509
+ w(j) = a + (real(i, kind=wp) - HALF)*dr
510
+ w(i) = (a + real(i - 1, kind=wp)*dr)/dr2
511
+ k = iwc + i
512
+ w(k) = (a + real(i, kind=wp)*dr)/dr2
513
+ k = iwb + i
514
+ w(k) = (elmbda - TWO/dr2)*w(j)
515
+ end do
516
+
517
+ do i = 1, m
518
+ j = iwr + i
519
+ f(i,:n) = w(j)*f(i,:n)
520
+ end do
521
+ !
522
+ ! Enter boundary data for r-boundaries.
523
+ !
524
+ select case (mb)
525
+ case (1:2)
526
+ a1 = TWO*w(1)
527
+ w(iwb+1) = w(iwb+1) - w(1)
528
+ f(1,:n) = f(1,:n) - a1*bda(:n)
529
+ case (3:4)
530
+ a1 = dr*w(1)
531
+ w(iwb+1) = w(iwb+1) + w(1)
532
+ f(1,:n) = f(1,:n) + a1*bda(:n)
533
+ end select
534
+
535
+ select case (mb)
536
+ case (1, 4:5)
537
+ a1 = TWO *w(iwr)
538
+ w(iwc) = w(iwc) - w(iwr)
539
+ f(m,:n) = f(m,:n) - a1*bdb(:n)
540
+ case (2:3, 6)
541
+ a1 = dr*w(iwr)
542
+ w(iwc) = w(iwc) + w(iwr)
543
+ f(m,:n) = f(m,:n) - a1*bdb(:n)
544
+ end select
545
+
546
+ !
547
+ ! Enter boundary data for theta-boundaries.
548
+ !
549
+
550
+ a1 = TWO/dth2
551
+ select case (np)
552
+ case (2:3)
553
+ f(:m, 1) = f(:m, 1) - a1*bdc(:m)/w(iwr+1:m+iwr)
554
+ case (4:5)
555
+ a1 = ONE/dth
556
+ f(:m, 1) = f(:m, 1) + a1*bdc(:m)/w(iwr+1:m+iwr)
557
+ end select
558
+
559
+ a1 = TWO/dth2
560
+ select case (np)
561
+ case (2, 5)
562
+ f(:m, n) = f(:m, n) - a1*bdd(:m)/w(iwr+1:m+iwr)
563
+ case (3:4)
564
+ a1 = ONE /dth
565
+ f(:m, n) = f(:m, n) - a1*bdd(:m)/w(iwr+1:m+iwr)
566
+ end select
567
+
568
+ pertrb = ZERO
569
+ if (elmbda >= ZERO) then
570
+ if (elmbda /= ZERO) then
571
+ ierror = 11
572
+ return
573
+ else
574
+ select case (mb)
575
+ case (3, 6)
576
+ select case (np)
577
+ case (1, 4)
578
+ isw = 2
579
+ do j = 1, n
580
+ pertrb = pertrb + sum(f(:m, j))
581
+ end do
582
+ pertrb = pertrb/(real(m*n, kind=wp)*HALF*(a + b))
583
+ do i = 1, m
584
+ j = iwr + i
585
+ a1 = pertrb*w(j)
586
+ f(i,:n) = f(i,:n) - a1
587
+ end do
588
+ a2 = sum(f(1,:n))
589
+ a2 = a2/w(iwr+1)
590
+ end select
591
+ end select
592
+ end if
593
+ end if
594
+
595
+ do i = 1, m
596
+ j = iwr + i
597
+ a1 = dth2*w(j)
598
+ w(i) = a1*w(i)
599
+ j = iwc + i
600
+ w(j) = a1*w(j)
601
+ j = iwb + i
602
+ w(j) = a1*w(j)
603
+ f(i,:n) = a1*f(i,:n)
604
+ end do
605
+
606
+ lp = nbdcnd
607
+ w(1) = ZERO
608
+ w(iwr) = ZERO
609
+ !
610
+ ! To solve the system of equations.
611
+ !
612
+ local_error_flag = 0
613
+
614
+ set_arguments: associate( &
615
+ a_arg => w(1:m), &
616
+ b_arg => w(iwb+1:iwb+1+m), &
617
+ c_arg => w(iwc+1:iwc+1+m), &
618
+ w_arg => w(iwr+1:iwr+1+m) &
619
+ )
620
+ if (lp /= 0) then
621
+ call staggered_util%poistg_lower_routine(lp, n, 1, m, a_arg, b_arg, c_arg, idimf, f, local_error_flag, w_arg)
622
+ else
623
+ call centered_util%genbun_lower_routine(lp, n, 1, m, a_arg, b_arg, w_arg, idimf, f, local_error_flag, w_arg)
624
+ end if
625
+ end associate set_arguments
626
+
627
+ if (.not.(a /= ZERO .or. mbdcnd /= 2 .or. isw /= 2)) then
628
+ a1 = sum(f(1,:n))
629
+ a1 = (a1 - dr2*a2/16)/n
630
+
631
+ if (nbdcnd == 3) a1 = a1 + (bdd(1)-bdc(1))/(d - c)
632
+
633
+ a1 = bda(1) - a1
634
+ f(:m,:n) = f(:m,:n) + a1
635
+ end if
636
+
637
+ end subroutine hstplr_lower_routine
638
+
639
+ end submodule staggered_polar_solver
640
+ !
641
+ ! REVISION HISTORY
642
+ !
643
+ ! September 1973 Version 1
644
+ ! April 1976 Version 2
645
+ ! January 1978 Version 3
646
+ ! December 1979 Version 3.1
647
+ ! February 1985 Documentation upgrade
648
+ ! November 1988 Version 3.2, FORTRAN 77 changes
649
+ ! June 2004 Version 5.0, Fortran 90 changes
650
+ ! May 2016 Fortran 2008 changes
651
+ !