77 #include <fms_platform.h> 78 use constants_mod
, only: omega, pi=>pi_8, cnst_radius=>
radius 79 use mpp_mod
, only: fatal, mpp_error, warning
81 use mpp_domains_mod
, only: mpp_update_domains, dgrid_ne, mpp_global_sum
82 use mpp_domains_mod
, only: bitwise_exact_sum, domain2d, bitwise_efp_sum
83 use mpp_parameter_mod
, only: agrid_param=>agrid, cgrid_ne_param=>cgrid_ne
84 use mpp_parameter_mod
, only: corner, scalar_pair
90 use fv_mp_mod, only: mp_reduce_sum, mp_reduce_min, mp_reduce_max
91 use fv_mp_mod, only: fill_corners, xdir, ydir
97 #ifdef NO_QUAD_PRECISION 99 integer,
parameter::
f_p = selected_real_kind(15)
102 integer,
parameter::
f_p = selected_real_kind(20)
134 subroutine grid_utils_init(Atm, npx, npy, npz, non_ortho, grid_type, c2l_order)
137 logical,
intent(in):: non_ortho
138 integer,
intent(in):: npx, npy, npz
139 integer,
intent(in):: grid_type, c2l_order
149 real(kind=R_GRID) grid3(3,atm%bd%isd:atm%bd%ied+1,atm%bd%jsd:atm%bd%jed+1)
150 real(kind=R_GRID) p1(3), p2(3), p3(3), p4(3), pp(3), ex(3), ey(3), e1(3), e2(3)
151 real(kind=R_GRID) pp1(2), pp2(2), pp3(2)
152 real(kind=R_GRID) sin2, tmp1, tmp2
153 integer i, j, k, n, ip
155 integer :: is, ie, js, je
156 integer :: isd, ied, jsd, jed
159 real(kind=R_GRID),
pointer,
dimension(:,:,:) :: agrid, grid
160 real(kind=R_GRID),
pointer,
dimension(:,:) :: area, area_c
161 real(kind=R_GRID),
pointer,
dimension(:,:) :: sina, cosa, dx, dy, dxc, dyc, dxa, dya
162 real,
pointer,
dimension(:,:) :: del6_u, del6_v
163 real,
pointer,
dimension(:,:) :: divg_u, divg_v
164 real,
pointer,
dimension(:,:) :: cosa_u, cosa_v, cosa_s
165 real,
pointer,
dimension(:,:) :: sina_u, sina_v
166 real,
pointer,
dimension(:,:) :: rsin_u, rsin_v
167 real,
pointer,
dimension(:,:) :: rsina, rsin2
168 real,
pointer,
dimension(:,:,:) :: sin_sg, cos_sg
169 real(kind=R_GRID),
pointer,
dimension(:,:,:) :: ee1, ee2, ec1, ec2
170 real(kind=R_GRID),
pointer,
dimension(:,:,:,:) :: ew, es
171 real(kind=R_GRID),
pointer,
dimension(:,:,:) :: en1, en2
173 logical,
pointer :: sw_corner, se_corner, ne_corner, nw_corner
185 agrid => atm%gridstruct%agrid_64
186 grid => atm%gridstruct%grid_64
187 area => atm%gridstruct%area_64
188 area_c => atm%gridstruct%area_c_64
189 dx => atm%gridstruct%dx_64
190 dy => atm%gridstruct%dy_64
191 dxc => atm%gridstruct%dxc_64
192 dyc => atm%gridstruct%dyc_64
193 dxa => atm%gridstruct%dxa_64
194 dya => atm%gridstruct%dya_64
195 sina => atm%gridstruct%sina_64
196 cosa => atm%gridstruct%cosa_64
198 divg_u => atm%gridstruct%divg_u
199 divg_v => atm%gridstruct%divg_v
201 del6_u => atm%gridstruct%del6_u
202 del6_v => atm%gridstruct%del6_v
204 cosa_u => atm%gridstruct%cosa_u
205 cosa_v => atm%gridstruct%cosa_v
206 cosa_s => atm%gridstruct%cosa_s
207 sina_u => atm%gridstruct%sina_u
208 sina_v => atm%gridstruct%sina_v
209 rsin_u => atm%gridstruct%rsin_u
210 rsin_v => atm%gridstruct%rsin_v
211 rsina => atm%gridstruct%rsina
212 rsin2 => atm%gridstruct%rsin2
213 ee1 => atm%gridstruct%ee1
214 ee2 => atm%gridstruct%ee2
215 ec1 => atm%gridstruct%ec1
216 ec2 => atm%gridstruct%ec2
217 ew => atm%gridstruct%ew
218 es => atm%gridstruct%es
219 sin_sg => atm%gridstruct%sin_sg
220 cos_sg => atm%gridstruct%cos_sg
221 en1 => atm%gridstruct%en1
222 en2 => atm%gridstruct%en2
226 sw_corner => atm%gridstruct%sw_corner
227 se_corner => atm%gridstruct%se_corner
228 ne_corner => atm%gridstruct%ne_corner
229 nw_corner => atm%gridstruct%nw_corner
231 if ( (atm%flagstruct%do_schmidt .or. atm%flagstruct%do_cube_transform) .and. abs(atm%flagstruct%stretch_fac-1.) > 1.e-5 )
then 232 atm%gridstruct%stretched_grid = .true.
235 atm%gridstruct%stretched_grid = .false.
246 elseif ( .not. atm%flagstruct%hybrid_z )
then 248 if (.not. atm%flagstruct%external_eta)
then 249 call set_eta(npz, atm%ks, atm%ptop, atm%ak, atm%bk, atm%flagstruct%npz_type)
250 if ( is_master() )
then 251 write(*,*)
'Grid_init', npz, atm%ks, atm%ptop
252 tmp1 = atm%ak(atm%ks+1)
254 tmp1 = max(tmp1, (atm%ak(k)-atm%ak(k+1))/max(1.e-9, (atm%bk(k+1)-atm%bk(k))) )
256 write(*,*)
'Hybrid Sigma-P: minimum allowable surface pressure (hpa)=', tmp1/100.
257 if ( tmp1 > 420.e2 )
write(*,*)
'Warning: the chosen setting in set_eta can cause instability' 264 if (.not.
allocated(sst_ncep))
allocate (sst_ncep(i_sst,j_sst))
265 if (.not.
allocated(sst_anom))
allocate (sst_anom(i_sst,j_sst))
277 if (grid_type < 3 .and. .not. atm%gridstruct%bounded_domain)
then 278 if ( is==1 .and. js==1 ) sw_corner = .true.
279 if ( (ie+1)==npx .and. js==1 ) se_corner = .true.
280 if ( (ie+1)==npx .and. (je+1)==npy ) ne_corner = .true.
281 if ( is==1 .and. (je+1)==npy ) nw_corner = .true.
284 if ( sw_corner )
then 287 write(*,*)
'Corner interpolation coefficient=', tmp2/(tmp2-tmp1)
290 if (grid_type < 3)
then 292 if ( .not. atm%gridstruct%bounded_domain )
then 293 call fill_corners(grid(:,:,1), npx, npy, fill=xdir, bgrid=.true.)
294 call fill_corners(grid(:,:,2), npx, npy, fill=xdir, bgrid=.true.)
307 if (.not. atm%gridstruct%bounded_domain)
then 317 if ( ( (i<1 .and. j<1 ) .or. (i>npx .and. j<1 ) .or. &
318 (i>npx .and. j>(npy-1)) .or. (i<1 .and. j>(npy-1)) ) .and. .not. atm%gridstruct%bounded_domain)
then 321 call mid_pt_cart( grid(i,j,1:2), grid(i,j+1,1:2), pp)
322 if (i==1 .and. .not. atm%gridstruct%bounded_domain)
then 325 elseif(i==npx .and. .not. atm%gridstruct%bounded_domain)
then 336 call vect_cross(p1, grid3(1,i,j), grid3(1,i,j+1))
345 if ( ( (i<1 .and. j<1 ) .or. (i>(npx-1) .and. j<1 ) .or. &
346 (i>(npx-1) .and. j>npy) .or. (i<1 .and. j>npy) ) .and. .not. atm%gridstruct%bounded_domain)
then 349 call mid_pt_cart(grid(i,j,1:2), grid(i+1,j,1:2), pp)
350 if (j==1 .and. .not. atm%gridstruct%bounded_domain)
then 353 elseif (j==npy .and. .not. atm%gridstruct%bounded_domain)
then 364 call vect_cross(p3, grid3(1,i,j), grid3(1,i+1,j))
381 cos_sg(i,j,6) =
cos_angle( grid3(1,i,j), grid3(1,i+1,j), grid3(1,i,j+1) )
383 cos_sg(i,j,7) = -
cos_angle( grid3(1,i+1,j), grid3(1,i,j), grid3(1,i+1,j+1) )
385 cos_sg(i,j,8) =
cos_angle( grid3(1,i+1,j+1), grid3(1,i+1,j), grid3(1,i,j+1) )
387 cos_sg(i,j,9) = -
cos_angle( grid3(1,i,j+1), grid3(1,i,j), grid3(1,i+1,j+1) )
397 cos_sg(i,j,1) =
cos_angle( p1, p3, grid3(1,i,j+1) )
399 cos_sg(i,j,2) =
cos_angle( p1, grid3(1,i+1,j), p3 )
401 cos_sg(i,j,3) =
cos_angle( p1, p3, grid3(1,i+1,j) )
403 cos_sg(i,j,4) =
cos_angle( p1, grid3(1,i,j+1), p3 )
406 cos_sg(i,j,5) =
inner_prod( ec1(1:3,i,j), ec2(1:3,i,j) )
413 sin_sg(i,j,ip) = min(1.0, sqrt( max(0., 1.-cos_sg(i,j,ip)**2) ) )
422 if (.not. atm%gridstruct%bounded_domain)
then 423 if ( sw_corner )
then 425 sin_sg(0,i,3) = sin_sg(i,1,2)
426 sin_sg(i,0,4) = sin_sg(1,i,1)
429 if ( nw_corner )
then 431 sin_sg(0,i,3) = sin_sg(npy-i,npy-1,4)
434 sin_sg(i,npy,2) = sin_sg(1,npx+i,1)
437 if ( se_corner )
then 439 sin_sg(npx,j,1) = sin_sg(npx-j,1,2)
442 sin_sg(i,0,4) = sin_sg(npx-1,npx-i,3)
445 if ( ne_corner )
then 447 sin_sg(npx,i,1) = sin_sg(i,npy-1,4)
448 sin_sg(i,npy,2) = sin_sg(npx-1,i,3)
456 pp1(:) = grid(i ,j ,1:2)
457 pp2(:) = grid(i,j+1 ,1:2)
461 atm%gridstruct%l2c_v(i,j) = cos(pp3(2)) *
inner_prod(e2, ex)
466 pp1(:) = grid(i, j,1:2)
467 pp2(:) = grid(i+1,j,1:2)
471 atm%gridstruct%l2c_u(i,j) = cos(pp3(2)) *
inner_prod(e1, ex)
504 if ( non_ortho )
then 520 if (i==1 .and. .not. atm%gridstruct%bounded_domain)
then 521 call vect_cross(pp, grid3(1,i, j), grid3(1,i+1,j))
522 elseif(i==npx .and. .not. atm%gridstruct%bounded_domain)
then 523 call vect_cross(pp, grid3(1,i-1,j), grid3(1,i, j))
525 call vect_cross(pp, grid3(1,i-1,j), grid3(1,i+1,j))
527 call vect_cross(ee1(1:3,i,j), pp, grid3(1:3,i,j))
531 if (j==1 .and. .not. atm%gridstruct%bounded_domain)
then 532 call vect_cross(pp, grid3(1:3,i,j ), grid3(1:3,i,j+1))
533 elseif(j==npy .and. .not. atm%gridstruct%bounded_domain)
then 534 call vect_cross(pp, grid3(1:3,i,j-1), grid3(1:3,i,j ))
536 call vect_cross(pp, grid3(1:3,i,j-1), grid3(1:3,i,j+1))
538 call vect_cross(ee2(1:3,i,j), pp, grid3(1:3,i,j))
544 cosa(i,j) = sign(min(1., abs(tmp1)), tmp1)
545 sina(i,j) = sqrt(max(0.,1. -cosa(i,j)**2))
547 cosa(i,j) = 0.5*(cos_sg(i-1,j-1,8)+cos_sg(i,j,6))
548 sina(i,j) = 0.5*(sin_sg(i-1,j-1,8)+sin_sg(i,j,6))
560 cosa_u(i,j) = 0.5*(cos_sg(i-1,j,3)+cos_sg(i,j,1))
561 sina_u(i,j) = 0.5*(sin_sg(i-1,j,3)+sin_sg(i,j,1))
563 rsin_u(i,j) = 1. / max(
tiny_number, sina_u(i,j)**2)
568 cosa_v(i,j) = 0.5*(cos_sg(i,j-1,4)+cos_sg(i,j,2))
569 sina_v(i,j) = 0.5*(sin_sg(i,j-1,4)+sin_sg(i,j,2))
571 rsin_v(i,j) = 1. / max(
tiny_number, sina_v(i,j)**2)
577 cosa_s(i,j) = cos_sg(i,j,5)
579 rsin2(i,j) = 1. / max(
tiny_number, sin_sg(i,j,5)**2)
583 if (.not. atm%gridstruct%bounded_domain)
then 591 if ( i==npx .and. j==npy .and. .not. atm%gridstruct%bounded_domain)
then 592 else if ( ( i==1 .or. i==npx .or. j==1 .or. j==npy ) .and. .not. atm%gridstruct%bounded_domain )
then 603 if ( (i==1 .or. i==npx) .and. .not. atm%gridstruct%bounded_domain )
then 605 rsin_u(i,j) = 1. / sign(max(
tiny_number,abs(sina_u(i,j))), sina_u(i,j))
612 if ( (j==1 .or. j==npy) .and. .not. atm%gridstruct%bounded_domain )
then 614 rsin_v(i,j) = 1. / sign(max(
tiny_number,abs(sina_v(i,j))), sina_v(i,j))
623 if (.not. atm%gridstruct%bounded_domain)
then 633 if ( sw_corner )
then 635 sin_sg(0,i,3) = sin_sg(i,1,2)
636 sin_sg(i,0,4) = sin_sg(1,i,1)
637 cos_sg(0,i,3) = cos_sg(i,1,2)
638 cos_sg(i,0,4) = cos_sg(1,i,1)
647 if ( nw_corner )
then 649 sin_sg(0,i,3) = sin_sg(npy-i,npy-1,4)
650 cos_sg(0,i,3) = cos_sg(npy-i,npy-1,4)
655 sin_sg(i,npy,2) = sin_sg(1,npy-i,1)
656 cos_sg(i,npy,2) = cos_sg(1,npy-i,1)
662 if ( se_corner )
then 664 sin_sg(npx,j,1) = sin_sg(npx-j,1,2)
665 cos_sg(npx,j,1) = cos_sg(npx-j,1,2)
670 sin_sg(i,0,4) = sin_sg(npx-1,npx-i,3)
671 cos_sg(i,0,4) = cos_sg(npx-1,npx-i,3)
677 if ( ne_corner )
then 679 sin_sg(npx,npy+i,1) = sin_sg(npx+i,npy-1,4)
680 sin_sg(npx+i,npy,2) = sin_sg(npx-1,npy+i,3)
681 cos_sg(npx,npy+i,1) = cos_sg(npx+i,npy-1,4)
684 cos_sg(npx+i,npy,2) = cos_sg(npx-1,npy+i,3)
705 if ( grid_type < 3 )
then 712 if (.not. atm%gridstruct%bounded_domain)
then 716 call vect_cross(ew(1,i,j,1), grid3(1,i,j+1), grid3(1,i,j))
719 if ( (ie+1)==npx )
then 721 call vect_cross(ew(1,i,j,1), grid3(1,i,j+1), grid3(1,i,j))
729 call vect_cross(es(1,i,j,2), grid3(1,i,j),grid3(1,i+1,j))
733 if ( (je+1)==npy )
then 736 call vect_cross(es(1,i,j,2), grid3(1,i,j),grid3(1,i+1,j))
747 call vect_cross(en1(1:3,i,j), grid3(1,i,j), grid3(1,i+1,j))
753 call vect_cross(en2(1:3,i,j), grid3(1,i,j+1), grid3(1,i,j))
766 if ((j==1 .OR. j==npy) .and. .not. atm%gridstruct%bounded_domain)
then 768 divg_u(i,j) = 0.5*(sin_sg(i,j,2)+sin_sg(i,j-1,4))*dyc(i,j)/dx(i,j)
769 del6_u(i,j) = 0.5*(sin_sg(i,j,2)+sin_sg(i,j-1,4))*dx(i,j)/dyc(i,j)
773 divg_u(i,j) = sina_v(i,j)*dyc(i,j)/dx(i,j)
774 del6_u(i,j) = sina_v(i,j)*dx(i,j)/dyc(i,j)
780 divg_v(i,j) = sina_u(i,j)*dxc(i,j)/dy(i,j)
781 del6_v(i,j) = sina_u(i,j)*dy(i,j)/dxc(i,j)
783 if (is == 1 .and. .not. atm%gridstruct%bounded_domain)
then 784 divg_v(is,j) = 0.5*(sin_sg(1,j,1)+sin_sg(0,j,3))*dxc(is,j)/dy(is,j)
785 del6_v(is,j) = 0.5*(sin_sg(1,j,1)+sin_sg(0,j,3))*dy(is,j)/dxc(is,j)
787 if (ie+1 == npx .and. .not. atm%gridstruct%bounded_domain)
then 788 divg_v(ie+1,j) = 0.5*(sin_sg(npx,j,1)+sin_sg(npx-1,j,3))*dxc(ie+1,j)/dy(ie+1,j)
789 del6_v(ie+1,j) = 0.5*(sin_sg(npx,j,1)+sin_sg(npx-1,j,3))*dy(ie+1,j)/dxc(ie+1,j)
794 call init_cubed_to_latlon( atm%gridstruct, atm%flagstruct%hydrostatic, agrid, grid_type, c2l_order, atm%bd )
796 call global_mx(area, atm%ng, atm%gridstruct%da_min, atm%gridstruct%da_max, atm%bd)
797 if( is_master() )
write(*,*)
'da_max/da_min=', atm%gridstruct%da_max/atm%gridstruct%da_min
799 call global_mx_c(area_c(is:ie,js:je), is, ie, js, je, atm%gridstruct%da_min_c, atm%gridstruct%da_max_c)
801 if( is_master() )
write(*,*)
'da_max_c/da_min_c=', atm%gridstruct%da_max_c/atm%gridstruct%da_min_c
807 if (grid_type < 3 .and. .not. atm%gridstruct%bounded_domain )
then 808 call mpp_update_domains(divg_v, divg_u, atm%domain, flags=scalar_pair, &
809 gridtype=cgrid_ne_param, complete=.true.)
810 call mpp_update_domains(del6_v, del6_u, atm%domain, flags=scalar_pair, &
811 gridtype=cgrid_ne_param, complete=.true.)
812 call edge_factors (atm%gridstruct%edge_s, atm%gridstruct%edge_n, atm%gridstruct%edge_w, &
813 atm%gridstruct%edge_e, non_ortho, grid, agrid, npx, npy, atm%bd)
814 call efactor_a2c_v(atm%gridstruct%edge_vect_s, atm%gridstruct%edge_vect_n, &
815 atm%gridstruct%edge_vect_w, atm%gridstruct%edge_vect_e, &
816 non_ortho, grid, agrid, npx, npy, atm%gridstruct%bounded_domain, atm%bd)
834 atm%gridstruct%grid = atm%gridstruct%grid_64
835 atm%gridstruct%agrid = atm%gridstruct%agrid_64
836 atm%gridstruct%area = atm%gridstruct%area_64
837 atm%gridstruct%area_c = atm%gridstruct%area_c_64
838 atm%gridstruct%dx = atm%gridstruct%dx_64
839 atm%gridstruct%dy = atm%gridstruct%dy_64
840 atm%gridstruct%dxa = atm%gridstruct%dxa_64
841 atm%gridstruct%dya = atm%gridstruct%dya_64
842 atm%gridstruct%dxc = atm%gridstruct%dxc_64
843 atm%gridstruct%dyc = atm%gridstruct%dyc_64
844 atm%gridstruct%cosa = atm%gridstruct%cosa_64
845 atm%gridstruct%sina = atm%gridstruct%sina_64
851 deallocate ( atm%gridstruct%area_c_64 )
854 deallocate ( atm%gridstruct%dxa_64 )
855 deallocate ( atm%gridstruct%dya_64 )
856 deallocate ( atm%gridstruct%dxc_64 )
857 deallocate ( atm%gridstruct%dyc_64 )
858 deallocate ( atm%gridstruct%cosa_64 )
859 deallocate ( atm%gridstruct%sina_64 )
910 if (
allocated(sst_ncep))
deallocate( sst_ncep )
911 if (
allocated(sst_anom))
deallocate( sst_anom )
920 real(kind=R_GRID),
intent(in):: c
921 real(kind=R_GRID),
intent(in):: lon_p, lat_p
922 integer,
intent(in):: n
923 integer,
intent(in):: i1, i2, j1, j2
925 real(kind=R_GRID),
intent(inout),
dimension(i1:i2,j1:j2):: lon, lat
927 real(f_p):: lat_t, sin_p, cos_p, sin_lat, cos_lat, sin_o, p2, two_pi
928 real(f_p):: c2p1, c2m1
934 if( is_master() .and. n==1 )
then 935 write(*,*) n,
'Schmidt transformation: stretching factor=', c,
' center=', lon_p, lat_p
946 if ( abs(c2m1) > 1.d-7 )
then 947 sin_lat = sin(lat(i,j))
948 lat_t = asin( (c2m1+c2p1*sin_lat)/(c2p1+c2m1*sin_lat) )
954 sin_o = -(sin_p*sin_lat + cos_p*cos_lat*cos(lon(i,j)))
955 if ( (1.-abs(sin_o)) < 1.d-7 )
then 957 lat(i,j) = sign( p2, sin_o )
959 lat(i,j) = asin( sin_o )
960 lon(i,j) = lon_p + atan2( -cos_lat*sin(lon(i,j)), &
961 -sin_lat*cos_p+cos_lat*sin_p*cos(lon(i,j)))
962 if ( lon(i,j) < 0.d0 )
then 963 lon(i,j) = lon(i,j) + two_pi
964 elseif( lon(i,j) >= two_pi )
then 965 lon(i,j) = lon(i,j) - two_pi
974 subroutine cube_transform(c, i1, i2, j1, j2, lon_p, lat_p, n, lon, lat)
981 real(kind=R_GRID),
intent(in):: c
982 real(kind=R_GRID),
intent(in):: lon_p, lat_p
983 integer,
intent(in):: n
984 integer,
intent(in):: i1, i2, j1, j2
986 real(kind=R_GRID),
intent(inout),
dimension(i1:i2,j1:j2):: lon, lat
988 real(f_p):: lat_t, sin_p, cos_p, sin_lat, cos_lat, sin_o, p2, two_pi
989 real(f_p):: c2p1, c2m1
995 if( is_master() .and. n==1 )
then 996 write(*,*) n,
'Cube transformation (revised Schmidt): stretching factor=', c,
' center=', lon_p, lat_p
1009 if ( abs(c2m1) > 1.d-7 )
then 1010 sin_lat = sin(lat(i,j))
1011 lat_t = asin( (c2m1+c2p1*sin_lat)/(c2p1+c2m1*sin_lat) )
1015 sin_lat = sin(lat_t)
1016 cos_lat = cos(lat_t)
1017 lon(i,j) = lon(i,j) + pi
1018 sin_o = -(sin_p*sin_lat + cos_p*cos_lat*cos(lon(i,j)))
1019 if ( (1.-abs(sin_o)) < 1.d-7 )
then 1021 lat(i,j) = sign( p2, sin_o )
1023 lat(i,j) = asin( sin_o )
1024 lon(i,j) = lon_p + atan2( -cos_lat*sin(lon(i,j)), &
1025 -sin_lat*cos_p+cos_lat*sin_p*cos(lon(i,j)))
1026 if ( lon(i,j) < 0.d0 )
then 1027 lon(i,j) = lon(i,j) + two_pi
1028 elseif( lon(i,j) >= two_pi )
then 1029 lon(i,j) = lon(i,j) - two_pi
1039 real(kind=R_GRID),
intent(in):: v1(3), v2(3)
1040 real (f_p) :: vp1(3), vp2(3), prod16
1044 vp1(k) =
real(v1(k),kind=
f_p)
1045 vp2(k) =
real(v2(k),kind=
f_p)
1047 prod16 = vp1(1)*vp2(1) + vp1(2)*vp2(2) + vp1(3)*vp2(3)
1054 subroutine efactor_a2c_v(edge_vect_s, edge_vect_n, edge_vect_w, edge_vect_e, non_ortho, grid, agrid, npx, npy, bounded_domain, bd)
1056 real(kind=R_GRID),
intent(INOUT),
dimension(bd%isd:bd%ied) :: edge_vect_s, edge_vect_n
1057 real(kind=R_GRID),
intent(INOUT),
dimension(bd%jsd:bd%jed) :: edge_vect_w, edge_vect_e
1058 logical,
intent(in):: non_ortho, bounded_domain
1059 real(kind=R_GRID),
intent(in):: grid(bd%isd:bd%ied+1,bd%jsd:bd%jed+1,2)
1060 real(kind=R_GRID),
intent(in):: agrid(bd%isd:bd%ied ,bd%jsd:bd%jed ,2)
1061 integer,
intent(in):: npx, npy
1063 real(kind=R_GRID) px(2,bd%isd:bd%ied+1), py(2,bd%jsd:bd%jed+1)
1064 real(kind=R_GRID) p1(2,bd%isd:bd%ied+1), p2(2,bd%jsd:bd%jed+1)
1065 real(kind=R_GRID) d1, d2
1069 integer :: is, ie, js, je
1070 integer :: isd, ied, jsd, jed
1082 if ( .not. non_ortho )
then 1093 if ( npx /= npy .and. .not. (bounded_domain))
call mpp_error(fatal,
'efactor_a2c_v: npx /= npy')
1094 if ( (npx/2)*2 == npx )
call mpp_error(fatal,
'efactor_a2c_v: npx/npy is not an odd number')
1102 call mid_pt_sphere(agrid(i-1,j,1:2), agrid(i,j, 1:2), py(1,j))
1103 call mid_pt_sphere( grid(i, j,1:2), grid(i,j+1,1:2), p2(1,j))
1114 edge_vect_w(j) = d1 / ( d1 + d2 )
1118 edge_vect_w(j) = d1 / ( d2 + d1 )
1122 edge_vect_w(0) = edge_vect_w(1)
1124 if ( (je+1)==npy )
then 1125 edge_vect_w(npy) = edge_vect_w(je)
1132 if ( (ie+1)==npx )
then 1135 call mid_pt_sphere(agrid(i-1,j,1:2), agrid(i,j, 1:2), py(1,j))
1136 call mid_pt_sphere( grid(i, j,1:2), grid(i,j+1,1:2), p2(1,j))
1143 edge_vect_e(j) = d1 / ( d1 + d2 )
1147 edge_vect_e(j) = d1 / ( d2 + d1 )
1151 edge_vect_e(0) = edge_vect_e(1)
1153 if ( (je+1)==npy )
then 1154 edge_vect_e(npy) = edge_vect_e(je)
1164 call mid_pt_sphere(agrid(i,j-1,1:2), agrid(i, j,1:2), px(1,i))
1165 call mid_pt_sphere( grid(i,j, 1:2), grid(i+1,j,1:2), p1(1,i))
1175 edge_vect_s(i) = d1 / ( d1 + d2 )
1179 edge_vect_s(i) = d1 / ( d2 + d1 )
1183 edge_vect_s(0) = edge_vect_s(1)
1185 if ( (ie+1)==npx )
then 1186 edge_vect_s(npx) = edge_vect_s(ie)
1194 if ( (je+1)==npy )
then 1198 call mid_pt_sphere(agrid(i,j-1,1:2), agrid(i, j,1:2), px(1,i))
1199 call mid_pt_sphere( grid(i,j, 1:2), grid(i+1,j,1:2), p1(1,i))
1206 edge_vect_n(i) = d1 / ( d1 + d2 )
1210 edge_vect_n(i) = d1 / ( d2 + d1 )
1214 edge_vect_n(0) = edge_vect_n(1)
1216 if ( (ie+1)==npx )
then 1217 edge_vect_n(npx) = edge_vect_n(ie)
1231 subroutine edge_factors(edge_s, edge_n, edge_w, edge_e, non_ortho, grid, agrid, npx, npy, bd)
1233 real(kind=R_GRID),
intent(INOUT),
dimension(npx) :: edge_s, edge_n
1234 real(kind=R_GRID),
intent(INOUT),
dimension(npy) :: edge_w, edge_e
1235 logical,
intent(in):: non_ortho
1236 real(kind=R_GRID),
intent(in):: grid(bd%isd:bd%ied+1,bd%jsd:bd%jed+1,2)
1237 real(kind=R_GRID),
intent(in):: agrid(bd%isd:bd%ied ,bd%jsd:bd%jed ,2)
1238 integer,
intent(in):: npx, npy
1240 real(kind=R_GRID) px(2,npx), py(2,npy)
1241 real(kind=R_GRID) d1, d2
1244 integer :: is, ie, js, je
1245 integer :: isd, ied, jsd, jed
1256 if ( .not. non_ortho )
then 1273 do j=max(1,js-1), min(npy-1,je+1)
1274 call mid_pt_sphere(agrid(i-1,j,1:2), agrid(i,j,1:2), py(1,j))
1276 do j=max(2,js), min(npy-1,je+1)
1279 edge_w(j) = d2 / ( d1 + d2 )
1287 if ( (ie+1)==npx )
then 1289 do j=max(1,js-1), min(npy-1,je+1)
1290 call mid_pt_sphere(agrid(i-1,j,1:2), agrid(i,j,1:2), py(1,j))
1292 do j=max(2,js), min(npy-1,je+1)
1295 edge_e(j) = d2 / ( d1 + d2 )
1308 do i=max(1,is-1), min(npx-1,ie+1)
1309 call mid_pt_sphere(agrid(i,j-1,1:2), agrid(i,j,1:2), px(1,i))
1311 do i=max(2,is), min(npx-1,ie+1)
1314 edge_s(i) = d2 / ( d1 + d2 )
1322 if ( (je+1)==npy )
then 1324 do i=max(1,is-1), min(npx-1,ie+1)
1325 call mid_pt_sphere(agrid(i,j-1,1:2), agrid(i,j,1:2), px(1,i))
1327 do i=max(2,is), min(npx-1,ie+1)
1330 edge_n(i) = d2 / ( d1 + d2 )
1340 integer,
intent(in):: im, grid_type
1341 real(kind=R_GRID),
intent(out):: lon(im+1,im+1)
1342 real(kind=R_GRID),
intent(out):: lat(im+1,im+1)
1350 if(grid_type<3)
then 1354 lon(i,j) = lon(i,j) - pi
1376 integer,
intent(in):: im
1377 real(kind=R_GRID),
intent(out):: lamda(im+1,im+1)
1378 real(kind=R_GRID),
intent(out):: theta(im+1,im+1)
1381 real(kind=R_GRID) pp(3,im+1,im+1)
1382 real(kind=R_GRID) p1(2), p2(2)
1383 real(f_p):: rsq3, alpha, delx, dely
1386 rsq3 = 1.d0/sqrt(3.d0)
1387 alpha = asin( rsq3 )
1393 dely = 2.d0*alpha /
real(im,kind=
f_p)
1397 lamda(1, j) = 0.75d0*pi
1398 lamda(im+1,j) = 1.25d0*pi
1399 theta(1, j) = -alpha + dely*
real(j-1,kind=f_p) 1400 theta(im+1,j) = theta(1,j)
1406 call mirror_latlon(lamda(1,1), theta(1,1), lamda(im+1,im+1), theta(im+1,im+1), &
1407 lamda(1,i), theta(1,i), lamda(i,1), theta(i, 1) )
1408 lamda(i,im+1) = lamda(i,1)
1409 theta(i,im+1) = -theta(i,1)
1413 call latlon2xyz2(lamda(1 , 1), theta(1, 1), pp(1, 1, 1))
1414 call latlon2xyz2(lamda(im+1, 1), theta(im+1, 1), pp(1,im+1, 1))
1415 call latlon2xyz2(lamda(1, im+1), theta(1, im+1), pp(1, 1,im+1))
1416 call latlon2xyz2(lamda(im+1,im+1), theta(im+1,im+1), pp(1,im+1,im+1))
1423 call latlon2xyz2(lamda(i,j), theta(i,j), pp(1,i,j))
1424 pp(2,i,j) = -pp(2,i,j)*rsq3/pp(1,i,j)
1425 pp(3,i,j) = -pp(3,i,j)*rsq3/pp(1,i,j)
1430 call latlon2xyz2(lamda(i,j), theta(i,j), pp(1,i,1))
1431 pp(2,i,1) = -pp(2,i,1)*rsq3/pp(1,i,1)
1432 pp(3,i,1) = -pp(3,i,1)*rsq3/pp(1,i,1)
1444 pp(2,i,j) = pp(2,i,1)
1446 pp(3,i,j) = pp(3,1,j)
1453 if ( is_master() )
then 1454 p1(1) = lamda(1,1); p1(2) = theta(1,1)
1455 p2(1) = lamda(2,1); p2(2) = theta(2,1)
1471 integer,
intent(IN) :: im, in, nghost
1472 real(kind=R_GRID),
intent(IN),
dimension(2) :: lL, lR, uL, uR
1473 real(kind=R_GRID),
intent(OUT) :: lamda(1-nghost:im+1+nghost,1-nghost:in+1+nghost)
1474 real(kind=R_GRID),
intent(OUT) :: theta(1-nghost:im+1+nghost,1-nghost:in+1+nghost)
1477 real(kind=R_GRID) pp(3,1-nghost:im+1+nghost,1-nghost:in+1+nghost)
1478 real(kind=R_GRID) p1(2), p2(2)
1479 real(f_p):: rsq3, alpha, delx, dely
1480 integer i, j, k, irefl
1482 rsq3 = 1.d0/sqrt(3.d0)
1483 alpha = asin( rsq3 )
1485 lamda(1,1) = ll(1); theta(1,1) = ll(2)
1486 lamda(im+1,1) = lr(1); theta(im+1,1) = lr(2)
1487 lamda(1,in+1) = ul(1); theta(1,in+1) = ul(2)
1488 lamda(im+1,in+1) = ur(1); theta(im+1,in+1) = ur(2)
1492 dely = (ul(2) - ll(2))/in
1494 theta(1,j) = theta(1,j-1) + dely
1495 theta(in+1,j) = theta(in+1,j-1) + dely
1496 lamda(1,j) = lamda(1,1)
1497 lamda(in+1,j) = lamda(in+1,1)
1500 theta(1,j) = theta(1,j+1) - dely
1501 theta(in+1,j) = theta(in+1,j+1) - dely
1502 lamda(1,j) = lamda(1,1)
1503 lamda(in+1,j) = lamda(in+1,1)
1506 lamda(1,:) = lamda(1,1)
1507 lamda(in+1,:) = lamda(in+1,1)
1511 do i=1-nghost,im+1+nghost
1516 (/lamda(1,1),theta(1,1)/), (/lamda(im+1,1),theta(im+1,1)/), p1 )
1518 (/lamda(1,in+1),theta(1,in+1)/), (/lamda(im+1,in+1),theta(im+1,in+1)/), p2 )
1520 lamda(i,1) = p1(1); theta(i,1) = p1(2)
1521 lamda(i,in+1) = p2(1); theta(i,in+1) = p2(2)
1528 do j=1-nghost,in+1+nghost
1529 call latlon2xyz2(lamda(i,j), theta(i,j), pp(1,i,j))
1530 pp(2,i,j) = -pp(2,i,j)*rsq3/pp(1,i,j)
1531 pp(3,i,j) = -pp(3,i,j)*rsq3/pp(1,i,j)
1535 do i=1-nghost,im+1+nghost
1536 call latlon2xyz2(lamda(i,j), theta(i,j), pp(1,i,1))
1537 pp(2,i,1) = -pp(2,i,1)*rsq3/pp(1,i,1)
1538 pp(3,i,1) = -pp(3,i,1)*rsq3/pp(1,i,1)
1543 do j=1-nghost,in+1+nghost
1544 do i=1-nghost,im+1+nghost
1549 do j=1-nghost,in+1+nghost
1550 do i=1-nghost,im+1+nghost
1552 pp(2,i,j) = pp(2,i,1)
1554 pp(3,i,j) = pp(3,1,j)
1559 pp(:,1-nghost:im+1+nghost,1-nghost:in+1+nghost), &
1560 lamda(1-nghost:im+1+nghost,1-nghost:in+1+nghost), &
1561 theta(1-nghost:im+1+nghost,1-nghost:in+1+nghost))
1565 if ( is_master() )
then 1566 p1(1) = lamda(1,1); p1(2) = theta(1,1)
1567 p2(1) = lamda(2,1); p2(2) = theta(2,1)
1569 p2(1) = lamda(1,2); p2(2) = theta(1,2)
1582 real(kind=R_GRID) lamda(im+1,im+1)
1583 real(kind=R_GRID) theta(im+1,im+1)
1584 real(kind=R_GRID) p(3,im+1,im+1)
1586 real(kind=R_GRID) rsq3, xf, y0, z0, y, x, z, ds
1587 real(kind=R_GRID) dy, dz
1589 real(kind=R_GRID) dp
1591 dp = 0.5d0*pi/
real(im,kind=
r_grid)
1593 rsq3 = 1.d0/sqrt(3.d0)
1597 p(2,j,k) =-rsq3*tan(-0.25d0*pi+(j-1)*dp)
1598 p(3,j,k) = rsq3*tan(-0.25d0*pi+(k-1)*dp)
1609 real(kind=R_GRID) lamda(im+1,im+1)
1610 real(kind=R_GRID) theta(im+1,im+1)
1611 real(kind=R_GRID) p(3,im+1,im+1)
1613 real(kind=R_GRID) rsq3, xf, y0, z0, y, x, z, ds
1614 real(kind=R_GRID) dy, dz
1619 rsq3 = 1.d0/sqrt(3.d0)
1621 y0 = rsq3; dy = -2.d0*rsq3/im
1622 z0 = -rsq3; dz = 2.d0*rsq3/im
1627 p(2,j,k) = y0 + (j-1)*dy
1628 p(3,j,k) = z0 + (k-1)*dz
1635 subroutine symm_ed(im, lamda, theta)
1638 real(kind=R_GRID) lamda(im+1,im+1)
1639 real(kind=R_GRID) theta(im+1,im+1)
1641 real(kind=R_GRID) avg
1645 lamda(i,j) = lamda(i,1)
1652 avg = 0.5d0*(lamda(i,j)-lamda(ip,j))
1653 lamda(i, j) = avg + pi
1654 lamda(ip,j) = pi - avg
1655 avg = 0.5d0*(theta(i,j)+theta(ip,j))
1665 avg = 0.5d0*(lamda(i,j)+lamda(i,jp))
1668 avg = 0.5d0*(theta(i,j)-theta(i,jp))
1677 real(kind=R_GRID),
intent(in):: lon, lat
1678 real(kind=R_GRID),
intent(out):: p3(3)
1679 real(kind=R_GRID) e(2)
1681 e(1) = lon; e(2) = lat
1689 real(kind=R_GRID),
intent(in) :: p(2)
1690 real(kind=R_GRID),
intent(out):: e(3)
1691 integer,
optional,
intent(in):: id
1695 real (f_p):: e1, e2, e3
1701 e1 = cos(q(2)) * cos(q(1))
1702 e2 = cos(q(2)) * sin(q(1))
1727 real(kind=R_GRID),
intent(in) :: p1(3), p2(3), p0(3)
1728 real(kind=R_GRID),
intent(out):: p(3)
1730 real(kind=R_GRID):: x1, y1, z1, x2, y2, z2, x0, y0, z0
1731 real(kind=R_GRID) nb(3)
1732 real(kind=R_GRID) pdot
1736 pdot = sqrt(nb(1)**2+nb(2)**2+nb(3)**2)
1738 nb(k) = nb(k) / pdot
1741 pdot = p0(1)*nb(1) + p0(2)*nb(2) + p0(3)*nb(3)
1743 p(k) = p0(k) - 2.d0*pdot*nb(k)
1751 subroutine mirror_latlon(lon1, lat1, lon2, lat2, lon0, lat0, lon3, lat3)
1752 real(kind=R_GRID),
intent(in):: lon1, lat1, lon2, lat2, lon0, lat0
1753 real(kind=R_GRID),
intent(out):: lon3, lat3
1755 real(kind=R_GRID) p0(3), p1(3), p2(3), nb(3), pp(3), sp(2)
1756 real(kind=R_GRID) pdot
1764 pdot = sqrt(nb(1)**2+nb(2)**2+nb(3)**2)
1766 nb(k) = nb(k) / pdot
1769 pdot = p0(1)*nb(1) + p0(2)*nb(2) + p0(3)*nb(3)
1771 pp(k) = p0(k) - 2.d0*pdot*nb(k)
1783 integer,
intent(in):: np
1784 real(kind=R_GRID),
intent(inout):: q(3,np)
1785 real(kind=R_GRID),
intent(inout):: xs(np), ys(np)
1787 real(kind=R_GRID),
parameter:: esl=1.d-10
1789 real (f_p):: dist, lat, lon
1796 dist = sqrt(p(1)**2 + p(2)**2 + p(3)**2)
1801 if ( (abs(p(1))+abs(p(2))) < esl )
then 1802 lon =
real(0.,kind=
f_p)
1804 lon = atan2( p(2), p(1) )
1807 if ( lon < 0.) lon =
real(2.,kind=
f_p)*pi + lon
1824 real(kind=R_GRID),
intent(in) :: p1(3), p2(3)
1825 real(kind=R_GRID),
intent(out):: e(3)
1827 e(1) = p1(2)*p2(3) - p1(3)*p2(2)
1828 e(2) = p1(3)*p2(1) - p1(1)*p2(3)
1829 e(3) = p1(1)*p2(2) - p1(2)*p2(1)
1835 integer,
intent(in):: npx, npy
1836 real(kind=R_GRID),
intent(in) :: pp(3,bd%isd:bd%ied+1,bd%jsd:bd%jed+1)
1837 real(kind=R_GRID),
intent(out):: u1(3,bd%isd:bd%ied, bd%jsd:bd%jed)
1838 real(kind=R_GRID),
intent(out):: u2(3,bd%isd:bd%ied, bd%jsd:bd%jed)
1841 real(kind=R_GRID) p1(3), p2(3), pc(3), p3(3)
1843 integer :: isd, ied, jsd, jed
1852 if ( (i<1 .and. j<1 ) .or. (i>(npx-1) .and. j<1) .or. &
1853 (i>(npx-1) .and. j>(npy-1)) .or. (i<1 .and. j>(npy-1)))
then 1859 u1(k,i,j) = pp(k,i+1,j)+pp(k,i+1,j+1) - pp(k,i,j)-pp(k,i,j+1)
1860 u2(k,i,j) = pp(k,i,j+1)+pp(k,i+1,j+1) - pp(k,i,j)-pp(k,i+1,j)
1865 call cell_center3(pp(1,i,j), pp(1,i+1,j), pp(1,i,j+1), pp(1,i+1,j+1), pc)
1887 real(kind=R_GRID),
intent(in) :: e1(2), e2(2)
1888 real(kind=R_GRID),
intent(out):: uc(3)
1890 real(kind=R_GRID),
dimension(3):: pc, p1, p2, p3
1904 real(kind=R_GRID),
intent(in) :: p1(3), p2(3)
1905 real(kind=R_GRID),
intent(out):: uc(3)
1907 real(kind=R_GRID),
dimension(3):: pc, p3
1919 real(kind=R_GRID),
intent(inout):: e(3)
1923 pdot = e(1)**2 + e(2)**2 + e(3)**2
1934 real(kind=R_GRID),
intent(in):: beta
1935 real(kind=R_GRID),
intent(in):: p1(2), p2(2)
1936 real(kind=R_GRID),
intent(out):: x_o, y_o
1938 real(kind=R_GRID):: pm(2)
1939 real(kind=R_GRID):: e1(3), e2(3), e3(3)
1940 real(kind=R_GRID):: s1, s2, s3, dd, alpha
1947 s1 = alpha*e1(1) + beta*e2(1)
1948 s2 = alpha*e1(2) + beta*e2(2)
1949 s3 = alpha*e1(3) + beta*e2(3)
1951 dd = sqrt( s1**2 + s2**2 + s3**2 )
1969 real(kind=R_GRID),
intent(in):: beta
1970 real(kind=R_GRID),
intent(in):: p1(2), p2(2)
1971 real(kind=R_GRID),
intent(out):: pb(2)
1973 real(kind=R_GRID):: pm(2)
1974 real(kind=R_GRID):: e1(3), e2(3), eb(3)
1975 real(kind=R_GRID):: dd, alpha, omg
1977 if ( abs(p1(1) - p2(1)) < 1.d-8 .and. abs(p1(2) - p2(2)) < 1.d-8)
then 1978 call mpp_error(warning,
'spherical_linear_interpolation was passed two colocated points.')
1986 dd = sqrt( e1(1)**2 + e1(2)**2 + e1(3)**2 )
1992 dd = sqrt( e2(1)**2 + e2(2)**2 + e2(3)**2 )
2000 omg = acos( e1(1)*e2(1) + e1(2)*e2(2) + e1(3)*e2(3) )
2002 if ( abs(omg) < 1.d-5 )
then 2003 print*,
'spherical_linear_interpolation: ', omg, p1, p2
2004 call mpp_error(fatal,
'spherical_linear_interpolation: interpolation not well defined between antipodal points')
2007 eb(1) = sin( beta*omg )*e2(1) + sin(alpha*omg)*e1(1)
2008 eb(2) = sin( beta*omg )*e2(2) + sin(alpha*omg)*e1(2)
2009 eb(3) = sin( beta*omg )*e2(3) + sin(alpha*omg)*e1(3)
2011 eb(1) = eb(1) / sin(omg)
2012 eb(2) = eb(2) / sin(omg)
2013 eb(3) = eb(3) / sin(omg)
2020 real(kind=R_GRID) ,
intent(IN) :: p1(2), p2(2)
2021 real(kind=R_GRID) ,
intent(OUT) :: pm(2)
2023 real(kind=R_GRID) e1(3), e2(3), e3(3)
2035 real(kind=R_GRID),
intent(IN) :: p1(3), p2(3)
2036 real(kind=R_GRID),
intent(OUT) :: e(3)
2038 real (f_p):: q1(3), q2(3)
2039 real (f_p):: dd, e1, e2, e3
2051 dd = sqrt( e1**2 + e2**2 + e3**2 )
2065 real(kind=R_GRID),
intent(IN) :: p1(2), p2(2)
2066 real(kind=R_GRID),
intent(OUT) :: e3(3)
2068 real(kind=R_GRID) e1(3), e2(3)
2079 real(kind=R_GRID),
intent(IN) :: q1(2), q2(2)
2080 real(kind=R_GRID),
intent(IN),
optional :: radius
2082 real (f_p):: p1(2), p2(2)
2091 beta = asin( sqrt( sin((p1(2)-p2(2))/2.)**2 + cos(p1(2))*cos(p2(2))* &
2092 sin((p1(1)-p2(1))/2.)**2 ) ) * 2.
2094 if (
present(radius) )
then 2108 real(kind=R_GRID) :: great_circle_dist_cart
2109 real(kind=R_GRID),
dimension(3),
intent(in) :: v1, v2
2110 real(kind=R_GRID),
intent(IN),
optional :: radius
2111 real(kind=R_GRID) :: norm
2113 norm = (v1(1)*v1(1)+v1(2)*v1(2)+v1(3)*v1(3)) &
2114 *(v2(1)*v2(1)+v2(2)*v2(2)+v2(3)*v2(3))
2118 great_circle_dist_cart=(v1(1)*v2(1)+v1(2)*v2(2)+v1(3)*v2(3)) &
2120 great_circle_dist_cart = sign(min(1.,abs(great_circle_dist_cart)),great_circle_dist_cart)
2121 great_circle_dist_cart=acos(great_circle_dist_cart)
2123 if (
present(radius) )
then 2124 great_circle_dist_cart = radius * great_circle_dist_cart
2141 subroutine intersect(a1,a2,b1,b2,radius,x_inter,local_a,local_b)
2143 real(kind=R_GRID),
dimension(3),
intent(in) :: a1, a2, b1, b2
2144 real(kind=R_GRID),
intent(in) :: radius
2145 real(kind=R_GRID),
dimension(3),
intent(out) :: x_inter
2146 logical,
intent(out) :: local_a,local_b
2150 real(kind=R_GRID) :: a2_xy, b1_xy, b2_xy, a2_xz, b1_xz, b2_xz, &
2151 b1_xyz, b2_xyz, length
2155 a2_xy=a2(1)*a1(2)-a2(2)*a1(1)
2156 b1_xy=b1(1)*a1(2)-b1(2)*a1(1)
2157 b2_xy=b2(1)*a1(2)-b2(2)*a1(1)
2159 a2_xz=a2(1)*a1(3)-a2(3)*a1(1)
2160 b1_xz=b1(1)*a1(3)-b1(3)*a1(1)
2161 b2_xz=b2(1)*a1(3)-b2(3)*a1(1)
2163 b1_xyz=b1_xy*a2_xz-b1_xz*a2_xy
2164 b2_xyz=b2_xy*a2_xz-b2_xz*a2_xy
2166 if (b1_xyz==0.0d0)
then 2168 elseif (b2_xyz==0.0d0)
then 2171 x_inter(:)=b2(:)-b1(:)*b2_xyz/b1_xyz
2172 length=sqrt(x_inter(1)*x_inter(1)+x_inter(2)*x_inter(2)+x_inter(3)*x_inter(3))
2173 x_inter(:)=radius/length*x_inter(:)
2185 real(kind=R_GRID),
dimension(3) :: center, dx
2186 real(kind=R_GRID) :: dist1,dist2
2188 center(:)=0.25*(a1(:)+a2(:)+b1(:)+b2(:))
2189 dx(:)=+x_inter(:)-center(:)
2190 dist1=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2191 dx(:)=-x_inter(:)-center(:)
2192 dist2=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2194 if (dist2<dist1) x_inter(:)=-x_inter(:)
2199 real(kind=R_GRID),
dimension(3),
intent(in) :: x1,x2
2200 logical,
intent(out) :: local
2202 real(kind=R_GRID),
dimension(3) :: dx
2203 real(kind=R_GRID) :: dist, dist1, dist2
2206 dist=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2208 dx(:)=x1(:)-x_inter(:)
2209 dist1=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2210 dx(:)=x2(:)-x_inter(:)
2211 dist2=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2213 if (dist1<=dist .and. dist2<=dist)
then 2233 subroutine intersect_cross(a1,a2,b1,b2,radius,x_inter,local_a,local_b)
2235 real(kind=R_GRID),
dimension(3),
intent(in) :: a1, a2, b1, b2
2236 real(kind=R_GRID),
intent(in) :: radius
2237 real(kind=R_GRID),
dimension(3),
intent(out) :: x_inter
2238 logical,
intent(out) :: local_a,local_b
2239 real(kind=R_GRID),
dimension(3) :: v1, v2
2257 v1 = v1/sqrt(v1(1)**2 + v1(2)**2 + v1(3)**2)
2258 v2 = v2/sqrt(v2(1)**2 + v2(2)**2 + v2(3)**2)
2262 x_inter = x_inter/sqrt(x_inter(1)**2 + x_inter(2)**2 + x_inter(3)**2)
2271 real(kind=R_GRID),
dimension(3) :: center, dx
2272 real(kind=R_GRID) :: dist1,dist2
2274 center(:)=0.25*(a1(:)+a2(:)+b1(:)+b2(:))
2275 dx(:)=+x_inter(:)-center(:)
2276 dist1=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2277 dx(:)=-x_inter(:)-center(:)
2278 dist2=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2280 if (dist2<dist1) x_inter(:)=-x_inter(:)
2285 real(kind=R_GRID),
dimension(3),
intent(in) :: x1,x2
2286 logical,
intent(out) :: local
2288 real(kind=R_GRID),
dimension(3) :: dx
2289 real(kind=R_GRID) :: dist, dist1, dist2
2292 dist=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2294 dx(:)=x1(:)-x_inter(:)
2295 dist1=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2296 dx(:)=x2(:)-x_inter(:)
2297 dist2=dx(1)*dx(1)+dx(2)*dx(2)+dx(3)*dx(3)
2299 if (dist1<=dist .and. dist2<=dist)
then 2312 real(kind=R_GRID),
intent(IN) :: pp(2)
2313 real(kind=R_GRID),
intent(OUT) :: elon(3), elat(3)
2315 real (f_p):: lon, lat
2316 real (f_p):: sin_lon, cos_lon, sin_lat, cos_lat
2330 elat(1) = -sin_lat*cos_lon
2331 elat(2) = -sin_lat*sin_lon
2338 real(kind=R_GRID) function v_prod(v1, v2)
2339 real(kind=R_GRID) v1(3), v2(3)
2341 v_prod = v1(1)*v2(1) + v1(2)*v2(2) + v1(3)*v2(3)
2348 logical,
intent(in):: hydrostatic
2349 real(kind=R_GRID),
intent(in) :: agrid(bd%isd:bd%ied,bd%jsd:bd%jed,2)
2350 integer,
intent(in) :: grid_type
2351 integer,
intent(in) :: ord
2352 type(
fv_grid_type),
intent(INOUT),
target :: gridstruct
2355 integer :: is, ie, js, je
2358 real,
pointer,
dimension(:,:) :: a11, a12, a21, a22
2359 real,
pointer,
dimension(:,:) :: z11, z12, z21, z22
2360 real(kind=R_GRID),
pointer,
dimension(:,:,:) :: vlon, vlat
2361 real(kind=R_GRID),
pointer,
dimension(:,:,:) :: ee1, ee2, ec1, ec2
2368 if ( grid_type < 4 )
then 2370 vlon => gridstruct%vlon
2371 vlat => gridstruct%vlat
2372 a11 => gridstruct%a11
2373 a12 => gridstruct%a12
2374 a21 => gridstruct%a21
2375 a22 => gridstruct%a22
2376 z11 => gridstruct%z11
2377 z12 => gridstruct%z12
2378 z21 => gridstruct%z21
2379 z22 => gridstruct%z22
2380 ee1 => gridstruct%ee1
2381 ee2 => gridstruct%ee2
2382 ec1 => gridstruct%ec1
2383 ec2 => gridstruct%ec2
2393 z11(i,j) =
v_prod(ec1(1:3,i,j), vlon(i,j,1:3))
2394 z12(i,j) =
v_prod(ec1(1:3,i,j), vlat(i,j,1:3))
2395 z21(i,j) =
v_prod(ec2(1:3,i,j), vlon(i,j,1:3))
2396 z22(i,j) =
v_prod(ec2(1:3,i,j), vlat(i,j,1:3))
2398 a11(i,j) = 0.5d0*z22(i,j) / gridstruct%sin_sg(i,j,5)
2399 a12(i,j) = -0.5d0*z12(i,j) / gridstruct%sin_sg(i,j,5)
2400 a21(i,j) = -0.5d0*z21(i,j) / gridstruct%sin_sg(i,j,5)
2401 a22(i,j) = 0.5d0*z11(i,j) / gridstruct%sin_sg(i,j,5)
2411 subroutine cubed_to_latlon(u, v, ua, va, gridstruct, npx, npy, km, mode, grid_type, domain, bounded_domain, c2l_ord, bd)
2413 integer,
intent(in) :: km, npx, npy, grid_type, c2l_ord
2414 integer,
intent(in) :: mode
2416 real,
intent(inout):: u(bd%isd:bd%ied,bd%jsd:bd%jed+1,km)
2417 real,
intent(inout):: v(bd%isd:bd%ied+1,bd%jsd:bd%jed,km)
2418 real,
intent(out):: ua(bd%isd:bd%ied, bd%jsd:bd%jed,km)
2419 real,
intent(out):: va(bd%isd:bd%ied, bd%jsd:bd%jed,km)
2420 type(domain2d),
intent(INOUT) :: domain
2421 logical,
intent(IN) :: bounded_domain
2423 if ( c2l_ord == 2 )
then 2424 call c2l_ord2(u, v, ua, va, gridstruct, km, grid_type, bd, .false.)
2426 call c2l_ord4(u, v, ua, va, gridstruct, npx, npy, km, grid_type, domain, bounded_domain, mode, bd)
2432 subroutine c2l_ord4(u, v, ua, va, gridstruct, npx, npy, km, grid_type, domain, bounded_domain, mode, bd)
2435 integer,
intent(in) :: km, npx, npy, grid_type
2436 integer,
intent(in):: mode
2438 real,
intent(inout):: u(bd%isd:bd%ied,bd%jsd:bd%jed+1,km)
2439 real,
intent(inout):: v(bd%isd:bd%ied+1,bd%jsd:bd%jed,km)
2440 real,
intent(out):: ua(bd%isd:bd%ied, bd%jsd:bd%jed,km)
2441 real,
intent(out):: va(bd%isd:bd%ied, bd%jsd:bd%jed,km)
2442 type(domain2d),
intent(INOUT) :: domain
2443 logical,
intent(IN) :: bounded_domain
2447 real :: a2 = -0.0625
2450 real utmp(bd%is:bd%ie, bd%js:bd%je+1)
2451 real vtmp(bd%is:bd%ie+1,bd%js:bd%je)
2452 real wu(bd%is:bd%ie, bd%js:bd%je+1)
2453 real wv(bd%is:bd%ie+1,bd%js:bd%je)
2456 integer :: is, ie, js, je
2464 if ( mode > 0 )
then 2466 call mpp_update_domains(u, v, domain, gridtype=dgrid_ne)
2474 if ( grid_type < 4 )
then 2475 if (bounded_domain)
then 2476 do j=max(1,js),min(npy-1,je)
2477 do i=max(1,is),min(npx-1,ie)
2478 utmp(i,j) = c2*(u(i,j-1,k)+u(i,j+2,k)) + c1*(u(i,j,k)+u(i,j+1,k))
2479 vtmp(i,j) = c2*(v(i-1,j,k)+v(i+2,j,k)) + c1*(v(i,j,k)+v(i+1,j,k))
2483 do j=max(2,js),min(npy-2,je)
2484 do i=max(2,is),min(npx-2,ie)
2485 utmp(i,j) = c2*(u(i,j-1,k)+u(i,j+2,k)) + c1*(u(i,j,k)+u(i,j+1,k))
2486 vtmp(i,j) = c2*(v(i-1,j,k)+v(i+2,j,k)) + c1*(v(i,j,k)+v(i+1,j,k))
2492 wv(i,1) = v(i,1,k)*gridstruct%dy(i,1)
2495 vtmp(i,1) = 2.*(wv(i,1) + wv(i+1,1)) / (gridstruct%dy(i,1)+gridstruct%dy(i+1,1))
2496 utmp(i,1) = 2.*(u(i,1,k)*gridstruct%dx(i,1) + u(i,2,k)*gridstruct%dx(i,2)) &
2497 / ( gridstruct%dx(i,1) + gridstruct%dx(i,2))
2503 if ( (je+1)==npy )
then 2506 wv(i,j) = v(i,j,k)*gridstruct%dy(i,j)
2509 vtmp(i,j) = 2.*(wv(i,j) + wv(i+1,j)) / (gridstruct%dy(i,j)+gridstruct%dy(i+1,j))
2510 utmp(i,j) = 2.*(u(i,j,k)*gridstruct%dx(i,j) + u(i,j+1,k)*gridstruct%dx(i,j+1)) &
2511 / ( gridstruct%dx(i,j) + gridstruct%dx(i,j+1))
2520 wv(1,j) = v(1,j,k)*gridstruct%dy(1,j)
2521 wv(2,j) = v(2,j,k)*gridstruct%dy(2,j)
2524 wu(i,j) = u(i,j,k)*gridstruct%dx(i,j)
2527 utmp(i,j) = 2.*(wu(i,j) + wu(i,j+1))/(gridstruct%dx(i,j)+gridstruct%dx(i,j+1))
2528 vtmp(i,j) = 2.*(wv(1,j) + wv(2,j ))/(gridstruct%dy(1,j)+gridstruct%dy(2,j))
2534 if ( (ie+1)==npx)
then 2537 wv(i, j) = v(i, j,k)*gridstruct%dy(i, j)
2538 wv(i+1,j) = v(i+1,j,k)*gridstruct%dy(i+1,j)
2541 wu(i,j) = u(i,j,k)*gridstruct%dx(i,j)
2544 utmp(i,j) = 2.*(wu(i,j) + wu(i, j+1))/(gridstruct%dx(i,j)+gridstruct%dx(i,j+1))
2545 vtmp(i,j) = 2.*(wv(i,j) + wv(i+1,j ))/(gridstruct%dy(i,j)+gridstruct%dy(i+1,j))
2556 ua(i,j,k) = gridstruct%a11(i,j)*utmp(i,j) + gridstruct%a12(i,j)*vtmp(i,j)
2557 va(i,j,k) = gridstruct%a21(i,j)*utmp(i,j) + gridstruct%a22(i,j)*vtmp(i,j)
2564 ua(i,j,k) = a2*(u(i,j-1,k)+u(i,j+2,k)) + a1*(u(i,j,k)+u(i,j+1,k))
2565 va(i,j,k) = a2*(v(i-1,j,k)+v(i+2,j,k)) + a1*(v(i,j,k)+v(i+1,j,k))
2572 subroutine c2l_ord2(u, v, ua, va, gridstruct, km, grid_type, bd, do_halo)
2574 integer,
intent(in) :: km, grid_type
2575 real,
intent(in) :: u(bd%isd:bd%ied,bd%jsd:bd%jed+1,km)
2576 real,
intent(in) :: v(bd%isd:bd%ied+1,bd%jsd:bd%jed,km)
2578 logical,
intent(in) :: do_halo
2580 real,
intent(out):: ua(bd%isd:bd%ied, bd%jsd:bd%jed,km)
2581 real,
intent(out):: va(bd%isd:bd%ied, bd%jsd:bd%jed,km)
2584 real wu(bd%is-1:bd%ie+1, bd%js-1:bd%je+2)
2585 real wv(bd%is-1:bd%ie+2, bd%js-1:bd%je+1)
2586 real u1(bd%is-1:bd%ie+1), v1(bd%is-1:bd%ie+1)
2588 integer :: is, ie, js, je
2590 real,
dimension(:,:),
pointer :: a11, a12, a21, a22
2591 real,
dimension(:,:),
pointer :: dx, dy, rdxa, rdya
2593 a11 => gridstruct%a11
2594 a12 => gridstruct%a12
2595 a21 => gridstruct%a21
2596 a22 => gridstruct%a22
2600 rdxa => gridstruct%rdxa
2601 rdya => gridstruct%rdya
2618 if ( grid_type < 4 )
then 2621 wu(i,j) = u(i,j,k)*dx(i,j)
2626 wv(i,j) = v(i,j,k)*dy(i,j)
2633 u1(i) = 2.*(wu(i,j) + wu(i,j+1)) / (dx(i,j)+dx(i,j+1))
2634 v1(i) = 2.*(wv(i,j) + wv(i+1,j)) / (dy(i,j)+dy(i+1,j))
2638 ua(i,j,k) = a11(i,j)*u1(i) + a12(i,j)*v1(i)
2639 va(i,j,k) = a21(i,j)*u1(i) + a22(i,j)*v1(i)
2646 ua(i,j,k) = 0.5*(u(i,j,k)+u(i, j+1,k))
2647 va(i,j,k) = 0.5*(v(i,j,k)+v(i+1,j, k))
2656 subroutine expand_cell(q1, q2, q3, q4, a1, a2, a3, a4, fac)
2663 real(kind=R_GRID),
intent(in):: q1(2), q2(2), q3(2), q4(2)
2664 real(kind=R_GRID),
intent(in):: fac
2667 real(kind=R_GRID),
intent(out):: a1(2), a2(2), a3(2), a4(2)
2669 real(kind=R_GRID) qq1(3), qq2(3), qq3(3), qq4(3)
2670 real(kind=R_GRID) p1(3), p2(3), p3(3), p4(3)
2671 real(kind=R_GRID) ec(3)
2672 real(f_p):: dd, d1, d2, d3, d4
2683 ec(k) = p1(k) + p2(k) + p3(k) + p4(k)
2685 dd = sqrt( ec(1)**2 + ec(2)**2 + ec(3)**2 )
2693 qq1(k) = ec(k) + fac*(p1(k)-ec(k))
2694 qq2(k) = ec(k) + fac*(p2(k)-ec(k))
2695 qq3(k) = ec(k) + fac*(p3(k)-ec(k))
2696 qq4(k) = ec(k) + fac*(p4(k)-ec(k))
2702 d1 = sqrt( qq1(1)**2 + qq1(2)**2 + qq1(3)**2 )
2703 d2 = sqrt( qq2(1)**2 + qq2(2)**2 + qq2(3)**2 )
2704 d3 = sqrt( qq3(1)**2 + qq3(2)**2 + qq3(3)**2 )
2705 d4 = sqrt( qq4(1)**2 + qq4(2)**2 + qq4(3)**2 )
2707 qq1(k) = qq1(k) / d1
2708 qq2(k) = qq2(k) / d2
2709 qq3(k) = qq3(k) / d3
2710 qq4(k) = qq4(k) / d4
2726 real(kind=R_GRID) ,
intent(in ) :: q1(2), q2(2), q3(2), q4(2)
2727 real(kind=R_GRID) ,
intent(out) :: e2(2)
2729 real(kind=R_GRID) p1(3), p2(3), p3(3), p4(3)
2730 real(kind=R_GRID) ec(3)
2731 real(kind=R_GRID) dd
2740 ec(k) = p1(k) + p2(k) + p3(k) + p4(k)
2742 dd = sqrt( ec(1)**2 + ec(2)**2 + ec(3)**2 )
2754 real(kind=R_GRID) ,
intent(IN) :: p1(3), p2(3), p3(3), p4(3)
2755 real(kind=R_GRID) ,
intent(OUT) :: ec(3)
2761 ec(k) = p1(k) + p2(k) + p3(k) + p4(k)
2763 dd = sqrt( ec(1)**2 + ec(2)**2 + ec(3)**2 )
2773 real(kind=R_GRID) function get_area(p1, p4, p2, p3, radius)
2775 real(kind=R_GRID),
intent(in),
dimension(2):: p1, p2, p3, p4
2776 real(kind=R_GRID),
intent(in),
optional:: radius
2778 real(kind=R_GRID) e1(3), e2(3), e3(3)
2779 real(kind=R_GRID) ang1, ang2, ang3, ang4
2808 if (
present(radius) )
then 2809 get_area = (ang1 + ang2 + ang3 + ang4 - 2.*pi) * radius**2
2811 get_area = ang1 + ang2 + ang3 + ang4 - 2.*pi
2822 real(kind=R_GRID) :: dist2side
2823 real(kind=R_GRID),
dimension(3),
intent(in) :: v1, v2, point
2825 real(kind=R_GRID) :: angle, side
2829 dist2side = asin(sin(side)*sin(angle))
2837 real(kind=R_GRID) :: dist2side_latlon
2838 real(kind=R_GRID),
dimension(2),
intent(in) :: v1, v2, point
2840 real(kind=R_GRID),
dimension(3) :: c1, c2, cpoint
2842 real(kind=R_GRID) :: angle,side
2852 dist2side_latlon = asin(sin(side)*sin(angle))
2870 real(kind=R_GRID) p1(3), p2(3), p3(3)
2872 real (f_p):: e1(3), e2(3), e3(3)
2873 real (f_p):: px, py, pz
2874 real (f_p):: qx, qy, qz
2875 real (f_p):: angle, ddd
2888 px = e1(2)*e2(3) - e1(3)*e2(2)
2889 py = e1(3)*e2(1) - e1(1)*e2(3)
2890 pz = e1(1)*e2(2) - e1(2)*e2(1)
2892 qx = e1(2)*e3(3) - e1(3)*e3(2)
2893 qy = e1(3)*e3(1) - e1(1)*e3(3)
2894 qz = e1(1)*e3(2) - e1(2)*e3(1)
2896 ddd = (px*px+py*py+pz*pz)*(qx*qx+qy*qy+qz*qz)
2898 if ( ddd <= 0.0d0 )
then 2901 ddd = (px*qx+py*qy+pz*qz) / sqrt(ddd)
2902 if ( abs(ddd)>1.d0)
then 2903 angle = 2.d0*atan(1.0)
2905 if (ddd < 0.d0)
then 2906 angle = 4.d0*atan(1.0d0)
2920 real(kind=R_GRID) function cos_angle(p1, p2, p3)
2928 real(kind=R_GRID),
intent(in):: p1(3), p2(3), p3(3)
2930 real (f_p):: e1(3), e2(3), e3(3)
2931 real (f_p):: px, py, pz
2932 real (f_p):: qx, qy, qz
2933 real (f_p):: angle, ddd
2946 px = e1(2)*e2(3) - e1(3)*e2(2)
2947 py = e1(3)*e2(1) - e1(1)*e2(3)
2948 pz = e1(1)*e2(2) - e1(2)*e2(1)
2951 qx = e1(2)*e3(3) - e1(3)*e3(2)
2952 qy = e1(3)*e3(1) - e1(1)*e3(3)
2953 qz = e1(1)*e3(2) - e1(2)*e3(1)
2956 ddd = sqrt( (px**2+py**2+pz**2)*(qx**2+qy**2+qz**2) )
2957 if ( ddd > 0.d0 )
then 2958 angle = (px*qx+py*qy+pz*qz) / ddd
2967 real function g_sum(domain, p, ifirst, ilast, jfirst, jlast, ngc, area, mode, reproduce)
2968 integer,
intent(IN) :: ifirst, ilast
2969 integer,
intent(IN) :: jfirst, jlast, ngc
2970 integer,
intent(IN) :: mode
2971 logical,
intent(in),
optional :: reproduce
2972 real,
intent(IN) :: p(ifirst:ilast,jfirst:jlast)
2973 real(kind=R_GRID),
intent(IN) :: area(ifirst-ngc:ilast+ngc,jfirst-ngc:jlast+ngc)
2974 type(domain2d),
intent(IN) :: domain
2977 logical,
SAVE :: g_sum_initialized = .false.
2978 real(kind=R_GRID),
SAVE :: global_area
2979 real :: tmp(ifirst:ilast,jfirst:jlast)
2981 if ( .not. g_sum_initialized )
then 2982 global_area = mpp_global_sum(domain, area, flags=bitwise_efp_sum)
2983 if ( is_master() )
write(*,*)
'Global Area=',global_area
2984 g_sum_initialized = .true.
2990 if (
present(reproduce) )
then 2992 gsum = mpp_global_sum(domain, p(:,:)*area(ifirst:ilast,jfirst:jlast), &
2993 flags=bitwise_efp_sum)
2995 gsum = mpp_global_sum(domain, p(:,:)*area(ifirst:ilast,jfirst:jlast))
3004 gsum = gsum + p(i,j)*area(i,j)
3007 call mp_reduce_sum(gsum)
3011 g_sum = gsum / global_area
3019 real function global_qsum(p, ifirst, ilast, jfirst, jlast)
3020 integer,
intent(IN) :: ifirst, ilast
3021 integer,
intent(IN) :: jfirst, jlast
3022 real,
intent(IN) :: p(ifirst:ilast,jfirst:jlast)
3029 gsum = gsum + p(i,j)
3032 call mp_reduce_sum(gsum)
3039 subroutine global_mx(q, n_g, qmin, qmax, bd)
3042 integer,
intent(in):: n_g
3043 real(kind=R_GRID),
intent(in)::q(bd%is-n_g:bd%ie+n_g, bd%js-n_g:bd%je+n_g)
3044 real(kind=R_GRID),
intent(out):: qmin, qmax
3047 integer :: is, ie, js, je
3058 qmin = min(qmin, q(i,j))
3059 qmax = max(qmax, q(i,j))
3062 call mp_reduce_min(qmin)
3063 call mp_reduce_max(qmax)
3068 subroutine global_mx_c(q, i1, i2, j1, j2, qmin, qmax)
3069 integer,
intent(in):: i1, i2, j1, j2
3070 real(kind=R_GRID),
intent(in) :: q(i1:i2,j1:j2)
3071 real(kind=R_GRID),
intent(out) :: qmin, qmax
3078 qmin = min(qmin, q(i,j))
3079 qmax = max(qmax, q(i,j))
3082 call mp_reduce_min(qmin)
3083 call mp_reduce_max(qmax)
3092 real(kind=4),
intent(inout):: q(bd%isd:bd%ied,bd%jsd:bd%jed)
3093 integer,
intent(in):: npx, npy
3094 real,
intent(in):: value
3097 integer :: is, ie, js, je
3098 integer :: isd, ied, jsd, jed
3111 if ( (i<1 .and. j<1) )
then 3114 if ( i>(npx-1) .and. j<1 )
then 3117 if ( i>(npx-1) .and. j>(npy-1) )
then 3120 if ( i<1 .and. j>(npy-1) )
then 3132 real(kind=R_GRID),
intent(inout):: q(bd%isd:bd%ied,bd%jsd:bd%jed)
3133 integer,
intent(in):: npx, npy
3134 real,
intent(in):: value
3137 integer :: is, ie, js, je
3138 integer :: isd, ied, jsd, jed
3151 if ( (i<1 .and. j<1) )
then 3154 if ( i>(npx-1) .and. j<1 )
then 3157 if ( i>(npx-1) .and. j>(npy-1) )
then 3160 if ( i<1 .and. j>(npy-1) )
then 3170 subroutine make_eta_level(km, pe, area, kks, ak, bk, ptop, domain, bd)
3172 integer,
intent(in ):: km
3173 integer,
intent(out):: kks
3174 real(kind=R_GRID),
intent(in):: area(bd%isd:bd%ied,bd%jsd:bd%jed)
3175 real,
intent(INOUT) :: ptop
3176 real,
intent(inout):: pe(bd%is-1:bd%ie+1,km+1,bd%js-1:bd%je+1)
3177 real,
intent(out):: ak(km+1), bk(km+1)
3178 type(domain2d),
intent(IN) :: domain
3181 real,
allocatable:: pem(:,:)
3184 integer :: is, ie, js, je, ng
3192 allocate ( pem(is:ie,js:je) )
3198 pem(i,j) = pe(i,k,j)
3203 p4 =
g_sum(domain, pem, is, ie, js, je, ng, area, 1)
3222 bk(k) = (ph(k) - ph(1)) / (ph(km+1)-ph(1))
3223 ak(k) = ph(1)*(1.-bk(k))
3226 if ( is_master() )
then 3227 write(*,*)
'Make_eta_level ...., ptop=', ptop
3230 write(*,*) ph(k), ak(k), bk(k)
3240 integer,
intent (in) :: n
3242 real(kind=R_GRID),
intent (inout),
dimension (n,n):: a
3243 real(kind=R_GRID),
intent (out),
dimension (n,n):: x
3244 real(kind=R_GRID),
dimension (n,n) :: b
3257 call elgs (a,n,indx)
3262 b(indx(j),k) = b(indx(j),k) - a(indx(j),i)*b(indx(i),k)
3268 x(n,i) = b(indx(n),i)/a(indx(n),n)
3270 x(j,i) = b(indx(j),i)
3272 x(j,i) = x(j,i)-a(indx(j),k)*x(k,i)
3274 x(j,i) = x(j,i)/a(indx(j),j)
3283 subroutine elgs (a,n,indx)
3284 integer,
intent (in) :: n
3285 integer :: i,j,k,itmp
3286 integer,
intent (out),
dimension (n) :: indx
3287 real(kind=R_GRID),
intent (inout),
dimension (n,n) :: a
3289 real(kind=R_GRID) :: c1, pie, pi1, pj
3290 real(kind=R_GRID),
dimension (n) :: c
3301 c1 = max(c1,abs(a(i,j)))
3311 pie = abs(a(indx(i),j))/c(indx(i))
3324 pj = a(indx(i),j)/a(indx(j),j)
3333 a(indx(i),k) = a(indx(i),k)-pj*a(indx(j),k)
3341 real(kind=R_GRID),
intent(IN) :: pp(2)
3342 real(kind=R_GRID),
intent(OUT) :: elon(3), elat(3)
3344 elon(1) = -sin(pp(1))
3345 elon(2) = cos(pp(1))
3347 elat(1) = -sin(pp(2))*cos(pp(1))
3348 elat(2) = -sin(pp(2))*sin(pp(1))
3350 elat(3) = cos(pp(2))
3361 integer,
intent(in):: np
3362 real(kind=R_GRID),
intent(in):: e(3,np)
3363 real(kind=R_GRID),
intent(inout):: f(3,np)
3369 ap = f(1,i)*e(1,i) + f(2,i)*e(2,i) + f(3,i)*e(3,i)
3370 f(1,i) = f(1,i) - ap*e(1,i)
3371 f(2,i) = f(2,i) - ap*e(2,i)
3372 f(3,i) = f(3,i) - ap*e(3,i)
3379 subroutine update_dwinds_phys(is, ie, js, je, isd, ied, jsd, jed, dt, u_dt, v_dt, u, v, gridstruct, npx, npy, npz, domain)
3383 integer,
intent(in):: is, ie, js, je
3384 integer,
intent(in):: isd, ied, jsd, jed
3385 integer,
intent(IN) :: npx,npy, npz
3386 real,
intent(in):: dt
3387 real,
intent(inout):: u(isd:ied, jsd:jed+1,npz)
3388 real,
intent(inout):: v(isd:ied+1,jsd:jed ,npz)
3389 real,
intent(inout),
dimension(isd:ied,jsd:jed,npz):: u_dt, v_dt
3391 type(domain2d),
intent(INOUT) :: domain
3394 real v3(is-1:ie+1,js-1:je+1,3)
3395 real ue(is-1:ie+1,js:je+1,3)
3396 real ve(is:ie+1,js-1:je+1, 3)
3397 real,
dimension(is:ie):: ut1, ut2, ut3
3398 real,
dimension(js:je):: vt1, vt2, vt3
3400 integer i, j, k, m, im2, jm2
3402 real(kind=R_GRID),
pointer,
dimension(:,:,:) :: vlon, vlat
3403 real(kind=R_GRID),
pointer,
dimension(:,:,:,:) :: es, ew
3404 real(kind=R_GRID),
pointer,
dimension(:) :: edge_vect_w, edge_vect_e, edge_vect_s, edge_vect_n
3408 vlon => gridstruct%vlon
3409 vlat => gridstruct%vlat
3411 edge_vect_w => gridstruct%edge_vect_w
3412 edge_vect_e => gridstruct%edge_vect_e
3413 edge_vect_s => gridstruct%edge_vect_s
3414 edge_vect_n => gridstruct%edge_vect_n
3426 if ( gridstruct%grid_type > 3 )
then 3430 u(i,j,k) = u(i,j,k) + dt5*(u_dt(i,j-1,k) + u_dt(i,j,k))
3435 v(i,j,k) = v(i,j,k) + dt5*(v_dt(i-1,j,k) + v_dt(i,j,k))
3443 v3(i,j,1) = u_dt(i,j,k)*vlon(i,j,1) + v_dt(i,j,k)*vlat(i,j,1)
3444 v3(i,j,2) = u_dt(i,j,k)*vlon(i,j,2) + v_dt(i,j,k)*vlat(i,j,2)
3445 v3(i,j,3) = u_dt(i,j,k)*vlon(i,j,3) + v_dt(i,j,k)*vlat(i,j,3)
3452 ue(i,j,1) = v3(i,j-1,1) + v3(i,j,1)
3453 ue(i,j,2) = v3(i,j-1,2) + v3(i,j,2)
3454 ue(i,j,3) = v3(i,j-1,3) + v3(i,j,3)
3460 ve(i,j,1) = v3(i-1,j,1) + v3(i,j,1)
3461 ve(i,j,2) = v3(i-1,j,2) + v3(i,j,2)
3462 ve(i,j,3) = v3(i-1,j,3) + v3(i,j,3)
3467 if ( is==1 .and. .not. gridstruct%bounded_domain )
then 3471 vt1(j) = edge_vect_w(j)*ve(i,j-1,1)+(1.-edge_vect_w(j))*ve(i,j,1)
3472 vt2(j) = edge_vect_w(j)*ve(i,j-1,2)+(1.-edge_vect_w(j))*ve(i,j,2)
3473 vt3(j) = edge_vect_w(j)*ve(i,j-1,3)+(1.-edge_vect_w(j))*ve(i,j,3)
3475 vt1(j) = edge_vect_w(j)*ve(i,j+1,1)+(1.-edge_vect_w(j))*ve(i,j,1)
3476 vt2(j) = edge_vect_w(j)*ve(i,j+1,2)+(1.-edge_vect_w(j))*ve(i,j,2)
3477 vt3(j) = edge_vect_w(j)*ve(i,j+1,3)+(1.-edge_vect_w(j))*ve(i,j,3)
3486 if ( (ie+1)==npx .and. .not. gridstruct%bounded_domain )
then 3490 vt1(j) = edge_vect_e(j)*ve(i,j-1,1)+(1.-edge_vect_e(j))*ve(i,j,1)
3491 vt2(j) = edge_vect_e(j)*ve(i,j-1,2)+(1.-edge_vect_e(j))*ve(i,j,2)
3492 vt3(j) = edge_vect_e(j)*ve(i,j-1,3)+(1.-edge_vect_e(j))*ve(i,j,3)
3494 vt1(j) = edge_vect_e(j)*ve(i,j+1,1)+(1.-edge_vect_e(j))*ve(i,j,1)
3495 vt2(j) = edge_vect_e(j)*ve(i,j+1,2)+(1.-edge_vect_e(j))*ve(i,j,2)
3496 vt3(j) = edge_vect_e(j)*ve(i,j+1,3)+(1.-edge_vect_e(j))*ve(i,j,3)
3506 if ( js==1 .and. .not. gridstruct%bounded_domain)
then 3510 ut1(i) = edge_vect_s(i)*ue(i-1,j,1)+(1.-edge_vect_s(i))*ue(i,j,1)
3511 ut2(i) = edge_vect_s(i)*ue(i-1,j,2)+(1.-edge_vect_s(i))*ue(i,j,2)
3512 ut3(i) = edge_vect_s(i)*ue(i-1,j,3)+(1.-edge_vect_s(i))*ue(i,j,3)
3514 ut1(i) = edge_vect_s(i)*ue(i+1,j,1)+(1.-edge_vect_s(i))*ue(i,j,1)
3515 ut2(i) = edge_vect_s(i)*ue(i+1,j,2)+(1.-edge_vect_s(i))*ue(i,j,2)
3516 ut3(i) = edge_vect_s(i)*ue(i+1,j,3)+(1.-edge_vect_s(i))*ue(i,j,3)
3525 if ( (je+1)==npy .and. .not. gridstruct%bounded_domain)
then 3529 ut1(i) = edge_vect_n(i)*ue(i-1,j,1)+(1.-edge_vect_n(i))*ue(i,j,1)
3530 ut2(i) = edge_vect_n(i)*ue(i-1,j,2)+(1.-edge_vect_n(i))*ue(i,j,2)
3531 ut3(i) = edge_vect_n(i)*ue(i-1,j,3)+(1.-edge_vect_n(i))*ue(i,j,3)
3533 ut1(i) = edge_vect_n(i)*ue(i+1,j,1)+(1.-edge_vect_n(i))*ue(i,j,1)
3534 ut2(i) = edge_vect_n(i)*ue(i+1,j,2)+(1.-edge_vect_n(i))*ue(i,j,2)
3535 ut3(i) = edge_vect_n(i)*ue(i+1,j,3)+(1.-edge_vect_n(i))*ue(i,j,3)
3546 u(i,j,k) = u(i,j,k) + dt5*( ue(i,j,1)*es(1,i,j,1) + &
3547 ue(i,j,2)*es(2,i,j,1) + &
3548 ue(i,j,3)*es(3,i,j,1) )
3553 v(i,j,k) = v(i,j,k) + dt5*( ve(i,j,1)*ew(1,i,j,2) + &
3554 ve(i,j,2)*ew(2,i,j,2) + &
3555 ve(i,j,3)*ew(3,i,j,2) )
3568 subroutine update2d_dwinds_phys(is, ie, js, je, isd, ied, jsd, jed, dt, u_dt, v_dt, u, v, gridstruct, npx, npy, npz, domain)
3572 integer,
intent(in):: is, ie, js, je
3573 integer,
intent(in):: isd, ied, jsd, jed
3574 real,
intent(in):: dt
3575 real,
intent(inout):: u(isd:ied, jsd:jed+1,npz)
3576 real,
intent(inout):: v(isd:ied+1,jsd:jed ,npz)
3577 real,
intent(inout),
dimension(isd:ied,jsd:jed,npz):: u_dt, v_dt
3579 integer,
intent(IN) :: npx,npy, npz
3580 type(domain2d),
intent(INOUT) :: domain
3583 real ut(isd:ied,jsd:jed)
3587 real(kind=R_GRID),
pointer,
dimension(:,:,:) :: vlon, vlat
3588 real(kind=R_GRID),
pointer,
dimension(:,:,:,:) :: es, ew
3589 real(kind=R_GRID),
pointer,
dimension(:) :: edge_vect_w, edge_vect_e, edge_vect_s, edge_vect_n
3590 real,
pointer,
dimension(:,:) :: z11, z12, z21, z22, dya, dxa
3594 vlon => gridstruct%vlon
3595 vlat => gridstruct%vlat
3597 edge_vect_w => gridstruct%edge_vect_w
3598 edge_vect_e => gridstruct%edge_vect_e
3599 edge_vect_s => gridstruct%edge_vect_s
3600 edge_vect_n => gridstruct%edge_vect_n
3602 z11 => gridstruct%z11
3603 z21 => gridstruct%z21
3604 z12 => gridstruct%z12
3605 z22 => gridstruct%z22
3607 dxa => gridstruct%dxa
3608 dya => gridstruct%dya
3617 ut(i,j) = z11(i,j)*u_dt(i,j,k) + z12(i,j)*v_dt(i,j,k)
3618 v_dt(i,j,k) = z21(i,j)*u_dt(i,j,k) + z22(i,j)*v_dt(i,j,k)
3619 u_dt(i,j,k) = ut(i,j)
3625 call mpp_update_domains(u_dt, v_dt, domain, gridtype=agrid_param)
3635 if ( gridstruct%grid_type > 3 .or. gridstruct%bounded_domain)
then 3639 u(i,j,k) = u(i,j,k) + dt5*(u_dt(i,j-1,k) + u_dt(i,j,k))
3644 v(i,j,k) = v(i,j,k) + dt5*(v_dt(i-1,j,k) + v_dt(i,j,k))
3656 gratio = dya(i,2) / dya(i,1)
3657 u(i,1,k) = u(i,1,k) + dt5*((2.+gratio)*(u_dt(i,0,k)+u_dt(i,1,k)) &
3658 -(u_dt(i,-1,k)+u_dt(i,2,k)))/(1.+gratio)
3663 do j=max(2,js),min(npy-1,je+1)
3665 u(i,j,k) = u(i,j,k) + dt5*(u_dt(i,j-1,k)+u_dt(i,j,k))
3669 if ( (je+1)==npy )
then 3671 gratio = dya(i,npy-2) / dya(i,npy-1)
3672 u(i,npy,k) = u(i,npy,k) + dt5*((2.+gratio)*(u_dt(i,npy-1,k)+u_dt(i,npy,k)) &
3673 -(u_dt(i,npy-2,k)+u_dt(i,npy+1,k)))/(1.+gratio)
3683 gratio = dxa(2,j) / dxa(1,j)
3684 v(1,j,k) = v(1,j,k) + dt5*((2.+gratio)*(v_dt(0,j,k)+v_dt(1,j,k)) &
3685 -(v_dt(-1,j,k)+v_dt(2,j,k)))/(1.+gratio)
3691 do i=max(2,is),min(npx-1,ie+1)
3692 v(i,j,k) = v(i,j,k) + dt5*(v_dt(i-1,j,k)+v_dt(i,j,k))
3697 if ( (ie+1)==npx )
then 3699 gratio = dxa(npx-2,j) / dxa(npx-1,j)
3700 v(npx,j,k) = v(npx,j,k) + dt5*((2.+gratio)*(v_dt(npx-1,j,k)+v_dt(npx,j,k)) &
3701 -(v_dt(npx-2,j,k)+v_dt(npx+1,j,k)))/(1.+gratio)
3713 subroutine init_mq(phis, gridstruct, npx, npy, is, ie, js, je, ng)
3714 integer,
intent(in):: npx, npy, is, ie, js, je, ng
3715 real,
intent(in):: phis(is-ng:ie+ng, js-ng:je+ng)
3719 real zs(is-ng:ie+ng, js-ng:je+ng)
3720 real zb(is-ng:ie+ng, js-ng:je+ng)
3721 real pdx(3,is:ie,js:je+1)
3722 real pdy(3,is:ie+1,js:je)
3725 real,
pointer :: rarea(:,:)
3726 real,
pointer,
dimension(:,:) :: dx, dy
3727 real,
pointer,
dimension(:,:,:) :: en1, en2, agrid, vlon, vlat
3729 rarea => gridstruct%rarea
3732 en1 => gridstruct%en1
3733 en2 => gridstruct%en2
3734 agrid => gridstruct%agrid
3735 vlon => gridstruct%vlon
3736 vlat => gridstruct%vlat
3742 zs(i,j) = phis(i,j) / grav
3748 call a2b_ord4(zs, zb, gridstruct, npx, npy, is, ie, js, je, ng)
3753 pdx(n,i,j) = 0.5*(zb(i,j)+zb(i+1,j))*dx(i,j)*en1(n,i,j)
3760 pdy(n,i,j) = 0.5*(zb(i,j)+zb(i,j+1))*dy(i,j)*en2(n,i,j)
3768 idiag%zxg(i,j) = vlon(i,j,1)*(pdx(1,i,j+1)-pdx(1,i,j)-pdy(1,i,j)+pdy(1,i+1,j)) &
3769 + vlon(i,j,2)*(pdx(2,i,j+1)-pdx(2,i,j)-pdy(2,i,j)+pdy(2,i+1,j)) &
3770 + vlon(i,j,3)*(pdx(3,i,j+1)-pdx(3,i,j)-pdy(3,i,j)+pdy(3,i+1,j))
3773 idiag%zxg(i,j) = idiag%zxg(i,j)*rarea(i,j) *
radius*cos(agrid(i,j,2))
subroutine, public mid_pt_cart(p1, p2, e3)
subroutine, public cart_to_latlon(np, q, xs, ys)
subroutine elgs(a, n, indx)
The subroutine 'elgs' performs the partial-pivoting gaussian elimination.
subroutine global_mx_c(q, i1, i2, j1, j2, qmin, qmax)
The subroutine 'global_mx_c' computes the global max and min at the cell corners. ...
subroutine, public mid_pt_sphere(p1, p2, pm)
real(kind=r_grid) function, public cos_angle(p1, p2, p3)
subroutine init_cubed_to_latlon(gridstruct, hydrostatic, agrid, grid_type, ord, bd)
subroutine get_unit_vect3(p1, p2, uc)
real function, public global_qsum(p, ifirst, ilast, jfirst, jlast)
The function 'global_qsum' computes the quick global sum without area weighting.
subroutine efactor_a2c_v(edge_vect_s, edge_vect_n, edge_vect_w, edge_vect_e, non_ortho, grid, agrid, npx, npy, bounded_domain, bd)
The subroutine 'efactor_a2c_v' initializes interpolation factors at face edges for interpolating vect...
The module 'fv_mp_mod' is a single program multiple data (SPMD) parallel decompostion/communication m...
subroutine timing_off(blk_name)
The subroutine 'timing_off' stops a timer.
The type 'fv_grid_type' is made up of grid-dependent information from fv_grid_tools and fv_grid_utils...
real, parameter tiny_number
subroutine, public normalize_vect(e)
The subroutine 'normalize_vect' makes 'e' a unit vector.
subroutine init_mq(phis, gridstruct, npx, npy, is, ie, js, je, ng)
subroutine intersect_cross(a1, a2, b1, b2, radius, x_inter, local_a, local_b)
The subroutine 'intersect_cross' calculates the intersection of two great circles.
subroutine cell_center3(p1, p2, p3, p4, ec)
The subroutine 'cell_center3' gets the center position of a cell.
subroutine, public intp_great_circle(beta, p1, p2, x_o, y_o)
subroutine invert_matrix(n, a, x)
subroutine, public direct_transform(c, i1, i2, j1, j2, lon_p, lat_p, n, lon, lat)
The subroutine 'direct_transform' performs a direct transformation of the standard (symmetrical) cubi...
subroutine latlon2xyz2(lon, lat, p3)
real(kind=r_grid) function, public dist2side_latlon(v1, v2, point)
The function 'dist2side_latlon' is the version of 'dist2side' that takes points in latitude-longitude...
real(kind=r_grid) function, public spherical_angle(p1, p2, p3)
real function, public g_sum(domain, p, ifirst, ilast, jfirst, jlast, ngc, area, mode, reproduce)
The function 'g_sum' is the fast version of 'globalsum'.
real function, public inner_prod(v1, v2)
subroutine, public spherical_linear_interpolation(beta, p1, p2, pb)
The subroutine 'spherical_linear_interpolation' interpolates along the great circle connecting points...
subroutine, public get_latlon_vector(pp, elon, elat)
subroutine, public get_unit_vect2(e1, e2, uc)
subroutine gnomonic_angl(im, lamda, theta)
integer, parameter, public r_grid
subroutine, public make_eta_level(km, pe, area, kks, ak, bk, ptop, domain, bd)
The module 'fv_timing' contains FV3 timers.
subroutine, public unit_vect_latlon(pp, elon, elat)
subroutine mirror_latlon(lon1, lat1, lon2, lat2, lon0, lat0, lon3, lat3)
The subroutine 'mirror_latlon' computes the mirror image of (lon0, lat0) as (lon3, lat3) given the "mirror" as defined by (lon1, lat1), (lon2, lat2), and center of the sphere.
subroutine, public global_mx(q, n_g, qmin, qmax, bd)
real, parameter, public ptop_min
integer, parameter, public f_p
subroutine gnomonic_ed(im, lamda, theta)
The subroutine 'gnomonic_ed' computes the equal distances along the 4 edges of the cubed sphere...
logical, public symm_grid
subroutine symm_ed(im, lamda, theta)
subroutine, public cubed_to_latlon(u, v, ua, va, gridstruct, npx, npy, km, mode, grid_type, domain, bounded_domain, c2l_ord, bd)
The module 'fv_arrays' contains the 'fv_atmos_type' and associated datatypes.
real, parameter, public big_number
real function, public great_circle_dist(q1, q2, radius)
real(kind=r_grid) function, public get_area(p1, p4, p2, p3, radius)
subroutine gnomonic_ed_limited(im, in, nghost, lL, lR, uL, uR, lamda, theta)
The subroutine 'gnomonic_ed_limited' creates a limited-area equidistant gnomonic grid with corners gi...
subroutine, public cell_center2(q1, q2, q3, q4, e2)
subroutine, public set_eta(km, ks, ptop, ak, bk, npz_type)
The module 'fv_eta' contains routine to set up the reference (Eulerian) pressure coordinate.
real(kind=r_grid) function, public v_prod(v1, v2)
subroutine, public update_dwinds_phys(is, ie, js, je, isd, ied, jsd, jed, dt, u_dt, v_dt, u, v, gridstruct, npx, npy, npz, domain)
The subroutine 'update_dwinds_phys' transforms the wind tendencies from the A grid to the D grid for ...
subroutine, public grid_utils_init(Atm, npx, npy, npz, non_ortho, grid_type, c2l_order)
subroutine, public vect_cross(e, p1, p2)
The subroutine 'vect_cross performs cross products of 3D vectors: e = P1 X P2.
subroutine timing_on(blk_name)
The subroutine 'timing_on' starts a timer.
subroutine, public project_sphere_v(np, f, e)
subroutine, public c2l_ord2(u, v, ua, va, gridstruct, km, grid_type, bd, do_halo)
subroutine intersect(a1, a2, b1, b2, radius, x_inter, local_a, local_b)
The subroutine 'intersect' calculates the intersection of two great circles.
The module 'fv_grid_utils' contains routines for setting up and computing grid-related quantities...
real(kind=r_grid) function dist2side(v1, v2, point)
The function 'dist2side' calculates the shortest normalized distance on a sphere from point to straig...
subroutine check_local(x1, x2, local)
subroutine fill_ghost_r4(q, npx, npy, value, bd)
subroutine edge_factors(edge_s, edge_n, edge_w, edge_e, non_ortho, grid, agrid, npx, npy, bd)
The subroutine 'edge_factors' initializes interpolation factors at face edges for interpolation from ...
subroutine gnomonic_dist(im, lamda, theta)
subroutine mirror_xyz(p1, p2, p0, p)
The subroutine 'mirror_xyz' computes the mirror image of p0(x0, y0, z0) as p(x, y, z) given the "mirror" as defined by p1(x1, y1, z1), p2(x2, y2, z2), and the center of the sphere.
subroutine, public cube_transform(c, i1, i2, j1, j2, lon_p, lat_p, n, lon, lat)
subroutine fill_ghost_r8(q, npx, npy, value, bd)
subroutine get_center_vect(npx, npy, pp, u1, u2, bd)
subroutine, public grid_utils_end
subroutine, public expand_cell(q1, q2, q3, q4, a1, a2, a3, a4, fac)
subroutine, public gnomonic_grids(grid_type, im, lon, lat)
real(kind=r_grid) function great_circle_dist_cart(v1, v2, radius)
The function 'great_circle_dist_cart' calculates the normalized great circle distance between 'v1' an...
subroutine c2l_ord4(u, v, ua, va, gridstruct, npx, npy, km, grid_type, domain, bounded_domain, mode, bd)
subroutine mid_pt3_cart(p1, p2, e)
subroutine, public update2d_dwinds_phys(is, ie, js, je, isd, ied, jsd, jed, dt, u_dt, v_dt, u, v, gridstruct, npx, npy, npz, domain)
The subroutine 'update2d_dwinds_phys' transforms the wind tendencies.
subroutine, public latlon2xyz(p, e, id)
The subroutine 'latlon2xyz' maps (lon, lat) to (x,y,z)