61 real,
parameter::
r3 = 1./3.
68 real,
parameter::
b1 = 0.0375
69 real,
parameter::
b2 = -7./30.
70 real,
parameter::
b3 = -23./120.
71 real,
parameter::
b4 = 13./30.
72 real,
parameter::
b5 = -11./240.
75 real,
parameter::
b1 = 1./30.
76 real,
parameter::
b2 = -13./60.
77 real,
parameter::
b3 = -13./60.
78 real,
parameter::
b4 = 0.45
79 real,
parameter::
b5 = -0.05
81 real,
parameter::
t11 = 27./28.,
t12 = -13./28.,
t13=3./7.
82 real,
parameter::
s11 = 11./14.,
s14 = 4./7.,
s15=3./14.
87 real,
parameter::
c1 = -2./14.
88 real,
parameter::
c2 = 11./14.
89 real,
parameter::
c3 = 5./14.
93 real,
parameter::
p1 = 7./12.
94 real,
parameter::
p2 = -1./12.
107 subroutine fv_tp_2d(q, crx, cry, npx, npy, hord, fx, fy, xfx, yfx, &
108 gridstruct, bd, ra_x, ra_y, lim_fac, mfx, mfy, mass, nord, damp_c)
110 integer,
intent(in):: npx, npy
111 integer,
intent(in)::hord
113 real,
intent(in):: crx(bd%is:bd%ie+1,bd%jsd:bd%jed)
114 real,
intent(in):: xfx(bd%is:bd%ie+1,bd%jsd:bd%jed)
115 real,
intent(in):: cry(bd%isd:bd%ied,bd%js:bd%je+1 )
116 real,
intent(in):: yfx(bd%isd:bd%ied,bd%js:bd%je+1 )
117 real,
intent(in):: ra_x(bd%is:bd%ie,bd%jsd:bd%jed)
118 real,
intent(in):: ra_y(bd%isd:bd%ied,bd%js:bd%je)
119 real,
intent(inout):: q(bd%isd:bd%ied,bd%jsd:bd%jed)
120 real,
intent(out)::fx(bd%is:bd%ie+1 ,bd%js:bd%je)
121 real,
intent(out)::fy(bd%is:bd%ie, bd%js:bd%je+1 )
125 real,
intent(in):: lim_fac
127 real,
OPTIONAL,
intent(in):: mfx(bd%is:bd%ie+1,bd%js:bd%je )
128 real,
OPTIONAL,
intent(in):: mfy(bd%is:bd%ie ,bd%js:bd%je+1)
129 real,
OPTIONAL,
intent(in):: mass(bd%isd:bd%ied,bd%jsd:bd%jed)
130 real,
OPTIONAL,
intent(in):: damp_c
131 integer,
OPTIONAL,
intent(in):: nord
133 integer ord_ou, ord_in
134 real q_i(bd%isd:bd%ied,bd%js:bd%je)
135 real q_j(bd%is:bd%ie,bd%jsd:bd%jed)
136 real fx2(bd%is:bd%ie+1,bd%jsd:bd%jed)
137 real fy2(bd%isd:bd%ied,bd%js:bd%je+1)
138 real fyy(bd%isd:bd%ied,bd%js:bd%je+1)
139 real fx1(bd%is:bd%ie+1)
143 integer:: is, ie, js, je, isd, ied, jsd, jed
154 if ( hord == 10 )
then 161 if (.not. gridstruct%bounded_domain) &
162 call copy_corners(q, npx, npy, 2, gridstruct%bounded_domain, bd, &
163 gridstruct%sw_corner, gridstruct%se_corner, gridstruct%nw_corner, gridstruct%ne_corner)
165 call yppm(fy2, q, cry, ord_in, isd,ied,isd,ied, js,je,jsd,jed, npx,npy, gridstruct%dya, gridstruct%bounded_domain, gridstruct%grid_type, lim_fac)
169 fyy(i,j) = yfx(i,j) * fy2(i,j)
174 q_i(i,j) = (q(i,j)*gridstruct%area(i,j) + fyy(i,j)-fyy(i,j+1))/ra_y(i,j)
178 call xppm(fx, q_i, crx(is,js), ord_ou, is,ie,isd,ied, js,je,jsd,jed, npx,npy, gridstruct%dxa, gridstruct%bounded_domain, gridstruct%grid_type, lim_fac)
180 if (.not. gridstruct%bounded_domain) &
181 call copy_corners(q, npx, npy, 1, gridstruct%bounded_domain, bd, &
182 gridstruct%sw_corner, gridstruct%se_corner, gridstruct%nw_corner, gridstruct%ne_corner)
184 call xppm(fx2, q, crx, ord_in, is,ie,isd,ied, jsd,jed,jsd,jed, npx,npy, gridstruct%dxa, gridstruct%bounded_domain, gridstruct%grid_type, lim_fac)
188 fx1(i) = xfx(i,j) * fx2(i,j)
191 q_j(i,j) = (q(i,j)*gridstruct%area(i,j) + fx1(i)-fx1(i+1))/ra_x(i,j)
195 call yppm(fy, q_j, cry, ord_ou, is,ie,isd,ied, js,je,jsd,jed, npx, npy, gridstruct%dya, gridstruct%bounded_domain, gridstruct%grid_type, lim_fac)
201 if (
present(mfx) .and.
present(mfy) )
then 207 fx(i,j) = 0.5*(fx(i,j) + fx2(i,j)) * mfx(i,j)
212 fy(i,j) = 0.5*(fy(i,j) + fy2(i,j)) * mfy(i,j)
215 if (
present(nord) .and.
present(damp_c) .and.
present(mass) )
then 216 if ( damp_c > 1.e-4 )
then 217 damp = (damp_c * gridstruct%da_min)**(nord+1)
218 call deln_flux(nord, is,ie,js,je, npx, npy, damp, q, fx, fy, gridstruct, bd, mass )
227 fx(i,j) = 0.5*(fx(i,j) + fx2(i,j)) * xfx(i,j)
232 fy(i,j) = 0.5*(fy(i,j) + fy2(i,j)) * yfx(i,j)
235 if (
present(nord) .and.
present(damp_c) )
then 236 if ( damp_c > 1.e-4 )
then 237 damp = (damp_c * gridstruct%da_min)**(nord+1)
238 call deln_flux(nord, is,ie,js,je, npx, npy, damp, q, fx, fy, gridstruct, bd)
246 subroutine copy_corners(q, npx, npy, dir, bounded_domain, bd, &
247 sw_corner, se_corner, nw_corner, ne_corner)
249 integer,
intent(in):: npx, npy, dir
250 real,
intent(inout):: q(bd%isd:bd%ied,bd%jsd:bd%jed)
251 logical,
intent(IN) :: bounded_domain, sw_corner, se_corner, nw_corner, ne_corner
256 if (bounded_domain)
return 260 if ( sw_corner )
then 267 if ( se_corner )
then 270 q(i,j) = q(npy-j,i-npx+1)
274 if ( ne_corner )
then 277 q(i,j) = q(j,2*npx-1-i)
281 if ( nw_corner )
then 284 q(i,j) = q(npy-j,i-1+npx)
289 elseif ( dir == 2 )
then 292 if ( sw_corner )
then 299 if ( se_corner )
then 302 q(i,j) = q(npy+j-1,npx-i)
306 if ( ne_corner )
then 309 q(i,j) = q(2*npy-1-j,i)
313 if ( nw_corner )
then 316 q(i,j) = q(j+1-npx,npy-i)
325 subroutine xppm(flux, q, c, iord, is,ie,isd,ied, jfirst,jlast,jsd,jed, npx, npy, dxa, bounded_domain, grid_type, lim_fac)
326 integer,
INTENT(IN) :: is, ie, isd, ied, jsd, jed
327 integer,
INTENT(IN) :: jfirst, jlast
328 integer,
INTENT(IN) :: iord
329 integer,
INTENT(IN) :: npx, npy
330 real ,
INTENT(IN) :: q(isd:ied,jfirst:jlast)
331 real ,
INTENT(IN) :: c(is:ie+1,jfirst:jlast)
332 real ,
intent(IN) :: dxa(isd:ied,jsd:jed)
333 logical,
intent(IN) :: bounded_domain
334 integer,
intent(IN) :: grid_type
335 real ,
intent(IN) :: lim_fac
337 real ,
INTENT(OUT) :: flux(is:ie+1,jfirst:jlast)
339 real,
dimension(is-1:ie+1):: bl, br, b0
341 real,
dimension(is:ie+1):: fx0, fx1, xt1
342 logical,
dimension(is-1:ie+1):: smt5, smt6
343 logical,
dimension(is:ie+1):: hi5, hi6
347 integer:: i, j, ie3, is1, ie1, mord
348 real:: x0, x1, xt, qtmp, pmp_1, lac_1, pmp_2, lac_2
350 if ( .not. bounded_domain .and. grid_type<3 )
then 351 is1 = max(3,is-1); ie3 = min(npx-2,ie+2)
352 ie1 = min(npx-3,ie+1)
354 is1 = is-1; ie3 = ie+2
359 do 666 j=jfirst,jlast
370 al(i) =
p1*(q1(i-1)+q1(i)) +
p2*(q1(i-2)+q1(i+1))
373 if ( .not. bounded_domain .and. grid_type<3 )
then 375 al(0) =
c1*q1(-2) +
c2*q1(-1) +
c3*q1(0)
376 al(1) = 0.5*(((2.*dxa(0,j)+dxa(-1,j))*q1(0)-dxa(0,j)*q1(-1))/(dxa(-1,j)+dxa(0,j)) &
377 + ((2.*dxa(1,j)+dxa( 2,j))*q1(1)-dxa(1,j)*q1( 2))/(dxa(1, j)+dxa(2,j)))
378 al(2) =
c3*q1(1) +
c2*q1(2) +
c1*q1(3)
380 if ( (ie+1)==npx )
then 381 al(npx-1) =
c1*q1(npx-3) +
c2*q1(npx-2) +
c3*q1(npx-1)
382 al(npx) = 0.5*(((2.*dxa(npx-1,j)+dxa(npx-2,j))*q1(npx-1)-dxa(npx-1,j)*q1(npx-2))/(dxa(npx-2,j)+dxa(npx-1,j)) &
383 + ((2.*dxa(npx, j)+dxa(npx+1,j))*q1(npx )-dxa(npx, j)*q1(npx+1))/(dxa(npx, j)+dxa(npx+1,j)))
384 al(npx+1) =
c3*q1(npx) +
c2*q1(npx+1) +
c1*q1(npx+2)
390 al(i) = max(0., al(i))
396 bl(i) = al(i) - q1(i)
397 br(i) = al(i+1) - q1(i)
398 b0(i) = bl(i) + br(i)
399 smt5(i) = abs(lim_fac*b0(i)) < abs(bl(i)-br(i))
403 if ( c(i,j) > 0. )
then 404 fx1(i) = (1.-c(i,j))*(br(i-1) - c(i,j)*b0(i-1))
407 fx1(i) = (1.+c(i,j))*(bl(i) + c(i,j)*b0(i))
410 if (smt5(i-1).or.smt5(i)) flux(i,j) = flux(i,j) + fx1(i)
413 elseif ( mord==2 )
then 420 flux(i,j) = qtmp + (1.-xt)*(al(i)-qtmp-xt*(al(i-1)+al(i)-(qtmp+qtmp)))
423 flux(i,j) = qtmp + (1.+xt)*(al(i)-qtmp+xt*(al(i)+al(i+1)-(qtmp+qtmp)))
431 elseif ( mord==3 )
then 434 bl(i) = al(i) - q1(i)
435 br(i) = al(i+1) - q1(i)
436 b0(i) = bl(i) + br(i)
438 xt = abs(bl(i)-br(i))
445 hi5(i) = smt5(i-1) .and. smt5(i)
446 hi6(i) = smt6(i-1) .or. smt6(i)
449 if ( xt1(i) > 0. )
then 451 fx1(i) = br(i-1) - xt1(i)*b0(i-1)
452 elseif ( hi5(i) )
then 453 fx1(i) = sign(min(abs(bl(i-1)),abs(br(i-1))), br(i-1))
455 flux(i,j) = q1(i-1) + (1.-xt1(i))*fx1(i)
458 fx1(i) = bl(i) + xt1(i)*b0(i)
459 elseif ( hi5(i) )
then 460 fx1(i) = sign(min(abs(bl(i)), abs(br(i))), bl(i))
462 flux(i,j) = q1(i) + (1.+xt1(i))*fx1(i)
466 elseif ( mord==4 )
then 469 bl(i) = al(i) - q1(i)
470 br(i) = al(i+1) - q1(i)
471 b0(i) = bl(i) + br(i)
473 xt = abs(bl(i)-br(i))
479 hi5(i) = smt5(i-1) .and. smt5(i)
480 hi6(i) = smt6(i-1) .or. smt6(i)
481 hi5(i) = hi5(i) .or. hi6(i)
485 if ( xt1(i) > 0. )
then 486 fx1(i) = (1.-xt1(i))*(br(i-1) - xt1(i)*b0(i-1))
489 fx1(i) = (1.+xt1(i))*(bl(i) + xt1(i)*b0(i))
492 if ( hi5(i) ) flux(i,j) = flux(i,j) + fx1(i)
499 bl(i) = al(i) - q1(i)
500 br(i) = al(i+1) - q1(i)
501 b0(i) = bl(i) + br(i)
502 smt5(i) = bl(i)*br(i) < 0.
506 bl(i) = al(i) - q1(i)
507 br(i) = al(i+1) - q1(i)
508 b0(i) = bl(i) + br(i)
509 smt5(i) = 3.*abs(b0(i)) < abs(bl(i)-br(i))
515 if ( c(i,j) > 0. )
then 516 fx1(i) = (1.-c(i,j))*(br(i-1) - c(i,j)*b0(i-1))
519 fx1(i) = (1.+c(i,j))*(bl(i) + c(i,j)*b0(i))
522 if (smt5(i-1).or.smt5(i)) flux(i,j) = flux(i,j) + fx1(i)
536 xt = 0.25*(q1(i+1) - q1(i-1))
537 dm(i) = sign(min(abs(xt), max(q1(i-1), q1(i), q1(i+1)) - q1(i), &
538 q1(i) - min(q1(i-1), q1(i), q1(i+1))), xt)
541 al(i) = 0.5*(q1(i-1)+q1(i)) +
r3*(dm(i-1)-dm(i))
547 bl(i) = -sign(min(abs(xt), abs(al(i )-q1(i))), xt)
548 br(i) = sign(min(abs(xt), abs(al(i+1)-q1(i))), xt)
550 elseif ( iord==11 )
then 554 bl(i) = -sign(min(abs(xt), abs(al(i )-q1(i))), xt)
555 br(i) = sign(min(abs(xt), abs(al(i+1)-q1(i))), xt)
559 dq(i) = 2.*(q1(i+1) - q1(i))
562 bl(i) = al(i ) - q1(i)
563 br(i) = al(i+1) - q1(i)
564 if ( abs(dm(i-1))+abs(dm(i))+abs(dm(i+1)) <
near_zero )
then 567 elseif( abs(3.*(bl(i)+br(i))) > abs(bl(i)-br(i)) )
then 569 lac_2 = pmp_2 - 0.75*dq(i-2)
570 br(i) = min( max(0., pmp_2, lac_2), max(br(i), min(0., pmp_2, lac_2)) )
572 lac_1 = pmp_1 + 0.75*dq(i+1)
573 bl(i) = min( max(0., pmp_1, lac_1), max(bl(i), min(0., pmp_1, lac_1)) )
578 if(iord==9 .or. iord==13)
call pert_ppm(ie1-is1+1, q1(is1), bl(is1), br(is1), 0)
580 if (.not. bounded_domain .and. grid_type<3)
then 582 bl(0) =
s14*dm(-1) +
s11*(q1(-1)-q1(0))
584 xt = 0.5*(((2.*dxa(0,j)+dxa(-1,j))*q1(0)-dxa(0,j)*q1(-1))/(dxa(-1,j)+dxa(0,j)) &
585 + ((2.*dxa(1,j)+dxa( 2,j))*q1(1)-dxa(1,j)*q1( 2))/(dxa(1, j)+dxa(2,j)))
587 xt = max(xt, min(q1(-1),q1(0),q1(1),q1(2)))
588 xt = min(xt, max(q1(-1),q1(0),q1(1),q1(2)))
596 br(2) = al(3) - q1(2)
597 call pert_ppm(3, q1(0), bl(0), br(0), 1)
599 if ( (ie+1)==npx )
then 600 bl(npx-2) = al(npx-2) - q1(npx-2)
602 xt =
s15*q1(npx-1) +
s11*q1(npx-2) +
s14*dm(npx-2)
603 br(npx-2) = xt - q1(npx-2)
604 bl(npx-1) = xt - q1(npx-1)
606 xt = 0.5*(((2.*dxa(npx-1,j)+dxa(npx-2,j))*q1(npx-1)-dxa(npx-1,j)*q1(npx-2))/(dxa(npx-2,j)+dxa(npx-1,j)) &
607 + ((2.*dxa(npx, j)+dxa(npx+1,j))*q1(npx )-dxa(npx, j)*q1(npx+1))/(dxa(npx, j)+dxa(npx+1,j)))
609 xt = max(xt, min(q1(npx-2),q1(npx-1),q1(npx),q1(npx+1)))
610 xt = min(xt, max(q1(npx-2),q1(npx-1),q1(npx),q1(npx+1)))
612 br(npx-1) = xt - q1(npx-1)
613 bl(npx ) = xt - q1(npx )
615 br(npx) =
s11*(q1(npx+1)-q1(npx)) -
s14*dm(npx+1)
616 call pert_ppm(3, q1(npx-2), bl(npx-2), br(npx-2), 1)
624 flux(i,j) = q1(i-1) + (1.-c(i,j))*(br(i-1)-c(i,j)*(bl(i-1)+br(i-1)))
626 flux(i,j) = q1(i ) + (1.+c(i,j))*(bl(i )+c(i,j)*(bl(i)+br(i)))
634 subroutine yppm(flux, q, c, jord, ifirst,ilast, isd,ied, js,je,jsd,jed, npx, npy, dya, bounded_domain, grid_type, lim_fac)
635 integer,
INTENT(IN) :: ifirst,ilast
636 integer,
INTENT(IN) :: isd,ied, js,je,jsd,jed
637 integer,
INTENT(IN) :: jord
638 integer,
INTENT(IN) :: npx, npy
639 real ,
INTENT(IN) :: q(ifirst:ilast,jsd:jed)
640 real ,
intent(in) :: c(isd:ied,js:je+1 )
641 real ,
INTENT(OUT):: flux(ifirst:ilast,js:je+1)
642 real ,
intent(IN) :: dya(isd:ied,jsd:jed)
643 logical,
intent(IN) :: bounded_domain
644 integer,
intent(IN) :: grid_type
645 real ,
intent(IN) :: lim_fac
647 real:: dm(ifirst:ilast,js-2:je+2)
648 real:: al(ifirst:ilast,js-1:je+2)
649 real,
dimension(ifirst:ilast,js-1:je+1):: bl, br, b0
650 real:: dq(ifirst:ilast,js-3:je+2)
651 real,
dimension(ifirst:ilast):: fx0, fx1, xt1
652 logical,
dimension(ifirst:ilast,js-1:je+1):: smt5, smt6
653 logical,
dimension(ifirst:ilast):: hi5, hi6
654 real:: x0, xt, qtmp, pmp_1, lac_1, pmp_2, lac_2, r1
655 integer:: i, j, js1, je3, je1, mord
657 if ( .not.bounded_domain .and. grid_type < 3 )
then 659 js1 = max(3,js-1); je3 = min(npy-2,je+2)
660 je1 = min(npy-3,je+1)
663 js1 = js-1; je3 = je+2
673 al(i,j) =
p1*(q(i,j-1)+q(i,j)) +
p2*(q(i,j-2)+q(i,j+1))
677 if ( .not. bounded_domain .and. grid_type<3 )
then 680 al(i,0) =
c1*q(i,-2) +
c2*q(i,-1) +
c3*q(i,0)
681 al(i,1) = 0.5*(((2.*dya(i,0)+dya(i,-1))*q(i,0)-dya(i,0)*q(i,-1))/(dya(i,-1)+dya(i,0)) &
682 + ((2.*dya(i,1)+dya(i,2))*q(i,1)-dya(i,1)*q(i,2))/(dya(i,1)+dya(i,2)))
683 al(i,2) =
c3*q(i,1) +
c2*q(i,2) +
c1*q(i,3)
686 if( (je+1)==npy )
then 688 al(i,npy-1) =
c1*q(i,npy-3) +
c2*q(i,npy-2) +
c3*q(i,npy-1)
689 al(i,npy) = 0.5*(((2.*dya(i,npy-1)+dya(i,npy-2))*q(i,npy-1)-dya(i,npy-1)*q(i,npy-2))/(dya(i,npy-2)+dya(i,npy-1)) &
690 + ((2.*dya(i,npy)+dya(i,npy+1))*q(i,npy)-dya(i,npy)*q(i,npy+1))/(dya(i,npy)+dya(i,npy+1)))
691 al(i,npy+1) =
c3*q(i,npy) +
c2*q(i,npy+1) +
c1*q(i,npy+2)
699 al(i,j) = max(0., al(i,j))
707 bl(i,j) = al(i,j ) - q(i,j)
708 br(i,j) = al(i,j+1) - q(i,j)
709 b0(i,j) = bl(i,j) + br(i,j)
710 smt5(i,j) = abs(lim_fac*b0(i,j)) < abs(bl(i,j)-br(i,j))
716 if ( c(i,j) > 0. )
then 717 fx1(i) = (1.-c(i,j))*(br(i,j-1) - c(i,j)*b0(i,j-1))
720 fx1(i) = (1.+c(i,j))*(bl(i,j) + c(i,j)*b0(i,j))
723 if (smt5(i,j-1).or.smt5(i,j)) flux(i,j) = flux(i,j) + fx1(i)
727 elseif ( mord==2 )
then 736 flux(i,j) = qtmp + (1.-xt)*(al(i,j)-qtmp-xt*(al(i,j-1)+al(i,j)-(qtmp+qtmp)))
739 flux(i,j) = qtmp + (1.+xt)*(al(i,j)-qtmp+xt*(al(i,j)+al(i,j+1)-(qtmp+qtmp)))
744 elseif ( mord==3 )
then 748 bl(i,j) = al(i,j ) - q(i,j)
749 br(i,j) = al(i,j+1) - q(i,j)
750 b0(i,j) = bl(i,j) + br(i,j)
752 xt = abs(bl(i,j)-br(i,j))
754 smt6(i,j) = 3.*x0 < xt
761 hi5(i) = smt5(i,j-1) .and. smt5(i,j)
762 hi6(i) = smt6(i,j-1) .or. smt6(i,j)
765 if ( xt1(i) > 0. )
then 767 fx1(i) = br(i,j-1) - xt1(i)*b0(i,j-1)
768 elseif ( hi5(i) )
then 769 fx1(i) = sign(min(abs(bl(i,j-1)),abs(br(i,j-1))),br(i,j-1))
771 flux(i,j) = q(i,j-1) + (1.-xt1(i))*fx1(i)
774 fx1(i) = bl(i,j) + xt1(i)*b0(i,j)
775 elseif ( hi5(i) )
then 776 fx1(i) = sign(min(abs(bl(i,j)),abs(br(i,j))), bl(i,j))
778 flux(i,j) = q(i,j) + (1.+xt1(i))*fx1(i)
783 elseif ( mord==4 )
then 787 bl(i,j) = al(i,j ) - q(i,j)
788 br(i,j) = al(i,j+1) - q(i,j)
789 b0(i,j) = bl(i,j) + br(i,j)
791 xt = abs(bl(i,j)-br(i,j))
793 smt6(i,j) = 3.*x0 < xt
799 hi5(i) = smt5(i,j-1) .and. smt5(i,j)
800 hi6(i) = smt6(i,j-1) .or. smt6(i,j)
801 hi5(i) = hi5(i) .or. hi6(i)
805 if ( xt1(i) > 0. )
then 806 fx1(i) = (1.-xt1(i))*(br(i,j-1) - xt1(i)*b0(i,j-1))
809 fx1(i) = (1.+xt1(i))*(bl(i,j) + xt1(i)*b0(i,j))
812 if ( hi5(i) ) flux(i,j) = flux(i,j) + fx1(i)
820 bl(i,j) = al(i,j ) - q(i,j)
821 br(i,j) = al(i,j+1) - q(i,j)
822 b0(i,j) = bl(i,j) + br(i,j)
823 smt5(i,j) = bl(i,j)*br(i,j) < 0.
829 bl(i,j) = al(i,j ) - q(i,j)
830 br(i,j) = al(i,j+1) - q(i,j)
831 b0(i,j) = bl(i,j) + br(i,j)
832 smt5(i,j) = 3.*abs(b0(i,j)) < abs(bl(i,j)-br(i,j))
840 if ( c(i,j) > 0. )
then 841 fx1(i) = (1.-c(i,j))*(br(i,j-1) - c(i,j)*b0(i,j-1))
844 fx1(i) = (1.+c(i,j))*(bl(i,j) + c(i,j)*b0(i,j))
847 if (smt5(i,j-1).or.smt5(i,j)) flux(i,j) = flux(i,j) + fx1(i)
861 xt = 0.25*(q(i,j+1) - q(i,j-1))
862 dm(i,j) = sign(min(abs(xt), max(q(i,j-1), q(i,j), q(i,j+1)) - q(i,j), &
863 q(i,j) - min(q(i,j-1), q(i,j), q(i,j+1))), xt)
868 al(i,j) = 0.5*(q(i,j-1)+q(i,j)) +
r3*(dm(i,j-1) - dm(i,j))
876 bl(i,j) = -sign(min(abs(xt), abs(al(i,j)-q(i,j))), xt)
877 br(i,j) = sign(min(abs(xt), abs(al(i,j+1)-q(i,j))), xt)
880 elseif ( jord==11 )
then 884 bl(i,j) = -sign(min(abs(xt), abs(al(i,j)-q(i,j))), xt)
885 br(i,j) = sign(min(abs(xt), abs(al(i,j+1)-q(i,j))), xt)
891 dq(i,j) = 2.*(q(i,j+1) - q(i,j))
896 bl(i,j) = al(i,j ) - q(i,j)
897 br(i,j) = al(i,j+1) - q(i,j)
898 if ( abs(dm(i,j-1))+abs(dm(i,j))+abs(dm(i,j+1)) <
near_zero )
then 901 elseif( abs(3.*(bl(i,j)+br(i,j))) > abs(bl(i,j)-br(i,j)) )
then 903 lac_2 = pmp_2 - 0.75*dq(i,j-2)
904 br(i,j) = min(max(0.,pmp_2,lac_2), max(br(i,j), min(0.,pmp_2,lac_2)))
906 lac_1 = pmp_1 + 0.75*dq(i,j+1)
907 bl(i,j) = min(max(0.,pmp_1,lac_1), max(bl(i,j), min(0.,pmp_1,lac_1)))
912 if ( jord==9 .or. jord==13 )
then 915 call pert_ppm(ilast-ifirst+1, q(ifirst,j), bl(ifirst,j), br(ifirst,j), 0)
919 if (.not. bounded_domain .and. grid_type<3)
then 922 bl(i,0) =
s14*dm(i,-1) +
s11*(q(i,-1)-q(i,0))
924 xt = 0.5*(((2.*dya(i,0)+dya(i,-1))*q(i,0)-dya(i,0)*q(i,-1))/(dya(i,-1)+dya(i,0)) &
925 + ((2.*dya(i,1)+dya(i,2))*q(i,1)-dya(i,1)*q(i,2))/(dya(i,1)+dya(i,2)))
927 xt = max(xt, min(q(i,-1),q(i,0),q(i,1),q(i,2)))
928 xt = min(xt, max(q(i,-1),q(i,0),q(i,1),q(i,2)))
930 br(i,0) = xt - q(i,0)
931 bl(i,1) = xt - q(i,1)
933 xt =
s15*q(i,1) +
s11*q(i,2) -
s14*dm(i,2)
934 br(i,1) = xt - q(i,1)
935 bl(i,2) = xt - q(i,2)
937 br(i,2) = al(i,3) - q(i,2)
939 call pert_ppm(3*(ilast-ifirst+1), q(ifirst,0), bl(ifirst,0), br(ifirst,0), 1)
941 if( (je+1)==npy )
then 943 bl(i,npy-2) = al(i,npy-2) - q(i,npy-2)
945 xt =
s15*q(i,npy-1) +
s11*q(i,npy-2) +
s14*dm(i,npy-2)
946 br(i,npy-2) = xt - q(i,npy-2)
947 bl(i,npy-1) = xt - q(i,npy-1)
949 xt = 0.5*(((2.*dya(i,npy-1)+dya(i,npy-2))*q(i,npy-1)-dya(i,npy-1)*q(i,npy-2))/(dya(i,npy-2)+dya(i,npy-1)) &
950 + ((2.*dya(i,npy)+dya(i,npy+1))*q(i,npy)-dya(i,npy)*q(i,npy+1))/(dya(i,npy)+dya(i,npy+1)))
952 xt = max(xt, min(q(i,npy-2),q(i,npy-1),q(i,npy),q(i,npy+1)))
953 xt = min(xt, max(q(i,npy-2),q(i,npy-1),q(i,npy),q(i,npy+1)))
955 br(i,npy-1) = xt - q(i,npy-1)
956 bl(i,npy ) = xt - q(i,npy)
958 br(i,npy) =
s11*(q(i,npy+1)-q(i,npy)) -
s14*dm(i,npy+1)
960 call pert_ppm(3*(ilast-ifirst+1), q(ifirst,npy-2), bl(ifirst,npy-2), br(ifirst,npy-2), 1)
969 flux(i,j) = q(i,j-1) + (1.-c(i,j))*(br(i,j-1)-c(i,j)*(bl(i,j-1)+br(i,j-1)))
971 flux(i,j) = q(i,j ) + (1.+c(i,j))*(bl(i,j )+c(i,j)*(bl(i,j)+br(i,j)))
979 subroutine mp_ghost_ew(im, jm, km, nq, ifirst, ilast, jfirst, jlast, &
980 kfirst, klast, ng_w, ng_e, ng_s, ng_n, q_ghst, q)
983 integer,
intent(in):: im, jm, km, nq
984 integer,
intent(in):: ifirst, ilast
985 integer,
intent(in):: jfirst, jlast
986 integer,
intent(in):: kfirst, klast
987 integer,
intent(in):: ng_e
988 integer,
intent(in):: ng_w
989 integer,
intent(in):: ng_s
990 integer,
intent(in):: ng_n
991 real,
intent(inout):: q_ghst(ifirst-ng_w:ilast+ng_e,jfirst-ng_s:jlast+ng_n,kfirst:klast,nq)
992 real,
optional,
intent(in):: q(ifirst:ilast,jfirst:jlast,kfirst:klast,nq)
1006 if (
present(q))
then 1007 q_ghst(ifirst:ilast,jfirst:jlast,kfirst:klast,1:nq) = &
1008 q(ifirst:ilast,jfirst:jlast,kfirst:klast,1:nq)
1014 do j=jfirst-ng_s,jlast+ng_n
1016 q_ghst(ifirst-i,j,k,n) = q_ghst(ilast-i+1,j,k,n)
1019 q_ghst(ilast+i,j,k,n) = q_ghst(ifirst+i-1,j,k,n)
1029 subroutine pert_ppm(im, a0, al, ar, iv)
1030 integer,
intent(in):: im
1031 integer,
intent(in):: iv
1032 real,
intent(in) :: a0(im)
1033 real,
intent(inout):: al(im), ar(im)
1035 real a4, da1, da2, a6da, fmin
1037 real,
parameter:: r12 = 1./12.
1046 if ( a0(i) <= 0. )
then 1050 a4 = -3.*(ar(i) + al(i))
1052 if( abs(da1) < -a4 )
then 1053 fmin = a0(i) + 0.25/a4*da1**2 + a4*r12
1054 if( fmin < 0. )
then 1055 if( ar(i)>0. .and. al(i)>0. )
then 1058 elseif( da1 > 0. )
then 1070 if ( al(i)*ar(i) < 0. )
then 1073 a6da = 3.*(al(i)+ar(i))*da1
1075 if( a6da < -da2 )
then 1077 elseif( a6da > da2 )
then 1091 subroutine deln_flux(nord,is,ie,js,je, npx, npy, damp, q, fx, fy, gridstruct, bd, mass )
1100 integer,
intent(in):: nord
1101 integer,
intent(in):: is,ie,js,je, npx, npy
1102 real,
intent(in):: damp
1103 real,
intent(in):: q(bd%isd:bd%ied, bd%jsd:bd%jed)
1105 real,
optional,
intent(in):: mass(bd%isd:bd%ied, bd%jsd:bd%jed)
1107 real,
intent(inout):: fx(bd%is:bd%ie+1,bd%js:bd%je), fy(bd%is:bd%ie,bd%js:bd%je+1)
1109 real fx2(bd%isd:bd%ied+1,bd%jsd:bd%jed), fy2(bd%isd:bd%ied,bd%jsd:bd%jed+1)
1110 real d2(bd%isd:bd%ied,bd%jsd:bd%jed)
1112 integer i,j, n, nt, i1, i2, j1, j2
1115 real,
pointer,
dimension(:,:) :: dx, dy, rdxc, rdyc
1116 real,
pointer,
dimension(:,:,:) :: sin_sg
1119 rdxc => gridstruct%rdxc
1120 rdyc => gridstruct%rdyc
1121 sin_sg => gridstruct%sin_sg
1124 i1 = is-1-nord; i2 = ie+1+nord
1125 j1 = js-1-nord; j2 = je+1+nord
1127 if ( .not.
present(mass) )
then 1130 d2(i,j) = damp*q(i,j)
1141 if( nord>0 )
call copy_corners(d2, npx, npy, 1, gridstruct%bounded_domain, bd, &
1142 gridstruct%sw_corner, gridstruct%se_corner, gridstruct%nw_corner, gridstruct%ne_corner)
1144 do j=js-nord,je+nord
1145 do i=is-nord,ie+nord+1
1147 fx2(i,j) = 0.5*(sin_sg(i-1,j,3)+sin_sg(i,j,1))*dy(i,j)*(d2(i-1,j)-d2(i,j))*rdxc(i,j)
1149 fx2(i,j) = gridstruct%del6_v(i,j)*(d2(i-1,j)-d2(i,j))
1154 if( nord>0 )
call copy_corners(d2, npx, npy, 2, gridstruct%bounded_domain, bd, &
1155 gridstruct%sw_corner, gridstruct%se_corner, gridstruct%nw_corner, gridstruct%ne_corner)
1156 do j=js-nord,je+nord+1
1157 do i=is-nord,ie+nord
1159 fy2(i,j) = 0.5*(sin_sg(i,j-1,4)+sin_sg(i,j,2))*dx(i,j)*(d2(i,j-1)-d2(i,j))*rdyc(i,j)
1161 fy2(i,j) = gridstruct%del6_u(i,j)*(d2(i,j-1)-d2(i,j))
1176 do j=js-nt-1,je+nt+1
1177 do i=is-nt-1,ie+nt+1
1178 d2(i,j) = (fx2(i,j)-fx2(i+1,j)+fy2(i,j)-fy2(i,j+1))*gridstruct%rarea(i,j)
1182 call copy_corners(d2, npx, npy, 1, gridstruct%bounded_domain, bd, &
1183 gridstruct%sw_corner, gridstruct%se_corner, gridstruct%nw_corner, gridstruct%ne_corner)
1187 fx2(i,j) = 0.5*(sin_sg(i-1,j,3)+sin_sg(i,j,1))*dy(i,j)*(d2(i,j)-d2(i-1,j))*rdxc(i,j)
1189 fx2(i,j) = gridstruct%del6_v(i,j)*(d2(i,j)-d2(i-1,j))
1194 call copy_corners(d2, npx, npy, 2, gridstruct%bounded_domain, bd, &
1195 gridstruct%sw_corner, gridstruct%se_corner, gridstruct%nw_corner, gridstruct%ne_corner)
1199 fy2(i,j) = 0.5*(sin_sg(i,j-1,4)+sin_sg(i,j,2))*dx(i,j)*(d2(i,j)-d2(i,j-1))*rdyc(i,j)
1201 fy2(i,j) = gridstruct%del6_u(i,j)*(d2(i,j)-d2(i,j-1))
1213 if (
present(mass) )
then 1218 fx(i,j) = fx(i,j) + damp2*(mass(i-1,j)+mass(i,j))*fx2(i,j)
1223 fy(i,j) = fy(i,j) + damp2*(mass(i,j-1)+mass(i,j))*fy2(i,j)
1229 fx(i,j) = fx(i,j) + fx2(i,j)
1234 fy(i,j) = fy(i,j) + fy2(i,j)
subroutine, public fv_tp_2d(q, crx, cry, npx, npy, hord, fx, fy, xfx, yfx, gridstruct, bd, ra_x, ra_y, lim_fac, mfx, mfy, mass, nord, damp_c)
The subroutine 'fv_tp_2d' contains the FV advection scheme .
The type 'fv_grid_type' is made up of grid-dependent information from fv_grid_tools and fv_grid_utils...
subroutine xppm(flux, q, c, iord, is, ie, isd, ied, jfirst, jlast, jsd, jed, npx, npy, dxa, bounded_domain, grid_type, lim_fac)
subroutine deln_flux(nord, is, ie, js, je, npx, npy, damp, q, fx, fy, gridstruct, bd, mass)
real, parameter ppm_limiter
The module 'tp_core' is a collection of routines to support FV transport.
real, parameter near_zero
The module 'fv_arrays' contains the 'fv_atmos_type' and associated datatypes.
real, parameter, public big_number
subroutine, public pert_ppm(im, a0, al, ar, iv)
real, parameter ppm_fac
nonlinear scheme limiter: between 1 and 2
The module 'fv_grid_utils' contains routines for setting up and computing grid-related quantities...
subroutine mp_ghost_ew(im, jm, km, nq, ifirst, ilast, jfirst, jlast, kfirst, klast, ng_w, ng_e, ng_s, ng_n, q_ghst, q)
subroutine, public copy_corners(q, npx, npy, dir, bounded_domain, bd, sw_corner, se_corner, nw_corner, ne_corner)
subroutine yppm(flux, q, c, jord, ifirst, ilast, isd, ied, js, je, jsd, jed, npx, npy, dya, bounded_domain, grid_type, lim_fac)