1 #ifndef DOXYGEN_SHOULD_SKIP_THIS
12 #include "sll_assert.h"
13 #include "sll_working_precision.h"
24 sll_s_delete_mudpack_cartesian, &
25 sll_s_mudpack_cartesian_init, &
26 sll_s_mudpack_polar_init, &
29 sll_t_mudpack_solver, &
31 sll_s_solve_mudpack_cartesian, &
32 sll_s_solve_mudpack_polar
38 type :: sll_t_mudpack_solver
40 sll_real64,
dimension(:),
allocatable :: work
45 sll_int32,
pointer :: iwork(:, :)
47 end type sll_t_mudpack_solver
49 integer,
parameter :: CARTESIAN_2D = 2
50 integer,
parameter :: CARTESIAN_3D = 3
51 integer,
parameter :: POLAR = 11
52 integer,
parameter :: CYLINDRICAL = 12
54 interface sll_o_create
55 module procedure sll_s_mudpack_cartesian_init
56 end interface sll_o_create
59 module procedure sll_s_solve_mudpack_cartesian
60 end interface sll_o_solve
62 interface sll_o_delete
63 module procedure sll_s_delete_mudpack_cartesian
64 end interface sll_o_delete
69 subroutine sll_s_mudpack_cartesian_init(self, &
70 eta1_min, eta1_max, nc_eta1, &
71 eta2_min, eta2_max, nc_eta2, &
72 bc_eta1_left, bc_eta1_right, &
73 bc_eta2_left, bc_eta2_right)
77 type(sll_t_mudpack_solver):: self
78 sll_real64,
intent(in) :: eta1_min
79 sll_real64,
intent(in) :: eta1_max
80 sll_real64,
intent(in) :: eta2_min
81 sll_real64,
intent(in) :: eta2_max
82 sll_int32,
intent(in) :: nc_eta1
83 sll_int32,
intent(in) :: nc_eta2
84 sll_int32,
optional :: bc_eta1_left
85 sll_int32,
optional :: bc_eta1_right
86 sll_int32,
optional :: bc_eta2_left
87 sll_int32,
optional :: bc_eta2_right
88 sll_int32,
parameter :: iixp = 4, jjyq = 4
89 sll_int32 :: iiex, jjey, llwork
91 sll_real64 :: phi(nc_eta1 + 1, nc_eta2 + 1)
92 sll_real64 :: rhs(nc_eta1 + 1, nc_eta2 + 1)
99 sll_int32 :: intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny
100 sll_int32 :: iguess, maxcy, method, nwork, lwrkqd, itero
101 common/itmud2sp/intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
102 iguess, maxcy, method, nwork, lwrkqd, itero
103 sll_real64 :: xa, xb, yc, yd, tolmax, relmax
104 common/ftmud2sp/xa, xb, yc, yd, tolmax, relmax
111 equivalence(intl, iprm)
112 equivalence(xa, fprm)
118 llwork = (7*(nx + 2)*(ny + 2) + 44*nx*ny)/3
120 allocate (self%work(llwork))
121 iiex = ceiling(log((nx - 1.)/iixp)/log(2.)) + 1
122 jjey = ceiling(log((ny - 1.)/jjyq)/log(2.)) + 1
128 nxa = merge(bc_eta1_left, 0,
present(bc_eta1_left))
129 nxb = merge(bc_eta1_right, 0,
present(bc_eta1_right))
130 nyc = merge(bc_eta2_left, 0,
present(bc_eta2_left))
131 nyd = merge(bc_eta2_right, 0,
present(bc_eta2_right))
139 nx = ixp*(2**(iex - 1)) + 1
140 ny = jyq*(2**(jey - 1)) + 1
142 if (nx /= nc_eta1 + 1 .or. ny /= nc_eta2 + 1)
then
143 print *,
"nx,nc_eta1+1=", nx, nc_eta1 + 1
144 print *,
"ny,nc_eta2+1=", ny, nc_eta2 + 1
145 stop
' nx or ny different in sll_mudpack_cartesian '
178 write (*, 101) (iprm(i), i=1, 15)
179 write (*, 102) (self%mgopt(i), i=1, 4)
180 write (*, 103) xa, xb, yc, yd, tolmax
184 call mud2sp(iprm, fprm, self%work, cofx, cofy, bndsp, rhs, phi, self%mgopt, error)
188 write (*, 200) error, iprm(16)
189 if (error > 0) stop 0
191 101
format(/
'# integer input arguments ', &
192 /
'#intl = ', i2,
' nxa = ', i2,
' nxb = ', i2,
' nyc = ', i2,
' nyd = ', i2, &
193 /
'# ixp = ', i2,
' jyq = ', i2,
' iex = ', i2,
' jey = ', i2 &
194 /
'# nx = ', i3,
' ny = ', i3,
' iguess = ', i2,
' maxcy = ', i2, &
195 /
'# method = ', i2,
' work space estimate = ', i7)
197 102
format(/
'# multigrid option arguments ', &
198 /
'# kcycle = ', i2, &
203 103
format(/
'# floating point input parameters ', &
204 /
'# xa = ', f6.3,
' xb = ', f6.3,
' yc = ', f6.3,
' yd = ', f6.3, &
205 /
'# tolerance (error control) = ', e10.3)
207 104
format(/
'# discretization call to mud2sp',
' intl = ', i2)
209 200
format(
'# error = ', i2,
' minimum work space = ', i7)
213 end subroutine sll_s_mudpack_cartesian_init
216 subroutine sll_s_solve_mudpack_cartesian(self, phi, rhs, ex, ey, nrj)
218 type(sll_t_mudpack_solver) :: self
219 sll_real64 :: phi(:, :)
220 sll_real64 :: rhs(:, :)
221 sll_real64,
optional :: ex(:, :)
222 sll_real64,
optional :: ey(:, :)
223 sll_real64,
optional :: nrj
227 sll_int32 :: iprm(16)
228 sll_real64 :: fprm(6)
233 sll_int32 :: intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny
234 sll_int32 :: iguess, maxcy, method, nwork, lwrkqd, itero
235 common/itmud2sp/intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
236 iguess, maxcy, method, nwork, lwrkqd, itero
237 sll_real64 :: xa, xb, yc, yd, tolmax, relmax
238 common/ftmud2sp/xa, xb, yc, yd, tolmax, relmax
240 equivalence(intl, iprm)
241 equivalence(xa, fprm)
245 if (self%iguess == 0)
then
255 write (*, 106) intl, method, iguess
258 if (nxa == 0 .and. nyc == 0) &
259 rhs = rhs - sum(rhs)/real(nx*ny, f64)
261 call mud2sp(iprm, fprm, self%work, cofx, cofy, bndsp, rhs, phi, self%mgopt, error)
265 if (error > 0) stop 0
268 if (nxa == 0 .and. nyc == 0) &
269 phi = phi - sum(phi)/real(nx*ny, f64)
273 call mud24sp(self%work, phi, error)
277 if (error > 0) stop 0
279 106
format(/
'#approximation call to mud2sp', &
280 /
'# intl = ', i2,
' method = ', i2,
' iguess = ', i2)
281 107
format(
'#error = ', i2)
282 108
format(/
'# mud24sp test ',
' error = ', i2)
286 if (
present(ex) .and.
present(ey))
then
287 dx = (xb - xa)/(nx - 1)
288 dy = (yd - yc)/(ny - 1)
290 ex(i, :) = (phi(i + 1, :) - phi(i - 1, :))/(2*dx)
293 ey(:, j) = (phi(:, j + 1) - phi(:, j - 1))/(2*dy)
297 ex(nx, :) = (phi(2, :) - phi(nx - 1, :))/(2*dx)
301 ey(:, ny) = (phi(:, 2) - phi(:, ny - 1))/(2*dy)
305 if (
present(nrj))
then
306 nrj = sum(ex*ex + ey*ey)*dx*dy
311 end subroutine sll_s_solve_mudpack_cartesian
314 subroutine sll_s_delete_mudpack_cartesian(self)
315 type(sll_t_mudpack_solver) :: self
317 deallocate (self%work)
319 end subroutine sll_s_delete_mudpack_cartesian
323 subroutine sll_s_mudpack_polar_init(self, &
325 theta_min, theta_max, nth, &
326 bc_r_min, bc_r_max, &
327 bc_theta_min, bc_theta_max)
330 type(sll_t_mudpack_solver) :: self
331 sll_real64,
intent(in) :: r_min
332 sll_real64,
intent(in) :: r_max
333 sll_real64,
intent(in) :: theta_min
334 sll_real64,
intent(in) :: theta_max
335 sll_int32,
intent(in) :: nr
336 sll_int32,
intent(in) :: nth
340 sll_int32 :: bc_r_min
341 sll_int32 :: bc_r_max
342 sll_int32 :: bc_theta_min
343 sll_int32 :: bc_theta_max
345 sll_real64 :: phi(nr, nth)
346 sll_real64 :: rhs(nr, nth)
351 sll_int32 :: intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
352 iguess, maxcy, method, nwork, lwrkqd, itero
353 common/itmud2cr/intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
354 iguess, maxcy, method, nwork, lwrkqd, itero
355 sll_real64 :: xa, xb, yc, yd, tolmax, relmax
356 common/ftmud2cr/xa, xb, yc, yd, tolmax, relmax
360 sll_int32 :: iprm(16)
361 sll_real64 :: fprm(6)
363 equivalence(intl, iprm)
364 equivalence(xa, fprm)
370 llwork = (7*(nx + 2)*(ny + 2) + 44*nx*ny)/3
372 allocate (self%work(llwork))
387 iex = ceiling(log((nx - 1.)/ixp)/log(2.)) + 1
388 jey = ceiling(log((ny - 1.)/jyq)/log(2.)) + 1
390 nx = ixp*(2**(iex - 1)) + 1
391 ny = jyq*(2**(jey - 1)) + 1
394 print *,
"nx,nr=", nx, nr
395 stop
' nx different de nr dans mg_polar_poisson'
398 print *,
"ny,nth=", ny, nth
399 stop
' ny different de nth dans mg_polar_poisson'
431 write (*, 101) (iprm(i), i=1, 15)
432 write (*, 102) (self%mgopt(i), i=1, 4)
433 write (*, 103) xa, xb, yc, yd, tolmax
436 call mud2cr(iprm, fprm, self%work, coef_polar, bndcr, rhs, phi, self%mgopt, ierror)
438 write (*, 200) ierror, iprm(16)
439 if (ierror > 0) stop 0
441 100
format(//
' multigrid poisson solver in polar coordinates ')
442 101
format(/
' integer input arguments ', &
443 /
'intl = ', i2,
' nxa = ', i2,
' nxb = ', i2,
' nyc = ', i2,
' nyd = ', i2, &
444 /
' ixp = ', i2,
' jyq = ', i2,
' iex = ', i2,
' jey = ', i2 &
445 /
' nx = ', i3,
' ny = ', i3,
' iguess = ', i2,
' maxcy = ', i2, &
446 /
' method = ', i2,
' work space estimate = ', i7)
447 102
format(/
' multigrid option arguments ', &
452 103
format(/
' floating point input parameters ', &
453 /
' xa = ', f6.3,
' xb = ', f6.3,
' yc = ', f6.3,
' yd = ', f6.3, &
454 /
' tolerance (error control) = ', e10.3)
455 104
format(/
' discretization call to mud2cr',
' intl = ', i2)
456 200
format(
' ierror = ', i2,
' minimum work space = ', i7)
459 end subroutine sll_s_mudpack_polar_init
462 subroutine sll_s_solve_mudpack_polar(self, phi, rhs)
466 type(sll_t_mudpack_solver) :: self
468 sll_int32,
parameter :: iixp = 2, jjyq = 2
470 sll_real64,
intent(inout) :: phi(:, :)
471 sll_real64,
intent(inout) :: rhs(:, :)
476 sll_int32 :: intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny
477 sll_int32 :: iguess, maxcy, method, nwork, lwrkqd, itero
478 sll_real64 :: xa, xb, yc, yd, tolmax, relmax
480 sll_int32 :: iprm(16)
481 sll_real64 :: fprm(6)
483 common/itmud2cr/intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
484 iguess, maxcy, method, nwork, lwrkqd, itero
485 common/ftmud2cr/xa, xb, yc, yd, tolmax, relmax
487 equivalence(intl, iprm)
488 equivalence(xa, fprm)
492 write (*, 106) intl, method, iguess
494 call mud2cr(iprm, fprm, self%work, coef_polar, bndcr, rhs, phi, self%mgopt, ierror)
495 sll_assert(ierror == 0)
497 call mud24cr(self%work, coef_polar, bndcr, phi, ierror)
498 sll_assert(ierror == 0)
500 106
format(/
' approximation call to mud2cr', &
501 /
' intl = ', i2,
' method = ', i2,
' iguess = ', i2)
503 end subroutine sll_s_solve_mudpack_polar
507 subroutine coef_polar(x, y, cxx, cxy, cyy, cx, cy, ce)
508 real(8) :: x, y, cxx, cxy, cyy, cx, cy, ce
509 cxx = 1.0_8 + 0.0_8*y
515 end subroutine coef_polar
519 subroutine bndcr(kbdy, xory, alfa, beta, gama, gbdy)
521 real(8) :: xory, alfa, beta, gama, gbdy
523 if (kbdy .eq. 2)
then
530 alfa = 1.0_8 + 0.0_8*xory
555 subroutine cofx(x, cxx, cx, cex)
556 real(8) :: x, cxx, cx, cex
557 cxx = 1.0_8 + 0.0_8*x
563 subroutine cofy(y, cyy, cy, cey)
564 real(8) :: y, cyy, cy, cey
565 cyy = 1.0_8 + 0.0_8*y
571 subroutine bndsp(kbdy, xory, alfa, gbdy)
573 real(8) :: xory, alfa, gbdy, x, y, pe, px, py
574 real(8) :: xa, xb, yc, yd, tolmax, relmax
575 common/ftmud2sp/xa, xb, yc, yd, tolmax, relmax
595 end module sll_m_mudpack
597 #endif /* DOXYGEN_SHOULD_SKIP_THIS */