FV3 Bundle
advect_pv.f90
Go to the documentation of this file.
1 ! (C) Copyright 2009-2016 ECMWF.
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 ! In applying this licence, ECMWF does not waive the privileges and immunities
6 ! granted to it by virtue of its status as an intergovernmental organisation nor
7 ! does it submit to any jurisdiction.
8 
9 !> Advect potential vorticity
10 
11 !> Potential vorticity is advected using cubic Lagrange interpolation
12 !! in the zonal direction, and then the meridional direction.
13 !!
14 !! Note that this is a first-order scheme. The upstream point is
15 !! determined solely from the wind at the arrival point.
16 
17 subroutine advect_pv (qnew,q,q_north,q_south,u,v,nx,ny,deltax,deltay,dt)
18 
19 !--- semi-Lagrangian advection of pv
20 
21 use kinds
22 
23 implicit none
24 real(kind_real), intent(out) :: qnew(nx,ny,2) !< Output potential vorticity
25 real(kind_real), intent(in) :: q(nx,ny,2) !< Input potential vorticity
26 real(kind_real), intent(in) :: q_north(nx,2) !< PV on northern wall
27 real(kind_real), intent(in) :: q_south(nx,2) !< PV on southern wall
28 real(kind_real), intent(in) :: u(nx,ny,2) !< Advecting zonal wind
29 real(kind_real), intent(in) :: v(nx,ny,2) !< Advecting meridional wind
30 integer, intent(in) :: nx !< Zonal grid dimensions
31 integer, intent(in) :: ny !< Meridional grid dimensions
32 real(kind_real), intent(in) :: deltax !< Zonal grid spacing (non-dimensional)
33 real(kind_real), intent(in) :: deltay !< Meridional grid spacing (non-dimensional)
34 real(kind_real), intent(in) :: dt !< Timestep (non-dimensional)
35 
36 integer :: ii,jj,kk,ixm1,ix,ixp1,ixp2,jym1,jy,jyp1,jyp2
37 real(kind_real) :: ax,ay,qjm1,qj,qjp1,qjp2
38 real(kind_real), parameter :: one=1.0_kind_real
39 real(kind_real), parameter :: two=2.0_kind_real
40 real(kind_real), parameter :: half=0.5_kind_real
41 real(kind_real), parameter :: sixth=1.0_kind_real/6.0_kind_real
42 
43 !--- advect q, returning qnew
44 
45 do kk=1,2
46  do jj=1,ny
47  do ii=1,nx
48 
49 !--- find the interpolation point
50 
51  ax = real(ii,kind_real) - u(ii,jj,kk)*dt/deltax
52  ix = floor(ax)
53  ax = ax-real(ix,kind_real)
54  ixm1 = 1 + modulo(ix-2,nx)
55  ixp1 = 1 + modulo(ix ,nx)
56  ixp2 = 1 + modulo(ix+1,nx)
57  ix = 1 + modulo(ix-1,nx)
58 
59  ay = real(jj,kind_real) - v(ii,jj,kk)*dt/deltay
60  jy = floor(ay)
61  ay = ay-real(jy,kind_real)
62  jym1 = jy-1
63  jyp1 = jy+1
64  jyp2 = jy+2
65 
66 !--- Lagrange interpolation in the zonal direction
67 
68  if (jym1 < 1) then
69  qjm1 = ax *(ax-one)*(ax-two)*q_south(ixm1,kk)*(-sixth) + &
70  & (ax+one)*(ax-one)*(ax-two)*q_south(ix, kk)*half + &
71  & (ax+one)* ax *(ax-two)*q_south(ixp1,kk)*(-half) + &
72  & (ax+one)* ax *(ax-one)*q_south(ixp2,kk)*(sixth)
73  else if (jym1 > ny) then
74  qjm1 = ax *(ax-one)*(ax-two)*q_north(ixm1,kk)*(-sixth) + &
75  & (ax+one)*(ax-one)*(ax-two)*q_north(ix, kk)*half + &
76  & (ax+one)* ax *(ax-two)*q_north(ixp1,kk)*(-half) + &
77  & (ax+one)* ax *(ax-one)*q_north(ixp2,kk)*(sixth)
78  else
79  qjm1 = ax *(ax-one)*(ax-two)*q(ixm1,jym1,kk)*(-sixth) + &
80  & (ax+one)*(ax-one)*(ax-two)*q(ix, jym1,kk)*half + &
81  & (ax+one)* ax *(ax-two)*q(ixp1,jym1,kk)*(-half) + &
82  & (ax+one)* ax *(ax-one)*q(ixp2,jym1,kk)*(sixth)
83  endif
84 
85  if (jy < 1) then
86  qj = ax *(ax-one)*(ax-two)*q_south(ixm1,kk)*(-sixth) + &
87  & (ax+one)*(ax-one)*(ax-two)*q_south(ix ,kk)*half + &
88  & (ax+one)* ax *(ax-two)*q_south(ixp1,kk)*(-half) + &
89  & (ax+one)* ax *(ax-one)*q_south(ixp2,kk)*(sixth)
90  else if (jy > ny) then
91  qj = ax *(ax-one)*(ax-two)*q_north(ixm1,kk)*(-sixth) + &
92  & (ax+one)*(ax-one)*(ax-two)*q_north(ix ,kk)*half + &
93  & (ax+one)* ax *(ax-two)*q_north(ixp1,kk)*(-half) + &
94  & (ax+one)* ax *(ax-one)*q_north(ixp2,kk)*(sixth)
95  else
96  qj = ax *(ax-one)*(ax-two)*q(ixm1,jy,kk)*(-sixth) + &
97  & (ax+one)*(ax-one)*(ax-two)*q(ix ,jy,kk)*half + &
98  & (ax+one)* ax *(ax-two)*q(ixp1,jy,kk)*(-half) + &
99  & (ax+one)* ax *(ax-one)*q(ixp2,jy,kk)*(sixth)
100  endif
101 
102  if (jyp1 < 1) then
103  qjp1 = ax *(ax-one)*(ax-two)*q_south(ixm1,kk)*(-sixth) + &
104  & (ax+one)*(ax-one)*(ax-two)*q_south(ix ,kk)*half + &
105  & (ax+one)* ax *(ax-two)*q_south(ixp1,kk)*(-half) + &
106  & (ax+one)* ax *(ax-one)*q_south(ixp2,kk)*(sixth)
107  else if (jyp1 > ny) then
108  qjp1 = ax *(ax-one)*(ax-two)*q_north(ixm1,kk)*(-sixth) + &
109  & (ax+one)*(ax-one)*(ax-two)*q_north(ix ,kk)*half + &
110  & (ax+one)* ax *(ax-two)*q_north(ixp1,kk)*(-half) + &
111  & (ax+one)* ax *(ax-one)*q_north(ixp2,kk)*(sixth)
112  else
113  qjp1 = ax *(ax-one)*(ax-two)*q(ixm1,jyp1,kk)*(-sixth) + &
114  & (ax+one)*(ax-one)*(ax-two)*q(ix ,jyp1,kk)*half + &
115  & (ax+one)* ax *(ax-two)*q(ixp1,jyp1,kk)*(-half) + &
116  & (ax+one)* ax *(ax-one)*q(ixp2,jyp1,kk)*(sixth)
117  endif
118 
119  if (jyp2 < 1) then
120  qjp2 = ax *(ax-one)*(ax-two)*q_south(ixm1,kk)*(-sixth) + &
121  & (ax+one)*(ax-one)*(ax-two)*q_south(ix ,kk)*half + &
122  & (ax+one)* ax *(ax-two)*q_south(ixp1,kk)*(-half) + &
123  & (ax+one)* ax *(ax-one)*q_south(ixp2,kk)*(sixth)
124  else if (jyp2 > ny) then
125  qjp2 = ax *(ax-one)*(ax-two)*q_north(ixm1,kk)*(-sixth) + &
126  & (ax+one)*(ax-one)*(ax-two)*q_north(ix ,kk)*half + &
127  & (ax+one)* ax *(ax-two)*q_north(ixp1,kk)*(-half) + &
128  & (ax+one)* ax *(ax-one)*q_north(ixp2,kk)*(sixth)
129  else
130  qjp2 = ax *(ax-one)*(ax-two)*q(ixm1,jyp2,kk)*(-sixth) + &
131  & (ax+one)*(ax-one)*(ax-two)*q(ix ,jyp2,kk)*half + &
132  & (ax+one)* ax *(ax-two)*q(ixp1,jyp2,kk)*(-half) + &
133  & (ax+one)* ax *(ax-one)*q(ixp2,jyp2,kk)*(sixth)
134  endif
135 
136 !--- Lagrange interpolation in the meridional direction
137 
138  qnew(ii,jj,kk) = ay *(ay-one)*(ay-two)*(-sixth)*qjm1 + &
139  & (ay+one)*(ay-one)*(ay-two)*half *qj + &
140  & (ay+one)* ay *(ay-two)*(-half) *qjp1 + &
141  & (ay+one)* ay *(ay-one)*(sixth) *qjp2
142  enddo
143  enddo
144 enddo
145 
146 end subroutine advect_pv
subroutine advect_pv(qnew, q, q_north, q_south, u, v, nx, ny, deltax, deltay, dt)
Advect potential vorticity.
Definition: advect_pv.f90:18