18 #ifdef NO_QUAD_PRECISION 20 integer,
parameter:: f_p = selected_real_kind(15)
23 integer,
parameter:: f_p = selected_real_kind(20)
26 integer,
parameter :: xdir=1
27 integer,
parameter :: ydir=2
28 real,
parameter :: pi = 3.14159265358979323846d0
29 real,
parameter :: radius = 6371200.0
30 real,
parameter :: big_number=1.d8
31 real,
parameter :: tiny_number=1.d-8
37 integer :: n_del2_weak
43 real,
allocatable :: oro(:,:,:), mask(:,:,:)
44 real,
allocatable :: dx(:,:,:), dy(:,:,:)
45 real,
allocatable :: dxa(:,:,:), dya(:,:,:)
46 real,
allocatable :: dxc(:,:,:), dyc(:,:,:)
47 real,
allocatable :: area(:,:,:)
48 real,
allocatable :: sin_sg(:,:,:,:)
50 integer :: is,ie,js,je,isd,ied,jsd,jed
51 integer,
parameter :: ng = 3
52 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
66 call fv3_zs_filter(is,ie,js,je,isd,ied,jsd,jed,npx,npy,npx,ntiles,
grid_type, &
67 stretch_fac,
nested, area, dxa, dya, dx, dy, dxc, dyc, sin_sg, oro,
regional )
82 real,
intent(IN) :: q1(2), q2(2)
83 real,
intent(IN),
optional :: radius
85 real (f_p):: p1(2), p2(2)
94 beta = asin( sqrt( sin((p1(2)-p2(2))/2.)**2 + cos(p1(2))*cos(p2(2))* &
95 sin((p1(1)-p2(1))/2.)**2 ) ) * 2.
97 if (
present(radius) )
then 124 real p1(3), p2(3), p3(3)
126 real (f_p):: e1(3), e2(3), e3(3)
127 real (f_p):: px, py, pz
128 real (f_p):: qx, qy, qz
129 real (f_p):: angle, ddd
142 px = e1(2)*e2(3) - e1(3)*e2(2)
143 py = e1(3)*e2(1) - e1(1)*e2(3)
144 pz = e1(1)*e2(2) - e1(2)*e2(1)
146 qx = e1(2)*e3(3) - e1(3)*e3(2)
147 qy = e1(3)*e3(1) - e1(1)*e3(3)
148 qz = e1(1)*e3(2) - e1(2)*e3(1)
150 ddd = (px*px+py*py+pz*pz)*(qx*qx+qy*qy+qz*qz)
152 if ( ddd <= 0.0d0 )
then 155 ddd = (px*qx+py*qy+pz*qz) / sqrt(ddd)
156 if ( abs(ddd)>1.d0)
then 157 angle = 2.d0*atan(1.0)
160 angle = 4.d0*atan(1.0d0)
183 real function get_area(p1, p4, p2, p3, radius)
185 real,
intent(in),
dimension(2):: p1, p2, p3, p4
186 real,
intent(in),
optional:: radius
188 real e1(3), e2(3), e3(3)
189 real ang1, ang2, ang3, ang4
218 if (
present(radius) )
then 219 get_area = (ang1 + ang2 + ang3 + ang4 - 2.*pi) * radius**2
221 get_area = ang1 + ang2 + ang3 + ang4 - 2.*pi
237 integer,
intent(in) :: ng, npx, npy, isd, jsd
238 integer,
intent(in) :: fill
239 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: q
247 q(1-i ,1-j ,:) = q(1-j ,i ,:)
248 q(1-i ,npy-1+j,:) = q(1-j ,npy-1-i+1,:)
249 q(npx-1+i,1-j ,:) = q(npx-1+j,i ,:)
250 q(npx-1+i,npy-1+j,:) = q(npx-1+j,npy-1-i+1,:)
256 q(1-j ,1-i ,:) = q(i ,1-j ,:)
257 q(1-j ,npy-1+i,:) = q(i ,npy-1+j,:)
258 q(npx-1+j,1-i ,:) = q(npx-1-i+1,1-j ,:)
259 q(npx-1+j,npy-1+i,:) = q(npx-1-i+1,npy-1+j,:)
265 q(1-j ,1-i ,:) = q(i ,1-j ,:)
266 q(1-j ,npy-1+i,:) = q(i ,npy-1+j,:)
267 q(npx-1+j,1-i ,:) = q(npx-1-i+1,1-j ,:)
268 q(npx-1+j,npy-1+i,:) = q(npx-1-i+1,npy-1+j,:)
287 integer,
intent(in) :: ng, npx, npy, isd, jsd
288 integer,
intent(in) :: fill
289 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: q
297 q(1-i ,1-j ,:) = q(1-j ,i+1 ,:)
298 q(1-i ,npy+j,:) = q(1-j ,npy-i ,:)
299 q(npx+i,1-j ,:) = q(npx+j,i+1 ,:)
300 q(npx+i,npy+j,:) = q(npx+j,npy-i ,:)
306 q(1-j ,1-i ,:) = q(i+1 ,1-j ,:)
307 q(1-j ,npy+i,:) = q(i+1 ,npy+j ,:)
308 q(npx+j,1-i ,:) = q(npx-i,1-j ,:)
309 q(npx+j,npy+i,:) = q(npx-i,npy+j ,:)
315 q(1-i ,1-j ,:) = q(1-j ,i+1 ,:)
316 q(1-i ,npy+j,:) = q(1-j ,npy-i ,:)
317 q(npx+i,1-j ,:) = q(npx+j,i+1 ,:)
318 q(npx+i,npy+j,:) = q(npx+j,npy-i ,:)
338 integer,
intent(in) :: ng, npx, npy, isd, jsd
339 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: x
340 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: y
345 x(1-i ,1-j ,:) = y(1-j ,i ,:)
346 x(1-i ,npy-1+j,:) = y(1-j ,npy-1-i+1,:)
347 x(npx-1+i,1-j ,:) = y(npx-1+j,i ,:)
348 x(npx-1+i,npy-1+j,:) = y(npx-1+j,npy-1-i+1,:)
350 y(1-j ,1-i ,:) = x(i ,1-j ,:)
351 y(1-j ,npy-1+i,:) = x(i ,npy-1+j,:)
352 y(npx-1+j,1-i ,:) = x(npx-1-i+1,1-j ,:)
353 y(npx-1+j,npy-1+i,:) = x(npx-1-i+1,npy-1+j,:)
370 integer,
intent(in) :: ng, npx, npy, isd, jsd
371 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: x
372 real,
DIMENSION(isd:,jsd:,:),
intent(INOUT):: y
377 x(1-i ,1-j , :) = y(1-j ,i , :)
378 x(1-i ,npy+j , :) = y(1-j ,npy-i, :)
379 x(npx-1+i,1-j , :) = y(npx+j,i , :)
380 x(npx-1+i,npy+j , :) = y(npx+j,npy-i, :)
381 y(1-i ,1-j , :) = x(j ,1-i , :)
382 y(1-i ,npy-1+j, :) = x(j ,npy+i, :)
383 y(npx+i ,1-j , :) = x(npx-j,1-i , :)
384 y(npx+i ,npy-1+j, :) = x(npx-j,npy+i, :)
397 real,
intent(IN) :: p1(2), p2(2)
398 real,
intent(OUT) :: pm(2)
400 real :: e1(3), e2(3), e3(3)
416 real,
intent(IN) :: p1(3), p2(3)
417 real,
intent(OUT) :: e(3)
419 real (f_p):: q1(3), q2(3)
420 real (f_p):: dd, e1, e2, e3
432 dd = sqrt( e1**2 + e2**2 + e3**2 )
452 real,
intent(in) :: p(2)
453 real,
intent(out):: e(3)
457 real (f_p):: e1, e2, e3
463 e1 = cos(q(2)) * cos(q(1))
464 e2 = cos(q(2)) * sin(q(1))
484 integer,
intent(in):: np
485 real,
intent(inout):: q(3,np)
486 real,
intent(inout):: xs(np), ys(np)
488 real,
parameter:: esl=1.d-10
490 real (f_p):: dist, lat, lon
497 dist = sqrt(p(1)**2 + p(2)**2 + p(3)**2)
502 if ( (abs(p(1))+abs(p(2))) < esl )
then 503 lon =
real(0.,kind=f_p)
505 lon = atan2( p(2), p(1) )
508 if ( lon < 0.) lon =
real(2.,kind=f_p)*pi + lon
537 real,
intent(in):: p1(3), p2(3), p3(3)
539 real (f_p):: e1(3), e2(3), e3(3)
540 real (f_p):: px, py, pz
541 real (f_p):: qx, qy, qz
542 real (f_p):: angle, ddd
555 px = e1(2)*e2(3) - e1(3)*e2(2)
556 py = e1(3)*e2(1) - e1(1)*e2(3)
557 pz = e1(1)*e2(2) - e1(2)*e2(1)
560 qx = e1(2)*e3(3) - e1(3)*e3(2)
561 qy = e1(3)*e3(1) - e1(1)*e3(3)
562 qz = e1(1)*e3(2) - e1(2)*e3(1)
565 ddd = sqrt( (px**2+py**2+pz**2)*(qx**2+qy**2+qz**2) )
566 if ( ddd > 0.d0 )
then 567 angle = (px*qx+py*qy+pz*qz) / ddd
584 real,
intent(in ) :: q1(2), q2(2), q3(2), q4(2)
585 real,
intent(out) :: e2(2)
587 real p1(3), p2(3), p3(3), p4(3)
598 ec(k) = p1(k) + p2(k) + p3(k) + p4(k)
600 dd = sqrt( ec(1)**2 + ec(2)**2 + ec(3)**2 )
616 logical,
intent(in) :: regional
617 integer :: fsize=65536
618 integer :: status, ncid, id_dim, id_var, ncid2, t
619 integer :: ni, nj, i, j, tw, te, ip
620 real :: g1(2), g2(2), g3(2), g4(2), g5(2)
622 real :: p_lL(2), p_uL(2), p_lR(2), p_uR(2)
623 character(len=512) :: tile_file
624 real,
allocatable,
dimension(:,:) :: tmpvar, geolon_c_nest, geolat_c_nest
625 real,
allocatable,
dimension(:,:,:) :: geolon_c, geolat_c
626 real,
allocatable,
dimension(:,:,:) :: geolon_t, geolat_t, cos_sg, grid3
627 integer :: start(4), nread(4)
629 print*,
"Read the grid from file "//trim(
grid_file)
631 status=nf__open(trim(
grid_file),nf_nowrite,fsize,ncid)
634 status=nf_inq_dimid(ncid,
'ntiles', id_dim)
636 status=nf_inq_dimlen(ncid,id_dim,ntiles)
639 if( ntiles == 6)
then 640 print*,
" read_grid_file: This is a global grid." 641 elseif( ntiles >= 6 )
then 642 print*,
" read_grid_file: This is a nested grid." 643 print*,
" filter only the globe." 645 elseif( ntiles == 1 )
then 646 print*,
" read_grid_file: This is a standalone regional grid." 655 start(2) = t; nread(1) = 255
656 status = nf_inq_varid(ncid,
'gridfiles', id_var)
660 status = nf_get_vara_text(ncid, id_var, start, nread, tile_file )
663 status=nf__open(trim(tile_file),nf_nowrite,fsize,ncid2)
664 call handle_err(status,
'Open file '//trim(tile_file) )
666 status=nf_inq_dimid(ncid2,
'nx', id_dim)
668 status=nf_inq_dimlen(ncid2,id_dim,ni)
670 status=nf_inq_dimid(ncid2,
'ny', id_dim)
672 status=nf_inq_dimlen(ncid2,id_dim,nj)
676 if(mod(ni,2) .NE. 0 .or. mod(nj,2) .NE. 0) &
677 call handle_err(-1,
"read_grid_file: ni and nj must be even")
688 allocate(tmpvar(ni+1,nj+1))
689 allocate(geolon_c(isd:ied+1,jsd:jed+1,6))
690 allocate(geolat_c(isd:ied+1,jsd:jed+1,6))
691 else if ( t == 7 )
then 692 if(mod(ni,2) .NE. 0 .or. mod(nj,2) .NE. 0) &
693 call handle_err(-1,
"read_grid_file: ni and nj must be even")
697 npx_nest = nx_nest + 1
698 npy_nest = ny_nest + 1
699 is_nest = 1 ; ie_nest = nx
700 js_nest = 1 ; je_nest = ny
701 isd_nest=is_nest-ng; ied_nest=ie_nest+ng
702 jsd_nest=js_nest-ng; jed_nest=je_nest+ng
704 allocate(tmpvar(ni+1,nj+1))
705 allocate(geolon_c_nest(isd:ied+1,jsd:jed+1))
706 allocate(geolat_c_nest(isd:ied+1,jsd:jed+1))
709 if(ni .ne. nx*2 .OR. nj .ne. ny*2) &
710 call handle_err(-1,
"mismatch of grid size between tiles")
713 status=nf_inq_varid(ncid2,
'x', id_var)
715 status=nf_get_var_double(ncid2, id_var, tmpvar)
718 geolon_c_nest(1:npx,1:npy) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
720 geolon_c(1:npx,1:npy,t) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
723 status=nf_inq_varid(ncid2,
'y', id_var)
725 status=nf_get_var_double(ncid2, id_var, tmpvar)
728 geolat_c_nest(1:npx,1:npy) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
730 geolat_c(1:npx,1:npy,t) = tmpvar(1:ni+1:2,1:nj+1:2)*pi/180.
732 status = nf_close(ncid2)
733 call handle_err(status,
"close file "//trim(tile_file))
738 status = nf_close(ncid)
746 if( .not. regional )
then 757 allocate(geolon_t(isd:ied,jsd:jed,ntiles), geolat_t(isd:ied,jsd:jed,ntiles))
759 geolon_t(:,:,:) = -1.e25
760 geolat_t(:,:,:) = -1.e25
763 do j=js,je ;
do i=is,ie
764 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
765 g2(1) = geolon_c(i+1,j,t); g2(2) = geolat_c(i+1,j,t)
766 g3(1) = geolon_c(i,j+1,t); g3(2) = geolat_c(i,j+1,t)
767 g4(1) = geolon_c(i+1,j+1,t); g4(2) = geolat_c(i+1,j+1,t)
769 geolon_t(i,j,t) = g5(1)
770 geolat_t(i,j,t) = g5(2)
775 if( .not. regional )
then 783 allocate(dx(isd:ied,jsd:jed+1,ntiles))
784 allocate(dy(isd:ied+1,jsd:jed,ntiles))
786 do j = js, je+1 ;
do i = is, ie
787 g1(1) = geolon_c(i ,j,t)
788 g1(2) = geolat_c(i ,j,t)
789 g2(1) = geolon_c(i+1,j,t)
790 g2(2) = geolat_c(i+1,j,t)
797 g1(1) = geolon_c(i,j, t)
798 g1(2) = geolat_c(i,j, t)
799 g2(1) = geolon_c(i,j+1,t)
800 g2(2) = geolat_c(i,j+1,t)
806 if( .not. regional )
then 809 if(mod(t,2) ==0)
then 812 if(te > ntiles) te = te - ntiles
813 dy(is, js:je,t) = dy(ie+1,js:je,tw)
814 dy(ie+1, js:je, t) = dx(ie:is:-1,js, te)
817 if( tw <= 0) tw = tw + ntiles
819 dy(is, js:je, t) = dx(ie:is:-1, je+1, tw)
820 dy(ie+1, js:je,t) = dy(1,js:je,te)
831 allocate(dxa(isd:ied,jsd:jed,ntiles))
832 allocate(dya(isd:ied,jsd:jed,ntiles))
834 do j=js,je ;
do i=is,ie
835 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
836 g2(1) = geolon_c(i,j+1,t); g2(2) = geolat_c(i,j+1,t)
838 g1(1) = geolon_c(i+1,j,t); g1(2) = geolat_c(i+1,j,t)
839 g2(1) = geolon_c(i+1,j+1,t); g2(2) = geolat_c(i+1,j+1,t)
842 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
843 g2(1) = geolon_c(i+1,j,t); g2(2) = geolat_c(i+1,j,t)
845 g1(1) = geolon_c(i,j+1,t); g1(2) = geolat_c(i,j+1,t)
846 g2(1) = geolon_c(i+1,j+1,t); g2(2) = geolat_c(i+1,j+1,t)
860 allocate(dxc(isd:ied+1,jsd:jed,ntiles))
861 allocate(dyc(isd:ied,jsd:jed+1,ntiles))
865 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
866 g2(1) = geolon_c(i-1,j,t); g2(2) = geolat_c(i-1,j,t)
869 dxc(isd,j,t) = dxc(isd+1,j,t)
870 dxc(ied+1,j,t) = dxc(ied,j,t)
875 g1(1) = geolon_c(i,j,t); g1(2) = geolat_c(i,j,t)
876 g2(1) = geolon_c(i,j-1,t); g2(2) = geolat_c(i,j-1,t)
881 dyc(i,jsd,t) = dyc(i,jsd+1,t)
882 dyc(i,jed+1,t) = dyc(i,jed,t)
887 allocate(area(isd:ied,jsd:jed,ntiles))
891 p_ll(1) = geolon_c(i ,j ,t) ; p_ll(2) = geolat_c(i ,j ,t)
892 p_ul(1) = geolon_c(i ,j+1,t) ; p_ul(2) = geolat_c(i ,j+1,t)
893 p_lr(1) = geolon_c(i+1,j ,t) ; p_lr(2) = geolat_c(i+1,j ,t)
894 p_ur(1) = geolon_c(i+1,j+1,t) ; p_ur(2) = geolat_c(i+1,j+1,t)
897 area(i,j,t) =
get_area(p_ll, p_ul, p_lr, p_ur, radius)
906 da_min = minval(area(is:ie,js:je,:))
909 allocate(sin_sg(4,isd:ied,jsd:jed,ntiles))
910 allocate(cos_sg(4,isd:ied,jsd:jed))
911 allocate(grid3(3, npx, npy))
912 cos_sg(:,:,:) = big_number
913 sin_sg(:,:,:,:) = tiny_number
923 g1(1) = geolon_c(i,j,t)
924 g1(2) = geolat_c(i,j,t)
930 g1(1) = geolon_t(i,j,t); g1(2) = geolat_t(i,j,t)
933 cos_sg(1,i,j) =
cos_angle( p1, p3, grid3(1,i,j+1) )
935 cos_sg(2,i,j) =
cos_angle( p1, grid3(1,i+1,j), p3 )
937 cos_sg(3,i,j) =
cos_angle( p1, p3, grid3(1,i+1,j) )
939 cos_sg(4,i,j) =
cos_angle( p1, grid3(1,i,j+1), p3 )
946 sin_sg(ip,i,j,t) = min(1.0, sqrt( max(0., 1.-cos_sg(ip,i,j)**2) ) )
954 call fill_cubic_grid_halo(sin_sg(ip,:,:,:), sin_sg(ip,:,:,:), ng, 0, 0, 1, 1)
958 deallocate(cos_sg, grid3, geolon_c, geolat_c, geolon_t, geolat_t)
969 logical,
intent(in) :: regional
970 integer :: fsize=65536
971 integer :: status, ncid, id_var, ndim, dimsiz, nt
972 character(len=256) :: tile_file
973 character(len=32) :: text
974 integer :: len, t, dims(2)
975 real :: tmp(is:ie,js:je)
977 allocate(oro(isd:ied,jsd:jed,ntiles))
978 allocate(mask(isd:ied,jsd:jed,ntiles))
983 len = len_trim(topo_file)
984 if( index(topo_file,
'.nc', back=.true.) == len-2)
then 985 call handle_err(-1,
"remove .nc from namelist topo_file="//trim(topo_file) )
997 write(text,
'(i1.1)' ) t
998 tile_file = trim(topo_file)//
'.tile'//trim(text)//
'.nc' 999 status=nf__open(trim(tile_file),nf_nowrite,fsize,ncid)
1000 call handle_err(status,
'Open file '//trim(tile_file) )
1002 status=nf_inq_varid(ncid, topo_field, id_var)
1003 call handle_err(status,
'inquire varid of '//trim(topo_field)//
' from file '//trim(tile_file) )
1005 status = nf_inq_varndims(ncid, id_var, ndim)
1006 call handle_err(status,
'inquire ndims of '//trim(topo_field)//
' from file '//trim(tile_file) )
1008 if(ndim .NE. 2)
call handle_err(-1,
'ndims of '//trim(topo_field)//
' from file '// &
1009 trim(tile_file)//
' should be 2')
1012 status = nf_inq_vardimid(ncid, id_var,dims);
1013 call handle_err(status,
'inquire dimid of '//trim(topo_field)//
' from file '//trim(tile_file) )
1015 status = nf_inq_dimlen(ncid, dims(1), dimsiz)
1016 call handle_err(status,
'inquire first dimension length of '//trim(topo_field)//
' from file '//trim(tile_file) )
1017 if(dimsiz .NE. nx)
call handle_err(-1,
"mismatch of lon dimension size between "// &
1018 trim(grid_file)//
' and '//trim(tile_file) )
1020 status = nf_inq_dimlen(ncid, dims(2), dimsiz)
1021 call handle_err(status,
'inquire second dimension length of '//trim(topo_field)//
' from file '//trim(tile_file) )
1023 if(dimsiz .NE. ny)
call handle_err(-1,
"mismatch of lat dimension size between "// &
1024 trim(grid_file)//
' and '//trim(tile_file) )
1026 status = nf_get_var_double(ncid, id_var, oro(is:ie,js:je,nt))
1027 call handle_err(status,
'get the value of '//trim(topo_field)//
' from file '//trim(tile_file) )
1029 status=nf_inq_varid(ncid, mask_field, id_var)
1030 call handle_err(status,
'inquire varid of '//trim(mask_field)//
' from file '//trim(tile_file) )
1032 status = nf_get_var_double(ncid, id_var, tmp)
1033 call handle_err(status,
'get the value of '//trim(mask_field)//
' from file '//trim(tile_file) )
1035 mask(is:ie,js:je,nt) = tmp
1037 status = nf_close(ncid)
1038 call handle_err(status,
"close file "//trim(tile_file))
1041 if( .not.regional )
then 1048 call fill_regional_halo(oro, ng)
1049 oro(:,:,:) = max(oro(:,:,:),0.)
1050 call fill_regional_halo(mask, ng)
1051 mask(:,:,:) = min(max(mask(:,:,:),0.),1.)
1068 integer,
intent(in) :: is,ie,js,je,ntiles
1069 real,
intent(in) :: q(is:ie,js:je,ntiles)
1070 logical,
intent(in) :: regional
1072 integer :: fsize=65536
1073 integer :: nt, t, status, ncid, id_var
1074 character(len=256) :: tile_file
1075 character(len=3) :: text
1086 write(text,
'(i1.1)' ) t
1087 tile_file = trim(topo_file)//
'.tile'//trim(text)//
'.nc' 1088 status=nf__open(trim(tile_file),nf_write,fsize,ncid)
1089 call handle_err(status,
'write_topo_file: Open file '//trim(tile_file) )
1091 status=nf_inq_varid(ncid, topo_field, id_var)
1092 call handle_err(status,
'write_topo_file:inquire varid of '//trim(topo_field)//
' from file '//trim(tile_file) )
1094 status = nf_put_var_double(ncid, id_var, q(:,:,nt))
1095 call handle_err(status,
'write_topo_file: put the value of '//trim(topo_field)//
' from file '//trim(tile_file) )
1097 status = nf_close(ncid)
1098 call handle_err(status,
"write_topo_file: close file "//trim(tile_file))
1116 integer,
intent(in) :: halo
1117 real,
dimension(1-halo:,1-halo:,:),
intent(inout) :: data, data2
1118 integer,
intent(in) :: ioff, joff, sign1, sign2
1119 integer :: lw, le, ls, ln
1122 ntiles =
size(
data,3)
1125 if(mod(tile,2) == 0)
then 1126 lw = tile - 1; le = tile + 2; ls = tile - 2; ln = tile + 1
1127 if(le > 6 ) le = le - 6
1128 if(ls < 1 ) ls = ls + 6
1129 if(ln > 6 ) ln = ln - 6
1130 data(1-halo:0, 1:ny+joff, tile) =
data(nx-halo+1:nx, 1:ny+joff, lw)
1132 data(nx+i+ioff, 1:ny+joff, tile) = sign1*data2(nx+joff:1:-1, i+ioff, le)
1135 data(1:nx+ioff, 1-i, tile) = sign2*data2(nx-i+1, ny+ioff:1:-1, ls)
1137 data(1:nx+ioff, ny+1+joff:ny+halo+joff, tile) =
data(1:nx+ioff, 1+joff:halo+joff, ln)
1139 lw = tile - 2; le = tile + 1; ls = tile - 1; ln = tile + 2
1140 if(lw < 1 ) lw = lw + 6
1141 if(ls < 1 ) ls = ls + 6
1142 if(ln > 6 ) ln = ln - 6
1144 data(1-i, 1:ny+joff, tile) = sign1*data2(nx+joff:1:-1, ny-i+1, lw)
1146 data(nx+1+ioff:nx+halo+ioff, 1:ny+joff, tile) =
data(1+ioff:halo+ioff, 1:ny+joff, le)
1147 data(1:nx+ioff, 1-halo:0, tile) =
data(1:nx+ioff, ny-halo+1:ny, ls)
1149 data(1:nx+ioff, ny+i+joff, tile) = sign2*data2(i+joff, ny+ioff:1:-1, ln)
1184 subroutine fv3_zs_filter (is, ie, js, je, isd, ied, jsd, jed, npx, npy, npx_global, ntiles, &
1185 grid_type, stretch_fac, nested, area, dxa, dya, dx, dy, dxc, dyc, &
1186 sin_sg, phis, regional )
1187 integer,
intent(in) :: is, ie, js, je, ntiles
1188 integer,
intent(in) :: isd, ied, jsd, jed, npx, npy, npx_global, grid_type
1189 real,
intent(in),
dimension(isd:ied,jsd:jed, ntiles)::area, dxa, dya
1190 real,
intent(in),
dimension(isd:ied, jsd:jed+1, ntiles):: dx, dyc
1191 real,
intent(in),
dimension(isd:ied+1,jsd:jed, ntiles):: dy, dxc
1193 real,
intent(IN):: sin_sg(4,isd:ied,jsd:jed,ntiles)
1194 real,
intent(IN):: stretch_fac
1195 logical,
intent(IN) :: nested, regional
1196 real,
intent(inout):: phis(isd:ied,jsd:jed,ntiles)
1198 integer mdim, n_del2, n_del4
1200 mdim = nint(
real(npx_global) * min(10., stretch_fac) )
1203 if ( npx_global<=97 )
then 1205 elseif ( npx_global<=193 )
then 1213 call two_delta_filter(is,ie,js,je,isd,ied,jsd,jed, npx, npy, ntiles, phis, area, &
1214 dx, dy, dxa, dya, dxc, dyc, sin_sg, cd2, zero_ocean, &
1215 .true.,0, grid_type, mask, nested, n_del2, regional)
1218 if ( mdim<=193 )
then 1220 elseif ( mdim<=1537 )
then 1225 call del4_cubed_sphere(is,ie,js,je,isd,ied,jsd,jed,npx, npy, ntiles, &
1226 phis, area, dx, dy, dxc, dyc, sin_sg, n_del4, zero_ocean, mask, nested, regional)
1229 call two_delta_filter(is,ie,js,je,isd,ied,jsd,jed,npx, npy, ntiles, &
1230 phis, area, dx, dy, dxa, dya, dxc, dyc, sin_sg, cd2, zero_ocean, &
1231 .true., 1, grid_type, mask, nested, n_del2_weak, regional)
1267 subroutine two_delta_filter(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles, &
1268 q, area, dx, dy, dxa, dya, dxc, dyc, sin_sg, cd, zero_ocean, &
1269 check_slope, filter_type, grid_type, mask, nested, ntmax, regional)
1270 integer,
intent(in) :: is, ie, js, je
1271 integer,
intent(in) :: isd, ied, jsd, jed
1272 integer,
intent(in) :: npx, npy, grid_type
1273 integer,
intent(in) :: ntmax, ntiles
1274 integer,
intent(in) :: filter_type
1275 real,
intent(in) :: cd
1277 real,
intent(in)::area(isd:ied, jsd:jed, ntiles)
1278 real,
intent(in):: dx(isd:ied, jsd:jed+1, ntiles)
1279 real,
intent(in):: dy(isd:ied+1,jsd:jed, ntiles)
1280 real,
intent(in):: dxa(isd:ied, jsd:jed, ntiles)
1281 real,
intent(in):: dya(isd:ied, jsd:jed, ntiles)
1282 real,
intent(in):: dxc(isd:ied+1,jsd:jed, ntiles)
1283 real,
intent(in):: dyc(isd:ied, jsd:jed+1, ntiles)
1284 real,
intent(in):: sin_sg(4,isd:ied,jsd:jed, ntiles)
1285 real,
intent(in):: mask(isd:ied, jsd:jed, ntiles)
1286 logical,
intent(in):: zero_ocean, check_slope
1287 logical,
intent(in):: nested, regional
1289 real,
intent(inout):: q(isd:ied, jsd:jed,ntiles)
1291 real,
parameter:: p1 = 7./12.
1292 real,
parameter:: p2 = -1./12.
1293 real,
parameter:: c1 = -2./14.
1294 real,
parameter:: c2 = 11./14.
1295 real,
parameter:: c3 = 5./14.
1297 real:: ddx(is:ie+1,js:je), ddy(is:ie,js:je+1)
1298 logical:: extm(is-1:ie+1)
1299 logical:: ext2(is:ie,js-1:je+1)
1300 real:: a1(is-1:ie+2)
1301 real:: a2(is:ie,js-1:je+2)
1302 real:: a3(is:ie,js:je,ntiles)
1303 real:: smax, m_slope, fac
1304 integer:: i,j, nt, t
1305 integer:: is1, ie2, js1, je2
1307 if ( .not. nested .and. grid_type<3 )
then 1308 is1 = max(3,is-1); ie2 = min(npx-2,ie+2)
1309 js1 = max(3,js-1); je2 = min(npy-2,je+2)
1311 is1 = is-1; ie2 = ie+2
1312 js1 = js-1; je2 = je+2
1315 if ( check_slope )
then 1323 if( .not.regional )
then 1328 if ( nt==1 .and. check_slope )
then 1332 ddx(i,j) = (q(i,j,t) - q(i-1,j,t))/dxc(i,j,t)
1333 ddx(i,j) = abs(ddx(i,j))
1338 ddy(i,j) = (q(i,j,t) - q(i,j-1,t))/dyc(i,j,t)
1339 ddy(i,j) = abs(ddy(i,j))
1344 a3(i,j,t) = max( ddx(i,j), ddx(i+1,j), ddy(i,j), ddy(i,j+1) )
1348 smax = maxval(a3(is:ie,js:je,:))
1349 write(*,*)
'Before filter: Max_slope=', smax
1354 if ( .not. nested .and. nt==1 )
then 1356 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)) &
1357 / ( area(1,1,t)+ area(0,1,t)+ area(1,0,t) )
1361 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)) &
1362 / ( area(ie,1,t)+ area(npx,1,t)+ area(ie,0,t))
1363 q(npx,1,t) = q(ie,1,t)
1364 q(ie, 0,t) = q(ie,1,t)
1366 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)) &
1367 / ( area(1,je,t)+ area(0,je,t)+ area(1,npy,t))
1368 q(0, je,t) = q(1,je,t)
1369 q(1,npy,t) = q(1,je,t)
1371 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)) &
1372 / ( area(ie,je,t)+ area(npx,je,t)+ area(ie,npy,t))
1373 q(npx,je,t) = q(ie,je,t)
1374 q(ie,npy,t) = q(ie,je,t)
1376 if( .not.regional )
then 1386 a1(i) = p1*(q(i-1,j,t)+q(i,j,t)) + p2*(q(i-2,j,t)+q(i+1,j,t))
1389 if ( (.not. (nested .or. regional)) .and. grid_type<3 )
then 1390 a1(0) = c1*q(-2,j,t) + c2*q(-1,j,t) + c3*q(0,j,t)
1391 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)) &
1392 + ((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)))
1393 a1(2) = c3*q(1,j,t) + c2*q(2,j,t) +c1*q(3,j,t)
1395 a1(npx-1) = c1*q(npx-3,j,t) + c2*q(npx-2,j,t) + c3*q(npx-1,j,t)
1396 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)) &
1397 /(dxa(npx-2,j,t)+dxa(npx-1,j,t)) &
1398 + ((2.*dxa(npx, j,t)+dxa(npx+1,j,t))*q(npx, j,t)-dxa(npx, j,t)*q(npx+1,j,t))/ &
1399 (dxa(npx, j,t)+dxa(npx+1,j,t)))
1400 a1(npx+1) = c3*q(npx,j,t) + c2*q(npx+1,j,t) + c1*q(npx+2,j,t)
1403 if ( regional .and. grid_type<3 )
then 1404 a1(0) = c1*q(-1,j,t) + c2*q(-1,j,t) + c3*q(0,j,t)
1405 a1(2) = c3*q(1,j,t) + c2*q(2,j,t) + c1*q(3,j,t)
1406 a1(1) = 0.5*(a1(0) + a1(2))
1408 a1(npx-1) = c1*q(npx-3,j,t) + c2*q(npx-2,j,t) + c3*q(npx-1,j,t)
1409 a1(npx+1) = c3*q(npx,j,t) + c2*q(npx+1,j,t) + c1*q(npx+2,j,t)
1410 a1(npx) = 0.5*(a1(npx-1)+a1(npx+1))
1413 if ( filter_type == 0 )
then 1415 if( abs(3.*(a1(i)+a1(i+1)-2.*q(i,j,t))) > abs(a1(i)-a1(i+1)) )
then 1423 if ( (a1(i)-q(i,j,t))*(a1(i+1)-q(i,j,t)) > 0. )
then 1432 ddx(i,j) = (q(i-1,j,t)-q(i,j,t))/dxc(i,j,t)
1433 if ( extm(i-1).and.extm(i) )
then 1434 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)
1435 elseif ( abs(ddx(i,j)) > m_slope )
then 1436 fac = min(1., max( 0.1, ( abs(ddx(i,j))-m_slope )/m_slope) )
1437 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)
1447 a2(i,j) = p1*(q(i,j-1,t)+q(i,j,t)) + p2*(q(i,j-2,t)+q(i,j+1,t))
1450 if ( (.not. (nested .or. regional)) .and. grid_type<3 )
then 1452 a2(i,0) = c1*q(i,-2,t) + c2*q(i,-1,t) + c3*q(i,0,t)
1453 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)) &
1454 + ((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)))
1455 a2(i,2) = c3*q(i,1,t) + c2*q(i,2,t) + c1*q(i,3,t)
1459 a2(i,npy-1) = c1*q(i,npy-3,t) + c2*q(i,npy-2,t) + c3*q(i,npy-1,t)
1460 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))/ &
1461 (dya(i,npy-2,t)+dya(i,npy-1,t)) &
1462 + ((2.*dya(i,npy,t)+dya(i,npy+1,t))*q(i,npy,t)-dya(i,npy,t)*q(i,npy+1,t))/&
1463 (dya(i,npy,t)+dya(i,npy+1,t)))
1464 a2(i,npy+1) = c3*q(i,npy,t) + c2*q(i,npy+1,t) + c1*q(i,npy+2,t)
1468 if ( regional .and. grid_type<3 )
then 1470 a2(i,0) = c1*q(i,-2,t) + c2*q(i,-1,t) + c3*q(i,0,t)
1471 a2(i,2) = c3*q(i,1,t) + c2*q(i,2,t) + c1*q(i,3,t)
1472 a2(i,1) = 0.5*(a2(i,0) + a2(i,2))
1476 a2(i,npy-1) = c1*q(i,npy-3,t) + c2*q(i,npy-2,t) + c3*q(i,npy-1,t)
1477 a2(i,npy+1) = c3*q(i,npy,t) + c2*q(i,npy+1,t) + c1*q(i,npy+2,t)
1478 a2(i,npy) = 0.5*(a2(i,npy-1)+a2(i,npy+1))
1482 if ( filter_type == 0 )
then 1485 if( abs(3.*(a2(i,j)+a2(i,j+1)-2.*q(i,j,t))) > abs(a2(i,j)-a2(i,j+1)) )
then 1495 if ( (a2(i,j)-q(i,j,t))*(a2(i,j+1)-q(i,j,t)) > 0. )
then 1506 ddy(i,j) = (q(i,j-1,t)-q(i,j,t))/dyc(i,j,t)
1507 if ( ext2(i,j-1) .and. ext2(i,j) )
then 1508 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)
1509 elseif ( abs(ddy(i,j))>m_slope )
then 1510 fac = min(1., max(0.1,(abs(ddy(i,j))-m_slope)/m_slope))
1511 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)
1518 if ( zero_ocean )
then 1522 ddx(i,j) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * ddx(i,j)
1527 ddy(i,j) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * ddy(i,j)
1534 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))
1541 if ( check_slope )
then 1542 if( .not.regional )
then 1548 ddx(i,j) = (q(i,j,t) - q(i-1,j,t))/dxc(i,j,t)
1549 ddx(i,j) = abs(ddx(i,j))
1554 ddy(i,j) = (q(i,j,t) - q(i,j-1,t))/dyc(i,j,t)
1555 ddy(i,j) = abs(ddy(i,j))
1560 a3(i,j,t) = max( ddx(i,j), ddx(i+1,j), ddy(i,j), ddy(i,j+1) )
1564 smax = maxval(a3(is:ie,js:je,:))
1565 write(*,*)
'After filter: Max_slope=', smax
1597 subroutine del2_cubed_sphere(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles,&
1598 q, area, dx, dy, dxc, dyc, sin_sg, nmax, cd, zero_ocean, mask, nested, regional)
1599 integer,
intent(in) :: is, ie, js, je
1600 integer,
intent(in) :: isd, ied, jsd, jed
1601 integer,
intent(in):: npx, npy, ntiles
1602 integer,
intent(in):: nmax
1603 real,
intent(in):: cd
1604 logical,
intent(in):: zero_ocean
1606 real,
intent(in)::area(isd:ied, jsd:jed, ntiles)
1607 real,
intent(in):: dx(isd:ied, jsd:jed+1, ntiles)
1608 real,
intent(in):: dy(isd:ied+1,jsd:jed, ntiles)
1609 real,
intent(in):: dxc(isd:ied+1,jsd:jed, ntiles)
1610 real,
intent(in):: dyc(isd:ied, jsd:jed+1, ntiles)
1611 real,
intent(IN):: sin_sg(4,isd:ied,jsd:jed, ntiles)
1612 real,
intent(in):: mask(isd:ied, jsd:jed, ntiles)
1613 logical,
intent(IN) :: nested, regional
1616 real,
intent(inout):: q(is-ng:ie+ng, js-ng:je+ng, ntiles)
1618 real ddx(is:ie+1,js:je), ddy(is:ie,js:je+1)
1621 if( .not.regional )
then 1627 if ( .not. nested)
then 1628 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)) &
1629 / ( area(1,1,t)+ area(0,1,t)+ area(1,0,t) )
1633 if ( .not. nested)
then 1634 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)) &
1635 / ( area(ie,1,t)+ area(npx,1,t)+ area(ie,0,t))
1636 q(npx,1,t) = q(ie,1,t)
1637 q(ie, 0,t) = q(ie,1,t)
1639 if ( .not. nested )
then 1640 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)) &
1641 / ( area(ie,je,t)+ area(npx,je,t)+ area(ie,npy,t))
1642 q(npx,je,t) = q(ie,je,t)
1643 q(ie,npy,t) = q(ie,je,t)
1645 if ( .not. nested)
then 1646 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)) &
1647 / ( area(1,je,t)+ area(0,je,t)+ area(1,npy,t))
1648 q(0, je,t) = q(1,je,t)
1649 q(1,npy,t) = q(1,je,t)
1654 if( .not.regional )
then 1660 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)
1665 ddy(i,j) = dx(i,j,t)*(q(i,j-1,t)-q(i,j,t))/dyc(i,j,t) &
1666 *0.5*(sin_sg(4,i,j-1,t)+sin_sg(2,i,j,t))
1670 if ( zero_ocean )
then 1674 ddx(i,j) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * ddx(i,j)
1679 ddy(i,j) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * ddy(i,j)
1686 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))
1720 subroutine del4_cubed_sphere(is, ie, js, je, isd, ied, jsd, jed, npx, npy, ntiles, &
1721 q, area, dx, dy, dxc, dyc, sin_sg, nmax, zero_ocean, mask, nested, regional)
1722 integer,
intent(in) :: is, ie, js, je
1723 integer,
intent(in) :: isd, ied, jsd, jed
1724 integer,
intent(in) :: npx, npy, nmax, ntiles
1725 logical,
intent(in) :: zero_ocean
1726 real,
intent(in):: mask(isd:ied, jsd:jed, ntiles)
1727 real,
intent(in)::area(isd:ied, jsd:jed, ntiles)
1728 real,
intent(in):: dx(isd:ied, jsd:jed+1, ntiles)
1729 real,
intent(in):: dy(isd:ied+1,jsd:jed, ntiles)
1730 real,
intent(in):: dxc(isd:ied+1,jsd:jed, ntiles)
1731 real,
intent(in):: dyc(isd:ied, jsd:jed+1, ntiles)
1732 real,
intent(IN):: sin_sg(4,isd:ied,jsd:jed, ntiles)
1733 real,
intent(inout):: q(isd:ied, jsd:jed, ntiles)
1734 logical,
intent(IN) :: nested, regional
1737 real :: diff(is-1:ie+1,js-1:je+1, ntiles)
1739 real :: fx1(is:ie+1,js:je), fy1(is:ie,js:je+1)
1740 real :: fx2(is:ie+1,js:je,ntiles), fy2(is:ie,js:je+1,ntiles)
1741 real :: fx4(is:ie+1,js:je,ntiles), fy4(is:ie,js:je+1,ntiles)
1742 real,
dimension(isd:ied,jsd:jed,ntiles):: d2, win, wou
1743 real,
dimension(is:ie,js:je, ntiles) :: qlow, qmin, qmax
1744 real,
parameter:: esl = 1.e-20
1753 do j=js-1,je+1 ;
do i=is-1,ie+1
1754 diff(i,j,t) = cd4*area(i,j,t)
1757 do j=js,je ;
do i=is,ie
1758 qmax(i,j,t) = q(i,j,t) * peak_fac
1759 qmin(i,j,t) = q(i,j,t) / peak_fac
1764 if( .not.regional )
then 1769 if ( .not. nested .and. n==1 )
then 1771 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)) &
1772 / ( area(1,1,t)+ area(0,1,t)+ area(1,0,t) )
1777 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)) &
1778 / ( area(ie,1,t)+ area(npx,1,t)+ area(ie,0,t))
1779 q(npx,1,t) = q(ie,1,t)
1780 q(ie, 0,t) = q(ie,1,t)
1781 q(npx,0,t) = q(ie,1,t)
1783 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)) &
1784 / ( area(1,je,t)+ area(0,je,t)+ area(1,npy,t))
1785 q(0, je,t) = q(1,je,t)
1786 q(1,npy,t) = q(1,je,t)
1787 q(0,npy,t) = q(1,je,t)
1789 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)) &
1790 / ( area(ie,je,t)+ area(npx,je,t)+ area(ie,npy,t))
1791 q(npx, je,t) = q(ie,je,t)
1792 q(ie, npy,t) = q(ie,je,t)
1793 q(npx,npy,t) = q(ie,je,t)
1795 if( .not.regional )
then 1808 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) &
1809 *(sin_sg(1,i,j,t)+sin_sg(3,i-1,j,t))
1816 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) &
1817 *(sin_sg(2,i,j,t)+sin_sg(4,i,j-1,t))
1823 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)
1828 if ( zero_ocean )
then 1832 fx1(i,j) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * fx2(i,j,t)
1837 fy1(i,j) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * fy2(i,j,t)
1842 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)
1843 d2(i,j,t) = diff(i,j,t) * d2(i,j,t)
1849 qlow(i,j,t) = q(i,j,t) + d2(i,j,t)
1850 d2(i,j,t) = diff(i,j,t) * d2(i,j,t)
1855 if( .not.regional )
then 1866 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)
1873 fy4(i,j,t) = dx(i,j,t)*(d2(i,j,t)-d2(i,j-1,t))/dyc(i,j,t) &
1874 *0.5*(sin_sg(2,i,j,t)+sin_sg(4,i,j-1,t))-fy2(i,j,t)
1880 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), &
1881 q(i-1,j ,t), q(i,j ,t), q(i+1,j ,t), &
1882 q(i-1,j+1,t), q(i,j+1,t), q(i+1,j+1,t) )
1883 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), &
1884 q(i-1,j ,t), q(i,j ,t), q(i+1,j ,t), &
1885 q(i-1,j+1,t), q(i,j+1,t), q(i+1,j+1,t) )
1894 win(i,j,t) = max(0.,fx4(i, j,t)) - min(0.,fx4(i+1,j,t)) + &
1895 max(0.,fy4(i, j,t)) - min(0.,fy4(i,j+1,t)) + esl
1896 wou(i,j,t) = max(0.,fx4(i+1,j,t)) - min(0.,fx4(i, j,t)) + &
1897 max(0.,fy4(i,j+1,t)) - min(0.,fy4(i, j,t)) + esl
1898 win(i,j,t) = max(0., qmax(i,j,t) - qlow(i,j,t)) / win(i,j,t)*area(i,j,t)
1899 wou(i,j,t) = max(0., qlow(i,j,t) - qmin(i,j,t)) / wou(i,j,t)*area(i,j,t)
1903 if( .not.regional )
then 1910 if ( fx4(i,j,t) > 0. )
then 1911 fx4(i,j,t) = min(1., wou(i-1,j,t), win(i,j,t)) * fx4(i,j,t)
1913 fx4(i,j,t) = min(1., win(i-1,j,t), wou(i,j,t)) * fx4(i,j,t)
1919 if ( fy4(i,j,t) > 0. )
then 1920 fy4(i,j,t) = min(1., wou(i,j-1,t), win(i,j,t)) * fy4(i,j,t)
1922 fy4(i,j,t) = min(1., win(i,j-1,t), wou(i,j,t)) * fy4(i,j,t)
1928 if ( zero_ocean )
then 1932 fx4(i,j,t) = max(0., min(mask(i-1,j,t), mask(i,j,t))) * fx4(i,j,t)
1937 fy4(i,j,t) = max(0., min(mask(i,j-1,t), mask(i,j,t))) * fy4(i,j,t)
1945 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)
1958 subroutine check(status)
1960 integer,
intent(in) :: status
1962 if(status /= nf90_noerr)
then 1963 write(0,*)
' check netcdf status = ', status
1964 write(0,
'("error ", a)') trim(nf90_strerror(status))
1965 write(0,*)
"Stopped" 1968 end subroutine check 1978 integer,
parameter :: nres=8
1979 integer :: index1,index2,n
1983 real,
dimension(1:nres) :: cube_res=(/48.,96.,128.,192.,384.,768.,1152.,3072./)
1985 real,
dimension(1:nres) :: n_del2_weak_vals=(/4.,8.,8.,12.,12.,16.,20.,24./)
1986 real,
dimension(1:nres) :: cd4_vals =(/0.12,0.12,0.13,0.15,0.15,0.15,0.15,0.15/)
1987 real,
dimension(1:nres) :: max_slope_vals =(/0.12,0.12,0.12,0.12,0.12,0.12,0.16,0.30/)
1988 real,
dimension(1:nres) :: peak_fac_vals =(/1.1,1.1,1.1,1.05,1.0,1.0,1.0,1.0/)
1990 if(res<cube_res(1))
then 1994 elseif(res>cube_res(nres))
then 2000 if(res<=cube_res(n))
then 2003 factor = (res-cube_res(n-1))/(cube_res(n)-cube_res(n-1))
2009 n_del2_weak = nint(n_del2_weak_vals(index1)+factor*(n_del2_weak_vals(index2)-n_del2_weak_vals(index1)))
2010 cd4 = cd4_vals(index1)+factor*(cd4_vals(index2)-cd4_vals(index1))
2011 max_slope = max_slope_vals(index1)+factor*(max_slope_vals(index2)-max_slope_vals(index1))
2012 peak_fac = peak_fac_vals(index1)+factor*(peak_fac_vals(index2)-peak_fac_vals(index1))
2015 print*,
'- FILTER COEFFICIENTS FOR RESOLUTION ', res
2016 print*,
'- CD4: ', cd4
2017 print*,
'- N_DEL2_WEAK: ', n_del2_weak
2018 print*,
'- MAX_SLOPE: ', max_slope
2019 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)
???