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,969 @@
1
+ module iterative_solvers
2
+
3
+ use, intrinsic :: iso_c_binding, only: &
4
+ c_double, &
5
+ c_int, &
6
+ c_ptr, &
7
+ c_f_pointer
8
+
9
+ implicit none
10
+
11
+ contains
12
+
13
+ subroutine pyfp_sor_standard1d(n, s_ptr, a_ptr, b_ptr, f_ptr, delx, bcx, &
14
+ optarg, undef, mxloop, tolerance, overflow, relerr, loops) &
15
+ bind(C, name="pyfp_sor_standard1d")
16
+
17
+ integer(c_int), value :: n, bcx, mxloop
18
+ type(c_ptr), value :: s_ptr, a_ptr, b_ptr, f_ptr
19
+ real(c_double), value :: delx, optarg, undef, tolerance
20
+ integer(c_int), intent(out) :: overflow, loops
21
+ real(c_double), intent(out) :: relerr
22
+
23
+ real(c_double), pointer :: s(:), a(:), b(:), f(:)
24
+
25
+ call c_f_pointer(s_ptr, s, [n])
26
+ call c_f_pointer(a_ptr, a, [n])
27
+ call c_f_pointer(b_ptr, b, [n])
28
+ call c_f_pointer(f_ptr, f, [n])
29
+
30
+ call sor_standard1d(n, s, a, b, f, delx, bcx, optarg, undef, &
31
+ mxloop, tolerance, overflow, relerr, loops)
32
+
33
+ end subroutine pyfp_sor_standard1d
34
+
35
+ subroutine pyfp_sor_standard2d(ny, nx, s_ptr, a_ptr, b_ptr, ccoef_ptr, f_ptr, &
36
+ dely, delx, bcy, bcx, optarg, undef, mxloop, tolerance, overflow, &
37
+ relerr, loops) bind(C, name="pyfp_sor_standard2d")
38
+
39
+ integer(c_int), value :: ny, nx, bcy, bcx, mxloop
40
+ type(c_ptr), value :: s_ptr, a_ptr, b_ptr, ccoef_ptr, f_ptr
41
+ real(c_double), value :: dely, delx, optarg, undef, tolerance
42
+ integer(c_int), intent(out) :: overflow, loops
43
+ real(c_double), intent(out) :: relerr
44
+
45
+ real(c_double), pointer :: s(:, :), a(:, :), b(:, :), ccoef(:, :), f(:, :)
46
+
47
+ call c_f_pointer(s_ptr, s, [ny, nx])
48
+ call c_f_pointer(a_ptr, a, [ny, nx])
49
+ call c_f_pointer(b_ptr, b, [ny, nx])
50
+ call c_f_pointer(ccoef_ptr, ccoef, [ny, nx])
51
+ call c_f_pointer(f_ptr, f, [ny, nx])
52
+
53
+ call sor_standard2d(ny, nx, s, a, b, ccoef, f, dely, delx, bcy, bcx, &
54
+ optarg, undef, mxloop, tolerance, overflow, relerr, loops)
55
+
56
+ end subroutine pyfp_sor_standard2d
57
+
58
+ subroutine pyfp_sor_general2d(ny, nx, s_ptr, a_ptr, b_ptr, ccoef_ptr, &
59
+ d_ptr, e_ptr, fcoef_ptr, g_ptr, dely, delx, bcy, bcx, optarg, undef, &
60
+ mxloop, tolerance, overflow, relerr, loops) bind(C, name="pyfp_sor_general2d")
61
+
62
+ integer(c_int), value :: ny, nx, bcy, bcx, mxloop
63
+ type(c_ptr), value :: s_ptr, a_ptr, b_ptr, ccoef_ptr, d_ptr, e_ptr, fcoef_ptr, g_ptr
64
+ real(c_double), value :: dely, delx, optarg, undef, tolerance
65
+ integer(c_int), intent(out) :: overflow, loops
66
+ real(c_double), intent(out) :: relerr
67
+
68
+ real(c_double), pointer :: s(:, :), a(:, :), b(:, :), ccoef(:, :)
69
+ real(c_double), pointer :: d(:, :), e(:, :), fcoef(:, :), g(:, :)
70
+
71
+ call c_f_pointer(s_ptr, s, [ny, nx])
72
+ call c_f_pointer(a_ptr, a, [ny, nx])
73
+ call c_f_pointer(b_ptr, b, [ny, nx])
74
+ call c_f_pointer(ccoef_ptr, ccoef, [ny, nx])
75
+ call c_f_pointer(d_ptr, d, [ny, nx])
76
+ call c_f_pointer(e_ptr, e, [ny, nx])
77
+ call c_f_pointer(fcoef_ptr, fcoef, [ny, nx])
78
+ call c_f_pointer(g_ptr, g, [ny, nx])
79
+
80
+ call sor_general2d(ny, nx, s, a, b, ccoef, d, e, fcoef, g, dely, delx, &
81
+ bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops)
82
+
83
+ end subroutine pyfp_sor_general2d
84
+
85
+ subroutine pyfp_sor_standard3d(nz, ny, nx, s_ptr, a_ptr, b_ptr, ccoef_ptr, f_ptr, &
86
+ delz, dely, delx, bcz, bcy, bcx, optarg, undef, mxloop, tolerance, overflow, &
87
+ relerr, loops) bind(C, name="pyfp_sor_standard3d")
88
+
89
+ integer(c_int), value :: nz, ny, nx, bcz, bcy, bcx, mxloop
90
+ type(c_ptr), value :: s_ptr, a_ptr, b_ptr, ccoef_ptr, f_ptr
91
+ real(c_double), value :: delz, dely, delx, optarg, undef, tolerance
92
+ integer(c_int), intent(out) :: overflow, loops
93
+ real(c_double), intent(out) :: relerr
94
+
95
+ real(c_double), pointer :: s(:, :, :), a(:, :, :), b(:, :, :), ccoef(:, :, :), f(:, :, :)
96
+
97
+ call c_f_pointer(s_ptr, s, [nz, ny, nx])
98
+ call c_f_pointer(a_ptr, a, [nz, ny, nx])
99
+ call c_f_pointer(b_ptr, b, [nz, ny, nx])
100
+ call c_f_pointer(ccoef_ptr, ccoef, [nz, ny, nx])
101
+ call c_f_pointer(f_ptr, f, [nz, ny, nx])
102
+
103
+ call sor_standard3d(nz, ny, nx, s, a, b, ccoef, f, delz, dely, delx, &
104
+ bcz, bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops)
105
+
106
+ end subroutine pyfp_sor_standard3d
107
+
108
+ subroutine pyfp_sor_general3d(nz, ny, nx, s_ptr, a_ptr, b_ptr, ccoef_ptr, &
109
+ d_ptr, e_ptr, fcoef_ptr, g_ptr, h_ptr, delz, dely, delx, bcz, bcy, bcx, &
110
+ optarg, undef, mxloop, tolerance, overflow, relerr, loops) bind(C, name="pyfp_sor_general3d")
111
+
112
+ integer(c_int), value :: nz, ny, nx, bcz, bcy, bcx, mxloop
113
+ type(c_ptr), value :: s_ptr, a_ptr, b_ptr, ccoef_ptr, d_ptr, e_ptr, fcoef_ptr, g_ptr, h_ptr
114
+ real(c_double), value :: delz, dely, delx, optarg, undef, tolerance
115
+ integer(c_int), intent(out) :: overflow, loops
116
+ real(c_double), intent(out) :: relerr
117
+
118
+ real(c_double), pointer :: s(:, :, :), a(:, :, :), b(:, :, :), ccoef(:, :, :)
119
+ real(c_double), pointer :: d(:, :, :), e(:, :, :), fcoef(:, :, :), g(:, :, :), h(:, :, :)
120
+
121
+ call c_f_pointer(s_ptr, s, [nz, ny, nx])
122
+ call c_f_pointer(a_ptr, a, [nz, ny, nx])
123
+ call c_f_pointer(b_ptr, b, [nz, ny, nx])
124
+ call c_f_pointer(ccoef_ptr, ccoef, [nz, ny, nx])
125
+ call c_f_pointer(d_ptr, d, [nz, ny, nx])
126
+ call c_f_pointer(e_ptr, e, [nz, ny, nx])
127
+ call c_f_pointer(fcoef_ptr, fcoef, [nz, ny, nx])
128
+ call c_f_pointer(g_ptr, g, [nz, ny, nx])
129
+ call c_f_pointer(h_ptr, h, [nz, ny, nx])
130
+
131
+ call sor_general3d(nz, ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, &
132
+ delz, dely, delx, bcz, bcy, bcx, optarg, undef, mxloop, tolerance, &
133
+ overflow, relerr, loops)
134
+
135
+ end subroutine pyfp_sor_general3d
136
+
137
+ subroutine pyfp_sor_biharmonic2d(ny, nx, s_ptr, a_ptr, b_ptr, ccoef_ptr, &
138
+ d_ptr, e_ptr, fcoef_ptr, g_ptr, h_ptr, icoef_ptr, jcoef_ptr, dely, delx, &
139
+ bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops) &
140
+ bind(C, name="pyfp_sor_biharmonic2d")
141
+
142
+ integer(c_int), value :: ny, nx, bcy, bcx, mxloop
143
+ type(c_ptr), value :: s_ptr, a_ptr, b_ptr, ccoef_ptr, d_ptr, e_ptr
144
+ type(c_ptr), value :: fcoef_ptr, g_ptr, h_ptr, icoef_ptr, jcoef_ptr
145
+ real(c_double), value :: dely, delx, optarg, undef, tolerance
146
+ integer(c_int), intent(out) :: overflow, loops
147
+ real(c_double), intent(out) :: relerr
148
+
149
+ real(c_double), pointer :: s(:, :), a(:, :), b(:, :), ccoef(:, :)
150
+ real(c_double), pointer :: d(:, :), e(:, :), fcoef(:, :), g(:, :)
151
+ real(c_double), pointer :: h(:, :), icoef(:, :), jcoef(:, :)
152
+
153
+ call c_f_pointer(s_ptr, s, [ny, nx])
154
+ call c_f_pointer(a_ptr, a, [ny, nx])
155
+ call c_f_pointer(b_ptr, b, [ny, nx])
156
+ call c_f_pointer(ccoef_ptr, ccoef, [ny, nx])
157
+ call c_f_pointer(d_ptr, d, [ny, nx])
158
+ call c_f_pointer(e_ptr, e, [ny, nx])
159
+ call c_f_pointer(fcoef_ptr, fcoef, [ny, nx])
160
+ call c_f_pointer(g_ptr, g, [ny, nx])
161
+ call c_f_pointer(h_ptr, h, [ny, nx])
162
+ call c_f_pointer(icoef_ptr, icoef, [ny, nx])
163
+ call c_f_pointer(jcoef_ptr, jcoef, [ny, nx])
164
+
165
+ call sor_biharmonic2d(ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, icoef, jcoef, &
166
+ dely, delx, bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops)
167
+
168
+ end subroutine pyfp_sor_biharmonic2d
169
+
170
+ subroutine sor_standard1d(n, s, a, b, f, delx, bcx, optarg, undef, &
171
+ mxloop, tolerance, overflow, relerr, loops)
172
+
173
+ integer(c_int), intent(in) :: n, bcx, mxloop
174
+ real(c_double), intent(inout) :: s(n)
175
+ real(c_double), intent(in) :: a(n), b(n), f(n), delx, optarg, undef, tolerance
176
+ integer(c_int), intent(out) :: overflow, loops
177
+ real(c_double), intent(out) :: relerr
178
+
179
+ integer :: i, loop
180
+ real(c_double) :: temp, norm, norm_prev, delx_sqr, denom
181
+
182
+ overflow = 0_c_int
183
+ loops = 0_c_int
184
+ relerr = 1.0_c_double
185
+ norm_prev = huge(1.0_c_double)
186
+ delx_sqr = delx * delx
187
+ loop = 0
188
+
189
+ do
190
+ if (bcx == 1_c_int) then
191
+ if (s(2) /= undef) s(1) = s(2)
192
+ if (s(n - 1) /= undef) s(n) = s(n - 1)
193
+ end if
194
+
195
+ if (bcx == 2_c_int) then
196
+ if (f(1) /= undef .and. a(1) /= undef .and. a(2) /= undef .and. b(1) /= undef) then
197
+ denom = (a(2) + a(1)) / delx_sqr - b(1)
198
+ temp = (a(2) * (s(2) - s(1)) - a(1) * (s(1) - s(n))) / delx_sqr &
199
+ + (b(1) * s(1) - f(1))
200
+ s(1) = s(1) + optarg * temp / denom
201
+ end if
202
+ end if
203
+
204
+ do i = 2, n - 1
205
+ if (f(i) /= undef .and. a(i) /= undef .and. a(i + 1) /= undef .and. b(i) /= undef) then
206
+ denom = (a(i + 1) + a(i)) / delx_sqr - b(i)
207
+ temp = (a(i + 1) * (s(i + 1) - s(i)) - a(i) * (s(i) - s(i - 1))) / delx_sqr &
208
+ + (b(i) * s(i) - f(i))
209
+ s(i) = s(i) + optarg * temp / denom
210
+ end if
211
+ end do
212
+
213
+ if (bcx == 2_c_int) then
214
+ if (f(n) /= undef .and. a(n) /= undef .and. a(1) /= undef .and. b(n) /= undef) then
215
+ denom = (a(1) + a(n)) / delx_sqr - b(n)
216
+ temp = (a(1) * (s(1) - s(n)) - a(n) * (s(n) - s(n - 1))) / delx_sqr &
217
+ + (b(n) * s(n) - f(n))
218
+ s(n) = s(n) + optarg * temp / denom
219
+ end if
220
+ end if
221
+
222
+ norm = abs_norm1d(n, s, undef)
223
+ if (norm /= norm .or. norm > 1.0e100_c_double) then
224
+ overflow = 1_c_int
225
+ exit
226
+ end if
227
+
228
+ relerr = abs(norm - norm_prev) / norm_prev
229
+ loops = int(loop, c_int)
230
+ if (relerr < tolerance .or. loop >= mxloop .or. norm == 0.0_c_double) exit
231
+
232
+ norm_prev = norm
233
+ loop = loop + 1
234
+ end do
235
+
236
+ end subroutine sor_standard1d
237
+
238
+ subroutine sor_standard2d(ny, nx, s, a, b, ccoef, f, dely, delx, bcy, bcx, &
239
+ optarg, undef, mxloop, tolerance, overflow, relerr, loops)
240
+
241
+ integer(c_int), intent(in) :: ny, nx, bcy, bcx, mxloop
242
+ real(c_double), intent(inout) :: s(ny, nx)
243
+ real(c_double), intent(in) :: a(ny, nx), b(ny, nx), ccoef(ny, nx), f(ny, nx)
244
+ real(c_double), intent(in) :: dely, delx, optarg, undef, tolerance
245
+ integer(c_int), intent(out) :: overflow, loops
246
+ real(c_double), intent(out) :: relerr
247
+
248
+ integer :: i, j, loop
249
+ real(c_double) :: norm, norm_prev, ratio_sqr, ratio_qtr, delx_sqr
250
+
251
+ overflow = 0_c_int
252
+ loops = 0_c_int
253
+ relerr = 1.0_c_double
254
+ norm_prev = huge(1.0_c_double)
255
+ delx_sqr = delx * delx
256
+ ratio_sqr = (delx / dely) ** 2
257
+ ratio_qtr = (delx / dely) / 4.0_c_double
258
+ loop = 0
259
+
260
+ do
261
+ if (bcy == 1_c_int) call apply_extend_y(ny, nx, s, undef, bcx)
262
+ if (bcx == 1_c_int) call apply_extend_x(ny, nx, s, undef)
263
+
264
+ do j = 2, ny - 1
265
+ if (bcx == 2_c_int) then
266
+ i = 1
267
+ call update_standard2d_point(ny, nx, s, a, b, ccoef, f, j, i, &
268
+ delx_sqr, ratio_sqr, ratio_qtr, optarg, undef)
269
+ end if
270
+
271
+ do i = 2, nx - 1
272
+ call update_standard2d_point(ny, nx, s, a, b, ccoef, f, j, i, &
273
+ delx_sqr, ratio_sqr, ratio_qtr, optarg, undef)
274
+ end do
275
+
276
+ if (bcx == 2_c_int) then
277
+ i = nx
278
+ call update_standard2d_point(ny, nx, s, a, b, ccoef, f, j, i, &
279
+ delx_sqr, ratio_sqr, ratio_qtr, optarg, undef)
280
+ end if
281
+ end do
282
+
283
+ norm = abs_norm2d(ny, nx, s, undef)
284
+ if (norm /= norm .or. norm > 1.0e100_c_double) then
285
+ overflow = 1_c_int
286
+ exit
287
+ end if
288
+
289
+ relerr = abs(norm - norm_prev) / norm_prev
290
+ loops = int(loop, c_int)
291
+ if (relerr < tolerance .or. loop >= mxloop) exit
292
+
293
+ norm_prev = norm
294
+ loop = loop + 1
295
+ end do
296
+
297
+ end subroutine sor_standard2d
298
+
299
+ subroutine sor_standard3d(nz, ny, nx, s, a, b, ccoef, f, delz, dely, delx, &
300
+ bcz, bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops)
301
+
302
+ integer(c_int), intent(in) :: nz, ny, nx, bcz, bcy, bcx, mxloop
303
+ real(c_double), intent(inout) :: s(nz, ny, nx)
304
+ real(c_double), intent(in) :: a(nz, ny, nx), b(nz, ny, nx), ccoef(nz, ny, nx), f(nz, ny, nx)
305
+ real(c_double), intent(in) :: delz, dely, delx, optarg, undef, tolerance
306
+ integer(c_int), intent(out) :: overflow, loops
307
+ real(c_double), intent(out) :: relerr
308
+
309
+ integer :: i, j, k, loop
310
+ real(c_double) :: norm, norm_prev, ratio_z_sqr, ratio_y_sqr, delx_sqr
311
+
312
+ overflow = 0_c_int
313
+ loops = 0_c_int
314
+ relerr = 1.0_c_double
315
+ norm_prev = huge(1.0_c_double)
316
+ delx_sqr = delx * delx
317
+ ratio_z_sqr = (delx / delz) ** 2
318
+ ratio_y_sqr = (delx / dely) ** 2
319
+ loop = 0
320
+
321
+ do
322
+ if (bcz == 1_c_int) call apply_extend_z3d(nz, ny, nx, s, undef)
323
+ if (bcy == 1_c_int) call apply_extend_y3d(nz, ny, nx, s, undef, bcx)
324
+ if (bcx == 1_c_int) call apply_extend_x3d(nz, ny, nx, s, undef)
325
+
326
+ do k = 2, nz - 1
327
+ do j = 2, ny - 1
328
+ if (bcx == 2_c_int) then
329
+ i = 1
330
+ call update_standard3d_point(nz, ny, nx, s, a, b, ccoef, f, k, j, i, &
331
+ delx_sqr, ratio_z_sqr, ratio_y_sqr, optarg, undef)
332
+ end if
333
+
334
+ do i = 2, nx - 1
335
+ call update_standard3d_point(nz, ny, nx, s, a, b, ccoef, f, k, j, i, &
336
+ delx_sqr, ratio_z_sqr, ratio_y_sqr, optarg, undef)
337
+ end do
338
+
339
+ if (bcx == 2_c_int) then
340
+ i = nx
341
+ call update_standard3d_point(nz, ny, nx, s, a, b, ccoef, f, k, j, i, &
342
+ delx_sqr, ratio_z_sqr, ratio_y_sqr, optarg, undef)
343
+ end if
344
+ end do
345
+ end do
346
+
347
+ norm = abs_norm3d(nz, ny, nx, s, undef)
348
+ if (norm /= norm .or. norm > 1.0e100_c_double) then
349
+ overflow = 1_c_int
350
+ exit
351
+ end if
352
+
353
+ relerr = abs(norm - norm_prev) / norm_prev
354
+ loops = int(loop, c_int)
355
+ if (relerr < tolerance .or. loop >= mxloop) exit
356
+
357
+ norm_prev = norm
358
+ loop = loop + 1
359
+ end do
360
+
361
+ end subroutine sor_standard3d
362
+
363
+ subroutine sor_general2d(ny, nx, s, a, b, ccoef, d, e, fcoef, g, dely, delx, &
364
+ bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops)
365
+
366
+ integer(c_int), intent(in) :: ny, nx, bcy, bcx, mxloop
367
+ real(c_double), intent(inout) :: s(ny, nx)
368
+ real(c_double), intent(in) :: a(ny, nx), b(ny, nx), ccoef(ny, nx)
369
+ real(c_double), intent(in) :: d(ny, nx), e(ny, nx), fcoef(ny, nx), g(ny, nx)
370
+ real(c_double), intent(in) :: dely, delx, optarg, undef, tolerance
371
+ integer(c_int), intent(out) :: overflow, loops
372
+ real(c_double), intent(out) :: relerr
373
+
374
+ integer :: i, j, loop
375
+ real(c_double) :: norm, norm_prev, ratio, ratio_sqr, ratio_qtr, delx_sqr
376
+
377
+ overflow = 0_c_int
378
+ loops = 0_c_int
379
+ relerr = 1.0_c_double
380
+ norm_prev = huge(1.0_c_double)
381
+ delx_sqr = delx * delx
382
+ ratio = delx / dely
383
+ ratio_sqr = ratio * ratio
384
+ ratio_qtr = ratio / 4.0_c_double
385
+ loop = 0
386
+
387
+ do
388
+ if (bcy == 1_c_int) call apply_extend_y(ny, nx, s, undef, bcx)
389
+ if (bcx == 1_c_int) call apply_extend_x(ny, nx, s, undef)
390
+
391
+ do j = 2, ny - 1
392
+ if (bcx == 2_c_int) then
393
+ i = 1
394
+ call update_general2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, g, j, i, &
395
+ delx, delx_sqr, ratio, ratio_sqr, ratio_qtr, optarg, undef)
396
+ end if
397
+
398
+ do i = 2, nx - 1
399
+ call update_general2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, g, j, i, &
400
+ delx, delx_sqr, ratio, ratio_sqr, ratio_qtr, optarg, undef)
401
+ end do
402
+
403
+ if (bcx == 2_c_int) then
404
+ i = nx
405
+ call update_general2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, g, j, i, &
406
+ delx, delx_sqr, ratio, ratio_sqr, ratio_qtr, optarg, undef)
407
+ end if
408
+ end do
409
+
410
+ norm = abs_norm2d(ny, nx, s, undef)
411
+ if (norm /= norm .or. norm > 1.0e100_c_double) then
412
+ overflow = 1_c_int
413
+ exit
414
+ end if
415
+
416
+ relerr = abs(norm - norm_prev) / norm_prev
417
+ loops = int(loop, c_int)
418
+ if (relerr < tolerance .or. loop >= mxloop) exit
419
+
420
+ norm_prev = norm
421
+ loop = loop + 1
422
+ end do
423
+
424
+ end subroutine sor_general2d
425
+
426
+ subroutine sor_general3d(nz, ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, &
427
+ delz, dely, delx, bcz, bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops)
428
+
429
+ integer(c_int), intent(in) :: nz, ny, nx, bcz, bcy, bcx, mxloop
430
+ real(c_double), intent(inout) :: s(nz, ny, nx)
431
+ real(c_double), intent(in) :: a(nz, ny, nx), b(nz, ny, nx), ccoef(nz, ny, nx)
432
+ real(c_double), intent(in) :: d(nz, ny, nx), e(nz, ny, nx), fcoef(nz, ny, nx)
433
+ real(c_double), intent(in) :: g(nz, ny, nx), h(nz, ny, nx)
434
+ real(c_double), intent(in) :: delz, dely, delx, optarg, undef, tolerance
435
+ integer(c_int), intent(out) :: overflow, loops
436
+ real(c_double), intent(out) :: relerr
437
+
438
+ integer :: i, j, k, loop
439
+ real(c_double) :: norm, norm_prev, ratio_z, ratio_y, ratio_z_sqr, ratio_y_sqr, delx_sqr
440
+
441
+ overflow = 0_c_int
442
+ loops = 0_c_int
443
+ relerr = 1.0_c_double
444
+ norm_prev = huge(1.0_c_double)
445
+ delx_sqr = delx * delx
446
+ ratio_z = delx / delz
447
+ ratio_y = delx / dely
448
+ ratio_z_sqr = ratio_z * ratio_z
449
+ ratio_y_sqr = ratio_y * ratio_y
450
+ loop = 0
451
+
452
+ do
453
+ if (bcz == 1_c_int) call apply_extend_z3d(nz, ny, nx, s, undef)
454
+ if (bcy == 1_c_int) call apply_extend_y3d(nz, ny, nx, s, undef, bcx)
455
+ if (bcx == 1_c_int) call apply_extend_x3d(nz, ny, nx, s, undef)
456
+
457
+ do k = 2, nz - 1
458
+ do j = 2, ny - 1
459
+ if (bcx == 2_c_int) then
460
+ i = 1
461
+ call update_general3d_point(nz, ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, k, j, i, &
462
+ delx, delx_sqr, ratio_z, ratio_y, ratio_z_sqr, ratio_y_sqr, optarg, undef)
463
+ end if
464
+
465
+ do i = 2, nx - 1
466
+ call update_general3d_point(nz, ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, k, j, i, &
467
+ delx, delx_sqr, ratio_z, ratio_y, ratio_z_sqr, ratio_y_sqr, optarg, undef)
468
+ end do
469
+
470
+ if (bcx == 2_c_int) then
471
+ i = nx
472
+ call update_general3d_point(nz, ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, k, j, i, &
473
+ delx, delx_sqr, ratio_z, ratio_y, ratio_z_sqr, ratio_y_sqr, optarg, undef)
474
+ end if
475
+ end do
476
+ end do
477
+
478
+ norm = abs_norm3d(nz, ny, nx, s, undef)
479
+ if (norm /= norm .or. norm > 1.0e100_c_double) then
480
+ overflow = 1_c_int
481
+ exit
482
+ end if
483
+
484
+ relerr = abs(norm - norm_prev) / norm_prev
485
+ loops = int(loop, c_int)
486
+ if (relerr < tolerance .or. loop >= mxloop) exit
487
+
488
+ norm_prev = norm
489
+ loop = loop + 1
490
+ end do
491
+
492
+ end subroutine sor_general3d
493
+
494
+ subroutine sor_biharmonic2d(ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, icoef, jcoef, &
495
+ dely, delx, bcy, bcx, optarg, undef, mxloop, tolerance, overflow, relerr, loops)
496
+
497
+ integer(c_int), intent(in) :: ny, nx, bcy, bcx, mxloop
498
+ real(c_double), intent(inout) :: s(ny, nx)
499
+ real(c_double), intent(in) :: a(ny, nx), b(ny, nx), ccoef(ny, nx)
500
+ real(c_double), intent(in) :: d(ny, nx), e(ny, nx), fcoef(ny, nx)
501
+ real(c_double), intent(in) :: g(ny, nx), h(ny, nx), icoef(ny, nx), jcoef(ny, nx)
502
+ real(c_double), intent(in) :: dely, delx, optarg, undef, tolerance
503
+ integer(c_int), intent(out) :: overflow, loops
504
+ real(c_double), intent(out) :: relerr
505
+
506
+ integer :: i, j, loop
507
+ real(c_double) :: norm, norm_prev, ratio, ratio_sqr, ratio_qtr
508
+ real(c_double) :: ratio_fourth, delx_sqr, delx_cubed, delx_fourth
509
+
510
+ overflow = 0_c_int
511
+ loops = 0_c_int
512
+ relerr = 1.0_c_double
513
+ norm_prev = huge(1.0_c_double)
514
+ ratio = delx / dely
515
+ ratio_sqr = ratio * ratio
516
+ ratio_qtr = ratio / 4.0_c_double
517
+ ratio_fourth = ratio_sqr * ratio_sqr
518
+ delx_sqr = delx * delx
519
+ delx_cubed = delx_sqr * delx
520
+ delx_fourth = delx_sqr * delx_sqr
521
+ loop = 0
522
+
523
+ do
524
+ if (bcy == 1_c_int) call apply_extend_biharmonic_y(ny, nx, s, undef, bcx)
525
+ if (bcx == 1_c_int) call apply_extend_biharmonic_x(ny, nx, s, undef)
526
+
527
+ do j = 3, ny - 2
528
+ if (bcx == 2_c_int) then
529
+ i = 1
530
+ call update_biharmonic2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, &
531
+ g, h, icoef, jcoef, j, i, delx_sqr, delx_cubed, delx_fourth, &
532
+ ratio, ratio_sqr, ratio_qtr, ratio_fourth, optarg, undef)
533
+ i = 2
534
+ call update_biharmonic2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, &
535
+ g, h, icoef, jcoef, j, i, delx_sqr, delx_cubed, delx_fourth, &
536
+ ratio, ratio_sqr, ratio_qtr, ratio_fourth, optarg, undef)
537
+ end if
538
+
539
+ do i = 3, nx - 2
540
+ call update_biharmonic2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, &
541
+ g, h, icoef, jcoef, j, i, delx_sqr, delx_cubed, delx_fourth, &
542
+ ratio, ratio_sqr, ratio_qtr, ratio_fourth, optarg, undef)
543
+ end do
544
+
545
+ if (bcx == 2_c_int) then
546
+ i = nx - 1
547
+ call update_biharmonic2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, &
548
+ g, h, icoef, jcoef, j, i, delx_sqr, delx_cubed, delx_fourth, &
549
+ ratio, ratio_sqr, ratio_qtr, ratio_fourth, optarg, undef)
550
+ i = nx
551
+ call update_biharmonic2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, &
552
+ g, h, icoef, jcoef, j, i, delx_sqr, delx_cubed, delx_fourth, &
553
+ ratio, ratio_sqr, ratio_qtr, ratio_fourth, optarg, undef)
554
+ end if
555
+ end do
556
+
557
+ norm = abs_norm2d(ny, nx, s, undef)
558
+ if (norm /= norm .or. norm > 1.0e100_c_double) then
559
+ overflow = 1_c_int
560
+ exit
561
+ end if
562
+
563
+ relerr = abs(norm - norm_prev) / norm_prev
564
+ loops = int(loop, c_int)
565
+ if (relerr < tolerance .or. loop >= mxloop) exit
566
+
567
+ norm_prev = norm
568
+ loop = loop + 1
569
+ end do
570
+
571
+ end subroutine sor_biharmonic2d
572
+
573
+ subroutine update_standard2d_point(ny, nx, s, a, b, ccoef, f, j, i, &
574
+ delx_sqr, ratio_sqr, ratio_qtr, optarg, undef)
575
+
576
+ integer, intent(in) :: ny, nx, j, i
577
+ real(c_double), intent(inout) :: s(ny, nx)
578
+ real(c_double), intent(in) :: a(ny, nx), b(ny, nx), ccoef(ny, nx), f(ny, nx)
579
+ real(c_double), intent(in) :: delx_sqr, ratio_sqr, ratio_qtr, optarg, undef
580
+
581
+ integer :: im, ip
582
+ real(c_double) :: temp, denom
583
+
584
+ im = i - 1
585
+ ip = i + 1
586
+ if (i == 1) im = nx
587
+ if (i == nx) ip = 1
588
+
589
+ if (f(j, i) == undef) return
590
+ if (a(j + 1, i) == undef .or. a(j, i) == undef) return
591
+ if (b(j, ip) == undef .or. b(j, im) == undef .or. b(j + 1, i) == undef .or. b(j - 1, i) == undef) return
592
+ if (ccoef(j, ip) == undef .or. ccoef(j, i) == undef) return
593
+
594
+ temp = (a(j + 1, i) * (s(j + 1, i) - s(j, i)) - a(j, i) * (s(j, i) - s(j - 1, i))) &
595
+ * ratio_sqr &
596
+ + (b(j + 1, ip) * (s(j + 1, ip) - s(j + 1, im)) &
597
+ - b(j - 1, i) * (s(j - 1, i) - s(j - 1, im))) * ratio_qtr &
598
+ + (b(j, ip) * (s(j + 1, ip) - s(j - 1, ip)) &
599
+ - b(j, im) * (s(j + 1, im) - s(j - 1, im))) * ratio_qtr &
600
+ + ccoef(j, ip) * (s(j, ip) - s(j, i)) &
601
+ - ccoef(j, i) * (s(j, i) - s(j, im)) &
602
+ - f(j, i) * delx_sqr
603
+
604
+ denom = (a(j + 1, i) + a(j, i)) * ratio_sqr + ccoef(j, ip) + ccoef(j, i)
605
+ s(j, i) = s(j, i) + optarg * temp / denom
606
+
607
+ end subroutine update_standard2d_point
608
+
609
+ subroutine update_standard3d_point(nz, ny, nx, s, a, b, ccoef, f, k, j, i, &
610
+ delx_sqr, ratio_z_sqr, ratio_y_sqr, optarg, undef)
611
+
612
+ integer, intent(in) :: nz, ny, nx, k, j, i
613
+ real(c_double), intent(inout) :: s(nz, ny, nx)
614
+ real(c_double), intent(in) :: a(nz, ny, nx), b(nz, ny, nx), ccoef(nz, ny, nx), f(nz, ny, nx)
615
+ real(c_double), intent(in) :: delx_sqr, ratio_z_sqr, ratio_y_sqr, optarg, undef
616
+
617
+ integer :: im, ip
618
+ real(c_double) :: temp, denom
619
+
620
+ im = i - 1
621
+ ip = i + 1
622
+ if (i == 1) im = nx
623
+ if (i == nx) ip = 1
624
+
625
+ if (f(k, j, i) == undef) return
626
+ if (a(k + 1, j, i) == undef .or. a(k, j, i) == undef) return
627
+ if (b(k, j + 1, i) == undef .or. b(k, j, i) == undef) return
628
+ if (ccoef(k, j, ip) == undef .or. ccoef(k, j, i) == undef) return
629
+
630
+ temp = (a(k + 1, j, i) * (s(k + 1, j, i) - s(k, j, i)) &
631
+ - a(k, j, i) * (s(k, j, i) - s(k - 1, j, i))) * ratio_z_sqr &
632
+ + (b(k, j + 1, i) * (s(k, j + 1, i) - s(k, j, i)) &
633
+ - b(k, j, i) * (s(k, j, i) - s(k, j - 1, i))) * ratio_y_sqr &
634
+ + ccoef(k, j, ip) * (s(k, j, ip) - s(k, j, i)) &
635
+ - ccoef(k, j, i) * (s(k, j, i) - s(k, j, im)) &
636
+ - f(k, j, i) * delx_sqr
637
+
638
+ denom = (a(k + 1, j, i) + a(k, j, i)) * ratio_z_sqr &
639
+ + (b(k, j + 1, i) + b(k, j, i)) * ratio_y_sqr &
640
+ + ccoef(k, j, ip) + ccoef(k, j, i)
641
+ s(k, j, i) = s(k, j, i) + optarg * temp / denom
642
+
643
+ end subroutine update_standard3d_point
644
+
645
+ subroutine update_general2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, g, j, i, &
646
+ delx, delx_sqr, ratio, ratio_sqr, ratio_qtr, optarg, undef)
647
+
648
+ integer, intent(in) :: ny, nx, j, i
649
+ real(c_double), intent(inout) :: s(ny, nx)
650
+ real(c_double), intent(in) :: a(ny, nx), b(ny, nx), ccoef(ny, nx)
651
+ real(c_double), intent(in) :: d(ny, nx), e(ny, nx), fcoef(ny, nx), g(ny, nx)
652
+ real(c_double), intent(in) :: delx, delx_sqr, ratio, ratio_sqr, ratio_qtr, optarg, undef
653
+
654
+ integer :: im, ip
655
+ real(c_double) :: temp, denom
656
+
657
+ im = i - 1
658
+ ip = i + 1
659
+ if (i == 1) im = nx
660
+ if (i == nx) ip = 1
661
+
662
+ if (g(j, i) == undef) return
663
+ if (a(j, i) == undef .or. b(j, i) == undef .or. ccoef(j, i) == undef) return
664
+ if (d(j, i) == undef .or. e(j, i) == undef .or. fcoef(j, i) == undef) return
665
+
666
+ temp = a(j, i) * ((s(j + 1, i) - s(j, i)) - (s(j, i) - s(j - 1, i))) * ratio_sqr &
667
+ + b(j, i) * ((s(j + 1, ip) - s(j - 1, ip)) - (s(j + 1, im) - s(j - 1, im))) * ratio_qtr &
668
+ + ccoef(j, i) * ((s(j, ip) - s(j, i)) - (s(j, i) - s(j, im))) &
669
+ + (d(j, i) * (s(j + 1, i) - s(j - 1, i)) * ratio &
670
+ + e(j, i) * (s(j, ip) - s(j, im))) * delx / 2.0_c_double &
671
+ + (fcoef(j, i) * s(j, i) - g(j, i)) * delx_sqr
672
+
673
+ denom = (a(j, i) * ratio_sqr + ccoef(j, i)) * 2.0_c_double - fcoef(j, i) * delx_sqr
674
+ s(j, i) = s(j, i) + optarg * temp / denom
675
+
676
+ end subroutine update_general2d_point
677
+
678
+ subroutine update_general3d_point(nz, ny, nx, s, a, b, ccoef, d, e, fcoef, g, h, k, j, i, &
679
+ delx, delx_sqr, ratio_z, ratio_y, ratio_z_sqr, ratio_y_sqr, optarg, undef)
680
+
681
+ integer, intent(in) :: nz, ny, nx, k, j, i
682
+ real(c_double), intent(inout) :: s(nz, ny, nx)
683
+ real(c_double), intent(in) :: a(nz, ny, nx), b(nz, ny, nx), ccoef(nz, ny, nx)
684
+ real(c_double), intent(in) :: d(nz, ny, nx), e(nz, ny, nx), fcoef(nz, ny, nx)
685
+ real(c_double), intent(in) :: g(nz, ny, nx), h(nz, ny, nx)
686
+ real(c_double), intent(in) :: delx, delx_sqr, ratio_z, ratio_y, ratio_z_sqr, ratio_y_sqr, optarg, undef
687
+
688
+ integer :: im, ip
689
+ real(c_double) :: temp, denom
690
+
691
+ im = i - 1
692
+ ip = i + 1
693
+ if (i == 1) im = nx
694
+ if (i == nx) ip = 1
695
+
696
+ if (h(k, j, i) == undef .or. g(k, j, i) == undef) return
697
+ if (a(k, j, i) == undef .or. b(k, j, i) == undef .or. ccoef(k, j, i) == undef) return
698
+ if (d(k, j, i) == undef .or. e(k, j, i) == undef .or. fcoef(k, j, i) == undef) return
699
+
700
+ temp = a(k, j, i) * ((s(k + 1, j, i) - s(k, j, i)) - (s(k, j, i) - s(k - 1, j, i))) &
701
+ * ratio_z_sqr &
702
+ + b(k, j, i) * ((s(k, j + 1, i) - s(k, j, i)) - (s(k, j, i) - s(k, j - 1, i))) &
703
+ * ratio_y_sqr &
704
+ + ccoef(k, j, i) * ((s(k, j, ip) - s(k, j, i)) - (s(k, j, i) - s(k, j, im))) &
705
+ + (d(k, j, i) * (s(k + 1, j, i) - s(k - 1, j, i)) * ratio_z &
706
+ + e(k, j, i) * (s(k, j + 1, i) - s(k, j - 1, i)) * ratio_y &
707
+ + fcoef(k, j, i) * (s(k, j, ip) - s(k, j, im))) * delx / 2.0_c_double &
708
+ + (g(k, j, i) * s(k, j, i) - h(k, j, i)) * delx_sqr
709
+
710
+ denom = (a(k, j, i) * ratio_z_sqr + b(k, j, i) * ratio_y_sqr + ccoef(k, j, i)) &
711
+ * 2.0_c_double - g(k, j, i) * delx_sqr
712
+ s(k, j, i) = s(k, j, i) + optarg * temp / denom
713
+
714
+ end subroutine update_general3d_point
715
+
716
+ subroutine update_biharmonic2d_point(ny, nx, s, a, b, ccoef, d, e, fcoef, &
717
+ g, h, icoef, jcoef, j, i, delx_sqr, delx_cubed, delx_fourth, ratio, &
718
+ ratio_sqr, ratio_qtr, ratio_fourth, optarg, undef)
719
+
720
+ integer, intent(in) :: ny, nx, j, i
721
+ real(c_double), intent(inout) :: s(ny, nx)
722
+ real(c_double), intent(in) :: a(ny, nx), b(ny, nx), ccoef(ny, nx)
723
+ real(c_double), intent(in) :: d(ny, nx), e(ny, nx), fcoef(ny, nx)
724
+ real(c_double), intent(in) :: g(ny, nx), h(ny, nx), icoef(ny, nx), jcoef(ny, nx)
725
+ real(c_double), intent(in) :: delx_sqr, delx_cubed, delx_fourth, ratio
726
+ real(c_double), intent(in) :: ratio_sqr, ratio_qtr, ratio_fourth, optarg, undef
727
+
728
+ integer :: im1, im2, ip1, ip2
729
+ real(c_double) :: temp, denom
730
+
731
+ im1 = i - 1
732
+ im2 = i - 2
733
+ ip1 = i + 1
734
+ ip2 = i + 2
735
+ if (i == 1) then
736
+ im1 = nx
737
+ im2 = nx - 1
738
+ else if (i == 2) then
739
+ im2 = nx
740
+ end if
741
+ if (i == nx) then
742
+ ip1 = 1
743
+ ip2 = 2
744
+ else if (i == nx - 1) then
745
+ ip2 = 1
746
+ end if
747
+
748
+ if (jcoef(j, i) == undef) return
749
+ if (a(j, i) == undef .or. b(j, i) == undef .or. ccoef(j, i) == undef) return
750
+ if (d(j, i) == undef .or. e(j, i) == undef .or. fcoef(j, i) == undef) return
751
+ if (g(j, i) == undef .or. h(j, i) == undef .or. icoef(j, i) == undef) return
752
+
753
+ temp = a(j, i) * (s(j + 2, i) - 4.0_c_double * s(j + 1, i) + 6.0_c_double * s(j, i) &
754
+ - 4.0_c_double * s(j - 1, i) + s(j - 2, i)) * ratio_fourth &
755
+ + b(j, i) * (s(j + 2, ip2) - 2.0_c_double * s(j + 2, i) + s(j + 2, im2) &
756
+ - 2.0_c_double * s(j, ip2) + 4.0_c_double * s(j, i) - 2.0_c_double * s(j, im2) &
757
+ + s(j - 2, ip2) - 2.0_c_double * s(j - 2, i) + s(j - 2, im2)) * ratio_sqr / 16.0_c_double &
758
+ + ccoef(j, i) * (s(j, ip2) - 4.0_c_double * s(j, ip1) + 6.0_c_double * s(j, i) &
759
+ - 4.0_c_double * s(j, im1) + s(j, im2)) &
760
+ + d(j, i) * ((s(j + 1, i) - s(j, i)) - (s(j, i) - s(j - 1, i))) * ratio_sqr * delx_sqr &
761
+ + e(j, i) * ((s(j + 1, ip1) - s(j - 1, ip1)) - (s(j + 1, im1) - s(j - 1, im1))) &
762
+ * ratio_qtr * delx_sqr &
763
+ + fcoef(j, i) * ((s(j, ip1) - s(j, i)) - (s(j, i) - s(j, im1))) * delx_sqr &
764
+ + g(j, i) * (s(j + 1, i) - s(j - 1, i)) * delx_cubed * ratio / 2.0_c_double &
765
+ + h(j, i) * (s(j, ip1) - s(j, im1)) * delx_cubed / 2.0_c_double &
766
+ + (icoef(j, i) * s(j, i) - jcoef(j, i)) * delx_fourth
767
+
768
+ denom = (a(j, i) * ratio_fourth + ccoef(j, i)) * 6.0_c_double &
769
+ + b(j, i) * ratio_sqr / 4.0_c_double &
770
+ - (d(j, i) * ratio_sqr + fcoef(j, i)) * 2.0_c_double * delx_sqr &
771
+ + icoef(j, i) * delx_fourth
772
+ s(j, i) = s(j, i) - optarg * temp / denom
773
+
774
+ end subroutine update_biharmonic2d_point
775
+
776
+ subroutine apply_extend_y(ny, nx, s, undef, bcx)
777
+ integer, intent(in) :: ny, nx, bcx
778
+ real(c_double), intent(inout) :: s(ny, nx)
779
+ real(c_double), intent(in) :: undef
780
+ integer :: i
781
+
782
+ if (bcx == 2_c_int) then
783
+ do i = 1, nx
784
+ if (s(2, i) /= undef) s(1, i) = s(2, i)
785
+ if (s(ny - 1, i) /= undef) s(ny, i) = s(ny - 1, i)
786
+ end do
787
+ else
788
+ do i = 2, nx - 1
789
+ if (s(2, i) /= undef) s(1, i) = s(2, i)
790
+ if (s(ny - 1, i) /= undef) s(ny, i) = s(ny - 1, i)
791
+ end do
792
+ if (s(2, 2) /= undef) s(1, 1) = s(2, 2)
793
+ if (s(2, nx - 1) /= undef) s(1, nx) = s(2, nx - 1)
794
+ if (s(ny - 1, 2) /= undef) s(ny, 1) = s(ny - 1, 2)
795
+ if (s(ny - 1, nx - 1) /= undef) s(ny, nx) = s(ny - 1, nx - 1)
796
+ end if
797
+ end subroutine apply_extend_y
798
+
799
+ subroutine apply_extend_x(ny, nx, s, undef)
800
+ integer, intent(in) :: ny, nx
801
+ real(c_double), intent(inout) :: s(ny, nx)
802
+ real(c_double), intent(in) :: undef
803
+ integer :: j
804
+
805
+ do j = 2, ny - 1
806
+ if (s(j, 2) /= undef) s(j, 1) = s(j, 2)
807
+ if (s(j, nx - 1) /= undef) s(j, nx) = s(j, nx - 1)
808
+ end do
809
+ end subroutine apply_extend_x
810
+
811
+ subroutine apply_extend_biharmonic_y(ny, nx, s, undef, bcx)
812
+ integer, intent(in) :: ny, nx, bcx
813
+ real(c_double), intent(inout) :: s(ny, nx)
814
+ real(c_double), intent(in) :: undef
815
+ integer :: i, istart, iend
816
+
817
+ istart = 3
818
+ iend = nx - 2
819
+ if (bcx == 2_c_int) then
820
+ istart = 1
821
+ iend = nx
822
+ end if
823
+
824
+ do i = istart, iend
825
+ if (s(3, i) /= undef) then
826
+ s(1, i) = s(3, i)
827
+ s(2, i) = s(3, i)
828
+ end if
829
+ if (s(ny - 2, i) /= undef) then
830
+ s(ny, i) = s(ny - 2, i)
831
+ s(ny - 1, i) = s(ny - 2, i)
832
+ end if
833
+ end do
834
+ end subroutine apply_extend_biharmonic_y
835
+
836
+ subroutine apply_extend_biharmonic_x(ny, nx, s, undef)
837
+ integer, intent(in) :: ny, nx
838
+ real(c_double), intent(inout) :: s(ny, nx)
839
+ real(c_double), intent(in) :: undef
840
+ integer :: j
841
+
842
+ do j = 3, ny - 2
843
+ if (s(j, 3) /= undef) then
844
+ s(j, 1) = s(j, 3)
845
+ s(j, 2) = s(j, 3)
846
+ end if
847
+ if (s(j, nx - 2) /= undef) then
848
+ s(j, nx) = s(j, nx - 2)
849
+ s(j, nx - 1) = s(j, nx - 2)
850
+ end if
851
+ end do
852
+ end subroutine apply_extend_biharmonic_x
853
+
854
+ subroutine apply_extend_z3d(nz, ny, nx, s, undef)
855
+ integer, intent(in) :: nz, ny, nx
856
+ real(c_double), intent(inout) :: s(nz, ny, nx)
857
+ real(c_double), intent(in) :: undef
858
+ integer :: i, j
859
+
860
+ do i = 1, nx
861
+ do j = 1, ny
862
+ if (s(2, j, i) /= undef) s(1, j, i) = s(2, j, i)
863
+ if (s(nz - 1, j, i) /= undef) s(nz, j, i) = s(nz - 1, j, i)
864
+ end do
865
+ end do
866
+ end subroutine apply_extend_z3d
867
+
868
+ subroutine apply_extend_y3d(nz, ny, nx, s, undef, bcx)
869
+ integer, intent(in) :: nz, ny, nx, bcx
870
+ real(c_double), intent(inout) :: s(nz, ny, nx)
871
+ real(c_double), intent(in) :: undef
872
+ integer :: i, k, istart, iend
873
+
874
+ istart = 2
875
+ iend = nx - 1
876
+ if (bcx == 2_c_int) then
877
+ istart = 1
878
+ iend = nx
879
+ end if
880
+
881
+ do k = 2, nz - 1
882
+ do i = istart, iend
883
+ if (s(k, 2, i) /= undef) s(k, 1, i) = s(k, 2, i)
884
+ if (s(k, ny - 1, i) /= undef) s(k, ny, i) = s(k, ny - 1, i)
885
+ end do
886
+ end do
887
+ end subroutine apply_extend_y3d
888
+
889
+ subroutine apply_extend_x3d(nz, ny, nx, s, undef)
890
+ integer, intent(in) :: nz, ny, nx
891
+ real(c_double), intent(inout) :: s(nz, ny, nx)
892
+ real(c_double), intent(in) :: undef
893
+ integer :: j, k
894
+
895
+ do k = 2, nz - 1
896
+ do j = 2, ny - 1
897
+ if (s(k, j, 2) /= undef) s(k, j, 1) = s(k, j, 2)
898
+ if (s(k, j, nx - 1) /= undef) s(k, j, nx) = s(k, j, nx - 1)
899
+ end do
900
+ end do
901
+ end subroutine apply_extend_x3d
902
+
903
+ real(c_double) function abs_norm1d(n, s, undef) result(norm)
904
+ integer, intent(in) :: n
905
+ real(c_double), intent(in) :: s(n), undef
906
+ integer :: i, count
907
+
908
+ norm = 0.0_c_double
909
+ count = 0
910
+ do i = 1, n
911
+ if (s(i) /= undef) then
912
+ norm = norm + abs(s(i))
913
+ count = count + 1
914
+ end if
915
+ end do
916
+ if (count > 0) then
917
+ norm = norm / real(count, c_double)
918
+ else
919
+ norm = huge(1.0_c_double)
920
+ end if
921
+ end function abs_norm1d
922
+
923
+ real(c_double) function abs_norm2d(ny, nx, s, undef) result(norm)
924
+ integer, intent(in) :: ny, nx
925
+ real(c_double), intent(in) :: s(ny, nx), undef
926
+ integer :: i, j, count
927
+
928
+ norm = 0.0_c_double
929
+ count = 0
930
+ do i = 1, nx
931
+ do j = 1, ny
932
+ if (s(j, i) /= undef) then
933
+ norm = norm + abs(s(j, i))
934
+ count = count + 1
935
+ end if
936
+ end do
937
+ end do
938
+ if (count > 0) then
939
+ norm = norm / real(count, c_double)
940
+ else
941
+ norm = huge(1.0_c_double)
942
+ end if
943
+ end function abs_norm2d
944
+
945
+ real(c_double) function abs_norm3d(nz, ny, nx, s, undef) result(norm)
946
+ integer, intent(in) :: nz, ny, nx
947
+ real(c_double), intent(in) :: s(nz, ny, nx), undef
948
+ integer :: i, j, k, count
949
+
950
+ norm = 0.0_c_double
951
+ count = 0
952
+ do i = 1, nx
953
+ do j = 1, ny
954
+ do k = 1, nz
955
+ if (s(k, j, i) /= undef) then
956
+ norm = norm + abs(s(k, j, i))
957
+ count = count + 1
958
+ end if
959
+ end do
960
+ end do
961
+ end do
962
+ if (count > 0) then
963
+ norm = norm / real(count, c_double)
964
+ else
965
+ norm = huge(1.0_c_double)
966
+ end if
967
+ end function abs_norm3d
968
+
969
+ end module iterative_solvers