1 #ifndef DOXYGEN_SHOULD_SKIP_THIS
10 module sll_m_mudpack_curvilinear
12 #include "sll_working_precision.h"
36 sll_p_non_separable_with_cross_terms, &
37 sll_p_non_separable_without_cross_terms, &
44 type :: sll_t_mudpack_2d
46 sll_real64,
dimension(:),
allocatable :: work
51 sll_int32,
pointer :: iwork(:, :)
53 end type sll_t_mudpack_2d
55 integer,
parameter :: sll_p_separable = 1
56 integer,
parameter :: sll_p_non_separable_without_cross_terms = 2
57 integer,
parameter :: sll_p_non_separable_with_cross_terms = 3
60 class(sll_c_interpolator_2d),
pointer :: cxx_interp
61 type(sll_t_cubic_spline_interpolator_2d),
target :: cxx_cs2d
63 class(sll_c_interpolator_2d),
pointer :: cyy_interp
64 type(sll_t_cubic_spline_interpolator_2d),
target :: cyy_cs2d
66 class(sll_c_interpolator_2d),
pointer :: cxy_interp
67 type(sll_t_cubic_spline_interpolator_2d),
target :: cxy_cs2d
69 class(sll_c_interpolator_2d),
pointer :: cx_interp
70 type(sll_t_cubic_spline_interpolator_2d),
target :: cx_cs2d
72 class(sll_c_interpolator_2d),
pointer :: cy_interp
73 type(sll_t_cubic_spline_interpolator_2d),
target :: cy_cs2d
75 class(sll_c_interpolator_2d),
pointer :: ce_interp
76 type(sll_t_cubic_spline_interpolator_2d),
target :: ce_cs2d
78 class(sll_c_interpolator_2d),
pointer :: a12_interp
79 type(sll_t_cubic_spline_interpolator_2d),
target :: a12_cs2d
81 class(sll_c_interpolator_2d),
pointer :: a21_interp
82 type(sll_t_cubic_spline_interpolator_2d),
target :: a21_cs2d
85 class(sll_c_coordinate_transformation_2d_base),
pointer :: transformation
87 interface sll_o_create
88 module procedure initialize_poisson_curvilinear_mudpack
89 end interface sll_o_create
95 subroutine initialize_poisson_curvilinear_mudpack( &
114 type(sll_t_mudpack_2d) :: self
115 sll_real64,
intent(in) :: eta1_min
116 sll_real64,
intent(in) :: eta1_max
117 sll_real64,
intent(in) :: eta2_min
118 sll_real64,
intent(in) :: eta2_max
119 sll_int32,
intent(in) :: nc_eta1
120 sll_int32,
intent(in) :: nc_eta2
123 sll_int32 :: bc_eta1_left
124 sll_int32 :: bc_eta1_right
125 sll_int32 :: bc_eta2_left
126 sll_int32 :: bc_eta2_right
128 sll_real64,
pointer :: phi(:, :)
129 sll_real64,
pointer :: rhs(:, :)
131 sll_real64,
dimension(:, :),
pointer :: b11
132 sll_real64,
dimension(:, :),
pointer :: b12
133 sll_real64,
dimension(:, :),
pointer :: b21
134 sll_real64,
dimension(:, :),
pointer :: b22
135 sll_real64,
dimension(:, :),
pointer :: c
137 class(sll_c_coordinate_transformation_2d_base),
pointer :: transf
141 sll_int32 :: intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
142 iguess, maxcy, method, nwork, lwrkqd, itero
143 common/itmud2cr/intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
144 iguess, maxcy, method, nwork, lwrkqd, itero
145 sll_real64 :: xa, xb, yc, yd, tolmax, relmax
146 common/ftmud2cr/xa, xb, yc, yd, tolmax, relmax
147 sll_int32 :: i, ierror
148 sll_int32 :: iprm(16)
149 sll_real64 :: fprm(6)
150 sll_real64,
dimension(:, :),
allocatable :: cxx_array
151 sll_real64,
dimension(:, :),
allocatable :: cyy_array
152 sll_real64,
dimension(:, :),
allocatable :: cxy_array
153 sll_real64,
dimension(:, :),
allocatable :: cx_array
154 sll_real64,
dimension(:, :),
allocatable :: cy_array
155 sll_real64,
dimension(:, :),
allocatable :: ce_array
156 sll_real64,
dimension(:, :),
allocatable :: a12_array
157 sll_real64,
dimension(:, :),
allocatable :: a21_array
158 sll_real64 :: delta1, delta2
159 sll_int32,
parameter :: iixp = 2, jjyq = 2
161 equivalence(intl, iprm)
162 equivalence(xa, fprm)
167 delta1 = (eta1_max - eta1_min)/real(nc_eta1, f64)
168 delta2 = (eta2_max - eta2_min)/real(nc_eta2, f64)
170 llwork = (7*(nx + 2)*(ny + 2) + 44*nx*ny)/3
172 allocate (cxx_array(nx, ny))
173 allocate (cyy_array(nx, ny))
174 allocate (cxy_array(nx, ny))
175 allocate (cx_array(nx, ny))
176 allocate (cy_array(nx, ny))
177 allocate (ce_array(nx, ny))
178 allocate (a12_array(nx, ny))
179 allocate (a21_array(nx, ny))
180 allocate (phi(nx, ny))
182 transformation => transf
183 call cxx_cs2d%init( &
193 cxx_interp => cxx_cs2d
195 call cyy_cs2d%init( &
205 cyy_interp => cyy_cs2d
207 call cxy_cs2d%init( &
217 cxy_interp => cxy_cs2d
255 call a12_cs2d%init( &
265 a12_interp => a12_cs2d
267 call a21_cs2d%init( &
277 a21_interp => a21_cs2d
280 call coefxxyy_array(b11, b12, b21, b22, transf, eta1_min, eta2_min, delta1, delta2, nx, ny, cxx_array, cyy_array)
281 call cxx_interp%compute_interpolants(cxx_array)
282 call cyy_interp%compute_interpolants(cyy_array)
284 call coefxy_array(b11, b12, b21, b22, transf, eta1_min, eta2_min, delta1, delta2, nx, ny, cxy_array)
285 call cxy_interp%compute_interpolants(cxy_array)
287 call a12_a21_array(b11, b12, b21, b22, transf, eta1_min, eta2_min, delta1, delta2, nx, ny, a12_array, a21_array)
288 call a12_interp%compute_interpolants(a12_array)
289 call a21_interp%compute_interpolants(a21_array)
291 call coefx_array(eta1_min, eta2_min, delta1, delta2, nx, ny, cx_array)
292 call cx_interp%compute_interpolants(cx_array)
294 call coefy_array(eta1_min, eta2_min, delta1, delta2, nx, ny, cy_array)
295 call cy_interp%compute_interpolants(cy_array)
297 call ce_interp%compute_interpolants(ce_array)
299 allocate (self%work(llwork))
310 print *, nxa, nxb, nyc, nyd
314 iex = ceiling(log((nx - 1.)/ixp)/log(2.)) + 1
315 jey = ceiling(log((ny - 1.)/jyq)/log(2.)) + 1
317 nx = ixp*(2**(iex - 1)) + 1
318 ny = jyq*(2**(jey - 1)) + 1
319 allocate (self%iwork(ixp + 1, jyq + 1))
320 if (nx /= nc_eta1 + 1 .or. ny /= nc_eta2 + 1)
then
321 print *,
"nx,nc_eta1+1=", nx, nc_eta1 + 1
322 print *,
"ny,nc_eta2+1=", ny, nc_eta2 + 1
323 stop
' nx or ny different in sll_m_mudpack_curvilinear '
355 write (*, 101) (iprm(i), i=1, 15)
356 write (*, 102) (self%mgopt(i), i=1, 4)
357 write (*, 103) xa, xb, yc, yd, tolmax
361 call muh2cr(iprm, fprm, self%work, self%iwork, coefcr, bndcr, rhs, phi, self%mgopt, ierror)
363 write (*, 200) ierror, iprm(16)
364 if (ierror > 0) stop 0
366 100
format(//
' multigrid poisson solver in polar coordinates ')
367 101
format(/
' integer input arguments ', &
368 /
'intl = ', i2,
' nxa = ', i2,
' nxb = ', i2,
' nyc = ', i2,
' nyd = ', i2, &
369 /
' ixp = ', i2,
' jyq = ', i2,
' iex = ', i2,
' jey = ', i2 &
370 /
' nx = ', i3,
' ny = ', i3,
' iguess = ', i2,
' maxcy = ', i2, &
371 /
' method = ', i2,
' work space estimate = ', i7)
372 102
format(/
' multigrid option arguments ', &
377 103
format(/
' floating point input parameters ', &
378 /
' xa = ', f6.3,
' xb = ', f6.3,
' yc = ', f6.3,
' yd = ', f6.3, &
379 /
' tolerance (error control) = ', e10.3)
380 104
format(/
' discretization call to mud2cr',
' intl = ', i2)
381 200
format(
' ierror = ', i2,
' minimum work space = ', i7)
383 end subroutine initialize_poisson_curvilinear_mudpack
386 subroutine solve_poisson_curvilinear_mudpack(self, phi, rho)
388 type(sll_t_mudpack_2d) :: self
390 sll_int32,
parameter :: iixp = 2, jjyq = 2
392 sll_real64,
intent(inout) :: phi(:, :)
393 sll_real64,
intent(inout) :: rho(:, :)
394 sll_real64,
pointer :: rhs(:, :)
399 sll_int32 :: intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny
400 sll_int32 :: iguess, maxcy, method, nwork, lwrkqd, itero
401 sll_real64 :: xa, xb, yc, yd, tolmax, relmax
403 sll_int32 :: iprm(16)
404 sll_real64 :: fprm(6), eta1, eta2
407 common/itmud2cr/intl, nxa, nxb, nyc, nyd, ixp, jyq, iex, jey, nx, ny, &
408 iguess, maxcy, method, nwork, lwrkqd, itero
409 common/ftmud2cr/xa, xb, yc, yd, tolmax, relmax
411 equivalence(intl, iprm)
412 equivalence(xa, fprm)
414 allocate (rhs(nx, ny))
417 eta2 = yc + real(i2 - 1, f64)*(yd - yc)/real(ny - 1, 8)
419 eta1 = xa + real(i1 - 1, f64)*(xb - xa)/real(nx - 1, 8)
420 rhs(i1, i2) = -rho(i1, i2)*transformation%jacobian(eta1, eta2)
423 if (nxa == sll_p_dirichlet)
then
428 if (nxb == sll_p_dirichlet)
then
433 if (nyc == sll_p_dirichlet)
then
438 if (nyd == sll_p_dirichlet)
then
450 call muh2cr(iprm, fprm, self%work, self%iwork, coefcr, bndcr, rhs, phi, self%mgopt, ierror)
454 if (ierror > 0) stop 0
458 call muh24cr(self%work, self%iwork, coefcr, bndcr, phi, ierror)
462 if (ierror > 0) stop 0
471 end subroutine solve_poisson_curvilinear_mudpack
473 subroutine coefxxyy_array(b11, b12, b21, b22, transf, eta1_min, eta2_min, &
474 delta1, delta2, nx, ny, cxx_array, cyy_array)
476 sll_real64 :: eta1, eta1_min, eta2_min
477 sll_real64 :: eta2, delta1, delta2
478 sll_int32 :: i, j, nx, ny
479 sll_real64,
dimension(:, :):: cxx_array, cyy_array
480 sll_real64,
dimension(1:2, 1:2) :: jac_m
481 class(sll_c_coordinate_transformation_2d_base),
pointer :: transf
482 sll_real64,
dimension(:, :) :: b11
483 sll_real64,
dimension(:, :) :: b12
484 sll_real64,
dimension(:, :) :: b21
485 sll_real64,
dimension(:, :) :: b22
488 eta2 = eta2_min + real(j - 1, f64)*delta2
490 eta1 = eta1_min + real(i - 1, f64)*delta1
491 jac_m = transf%jacobian_matrix(eta1, eta2)
492 cxx_array(i, j) = (b11(i, j)*(jac_m(1, 2)*jac_m(1, 2) + jac_m(2, 2)*jac_m(2, 2)) - &
493 & b12(i, j)*(jac_m(2, 1)*jac_m(2, 2) + jac_m(1, 1)*jac_m(1, 2))) &
494 /transf%jacobian(eta1, eta2)
495 cyy_array(i, j) = (b22(i, j)*(jac_m(2, 1)*jac_m(2, 1) + jac_m(1, 1)*jac_m(1, 1)) - &
496 & b21(i, j)*(jac_m(2, 1)*jac_m(2, 2) + jac_m(1, 1)*jac_m(1, 2))) &
497 /transf%jacobian(eta1, eta2)
500 end subroutine coefxxyy_array
502 subroutine coefxy_array(b11, b12, b21, b22, transf, eta1_min, eta2_min, &
503 delta1, delta2, nx, ny, cxy_array)
505 sll_real64 :: eta1, eta1_min, eta2_min
506 sll_real64 :: eta2, delta1, delta2
507 sll_real64 :: a12, a21
508 sll_int32 :: i, j, nx, ny
509 sll_real64,
dimension(:, :):: cxy_array
510 sll_real64,
dimension(1:2, 1:2) :: jac_m
511 class(sll_c_coordinate_transformation_2d_base),
pointer :: transf
512 sll_real64,
dimension(:, :) :: b11
513 sll_real64,
dimension(:, :) :: b12
514 sll_real64,
dimension(:, :) :: b21
515 sll_real64,
dimension(:, :) :: b22
518 eta2 = eta2_min + real(j - 1, f64)*delta2
520 eta1 = eta1_min + real(i - 1, f64)*delta1
521 jac_m = transf%jacobian_matrix(eta1, eta2)
522 a12 = b12(i, j)*(jac_m(2, 1)*jac_m(2, 1) + jac_m(1, 1)*jac_m(1, 1)) - &
523 & b11(i, j)*(jac_m(2, 1)*jac_m(2, 2) + jac_m(1, 1)*jac_m(1, 2))
525 a21 = b21(i, j)*(jac_m(1, 2)*jac_m(1, 2) + jac_m(2, 2)*jac_m(2, 2)) - &
526 & b22(i, j)*(jac_m(2, 1)*jac_m(2, 2) + jac_m(1, 1)*jac_m(1, 2))
527 cxy_array(i, j) = (a12 + a21)/transf%jacobian(eta1, eta2)
530 end subroutine coefxy_array
532 subroutine a12_a21_array(b11, b12, b21, b22, transf, eta1_min, eta2_min, delta1, delta2, nx, ny, a12_array, a21_array)
533 sll_real64 :: eta1, eta1_min, eta2_min
534 sll_real64 :: eta2, delta1, delta2
535 sll_real64 :: a12, a21
536 sll_int32 :: i, j, nx, ny
537 sll_real64,
dimension(:, :):: a12_array
538 sll_real64,
dimension(:, :):: a21_array
539 class(sll_c_coordinate_transformation_2d_base),
pointer :: transf
540 sll_real64,
dimension(:, :) :: b11
541 sll_real64,
dimension(:, :) :: b12
542 sll_real64,
dimension(:, :) :: b21
543 sll_real64,
dimension(:, :) :: b22
544 sll_real64,
dimension(1:2, 1:2) :: jac_m
547 eta2 = eta2_min + real(j - 1, f64)*delta2
549 eta1 = eta1_min + real(i - 1, f64)*delta1
550 jac_m = transf%jacobian_matrix(eta1, eta2)
551 a12 = b12(i, j)*(jac_m(2, 1)*jac_m(2, 1) + jac_m(1, 1)*jac_m(1, 1)) - &
552 & b11(i, j)*(jac_m(2, 1)*jac_m(2, 2) + jac_m(1, 1)*jac_m(1, 2))
553 a12_array(i, j) = a12/transf%jacobian(eta1, eta2)
554 a21 = b21(i, j)*(jac_m(1, 2)*jac_m(1, 2) + jac_m(2, 2)*jac_m(2, 2)) - &
555 & b22(i, j)*(jac_m(2, 1)*jac_m(2, 2) + jac_m(1, 1)*jac_m(1, 2))
556 a21_array(i, j) = a21/transf%jacobian(eta1, eta2)
559 end subroutine a12_a21_array
561 subroutine coefx_array(eta1_min, eta2_min, &
562 delta1, delta2, nx, ny, cx_array)
563 sll_real64 :: eta1, eta1_min, eta2_min
564 sll_real64 :: eta2, delta1, delta2
565 sll_int32 :: i, j, nx, ny
566 sll_real64,
dimension(:, :):: cx_array
569 eta2 = eta2_min + real(j - 1, f64)*delta2
571 eta1 = eta1_min + real(i - 1, f64)*delta1
572 cx_array(i, j) = cxx_interp%interpolate_from_interpolant_derivative_eta1(eta1, eta2) + &
573 a21_interp%interpolate_from_interpolant_derivative_eta2(eta1, eta2)
576 end subroutine coefx_array
578 subroutine coefy_array(eta1_min, eta2_min, &
579 delta1, delta2, nx, ny, cy_array)
580 sll_real64 :: eta1, eta1_min, eta2_min
581 sll_real64 :: eta2, delta1, delta2
582 sll_int32 :: i, j, nx, ny
583 sll_real64,
dimension(:, :):: cy_array
586 eta2 = eta2_min + real(j - 1, f64)*delta2
588 eta1 = eta1_min + real(i - 1, f64)*delta1
589 cy_array(i, j) = cyy_interp%interpolate_from_interpolant_derivative_eta2(eta1, eta2) + &
590 a12_interp%interpolate_from_interpolant_derivative_eta1(eta1, eta2)
593 end subroutine coefy_array
597 subroutine coefcr(x, y, cxx, cxy, cyy, cx, cy, ce)
598 real(8) :: x, cxx, cx, cxy
599 real(8) :: y, cyy, cy, ce
600 cxx = cxx_interp%interpolate_from_interpolant_value(x, y)
601 cxy = cxy_interp%interpolate_from_interpolant_value(x, y)
602 cyy = cyy_interp%interpolate_from_interpolant_value(x, y)
603 cx = cx_interp%interpolate_from_interpolant_value(x, y)
604 cy = cy_interp%interpolate_from_interpolant_value(x, y)
605 ce = ce_interp%interpolate_from_interpolant_value(x, y)
606 end subroutine coefcr
627 subroutine bndcr(kbdy, xory, alfa, beta, gama, gbdy)
629 real(8) :: xory, alfa, beta, gama, gbdy
631 if (kbdy .eq. 2)
then
638 alfa = 0.0_8 + 0_8*xory
645 if (kbdy .eq. 1)
then
661 end module sll_m_mudpack_curvilinear
663 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
Describe different boundary conditions.
Class for the cubic spline sll_c_interpolator_2d.
abstract data type for 2d interpolation
The spline-based interpolator is only a wrapper around the capabilities of the cubic splines.
Base class/basic interface for 2D interpolators.