23 #include "sll_assert.h"
24 #include "sll_memory.h"
25 #include "sll_working_precision.h"
45 sll_real64,
dimension(:),
pointer :: eta1_coords
46 sll_real64,
dimension(:),
pointer :: eta2_coords
47 sll_real64,
dimension(:, :),
pointer :: charac_feet1
48 sll_real64,
dimension(:, :),
pointer :: charac_feet2
52 sll_real64,
dimension(:, :),
pointer :: tt
53 sll_real64,
dimension(:, :),
pointer :: tcell
54 sll_real64,
dimension(:),
pointer :: intx
55 sll_real64,
dimension(:),
pointer :: inty
56 sll_real64,
dimension(:, :),
pointer :: dir
57 sll_int32,
dimension(:, :, :),
pointer :: cell
82 sll_int32,
intent(in) :: npts1
83 sll_int32,
intent(in) :: npts2
84 sll_real64,
intent(in),
optional :: eta1_min
85 sll_real64,
intent(in),
optional :: eta1_max
86 sll_real64,
intent(in),
optional :: eta2_min
87 sll_real64,
intent(in),
optional :: eta2_max
88 sll_real64,
dimension(:),
pointer,
optional :: eta1_coords
89 sll_real64,
dimension(:),
pointer,
optional :: eta2_coords
92 sll_allocate(adv, ierr)
121 sll_int32,
intent(in) :: npts1
122 sll_int32,
intent(in) :: npts2
123 sll_real64,
intent(in),
optional :: eta1_min
124 sll_real64,
intent(in),
optional :: eta1_max
125 sll_real64,
intent(in),
optional :: eta2_min
126 sll_real64,
intent(in),
optional :: eta2_max
127 sll_real64,
dimension(:),
pointer,
optional :: eta1_coords
128 sll_real64,
dimension(:),
pointer,
optional :: eta2_coords
131 sll_real64 :: delta_eta1
132 sll_real64 :: delta_eta2
139 sll_allocate(adv%eta1_coords(npts1), ierr)
140 sll_allocate(adv%eta2_coords(npts2), ierr)
142 sll_allocate(adv%charac_feet1(npts1, npts2), ierr)
143 sll_allocate(adv%charac_feet2(npts1, npts2), ierr)
145 if (
present(eta1_min) .and.
present(eta1_max))
then
146 if (
present(eta1_coords))
then
147 print *,
'#provide either eta1_coords or eta1_min and eta1_max'
148 print *,
'#and not both in subroutine initialize_csl_2d_advector'
151 delta_eta1 = (eta1_max - eta1_min)/real(npts1 - 1, f64)
153 adv%eta1_coords(i) = eta1_min + real(i - 1, f64)*delta_eta1
156 else if (
present(eta1_coords))
then
157 if (
size(eta1_coords, 1) < npts1)
then
158 print *,
'#bad size for eta1_coords in initialize_csl_2d_advector'
161 adv%eta1_coords(1:npts1) = eta1_coords(1:npts1)
164 print *,
'#Warning, we assume eta1_min = 0._f64 eta1_max = 1._f64'
165 delta_eta1 = 1._f64/real(npts1 - 1, f64)
167 adv%eta1_coords(i) = real(i - 1, f64)*delta_eta1
171 if (
present(eta2_min) .and.
present(eta2_max))
then
172 if (
present(eta2_coords))
then
173 print *,
'#provide either eta2_coords or eta2_min and eta2_max'
174 print *,
'#and not both in subroutine initialize_csl_2d_advector'
177 delta_eta2 = (eta2_max - eta2_min)/real(npts2 - 1, f64)
179 adv%eta2_coords(i) = eta2_min + real(i - 1, f64)*delta_eta2
182 else if (
present(eta2_coords))
then
183 if (
size(eta2_coords, 1) < npts2)
then
184 print *,
'#bad size for eta2_coords in initialize_csl_2d_advector'
187 adv%eta2_coords(1:npts2) = eta2_coords(1:npts2)
190 print *,
'#Warning, we assume eta2_min = 0._f64 eta2_max = 1._f64'
191 delta_eta2 = 1._f64/real(npts2 - 1, f64)
193 adv%eta2_coords(i) = real(i - 1, f64)*delta_eta2
200 sll_allocate(adv%tt(adv%nbmax, 2), ierr)
201 sll_allocate(adv%cell(2, adv%nbmax, 4), ierr)
202 sll_allocate(adv%tcell(adv%nbmax, 4), ierr)
203 sll_allocate(adv%intx(0:adv%nbmax), ierr)
204 sll_allocate(adv%inty(0:adv%nbmax), ierr)
205 sll_allocate(adv%dir(adv%nbmax, 2), ierr)
218 sll_real64,
dimension(:, :),
intent(in) :: a1
219 sll_real64,
dimension(:, :),
intent(in) :: a2
220 sll_real64,
intent(in) :: dt
221 sll_real64,
dimension(:, :),
intent(in) :: input
222 sll_real64,
dimension(:, :),
intent(out) :: output
268 sll_assert(
size(input, 1) > 0)
270 nc_x1 = adv%Npts1 - 1
271 nc_x2 = adv%Npts2 - 1
273 x1_min = adv%eta1_coords(1)
274 x1_max = adv%eta1_coords(adv%Npts1)
275 x2_min = adv%eta2_coords(1)
276 x2_max = adv%eta2_coords(adv%Npts2)
278 call adv%charac%compute_characteristics( &
290 output(i + 1, j + 1) = 0._f64
292 xx(1) = adv%charac_feet1(i + 1, j + 1)
293 xx(2) = adv%charac_feet1(i + 2, j + 1)
294 xx(3) = adv%charac_feet1(i + 2, j + 2)
295 xx(4) = adv%charac_feet1(i + 1, j + 2)
297 yy(1) = adv%charac_feet2(i + 1, j + 1)
298 yy(2) = adv%charac_feet2(i + 2, j + 1)
299 yy(3) = adv%charac_feet2(i + 2, j + 2)
300 yy(4) = adv%charac_feet2(i + 1, j + 2)
302 xx(1) = (xx(1) - x1_min)/(x1_max - x1_min)*real(nc_x1, f64)
303 xx(2) = (xx(2) - x1_min)/(x1_max - x1_min)*real(nc_x1, f64)
304 xx(3) = (xx(3) - x1_min)/(x1_max - x1_min)*real(nc_x1, f64)
305 xx(4) = (xx(4) - x1_min)/(x1_max - x1_min)*real(nc_x1, f64)
307 yy(1) = (yy(1) - x2_min)/(x2_max - x2_min)*real(nc_x2, f64)
308 yy(2) = (yy(2) - x2_min)/(x2_max - x2_min)*real(nc_x2, f64)
309 yy(3) = (yy(3) - x2_min)/(x2_max - x2_min)*real(nc_x2, f64)
310 yy(4) = (yy(4) - x2_min)/(x2_max - x2_min)*real(nc_x2, f64)
325 imin = min(ii(1), ii(2), ii(3), ii(4))
326 jmin = min(jj(1), jj(2), jj(3), jj(4))
327 imax = max(ii(1), ii(2), ii(3), ii(4))
328 jmax = max(jj(1), jj(2), jj(3), jj(4))
348 adv%tt(s, 1) = (real(k, f64) - xa)/(xb - xa)
354 do k = i0, i1 + 1, -1
355 adv%tt(s, 1) = (real(k, f64) - xa)/(xb - xa)
364 adv%tt(s, 2) = (real(k, f64) - ya)/(yb - ya)
370 do k = j0, j1 + 1, -1
371 adv%tt(s, 2) = (real(k, f64) - ya)/(yb - ya)
378 adv%cell(1, 1, ell) = i0
379 adv%cell(2, 1, ell) = j0
380 adv%tcell(1, ell) = 0._f64
385 do while ((sx <= nbx(ell)) .and. (sy <= nby(ell)))
386 if (adv%tt(sx, 1) < adv%tt(sy, 2))
then
388 adv%cell(1, s, ell) = adv%cell(1, s - 1, ell) + dirx
389 adv%cell(2, s, ell) = adv%cell(2, s - 1, ell)
390 adv%tcell(s, ell) = adv%tt(sx, 1)
391 adv%intx(2*adv%cell(1, s - 1, ell) + (dirx - 1)/2 - 2*imin) = ya + adv%tt(sx, 1)*(yb - ya)
392 adv%dir(s, 1) = 1.0_f64
393 adv%dir(s, 2) = real(dirx, f64)
397 adv%cell(1, s, ell) = adv%cell(1, s - 1, ell)
398 adv%cell(2, s, ell) = adv%cell(2, s - 1, ell) + diry
399 adv%tcell(s, ell) = adv%tt(sy, 2)
400 adv%inty(2*adv%cell(2, s - 1, ell) + (diry - 1)/2 - 2*jmin) = xa + adv%tt(sy, 2)*(xb - xa)
401 adv%dir(s, 1) = 2.0_f64
402 adv%dir(s, 2) = real(diry, f64)
406 do while (sx <= nbx(ell))
408 adv%cell(1, s, ell) = adv%cell(1, s - 1, ell) + dirx
409 adv%cell(2, s, ell) = adv%cell(2, s - 1, ell)
410 adv%tcell(s, ell) = adv%tt(sx, 1)
411 adv%intx(2*adv%cell(1, s - 1, ell) + (dirx - 1)/2 - 2*imin) = ya + adv%tt(sx, 1)*(yb - ya)
412 adv%dir(s, 1) = 1.0_f64
413 adv%dir(s, 2) = real(dirx, f64)
416 do while (sy <= nby(ell))
418 adv%cell(1, s, ell) = adv%cell(1, s - 1, ell)
419 adv%cell(2, s, ell) = adv%cell(2, s - 1, ell) + diry
420 adv%tcell(s, ell) = adv%tt(sy, 2)
421 adv%inty(2*adv%cell(2, s - 1, ell) + (diry - 1)/2 - 2*jmin) = xa + adv%tt(sy, 2)*(xb - xa)
422 adv%dir(s, 1) = 2.0_f64
423 adv%dir(s, 2) = real(diry, f64)
429 if ((ell == 1) .or. (ell == 4) .or. &
430 ((ell == 2) .and. (i == nc_x1)) .or. &
431 ((ell == 3) .and. (j == nc_x2)))
then
434 do k = 2, nbx(ell) + nby(ell) + 2
437 i0_loc = adv%cell(1, k - 1, ell)
438 j0_loc = adv%cell(2, k - 1, ell)
439 if (k == nbx(ell) + nby(ell) + 2)
then
443 if (adv%dir(k, 1) == 1)
then
444 xb_loc = real(adv%cell(1, k, ell) + (1 - adv%dir(k, 2))/2, f64)
445 yb_loc = yy(ell) + adv%tcell(k, ell)*(yy(ell1) - yy(ell))
447 xb_loc = xx(ell) + adv%tcell(k, ell)*(xx(ell1) - xx(ell))
448 yb_loc = real(adv%cell(2, k, ell) + (1 - adv%dir(k, 2))/2, f64)
456 output(i + 1, j + 1) = output(i + 1, j + 1) + res
473 do ell = 0, imax - imin - 1
474 minfl = min(floor(adv%intx(2*ell)), floor(adv%intx(2*ell + 1)))
475 maxfl = max(floor(adv%intx(2*ell)), floor(adv%intx(2*ell + 1)))
478 yb_loc = min(adv%intx(2*ell), adv%intx(2*ell + 1))
479 do k = 0, maxfl - minfl
482 if (k == maxfl - minfl)
then
483 yb_loc = max(adv%intx(2*ell), adv%intx(2*ell + 1))
485 yb_loc = real(minfl + k + 1, f64)
490 output(i + 1, j + 1) = output(i + 1, j + 1) + res
499 do ell = 0, jmax - jmin - 1
500 minfl = min(floor(adv%inty(2*ell)), floor(adv%inty(2*ell + 1)))
501 maxfl = max(floor(adv%inty(2*ell)), floor(adv%inty(2*ell + 1)))
504 xa_loc = min(adv%inty(2*ell), adv%inty(2*ell + 1))
505 do k = 0, maxfl - minfl
508 if (k == maxfl - minfl)
then
509 xa_loc = max(adv%inty(2*ell), adv%inty(2*ell + 1))
511 xa_loc = real(minfl + k + 1, f64)
516 output(i + 1, j + 1) = output(i + 1, j + 1) + res
547 subroutine aux(N0, N1, f, aretesh, aretesv, sommets, ordre, dom)
549 sll_int32,
intent(in)::n0, n1, ordre
550 sll_real64,
dimension(0:1, 0:1),
intent(in)::dom
551 real(f64),
dimension(0:N0, 0:N1 - 1),
intent(in)::f
553 sll_int32::i, j, im3, im2, im1, ib, ip1, ip2, jm3, jm2, jm1, jb, jp1, jp2
554 real(f64),
dimension(0:N0, 0:N1 - 1),
intent(inout)::aretesh, aretesv, sommets
558 if (dom(1, 1) == 1e-23)
then
559 print *,
'#is this possible?'
569 if (i - 3 <= 0) im3 = 0;
570 if (i - 2 <= 0) im2 = 0;
571 if (i - 1 <= 0) im1 = 0;
573 if (i + 1 >= n0) ip1 = n0;
574 if (i + 2 >= n0) ip2 = n0;
575 jm3 = modulo(j - 3, n1)
576 jm2 = modulo(j - 2, n1)
577 jm1 = modulo(j - 1, n1)
579 jp1 = modulo(j + 1, n1)
580 jp2 = modulo(j + 2, n1)
582 aretesv(i, j) = 7._f64/12._f64*(f(im1, jb) + f(ib, jb)) &
583 - 1._f64/12._f64*(f(im2, jb) + f(ip1, jb))
584 aretesh(i, j) = 7._f64/12._f64*(f(ib, jm1) + f(ib, jb)) &
585 - 1._f64/12._f64*(f(ib, jm2) + f(ib, jp1))
586 else if (ordre == 2)
then
587 aretesv(i, j) = 1._f64/60._f64*(f(ip2, jb) + f(im3, jb)) &
588 - 8._f64/60._f64*(f(ip1, jb) + f(im2, jb)) &
589 + 37._f64/60._f64*(f(ib, jb) + f(im1, jb))
590 aretesh(i, j) = 1._f64/60._f64*(f(ib, jp2) + f(ib, jm3)) &
591 - 8._f64/60._f64*(f(ib, jp1) + f(ib, jm2)) &
592 + 37._f64/60._f64*(f(ib, jb) + f(ib, jm1))
593 else if (ordre == 0)
then
594 aretesv(i, j) = 1._f64/2._f64*(f(ib, jb) + f(im1, jb))
595 aretesh(i, j) = 1._f64/2._f64*(f(ib, jb) + f(ib, jm1))
607 if (i - 3 <= 0) im3 = 0;
608 if (i - 2 <= 0) im2 = 0;
609 if (i - 1 <= 0) im1 = 0;
611 if (i + 1 >= n0) ip1 = n0;
612 if (i + 2 >= n0) ip2 = n0;
613 jm3 = modulo(j - 3, n1)
614 jm2 = modulo(j - 2, n1)
615 jm1 = modulo(j - 1, n1)
617 jp1 = modulo(j + 1, n1)
618 jp2 = modulo(j + 2, n1)
621 sommets(i, j) = 7._f64/12._f64*(aretesv(ib, jm1) + aretesv(ib, jb)) &
622 - 1._f64/12._f64*(aretesv(ib, jm2) + aretesv(ib, jp1))
623 else if (ordre == 2)
then
624 sommets(i, j) = 1._f64/60._f64*(aretesv(ib, jp2) + aretesv(ib, jm3)) &
625 - 8._f64/60._f64*(aretesv(ib, jp1) + aretesv(ib, jm2)) &
626 + 37._f64/60._f64*(aretesv(ib, jb) + aretesv(ib, jm1))
627 else if (ordre == 0)
then
628 sommets(i, j) = 1._f64/2._f64*(aretesv(ib, jb) + aretesv(ib, jm1))
644 sll_int32,
intent(in) :: n_x1
645 sll_int32,
intent(in) :: n_x2
646 sll_int32,
intent(in) :: r_x1
647 sll_int32,
intent(in) :: s_x1
648 sll_int32,
intent(in) :: r_x2
649 sll_int32,
intent(in) :: s_x2
650 sll_real64,
dimension(:, :),
intent(in) :: input
651 sll_real64,
dimension(:, :, :, :),
intent(out) :: output
653 sll_real64,
dimension(:),
allocatable :: ww_x1
655 sll_real64,
dimension(:),
allocatable :: ww_x2
662 sll_assert(
size(input, 1) > 0)
663 sll_assert(
size(input, 2) > 0)
667 sll_allocate(ww_x1(r_x1:s_x1 - 1), ierr)
668 sll_allocate(ww_x2(r_x2:s_x2 - 1), ierr)
699 sll_real64,
dimension(:),
intent(out) :: ww
700 sll_int32,
intent(in) :: r
701 sll_int32,
intent(in) :: s
702 sll_real64,
dimension(:),
allocatable :: w
708 sll_allocate(w(r:s), ierr)
713 tmp = tmp*real(i - j, f64)
716 tmp = tmp*real(i - j, f64)
720 tmp = tmp*real(-j, f64)
723 tmp = tmp*real(-j, f64)
726 tmp = tmp*real(-j, f64)
734 tmp = tmp*real(i - j, f64)
737 tmp = tmp*real(i - j, f64)
741 tmp = tmp*real(-j, f64)
744 tmp = tmp*real(-j, f64)
747 tmp = tmp*real(-j, f64)
772 sll_deallocate_array(w, ierr)
776 subroutine aux2(N0, N1, f, areteshb, areteshh, aretesvg, aretesvd, sommetsbg, sommetsbd, &
777 sommetshg, sommetshd, ordre, carac, dom)
778 integer,
intent(in)::N0, N1, ordre
779 real(f64),
dimension(0:1, 0:1),
intent(in)::dom
780 real(f64),
dimension(0:N0, 0:N1 - 1),
intent(in)::f
781 real(f64),
dimension(2, -1:N0 + 1, -1:N1 + 1),
intent(in)::carac
783 real(f64),
dimension(0:N0, 0:N1 - 1),
intent(inout)::areteshb, areteshh, aretesvg, aretesvd, &
784 sommetsbg, sommetsbd, sommetshg, sommetshd
785 real(f64) ::w(-ordre:ordre + 1), tmp, ww(-ordre:ordre)
792 if (carac(1, 1, 1) == 1e-23)
then
793 print *,
'#is this possible?'
795 if (dom(1, 1) == 1e-23)
then
796 print *,
'#is this possible?'
812 tmp = tmp*real(i - j, f64)
815 tmp = tmp*real(i - j, f64)
819 tmp = tmp*real(-j, f64)
822 tmp = tmp*real(-j, f64)
825 tmp = tmp*real(-j, f64)
855 tmp = tmp*real(i - j, f64)
858 tmp = tmp*real(i - j, f64)
862 tmp = tmp*real(-j, f64)
865 tmp = tmp*real(-j, f64)
868 tmp = tmp*real(-j, f64)
923 i3 = i + ii - 1;
if (i3 <= 0) i3 = 0;
if (i3 >= n0) i3 = n0
924 tmp = tmp + ww(r + s - 1 - ii)*f(i3, j)
929 i3 = i + ii;
if (i3 <= 0) i3 = 0;
if (i3 >= n0) i3 = n0
930 tmp = tmp + ww(ii)*f(i3, j)
935 tmp = tmp + ww(ii)*f(i, modulo(j + ii, n1))
940 tmp = tmp + ww(r + s - 1 - ii)*f(i, modulo(j + ii - 1, n1))
950 i3 = i + ii;
if (i3 <= 0) i3 = 0;
if (i3 >= n0) i3 = n0
951 tmp = tmp + ww(ii)*areteshh(i3, j)
953 sommetshd(i, j) = tmp
956 i3 = i + ii - 1;
if (i3 <= 0) i3 = 0;
if (i3 >= n0) i3 = n0
957 tmp = tmp + ww(r + s - 1 - ii)*areteshh(i3, j)
959 sommetshg(i, j) = tmp
962 i3 = i + ii;
if (i3 <= 0) i3 = 0;
if (i3 >= n0) i3 = n0
963 tmp = tmp + ww(ii)*areteshb(i3, j)
965 sommetsbd(i, j) = tmp
968 i3 = i + ii - 1;
if (i3 <= 0) i3 = 0;
if (i3 >= n0) i3 = n0
969 tmp = tmp + ww(r + s - 1 - ii)*areteshb(i3, j)
971 sommetsbg(i, j) = tmp
type(sll_t_csl_2d_advector) function, pointer, public sll_f_new_csl_2d_advector(charac, Npts1, Npts2, eta1_min, eta1_max, eta2_min, eta2_max, eta1_coords, eta2_coords)
subroutine initialize_csl_2d_advector(adv, charac, Npts1, Npts2, eta1_min, eta1_max, eta2_min, eta2_max, eta1_coords, eta2_coords)
subroutine compute_ww(ww, r, s)
subroutine aux2(N0, N1, f, areteshb, areteshh, aretesvg, aretesvd, sommetsbg, sommetsbd, sommetshg, sommetshd, ordre, carac, dom)
subroutine aux(N0, N1, f, aretesh, aretesv, sommets, ordre, dom)
subroutine compute_aux2_new(N_x1, N_x2, r_x1, s_x1, r_x2, s_x2, input, output)
subroutine csl_advect_2d(adv, A1, A2, dt, input, output)
Abstract class to compute the characteristic in two dimensions.