19 #ifdef NO_QUAD_PRECISION 21 integer,
parameter:: f_p = selected_real_kind(15)
24 integer,
parameter:: f_p = selected_real_kind(20)
27 integer,
parameter :: xdir=1
28 integer,
parameter :: ydir=2
29 real,
parameter :: pi = 3.14159265358979323846d0
30 real,
parameter :: radius = 6371200.0
31 real,
parameter :: big_number=1.d8
32 real,
parameter :: tiny_number=1.d-8
38 integer :: n_del2_weak, tid, nthreads
44 real,
allocatable :: oro(:,:,:), mask(:,:,:)
45 real,
allocatable :: dx(:,:,:), dy(:,:,:)
46 real,
allocatable :: dxa(:,:,:), dya(:,:,:)
47 real,
allocatable :: dxc(:,:,:), dyc(:,:,:)
48 real,
allocatable :: area(:,:,:)
49 real,
allocatable :: sin_sg(:,:,:,:)
51 integer :: is,ie,js,je,isd,ied,jsd,jed
52 integer,
parameter :: ng = 3
53 integer :: nx, ny, npx, npy, nx_nest, ny_nest, npx_nest, npy_nest, is_nest, ie_nest, js_nest, je_nest, isd_nest, ied_nest, jsd_nest, jed_nest
56 tid = omp_get_thread_num()
58 nthreads = omp_get_num_threads()
60 print*,
'- BEGIN EXECUTION WITH NUMBER OF THREADS = ',nthreads
78 call fv3_zs_filter(is,ie,js,je,isd,ied,jsd,jed,npx,npy,npx,ntiles,
grid_type, &
79 stretch_fac,
nested, area, dxa, dya, dx, dy, dxc, dyc, sin_sg, oro,
regional )
85 print*,
'- NORMAL TERMINATION.' 97 real,
intent(IN) :: q1(2), q2(2)
98 real,
intent(IN),
optional :: radius
100 real (f_p):: p1(2), p2(2)
109 beta = asin( sqrt( sin((p1(2)-p2(2))/2.)**2 + cos(p1(2))*cos(p2(2))* &
110 sin((p1(1)-p2(1))/2.)**2 ) ) * 2.
112 if (
present(radius) )
then 139 real p1(3), p2(3), p3(3)
141 real (f_p):: e1(3), e2(3), e3(3)
142 real (f_p):: px, py, pz
143 real (f_p):: qx, qy, qz
144 real (f_p):: angle, ddd
157 px = e1(2)*e2(3) - e1(3)*e2(2)
158 py = e1(3)*e2(1) - e1(1)*e2(3)
159 pz = e1(1)*e2(2) - e1(2)*e2(1)
161 qx = e1(2)*e3(3) - e1(3)*e3(2)
162 qy = e1(3)*e3(1) - e1(1)*e3(3)
163 qz = e1(1)*e3(2) - e1(2)*e3(1)
165 ddd = (px*px+py*py+pz*pz)*(qx*qx+qy*qy+qz*qz)
167 if ( ddd <= 0.0d0 )
then 170 ddd = (px*qx+py*qy+pz*qz) / sqrt(ddd)
171 if ( abs(ddd)>1.d0)
then 172 angle = 2.d0*atan(1.0)
175 angle = 4.d0*atan(1.0d0)
198 real function get_area(p1, p4, p2, p3, radius)
200 real,
intent(in),
dimension(2):: p1, p2, p3, p4
201 real,
intent(in),
optional:: radius
203 real e1(3), e2(3), e3(3)
204 real ang1, ang2, ang3, ang4
233 if (
present(radius) )
then 234 get_area = (ang1 + ang2 + ang3 + ang4 - 2.*pi) * radius**2
236 get_area = ang1 + ang2 + ang3 + ang4 - 2.*pi
252 integer,
intent(in) :: ng, npx, npy, isd, jsd
253 integer,
intent(in) :: fill
254 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: q
262 q(1-i ,1-j ,:) = q(1-j ,i ,:)
263 q(1-i ,npy-1+j,:) = q(1-j ,npy-1-i+1,:)
264 q(npx-1+i,1-j ,:) = q(npx-1+j,i ,:)
265 q(npx-1+i,npy-1+j,:) = q(npx-1+j,npy-1-i+1,:)
271 q(1-j ,1-i ,:) = q(i ,1-j ,:)
272 q(1-j ,npy-1+i,:) = q(i ,npy-1+j,:)
273 q(npx-1+j,1-i ,:) = q(npx-1-i+1,1-j ,:)
274 q(npx-1+j,npy-1+i,:) = q(npx-1-i+1,npy-1+j,:)
280 q(1-j ,1-i ,:) = q(i ,1-j ,:)
281 q(1-j ,npy-1+i,:) = q(i ,npy-1+j,:)
282 q(npx-1+j,1-i ,:) = q(npx-1-i+1,1-j ,:)
283 q(npx-1+j,npy-1+i,:) = q(npx-1-i+1,npy-1+j,:)
302 integer,
intent(in) :: ng, npx, npy, isd, jsd
303 integer,
intent(in) :: fill
304 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: q
312 q(1-i ,1-j ,:) = q(1-j ,i+1 ,:)
313 q(1-i ,npy+j,:) = q(1-j ,npy-i ,:)
314 q(npx+i,1-j ,:) = q(npx+j,i+1 ,:)
315 q(npx+i,npy+j,:) = q(npx+j,npy-i ,:)
321 q(1-j ,1-i ,:) = q(i+1 ,1-j ,:)
322 q(1-j ,npy+i,:) = q(i+1 ,npy+j ,:)
323 q(npx+j,1-i ,:) = q(npx-i,1-j ,:)
324 q(npx+j,npy+i,:) = q(npx-i,npy+j ,:)
330 q(1-i ,1-j ,:) = q(1-j ,i+1 ,:)
331 q(1-i ,npy+j,:) = q(1-j ,npy-i ,:)
332 q(npx+i,1-j ,:) = q(npx+j,i+1 ,:)
333 q(npx+i,npy+j,:) = q(npx+j,npy-i ,:)
353 integer,
intent(in) :: ng, npx, npy, isd, jsd
354 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: x
355 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: y
360 x(1-i ,1-j ,:) = y(1-j ,i ,:)
361 x(1-i ,npy-1+j,:) = y(1-j ,npy-1-i+1,:)
362 x(npx-1+i,1-j ,:) = y(npx-1+j,i ,:)
363 x(npx-1+i,npy-1+j,:) = y(npx-1+j,npy-1-i+1,:)
365 y(1-j ,1-i ,:) = x(i ,1-j ,:)
366 y(1-j ,npy-1+i,:) = x(i ,npy-1+j,:)
367 y(npx-1+j,1-i ,:) = x(npx-1-i+1,1-j ,:)
368 y(npx-1+j,npy-1+i,:) = x(npx-1-i+1,npy-1+j,:)
385 integer,
intent(in) :: ng, npx, npy, isd, jsd
386 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: x
387 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: y
392 x(1-i ,1-j , :) = y(1-j ,i , :)
393 x(1-i ,npy+j , :) = y(1-j ,npy-i, :)
394 x(npx-1+i,1-j , :) = y(npx+j,i , :)
395 x(npx-1+i,npy+j , :) = y(npx+j,npy-i, :)
396 y(1-i ,1-j , :) = x(j ,1-i , :)
397 y(1-i ,npy-1+j, :) = x(j ,npy+i, :)
398 y(npx+i ,1-j , :) = x(npx-j,1-i , :)
399 y(npx+i ,npy-1+j, :) = x(npx-j,npy+i, :)
412 real,
intent(IN) :: p1(2), p2(2)
413 real,
intent(OUT) :: pm(2)
415 real :: e1(3), e2(3), e3(3)
431 real,
intent(IN) :: p1(3), p2(3)
432 real,
intent(OUT) :: e(3)
434 real (f_p):: q1(3), q2(3)
435 real (f_p):: dd, e1, e2, e3
447 dd = sqrt( e1**2 + e2**2 + e3**2 )
467 real,
intent(in) :: p(2)
468 real,
intent(out):: e(3)
472 real (f_p):: e1, e2, e3
478 e1 = cos(q(2)) * cos(q(1))
479 e2 = cos(q(2)) * sin(q(1))
499 integer,
intent(in):: np
500 real,
intent(inout):: q(3,np)
501 real,
intent(inout):: xs(np), ys(np)
503 real,
parameter:: esl=1.d-10
505 real (f_p):: dist, lat, lon
512 dist = sqrt(p(1)**2 + p(2)**2 + p(3)**2)
517 if ( (abs(p(1))+abs(p(2))) < esl )
then 518 lon =
real(0.,kind=f_p)
520 lon = atan2( p(2), p(1) )
523 if ( lon < 0.) lon =
real(2.,kind=f_p)*pi + lon
552 real,
intent(in):: p1(3), p2(3), p3(3)
554 real (f_p):: e1(3), e2(3), e3(3)
555 real (f_p):: px, py, pz
556 real (f_p):: qx, qy, qz
557 real (f_p):: angle, ddd
570 px = e1(2)*e2(3) - e1(3)*e2(2)
571 py = e1(3)*e2(1) - e1(1)*e2(3)
572 pz = e1(1)*e2(2) - e1(2)*e2(1)
575 qx = e1(2)*e3(3) - e1(3)*e3(2)
576 qy = e1(3)*e3(1) - e1(1)*e3(3)
577 qz = e1(1)*e3(2) - e1(2)*e3(1)
580 ddd = sqrt( (px**2+py**2+pz**2)*(qx**2+qy**2+qz**2) )
581 if ( ddd > 0.d0 )
then 582 angle = (px*qx+py*qy+pz*qz) / ddd
599 real,
intent(in ) :: q1(2), q2(2), q3(2), q4(2)
600 real,
intent(out) :: e2(2)
602 real p1(3), p2(3), p3(3), p4(3)
613 ec(k) = p1(k) + p2(k) + p3(k) + p4(k)
615 dd = sqrt( ec(1)**2 + ec(2)**2 + ec(3)**2 )
631 logical,
intent(in) :: regional
632 integer :: fsize=65536
633 integer :: status, ncid, id_dim, id_var, ncid2, t
634 integer :: ni, nj, i, j, tw, te, ip
635 real :: g1(2), g2(2), g3(2), g4(2), g5(2)
637 real :: p_lL(2), p_uL(2), p_lR(2), p_uR(2)
638 character(len=512) :: tile_file
639 real,
allocatable,
dimension(:,:) :: tmpvar, geolon_c_nest, geolat_c_nest
640 real,
allocatable,
dimension(:,:,:) :: geolon_c, geolat_c
641 real,
allocatable,
dimension(:,:,:) :: geolon_t, geolat_t, cos_sg, grid3
642 integer :: start(4), nread(4)
644 print*,
"Read the grid from file "//trim(
grid_file)
646 status=nf__open(trim(
grid_file),nf_nowrite,fsize,ncid)
649 status=nf_inq_dimid(ncid,
'ntiles', id_dim)
651 status=nf_inq_dimlen(ncid,id_dim,ntiles)
654 if( ntiles == 6)
then 655 print*,
" read_grid_file: This is a global grid." 656 elseif( ntiles >= 6 )
then 657 print*,
" read_grid_file: This is a nested grid." 658 print*,
" filter only the globe." 660 elseif( ntiles == 1 )
then 661 print*,
" read_grid_file: This is a standalone regional grid." 670 start(2) = t; nread(1) = 255
671 status = nf_inq_varid(ncid,
'gridfiles', id_var)
675 status = nf_get_vara_text(ncid, id_var, start, nread, tile_file )
678 status=nf__open(trim(tile_file),nf_nowrite,fsize,ncid2)
679 call handle_err(status,
'Open file '//trim(tile_file) )
681 status=nf_inq_dimid(ncid2,
'nx', id_dim)
683 status=nf_inq_dimlen(ncid2,id_dim,ni)
685 status=nf_inq_dimid(ncid2,
'ny', id_dim)
687 status=nf_inq_dimlen(ncid2,id_dim,nj)
691 if(mod(ni,2) .NE. 0 .or. mod(nj,2) .NE. 0) &
692 call handle_err(-1,
"read_grid_file: ni and nj must be even")
703 allocate(tmpvar(ni+1,nj+1))
704 allocate(geolon_c(isd:ied+1,jsd:jed+1,6))
705 allocate(geolat_c(isd:ied+1,jsd:jed+1,6))
706 else if ( t == 7 )
then 707 if(mod(ni,2) .NE. 0 .or. mod(nj,2) .NE. 0) &
708 call handle_err(-1,
"read_grid_file: ni and nj must be even")
712 npx_nest = nx_nest + 1
713 npy_nest = ny_nest + 1
714 is_nest = 1 ; ie_nest = nx
715 js_nest = 1 ; je_nest = ny
716 isd_nest=is_nest-ng; ied_nest=ie_nest+ng
717 jsd_nest=js_nest-ng; jed_nest=je_nest+ng
719 allocate(tmpvar(ni+1,nj+1))
720 allocate(geolon_c_nest(isd:ied+1,jsd:jed+1))
721 allocate(geolat_c_nest(isd:ied+1,jsd:jed+1))
724 if(ni .ne. nx*2 .OR. nj .ne. ny*2) &
725 call handle_err(-1,
"mismatch of grid size between tiles")
728 status=nf_inq_varid(ncid2,
'x', id_var)
730 status=nf_get_var_double(ncid2, id_var, tmpvar)
733 geolon_c_nest(1:npx,1:npy) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
735 geolon_c(1:npx,1:npy,t) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
738 status=nf_inq_varid(ncid2,
'y', id_var)
740 status=nf_get_var_double(ncid2, id_var, tmpvar)
743 geolat_c_nest(1:npx,1:npy) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
745 geolat_c(1:npx,1:npy,t) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
747 status = nf_close(ncid2)
748 call handle_err(status,
"close file "//trim(tile_file))
753 status = nf_close(ncid)
761 if( .not. regional )
then 772 allocate(geolon_t(isd:ied,jsd:jed,ntiles), geolat_t(isd:ied,jsd:jed,ntiles))
774 geolon_t(:,:,:) = -1.e25
775 geolat_t(:,:,:) = -1.e25
779 do j=js,je ;
do i=is,ie
780 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
781 g2(1) = geolon_c(i+1,j,t); g2(2) = geolat_c(i+1,j,t)
782 g3(1) = geolon_c(i,j+1,t); g3(2) = geolat_c(i,j+1,t)
783 g4(1) = geolon_c(i+1,j+1,t); g4(2) = geolat_c(i+1,j+1,t)
785 geolon_t(i,j,t) = g5(1)
786 geolat_t(i,j,t) = g5(2)
791 if( .not. regional )
then 799 allocate(dx(isd:ied,jsd:jed+1,ntiles))
800 allocate(dy(isd:ied+1,jsd:jed,ntiles))
803 do j = js, je+1 ;
do i = is, ie
804 g1(1) = geolon_c(i ,j,t)
805 g1(2) = geolat_c(i ,j,t)
806 g2(1) = geolon_c(i+1,j,t)
807 g2(2) = geolat_c(i+1,j,t)
816 g1(1) = geolon_c(i,j, t)
817 g1(2) = geolat_c(i,j, t)
818 g2(1) = geolon_c(i,j+1,t)
819 g2(2) = geolat_c(i,j+1,t)
826 if( .not. regional )
then 829 if(mod(t,2) ==0)
then 832 if(te > ntiles) te = te - ntiles
833 dy(is, js:je,t) = dy(ie+1,js:je,tw)
834 dy(ie+1, js:je, t) = dx(ie:is:-1,js, te)
837 if( tw <= 0) tw = tw + ntiles
839 dy(is, js:je, t) = dx(ie:is:-1, je+1, tw)
840 dy(ie+1, js:je,t) = dy(1,js:je,te)
851 allocate(dxa(isd:ied,jsd:jed,ntiles))
852 allocate(dya(isd:ied,jsd:jed,ntiles))
855 do j=js,je ;
do i=is,ie
856 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
857 g2(1) = geolon_c(i,j+1,t); g2(2) = geolat_c(i,j+1,t)
859 g1(1) = geolon_c(i+1,j,t); g1(2) = geolat_c(i+1,j,t)
860 g2(1) = geolon_c(i+1,j+1,t); g2(2) = geolat_c(i+1,j+1,t)
863 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
864 g2(1) = geolon_c(i+1,j,t); g2(2) = geolat_c(i+1,j,t)
866 g1(1) = geolon_c(i,j+1,t); g1(2) = geolat_c(i,j+1,t)
867 g2(1) = geolon_c(i+1,j+1,t); g2(2) = geolat_c(i+1,j+1,t)
882 allocate(dxc(isd:ied+1,jsd:jed,ntiles))
883 allocate(dyc(isd:ied,jsd:jed+1,ntiles))
889 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
890 g2(1) = geolon_c(i-1,j,t); g2(2) = geolat_c(i-1,j,t)
893 dxc(isd,j,t) = dxc(isd+1,j,t)
894 dxc(ied+1,j,t) = dxc(ied,j,t)
901 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
902 g2(1) = geolon_c(i,j-1,t); g2(2) = geolat_c(i,j-1,t)
910 dyc(i,jsd,t) = dyc(i,jsd+1,t)
911 dyc(i,jed+1,t) = dyc(i,jed,t)
917 allocate(area(isd:ied,jsd:jed,ntiles))
922 p_ll(1) = geolon_c(i ,j ,t) ; p_ll(2) = geolat_c(i ,j ,t)
923 p_ul(1) = geolon_c(i ,j+1,t) ; p_ul(2) = geolat_c(i ,j+1,t)
924 p_lr(1) = geolon_c(i+1,j ,t) ; p_lr(2) = geolat_c(i+1,j ,t)
925 p_ur(1) = geolon_c(i+1,j+1,t) ; p_ur(2) = geolat_c(i+1,j+1,t)
928 area(i,j,t) =
get_area(p_ll, p_ul, p_lr, p_ur, radius)
938 da_min = minval(area(is:ie,js:je,:))
941 allocate(sin_sg(4,isd:ied,jsd:jed,ntiles))
942 allocate(cos_sg(4,isd:ied,jsd:jed))
943 allocate(grid3(3, npx, npy))
944 cos_sg(:,:,:) = big_number
945 sin_sg(:,:,:,:) = tiny_number
957 g1(1) = geolon_c(i,j,t)
958 g1(2) = geolat_c(i,j,t)
967 g1(1) = geolon_t(i,j,t); g1(2) = geolat_t(i,j,t)
970 cos_sg(1,i,j) =
cos_angle( p1, p3, grid3(1,i,j+1) )
972 cos_sg(2,i,j) =
cos_angle( p1, grid3(1,i+1,j), p3 )
974 cos_sg(3,i,j) =
cos_angle( p1, p3, grid3(1,i+1,j) )
976 cos_sg(4,i,j) =
cos_angle( p1, grid3(1,i,j+1), p3 )
985 sin_sg(ip,i,j,t) = min(1.0, sqrt( max(0., 1.-cos_sg(ip,i,j)**2) ) )
994 call fill_cubic_grid_halo(sin_sg(ip,:,:,:), sin_sg(ip,:,:,:), ng, 0, 0, 1, 1)
998 deallocate(cos_sg, grid3, geolon_c, geolat_c, geolon_t, geolat_t)
1009 logical,
intent(in) :: regional
1010 integer :: fsize=65536
1011 integer :: status, ncid, id_var, ndim, dimsiz, nt
1012 character(len=256) :: tile_file
1013 character(len=32) :: text
1014 integer :: len, t, dims(2)
1015 real :: tmp(is:ie,js:je)
1017 allocate(oro(isd:ied,jsd:jed,ntiles))
1018 allocate(mask(isd:ied,jsd:jed,ntiles))
1023 len = len_trim(topo_file)
1024 if( index(topo_file,
'.nc', back=.true.) == len-2)
then 1025 call handle_err(-1,
"remove .nc from namelist topo_file="//trim(topo_file) )
1037 write(text,
'(i1.1)' ) t
1038 tile_file = trim(topo_file)//
'.tile'//trim(text)//
'.nc' 1039 status=nf__open(trim(tile_file),nf_nowrite,fsize,ncid)
1040 call handle_err(status,
'Open file '//trim(tile_file) )
1042 status=nf_inq_varid(ncid, topo_field, id_var)
1043 call handle_err(status,
'inquire varid of '//trim(topo_field)//
' from file '//trim(tile_file) )
1045 status = nf_inq_varndims(ncid, id_var, ndim)
1046 call handle_err(status,
'inquire ndims of '//trim(topo_field)//
' from file '//trim(tile_file) )
1048 if(ndim .NE. 2)
call handle_err(-1,
'ndims of '//trim(topo_field)//
' from file '// &
1049 trim(tile_file)//
' should be 2')
1052 status = nf_inq_vardimid(ncid, id_var,dims);
1053 call handle_err(status,
'inquire dimid of '//trim(topo_field)//
' from file '//trim(tile_file) )
1055 status = nf_inq_dimlen(ncid, dims(1), dimsiz)
1056 call handle_err(status,
'inquire first dimension length of '//trim(topo_field)//
' from file '//trim(tile_file) )
1057 if(dimsiz .NE. nx)
call handle_err(-1,
"mismatch of lon dimension size between "// &
1058 trim(grid_file)//
' and '//trim(tile_file) )
1060 status = nf_inq_dimlen(ncid, dims(2), dimsiz)
1061 call handle_err(status,
'inquire second dimension length of '//trim(topo_field)//
' from file '//trim(tile_file) )
1063 if(dimsiz .NE. ny)
call handle_err(-1,
"mismatch of lat dimension size between "// &
1064 trim(grid_file)//
' and '//trim(tile_file) )
1066 status = nf_get_var_double(ncid, id_var, oro(is:ie,js:je,nt))
1067 call handle_err(status,
'get the value of '//trim(topo_field)//
' from file '//trim(tile_file) )
1069 status=nf_inq_varid(ncid, mask_field, id_var)
1070 call handle_err(status,
'inquire varid of '//trim(mask_field)//
' from file '//trim(tile_file) )
1072 status = nf_get_var_double(ncid, id_var, tmp)
1073 call handle_err(status,
'get the value of '//trim(mask_field)//
' from file '//trim(tile_file) )
1075 mask(is:ie,js:je,nt) = tmp
1077 status = nf_close(ncid)
1078 call handle_err(status,
"close file "//trim(tile_file))
1081 if( .not.regional )
then 1088 call fill_regional_halo(oro, ng)
1089 oro(:,:,:) = max(oro(:,:,:),0.)
1090 call fill_regional_halo(mask, ng)
1091 mask(:,:,:) = min(max(mask(:,:,:),0.),1.)
1108 integer,
intent(in) :: is,ie,js,je,ntiles
1109 real,
intent(in) :: q(is:ie,js:je,ntiles)
1110 logical,
intent(in) :: regional
1112 integer :: fsize=65536
1113 integer :: nt, t, status, ncid, id_var
1114 character(len=256) :: tile_file
1115 character(len=3) :: text
1126 write(text,
'(i1.1)' ) t
1127 tile_file = trim(topo_file)//
'.tile'//trim(text)//
'.nc' 1128 status=nf__open(trim(tile_file),nf_write,fsize,ncid)
1129 call handle_err(status,
'write_topo_file: Open file '//trim(tile_file) )
1131 status=nf_inq_varid(ncid, topo_field, id_var)
1132 call handle_err(status,
'write_topo_file:inquire varid of '//trim(topo_field)//
' from file '//trim(tile_file) )
1134 status = nf_put_var_double(ncid, id_var, q(:,:,nt))
1135 call handle_err(status,
'write_topo_file: put the value of '//trim(topo_field)//
' from file '//trim(tile_file) )
1137 status = nf_close(ncid)
1138 call handle_err(status,
"write_topo_file: close file "//trim(tile_file))
1156 integer,
intent(in) :: halo
1157 real,
dimension(1-halo:,1-halo:,:),
intent(inout) :: data, data2
1158 integer,
intent(in) :: ioff, joff, sign1, sign2
1159 integer :: lw, le, ls, ln
1162 ntiles =
size(
data,3)
1165 if(mod(tile,2) == 0)
then 1166 lw = tile - 1; le = tile + 2; ls = tile - 2; ln = tile + 1
1167 if(le > 6 ) le = le - 6
1168 if(ls < 1 ) ls = ls + 6
1169 if(ln > 6 ) ln = ln - 6
1170 data(1-halo:0, 1:ny+joff, tile) =
data(nx-halo+1:nx, 1:ny+joff, lw)
1172 data(nx+i+ioff, 1:ny+joff, tile) = sign1*data2(nx+joff:1:-1, i+ioff, le)
1175 data(1:nx+ioff, 1-i, tile) = sign2*data2(nx-i+1, ny+ioff:1:-1, ls)
1177 data(1:nx+ioff, ny+1+joff:ny+halo+joff, tile) =
data(1:nx+ioff, 1+joff:halo+joff, ln)
1179 lw = tile - 2; le = tile + 1; ls = tile - 1; ln = tile + 2
1180 if(lw < 1 ) lw = lw + 6
1181 if(ls < 1 ) ls = ls + 6
1182 if(ln > 6 ) ln = ln - 6
1184 data(1-i, 1:ny+joff, tile) = sign1*data2(nx+joff:1:-1, ny-i+1, lw)
1186 data(nx+1+ioff:nx+halo+ioff, 1:ny+joff, tile) =
data(1+ioff:halo+ioff, 1:ny+joff, le)
1187 data(1:nx+ioff, 1-halo:0, tile) =
data(1:nx+ioff, ny-halo+1:ny, ls)
1189 data(1:nx+ioff, ny+i+joff, tile) = sign2*data2(i+joff, ny+ioff:1:-1, ln)
1224 subroutine fv3_zs_filter (is, ie, js, je, isd, ied, jsd, jed, npx, npy, npx_global, ntiles, &
1225 grid_type, stretch_fac, nested, area, dxa, dya, dx, dy, dxc, dyc, &
1226 sin_sg, phis, regional )
1227 integer,
intent(in) :: is, ie, js, je, ntiles
1228 integer,
intent(in) :: isd, ied, jsd, jed, npx, npy, npx_global, grid_type
1229 real,
intent(in),
dimension(isd:ied,jsd:jed, ntiles)::area, dxa, dya
1230 real,
intent(in),
dimension(isd:ied, jsd:jed+1, ntiles):: dx, dyc
1231 real,
intent(in),
dimension(isd:ied+1,jsd:jed, ntiles):: dy, dxc
1233 real,
intent(IN):: sin_sg(4,isd:ied,jsd:jed,ntiles)
1234 real,
intent(IN):: stretch_fac
1235 logical,
intent(IN) :: nested, regional
1236 real,
intent(inout):: phis(isd:ied,jsd:jed,ntiles)
1238 integer mdim, n_del2, n_del4
1240 mdim = nint(
real(npx_global) * min(10., stretch_fac) )
1243 if ( npx_global<=97 )
then 1245 elseif ( npx_global<=193 )
then 1253 call two_delta_filter(is,ie,js,je,isd,ied,jsd,jed, npx, npy, ntiles, phis, area, &
1254 dx, dy, dxa, dya, dxc, dyc, sin_sg, cd2, zero_ocean, &
1255 .true.,0, grid_type, mask, nested, n_del2, regional)
1258 if ( mdim<=193 )
then 1260 elseif ( mdim<=1537 )
then 1265 call del4_cubed_sphere(is,ie,js,je,isd,ied,jsd,jed,npx, npy, ntiles, &
1266 phis, area, dx, dy, dxc, dyc, sin_sg, n_del4, zero_ocean, mask, nested, regional)
1269 call two_delta_filter(is,ie,js,je,isd,ied,jsd,jed,npx, npy, ntiles, &
1270 phis, area, dx, dy, dxa, dya, dxc, dyc, sin_sg, cd2, zero_ocean, &
1271 .true., 1, grid_type, mask, nested, n_del2_weak, regional)
1307 subroutine two_delta_filter(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles, &
1308 q, area, dx, dy, dxa, dya, dxc, dyc, sin_sg, cd, zero_ocean, &
1309 check_slope, filter_type, grid_type, mask, nested, ntmax, regional)
1310 integer,
intent(in) :: is, ie, js, je
1311 integer,
intent(in) :: isd, ied, jsd, jed
1312 integer,
intent(in) :: npx, npy, grid_type
1313 integer,
intent(in) :: ntmax, ntiles
1314 integer,
intent(in) :: filter_type
1315 real,
intent(in) :: cd
1317 real,
intent(in)::area(isd:ied, jsd:jed, ntiles)
1318 real,
intent(in):: dx(isd:ied, jsd:jed+1, ntiles)
1319 real,
intent(in):: dy(isd:ied+1,jsd:jed, ntiles)
1320 real,
intent(in):: dxa(isd:ied, jsd:jed, ntiles)
1321 real,
intent(in):: dya(isd:ied, jsd:jed, ntiles)
1322 real,
intent(in):: dxc(isd:ied+1,jsd:jed, ntiles)
1323 real,
intent(in):: dyc(isd:ied, jsd:jed+1, ntiles)
1324 real,
intent(in):: sin_sg(4,isd:ied,jsd:jed, ntiles)
1325 real,
intent(in):: mask(isd:ied, jsd:jed, ntiles)
1326 logical,
intent(in):: zero_ocean, check_slope
1327 logical,
intent(in):: nested, regional
1329 real,
intent(inout):: q(isd:ied, jsd:jed,ntiles)
1331 real,
parameter:: p1 = 7./12.
1332 real,
parameter:: p2 = -1./12.
1333 real,
parameter:: c1 = -2./14.
1334 real,
parameter:: c2 = 11./14.
1335 real,
parameter:: c3 = 5./14.
1337 real:: ddx(is:ie+1,js:je), ddy(is:ie,js:je+1)
1338 logical:: extm(is-1:ie+1)
1339 logical:: ext2(is:ie,js-1:je+1)
1340 real:: a1(is-1:ie+2)
1341 real:: a2(is:ie,js-1:je+2)
1342 real:: a3(is:ie,js:je,ntiles)
1343 real:: smax, m_slope, fac
1344 integer:: i,j, nt, t
1345 integer:: is1, ie2, js1, je2
1347 if ( .not. nested .and. grid_type<3 )
then 1348 is1 = max(3,is-1); ie2 = min(npx-2,ie+2)
1349 js1 = max(3,js-1); je2 = min(npy-2,je+2)
1351 is1 = is-1; ie2 = ie+2
1352 js1 = js-1; je2 = je+2
1355 if ( check_slope )
then 1363 if( .not.regional )
then 1368 if ( nt==1 .and. check_slope )
then 1372 ddx(i,j) = (q(i,j,t) - q(i-1,j,t))/dxc(i,j,t)
1373 ddx(i,j) = abs(ddx(i,j))
1378 ddy(i,j) = (q(i,j,t) - q(i,j-1,t))/dyc(i,j,t)
1379 ddy(i,j) = abs(ddy(i,j))
1384 a3(i,j,t) = max( ddx(i,j), ddx(i+1,j), ddy(i,j), ddy(i,j+1) )
1388 smax = maxval(a3(is:ie,js:je,:))
1389 write(*,*)
'Before filter: Max_slope=', smax
1394 if ( .not. nested .and. nt==1 )
then 1396 q(1,1,t) = (q(1,1,t)*area(1,1,t)+q(0,1,t)*area(0,1,t)+q(1,0,t)*area(1,0,t)) &
1397 / ( area(1,1,t)+ area(0,1,t)+ area(1,0,t) )
1401 q(ie, 1,t) = (q(ie,1,t)*area(ie,1,t)+q(npx,1,t)*area(npx,1,t)+q(ie,0,t)*area(ie,0,t)) &
1402 / ( area(ie,1,t)+ area(npx,1,t)+ area(ie,0,t))
1403 q(npx,1,t) = q(ie,1,t)
1404 q(ie, 0,t) = q(ie,1,t)
1406 q(1, je,t) = (q(1,je,t)*area(1,je,t)+q(0,je,t)*area(0,je,t)+q(1,npy,t)*area(1,npy,t)) &
1407 / ( area(1,je,t)+ area(0,je,t)+ area(1,npy,t))
1408 q(0, je,t) = q(1,je,t)
1409 q(1,npy,t) = q(1,je,t)
1411 q(ie, je,t) = (q(ie,je,t)*area(ie,je,t)+q(npx,je,t)*area(npx,je,t)+q(ie,npy,t)*area(ie,npy,t)) &
1412 / ( area(ie,je,t)+ area(npx,je,t)+ area(ie,npy,t))
1413 q(npx,je,t) = q(ie,je,t)
1414 q(ie,npy,t) = q(ie,je,t)
1416 if( .not.regional )
then 1426 a1(i) = p1*(q(i-1,j,t)+q(i,j,t)) + p2*(q(i-2,j,t)+q(i+1,j,t))
1429 if ( (.not. (nested .or. regional)) .and. grid_type<3 )
then 1430 a1(0) = c1*q(-2,j,t) + c2*q(-1,j,t) + c3*q(0,j,t)
1431 a1(1) = 0.5*(((2.*dxa(0,j,t)+dxa(-1,j,t))*q(0,j,t)-dxa(0,j,t)*q(-1,j,t))/(dxa(-1,j,t)+dxa(0,j,t)) &
1432 + ((2.*dxa(1,j,t)+dxa( 2,j,t))*q(1,j,t)-dxa(1,j,t)*q( 2,j,t))/(dxa(1, j,t)+dxa(2,j,t)))
1433 a1(2) = c3*q(1,j,t) + c2*q(2,j,t) +c1*q(3,j,t)
1435 a1(npx-1) = c1*q(npx-3,j,t) + c2*q(npx-2,j,t) + c3*q(npx-1,j,t)
1436 a1(npx) = 0.5*(((2.*dxa(npx-1,j,t)+dxa(npx-2,j,t))*q(npx-1,j,t)-dxa(npx-1,j,t)*q(npx-2,j,t)) &
1437 /(dxa(npx-2,j,t)+dxa(npx-1,j,t)) &
1438 + ((2.*dxa(npx, j,t)+dxa(npx+1,j,t))*q(npx, j,t)-dxa(npx, j,t)*q(npx+1,j,t))/ &
1439 (dxa(npx, j,t)+dxa(npx+1,j,t)))
1440 a1(npx+1) = c3*q(npx,j,t) + c2*q(npx+1,j,t) + c1*q(npx+2,j,t)
1443 if ( regional .and. grid_type<3 )
then 1444 a1(0) = c1*q(-1,j,t) + c2*q(-1,j,t) + c3*q(0,j,t)
1445 a1(2) = c3*q(1,j,t) + c2*q(2,j,t) + c1*q(3,j,t)
1446 a1(1) = 0.5*(a1(0) + a1(2))
1448 a1(npx-1) = c1*q(npx-3,j,t) + c2*q(npx-2,j,t) + c3*q(npx-1,j,t)
1449 a1(npx+1) = c3*q(npx,j,t) + c2*q(npx+1,j,t) + c1*q(npx+2,j,t)
1450 a1(npx) = 0.5*(a1(npx-1)+a1(npx+1))
1453 if ( filter_type == 0 )
then 1455 if( abs(3.*(a1(i)+a1(i+1)-2.*q(i,j,t))) > abs(a1(i)-a1(i+1)) )
then 1463 if ( (a1(i)-q(i,j,t))*(a1(i+1)-q(i,j,t)) > 0. )
then 1472 ddx(i,j) = (q(i-1,j,t)-q(i,j,t))/dxc(i,j,t)
1473 if ( extm(i-1).and.extm(i) )
then 1474 ddx(i,j) = 0.5*(sin_sg(3,i-1,j,t)+sin_sg(1,i,j,t))*dy(i,j,t)*ddx(i,j)
1475 elseif ( abs(ddx(i,j)) > m_slope )
then 1476 fac = min(1., max( 0.1, ( abs(ddx(i,j))-m_slope )/m_slope) )
1477 ddx(i,j) = fac*0.5*(sin_sg(3,i-1,j,t)+sin_sg(1,i,j,t))*dy(i,j,t)*ddx(i,j)
1487 a2(i,j) = p1*(q(i,j-1,t)+q(i,j,t)) + p2*(q(i,j-2,t)+q(i,j+1,t))
1490 if ( (.not. (nested .or. regional)) .and. grid_type<3 )
then 1492 a2(i,0) = c1*q(i,-2,t) + c2*q(i,-1,t) + c3*q(i,0,t)
1493 a2(i,1) = 0.5*(((2.*dya(i,0,t)+dya(i,-1,t))*q(i,0,t)-dya(i,0,t)*q(i,-1,t))/(dya(i,-1,t)+dya(i,0,t)) &
1494 + ((2.*dya(i,1,t)+dya(i, 2,t))*q(i,1,t)-dya(i,1,t)*q(i, 2,t))/(dya(i, 1,t)+dya(i,2,t)))
1495 a2(i,2) = c3*q(i,1,t) + c2*q(i,2,t) + c1*q(i,3,t)
1499 a2(i,npy-1) = c1*q(i,npy-3,t) + c2*q(i,npy-2,t) + c3*q(i,npy-1,t)
1500 a2(i,npy) = 0.5*(((2.*dya(i,npy-1,t)+dya(i,npy-2,t))*q(i,npy-1,t)-dya(i,npy-1,t)*q(i,npy-2,t))/ &
1501 (dya(i,npy-2,t)+dya(i,npy-1,t)) &
1502 + ((2.*dya(i,npy,t)+dya(i,npy+1,t))*q(i,npy,t)-dya(i,npy,t)*q(i,npy+1,t))/&
1503 (dya(i,npy,t)+dya(i,npy+1,t)))
1504 a2(i,npy+1) = c3*q(i,npy,t) + c2*q(i,npy+1,t) + c1*q(i,npy+2,t)
1508 if ( regional .and. grid_type<3 )
then 1510 a2(i,0) = c1*q(i,-2,t) + c2*q(i,-1,t) + c3*q(i,0,t)
1511 a2(i,2) = c3*q(i,1,t) + c2*q(i,2,t) + c1*q(i,3,t)
1512 a2(i,1) = 0.5*(a2(i,0) + a2(i,2))
1516 a2(i,npy-1) = c1*q(i,npy-3,t) + c2*q(i,npy-2,t) + c3*q(i,npy-1,t)
1517 a2(i,npy+1) = c3*q(i,npy,t) + c2*q(i,npy+1,t) + c1*q(i,npy+2,t)
1518 a2(i,npy) = 0.5*(a2(i,npy-1)+a2(i,npy+1))
1522 if ( filter_type == 0 )
then 1525 if( abs(3.*(a2(i,j)+a2(i,j+1)-2.*q(i,j,t))) > abs(a2(i,j)-a2(i,j+1)) )
then 1535 if ( (a2(i,j)-q(i,j,t))*(a2(i,j+1)-q(i,j,t)) > 0. )
then 1546 ddy(i,j) = (q(i,j-1,t)-q(i,j,t))/dyc(i,j,t)
1547 if ( ext2(i,j-1) .and. ext2(i,j) )
then 1548 ddy(i,j) = 0.5*(sin_sg(4,i,j-1,t)+sin_sg(2,i,j,t))*dx(i,j,t)*ddy(i,j)
1549 elseif ( abs(ddy(i,j))>m_slope )
then 1550 fac = min(1., max(0.1,(abs(ddy(i,j))-m_slope)/m_slope))
1551 ddy(i,j) = fac*0.5*(sin_sg(4,i,j-1,t)+sin_sg(2,i,j,t))*dx(i,j,t)*ddy(i,j)
1558 if ( zero_ocean )
then 1562 ddx(i,j) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * ddx(i,j)
1567 ddy(i,j) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * ddy(i,j)
1574 q(i,j,t) = q(i,j,t) + cd/area(i,j,t)*(ddx(i,j)-ddx(i+1,j)+ddy(i,j)-ddy(i,j+1))
1581 if ( check_slope )
then 1582 if( .not.regional )
then 1588 ddx(i,j) = (q(i,j,t) - q(i-1,j,t))/dxc(i,j,t)
1589 ddx(i,j) = abs(ddx(i,j))
1594 ddy(i,j) = (q(i,j,t) - q(i,j-1,t))/dyc(i,j,t)
1595 ddy(i,j) = abs(ddy(i,j))
1600 a3(i,j,t) = max( ddx(i,j), ddx(i+1,j), ddy(i,j), ddy(i,j+1) )
1604 smax = maxval(a3(is:ie,js:je,:))
1605 write(*,*)
'After filter: Max_slope=', smax
1637 subroutine del2_cubed_sphere(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles,&
1638 q, area, dx, dy, dxc, dyc, sin_sg, nmax, cd, zero_ocean, mask, nested, regional)
1639 integer,
intent(in) :: is, ie, js, je
1640 integer,
intent(in) :: isd, ied, jsd, jed
1641 integer,
intent(in):: npx, npy, ntiles
1642 integer,
intent(in):: nmax
1643 real,
intent(in):: cd
1644 logical,
intent(in):: zero_ocean
1646 real,
intent(in)::area(isd:ied, jsd:jed, ntiles)
1647 real,
intent(in):: dx(isd:ied, jsd:jed+1, ntiles)
1648 real,
intent(in):: dy(isd:ied+1,jsd:jed, ntiles)
1649 real,
intent(in):: dxc(isd:ied+1,jsd:jed, ntiles)
1650 real,
intent(in):: dyc(isd:ied, jsd:jed+1, ntiles)
1651 real,
intent(IN):: sin_sg(4,isd:ied,jsd:jed, ntiles)
1652 real,
intent(in):: mask(isd:ied, jsd:jed, ntiles)
1653 logical,
intent(IN) :: nested, regional
1656 real,
intent(inout):: q(is-ng:ie+ng, js-ng:je+ng, ntiles)
1658 real ddx(is:ie+1,js:je), ddy(is:ie,js:je+1)
1661 if( .not.regional )
then 1667 if ( .not. nested)
then 1668 q(1,1,t) = (q(1,1,t)*area(1,1,t)+q(0,1,t)*area(0,1,t)+q(1,0,t)*area(1,0,t)) &
1669 / ( area(1,1,t)+ area(0,1,t)+ area(1,0,t) )
1673 if ( .not. nested)
then 1674 q(ie, 1,t) = (q(ie,1,t)*area(ie,1,t)+q(npx,1,t)*area(npx,1,t)+q(ie,0,t)*area(ie,0,t)) &
1675 / ( area(ie,1,t)+ area(npx,1,t)+ area(ie,0,t))
1676 q(npx,1,t) = q(ie,1,t)
1677 q(ie, 0,t) = q(ie,1,t)
1679 if ( .not. nested )
then 1680 q(ie, je,t) = (q(ie,je,t)*area(ie,je,t)+q(npx,je,t)*area(npx,je,t)+q(ie,npy,t)*area(ie,npy,t)) &
1681 / ( area(ie,je,t)+ area(npx,je,t)+ area(ie,npy,t))
1682 q(npx,je,t) = q(ie,je,t)
1683 q(ie,npy,t) = q(ie,je,t)
1685 if ( .not. nested)
then 1686 q(1, je,t) = (q(1,je,t)*area(1,je,t)+q(0,je,t)*area(0,je,t)+q(1,npy,t)*area(1,npy,t)) &
1687 / ( area(1,je,t)+ area(0,je,t)+ area(1,npy,t))
1688 q(0, je,t) = q(1,je,t)
1689 q(1,npy,t) = q(1,je,t)
1694 if( .not.regional )
then 1700 ddx(i,j) = 0.5*(sin_sg(3,i-1,j,t)+sin_sg(1,i,j,t))*dy(i,j,t)*(q(i-1,j,t)-q(i,j,t))/dxc(i,j,t)
1705 ddy(i,j) = dx(i,j,t)*(q(i,j-1,t)-q(i,j,t))/dyc(i,j,t) &
1706 *0.5*(sin_sg(4,i,j-1,t)+sin_sg(2,i,j,t))
1710 if ( zero_ocean )
then 1714 ddx(i,j) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * ddx(i,j)
1719 ddy(i,j) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * ddy(i,j)
1726 q(i,j,t) = q(i,j,t) + cd/area(i,j,t)*(ddx(i,j)-ddx(i+1,j)+ddy(i,j)-ddy(i,j+1))
1760 subroutine del4_cubed_sphere(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles, &
1761 q, area, dx, dy, dxc, dyc, sin_sg, nmax, zero_ocean, mask, nested, regional)
1762 integer,
intent(in) :: is, ie, js, je
1763 integer,
intent(in) :: isd, ied, jsd, jed
1764 integer,
intent(in) :: npx, npy, nmax, ntiles
1765 logical,
intent(in) :: zero_ocean
1766 real,
intent(in):: mask(isd:ied, jsd:jed, ntiles)
1767 real,
intent(in)::area(isd:ied, jsd:jed, ntiles)
1768 real,
intent(in):: dx(isd:ied, jsd:jed+1, ntiles)
1769 real,
intent(in):: dy(isd:ied+1,jsd:jed, ntiles)
1770 real,
intent(in):: dxc(isd:ied+1,jsd:jed, ntiles)
1771 real,
intent(in):: dyc(isd:ied, jsd:jed+1, ntiles)
1772 real,
intent(IN):: sin_sg(4,isd:ied,jsd:jed, ntiles)
1773 real,
intent(inout):: q(isd:ied, jsd:jed, ntiles)
1774 logical,
intent(IN) :: nested, regional
1777 real :: diff(is-1:ie+1,js-1:je+1, ntiles)
1779 real :: fx1(is:ie+1,js:je), fy1(is:ie,js:je+1)
1780 real :: fx2(is:ie+1,js:je,ntiles), fy2(is:ie,js:je+1,ntiles)
1781 real :: fx4(is:ie+1,js:je,ntiles), fy4(is:ie,js:je+1,ntiles)
1782 real,
dimension(isd:ied,jsd:jed,ntiles):: d2, win, wou
1783 real,
dimension(is:ie,js:je, ntiles) :: qlow, qmin, qmax
1784 real,
parameter:: esl = 1.e-20
1793 do j=js-1,je+1 ;
do i=is-1,ie+1
1794 diff(i,j,t) = cd4*area(i,j,t)
1797 do j=js,je ;
do i=is,ie
1798 qmax(i,j,t) = q(i,j,t) * peak_fac
1799 qmin(i,j,t) = q(i,j,t) / peak_fac
1804 if( .not.regional )
then 1809 if ( .not. nested .and. n==1 )
then 1811 q(1,1,t) = (q(1,1,t)*area(1,1,t)+q(0,1,t)*area(0,1,t)+q(1,0,t)*area(1,0,t)) &
1812 / ( area(1,1,t)+ area(0,1,t)+ area(1,0,t) )
1817 q(ie, 1,t) = (q(ie,1,t)*area(ie,1,t)+q(npx,1,t)*area(npx,1,t)+q(ie,0,t)*area(ie,0,t)) &
1818 / ( area(ie,1,t)+ area(npx,1,t)+ area(ie,0,t))
1819 q(npx,1,t) = q(ie,1,t)
1820 q(ie, 0,t) = q(ie,1,t)
1821 q(npx,0,t) = q(ie,1,t)
1823 q(1, je,t) = (q(1,je,t)*area(1,je,t)+q(0,je,t)*area(0,je,t)+q(1,npy,t)*area(1,npy,t)) &
1824 / ( area(1,je,t)+ area(0,je,t)+ area(1,npy,t))
1825 q(0, je,t) = q(1,je,t)
1826 q(1,npy,t) = q(1,je,t)
1827 q(0,npy,t) = q(1,je,t)
1829 q(ie, je,t) = (q(ie,je,t)*area(ie,je,t)+q(npx,je,t)*area(npx,je,t)+q(ie,npy,t)*area(ie,npy,t)) &
1830 / ( area(ie,je,t)+ area(npx,je,t)+ area(ie,npy,t))
1831 q(npx, je,t) = q(ie,je,t)
1832 q(ie, npy,t) = q(ie,je,t)
1833 q(npx,npy,t) = q(ie,je,t)
1835 if( .not.regional )
then 1848 fx2(i,j,t) = 0.25*(diff(i-1,j,t)+diff(i,j,t))*dy(i,j,t)*(q(i-1,j,t)-q(i,j,t))/dxc(i,j,t) &
1849 *(sin_sg(1,i,j,t)+sin_sg(3,i-1,j,t))
1856 fy2(i,j,t) = 0.25*(diff(i,j-1,t)+diff(i,j,t))*dx(i,j,t)*(q(i,j-1,t)-q(i,j,t))/dyc(i,j,t) &
1857 *(sin_sg(2,i,j,t)+sin_sg(4,i,j-1,t))
1863 d2(i,j,t) = (fx2(i,j,t)-fx2(i+1,j,t)+fy2(i,j,t)-fy2(i,j+1,t)) / area(i,j,t)
1868 if ( zero_ocean )
then 1872 fx1(i,j) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * fx2(i,j,t)
1877 fy1(i,j) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * fy2(i,j,t)
1882 qlow(i,j,t) = q(i,j,t) + (fx1(i,j)-fx1(i+1,j)+fy1(i,j)-fy1(i,j+1)) / area(i,j,t)
1883 d2(i,j,t) = diff(i,j,t) * d2(i,j,t)
1889 qlow(i,j,t) = q(i,j,t) + d2(i,j,t)
1890 d2(i,j,t) = diff(i,j,t) * d2(i,j,t)
1895 if( .not.regional )
then 1906 fx4(i,j,t) = 0.5*(sin_sg(3,i-1,j,t)+sin_sg(1,i,j,t))*dy(i,j,t)*(d2(i,j,t)-d2(i-1,j,t))/dxc(i,j,t)-fx2(i,j,t)
1913 fy4(i,j,t) = dx(i,j,t)*(d2(i,j,t)-d2(i,j-1,t))/dyc(i,j,t) &
1914 *0.5*(sin_sg(2,i,j,t)+sin_sg(4,i,j-1,t))-fy2(i,j,t)
1920 qmin(i,j,t) = min(qmin(i,j,t), q(i-1,j-1,t), q(i,j-1,t), q(i+1,j-1,t), &
1921 q(i-1,j ,t), q(i,j ,t), q(i+1,j ,t), &
1922 q(i-1,j+1,t), q(i,j+1,t), q(i+1,j+1,t) )
1923 qmax(i,j,t) = max(qmax(i,j,t), q(i-1,j-1,t), q(i,j-1,t), q(i+1,j-1,t), &
1924 q(i-1,j ,t), q(i,j ,t), q(i+1,j ,t), &
1925 q(i-1,j+1,t), q(i,j+1,t), q(i+1,j+1,t) )
1934 win(i,j,t) = max(0.,fx4(i, j,t)) - min(0.,fx4(i+1,j,t)) + &
1935 max(0.,fy4(i, j,t)) - min(0.,fy4(i,j+1,t)) + esl
1936 wou(i,j,t) = max(0.,fx4(i+1,j,t)) - min(0.,fx4(i, j,t)) + &
1937 max(0.,fy4(i,j+1,t)) - min(0.,fy4(i, j,t)) + esl
1938 win(i,j,t) = max(0., qmax(i,j,t) - qlow(i,j,t)) / win(i,j,t)*area(i,j,t)
1939 wou(i,j,t) = max(0., qlow(i,j,t) - qmin(i,j,t)) / wou(i,j,t)*area(i,j,t)
1943 if( .not.regional )
then 1950 if ( fx4(i,j,t) > 0. )
then 1951 fx4(i,j,t) = min(1., wou(i-1,j,t), win(i,j,t)) * fx4(i,j,t)
1953 fx4(i,j,t) = min(1., win(i-1,j,t), wou(i,j,t)) * fx4(i,j,t)
1959 if ( fy4(i,j,t) > 0. )
then 1960 fy4(i,j,t) = min(1., wou(i,j-1,t), win(i,j,t)) * fy4(i,j,t)
1962 fy4(i,j,t) = min(1., win(i,j-1,t), wou(i,j,t)) * fy4(i,j,t)
1968 if ( zero_ocean )
then 1972 fx4(i,j,t) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * fx4(i,j,t)
1977 fy4(i,j,t) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * fy4(i,j,t)
1985 q(i,j,t) = qlow(i,j,t) + (fx4(i,j,t)-fx4(i+1,j,t)+fy4(i,j,t)-fy4(i,j+1,t))/area(i,j,t)
1998 subroutine check(status)
2000 integer,
intent(in) :: status
2002 if(status /= nf90_noerr)
then 2003 write(0,*)
' check netcdf status = ', status
2004 write(0,
'("error ", a)') trim(nf90_strerror(status))
2005 write(0,*)
"Stopped" 2008 end subroutine check 2018 integer,
parameter :: nres=8
2019 integer :: index1,index2,n
2023 real,
dimension(1:nres) :: cube_res=(/48.,96.,128.,192.,384.,768.,1152.,3072./)
2025 real,
dimension(1:nres) :: n_del2_weak_vals=(/4.,8.,8.,12.,12.,16.,20.,24./)
2026 real,
dimension(1:nres) :: cd4_vals =(/0.12,0.12,0.13,0.15,0.15,0.15,0.15,0.15/)
2027 real,
dimension(1:nres) :: max_slope_vals =(/0.12,0.12,0.12,0.12,0.12,0.12,0.16,0.30/)
2028 real,
dimension(1:nres) :: peak_fac_vals =(/1.1,1.1,1.1,1.05,1.0,1.0,1.0,1.0/)
2030 if(res<cube_res(1))
then 2034 elseif(res>cube_res(nres))
then 2040 if(res<=cube_res(n))
then 2043 factor = (res-cube_res(n-1))/(cube_res(n)-cube_res(n-1))
2049 n_del2_weak = nint(n_del2_weak_vals(index1)+factor*(n_del2_weak_vals(index2)-n_del2_weak_vals(index1)))
2050 cd4 = cd4_vals(index1)+factor*(cd4_vals(index2)-cd4_vals(index1))
2051 max_slope = max_slope_vals(index1)+factor*(max_slope_vals(index2)-max_slope_vals(index1))
2052 peak_fac = peak_fac_vals(index1)+factor*(peak_fac_vals(index2)-peak_fac_vals(index1))
2055 print*,
'- FILTER COEFFICIENTS FOR RESOLUTION ', res
2056 print*,
'- CD4: ', cd4
2057 print*,
'- N_DEL2_WEAK: ', n_del2_weak
2058 print*,
'- MAX_SLOPE: ', max_slope
2059 print*,
'- PEAK_FAC: ', peak_fac
subroutine cart_to_latlon(np, q, xs, ys)
???
subroutine cell_center2(q1, q2, q3, q4, e2)
???
subroutine read_topo_file(regional)
???
subroutine fill_regional_halo(data, halo)
This routine extrapolate geolat_c and geolon_c halo points for the regional standalone grid...
subroutine mid_pt3_cart(p1, p2, e)
???
real function cos_angle(p1, p2, p3)
???
subroutine fill_agrid_scalar_corners(q, ng, npx, npy, isd, jsd, fill)
???
subroutine latlon2xyz(p, e)
???
real function great_circle_dist(q1, q2, radius)
???
subroutine del4_cubed_sphere(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles, q, area, dx, dy, dxc, dyc, sin_sg, nmax, zero_ocean, mask, nested, regional)
???
subroutine del2_cubed_sphere(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles, q, area, dx, dy, dxc, dyc, sin_sg, nmax, cd, zero_ocean, mask, nested, regional)
???
logical nested
If true, process a global grid with a nest.
subroutine handle_err(status, string)
Prints an error message to standard output, then halts program execution with a bad status...
real function spherical_angle(p1, p2, p3)
???
real function get_area(p1, p4, p2, p3, radius)
???
subroutine fill_bgrid_scalar_corners(q, ng, npx, npy, isd, jsd, fill)
???
subroutine fv3_zs_filter(is, ie, js, je, isd, ied, jsd, jed, npx, npy, npx_global, ntiles, grid_type, stretch_fac, nested, area, dxa, dya, dx, dy, dxc, dyc, sin_sg, phis, regional)
???
subroutine read_namelist
Read the program namelist file.
character(len=512) grid_file
Path/name of the grid mosaic file.
logical regional
If true, process a stand-alone regional grid.
integer grid_type
Grid type.
subroutine fill_agrid_xy_corners(x, y, ng, npx, npy, isd, jsd)
???
subroutine fill_cubic_grid_halo(data, data2, halo, ioff, joff, sign1, sign2)
This routine fill the halo points for the cubic grid.
real stretch_fac
Grid stretching factor.
Module that contains general utility routines.
subroutine fill_dgrid_xy_corners(x, y, ng, npx, npy, isd, jsd)
???
subroutine read_grid_file(regional)
???
subroutine write_topo_file(is, ie, js, je, ntiles, q, regional)
Replace the topo_field.
subroutine mid_pt_sphere(p1, p2, pm)
???
subroutine check(status)
Check results of netCDF call.
subroutine compute_filter_constants
Compute resolution-dependent values for the filtering.
program filter_topo
This program does ???
subroutine two_delta_filter(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles, q, area, dx, dy, dxa, dya, dxc, dyc, sin_sg, cd, zero_ocean, check_slope, filter_type, grid_type, mask, nested, ntmax, regional)
???