Changeset 1575 for trunk/LMDZ.COMMON/libf/dynphy_lonlat/grid_atob_m.F90
- Timestamp:
- Jul 13, 2016, 4:29:03 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.COMMON/libf/dynphy_lonlat/grid_atob_m.F90
r1508 r1575 6 6 7 7 USE assert_eq_m, ONLY: assert_eq 8 REAL, SAVE :: pi, deg2rad9 8 10 9 PRIVATE … … 22 21 ! Arguments: 23 22 REAL, INTENT(IN) :: x_i(:), y_i(:) !-- INPUT X&Y COOR. (mi)(ni) 24 REAL, INTENT(IN) :: x_o(:), y_o(:) !-- OUTPUT X&Y COOR. (m i)(ni)23 REAL, INTENT(IN) :: x_o(:), y_o(:) !-- OUTPUT X&Y COOR. (mo)(no) 25 24 REAL, INTENT(OUT) :: d_o1(:,:) !-- OUTPUT FIELD (mo,no) 26 25 REAL, OPTIONAL, INTENT(IN) :: d_i (:,:) !-- INPUT FIELD (mi,ni) 27 LOGICAL, OPTIONAL, INTENT(IN) :: msk (:,:) !-- MASK (m i,ni)26 LOGICAL, OPTIONAL, INTENT(IN) :: msk (:,:) !-- MASK (mo,no) 28 27 REAL, OPTIONAL, INTENT(OUT) :: d_o2(:,:) !-- OUTPUT FOR d_i^2 (mo,no) 29 28 !------------------------------------------------------------------------------- 30 29 ! Local variables: 31 30 CHARACTER(LEN=256) :: modname="fine2coarse" 32 INTEGER :: mi, ni, ii, ji, mo, no, io, jo, nr(2), m1, n1, m2, n2, nn 33 INTEGER :: num_tot(SIZE(x_o),SIZE(y_o)) 34 LOGICAL :: found(SIZE(x_o),SIZE(y_o)), li 35 LOGICAL :: mask (SIZE(x_i),SIZE(y_i)), lo 36 REAL :: dist (SIZE(x_o),SIZE(y_o)) 37 REAL :: a(SIZE(x_o)), b(SIZE(x_o)), c(SIZE(y_o)), d(SIZE(y_o)), inc 38 REAL, PARAMETER :: thresh=1.E-5 39 !------------------------------------------------------------------------------- 40 mask(:,:)=.TRUE.; IF(PRESENT(msk)) mask(:,:)=msk(:,:) 41 mi=SIZE(x_i); m1=mi; ni=SIZE(y_i); n1=ni 42 mo=SIZE(x_o); m2=mo; no=SIZE(y_o); n2=no 31 INTEGER :: mi, ni, ii, ji, mo, no, io, jo, nr(2), m1,m2, n1,n2, mx,my, nn, i,j 32 LOGICAL :: li, lo, first=.TRUE. 33 REAL :: inc, cpa, spa, crlo(SIZE(x_i)) 34 REAL, SAVE :: pi, hpi 35 INTEGER, DIMENSION(SIZE(x_o),SIZE(y_o)) :: num_tot 36 LOGICAL, DIMENSION(SIZE(x_o),SIZE(y_o)) :: found, mask 37 REAL, DIMENSION(SIZE(x_i),SIZE(y_i)) :: dist 38 REAL, DIMENSION(SIZE(x_o)) :: a, b 39 REAL, DIMENSION(SIZE(y_o)) :: c, d 40 REAL, PARAMETER :: thresh=1.E-5 41 !------------------------------------------------------------------------------- 42 IF(first) THEN; pi=4.0*ATAN(1.0); hpi=pi/2.0; first=.FALSE.; END IF 43 mi=SIZE(x_i); ni=SIZE(y_i); mo=SIZE(x_o); no=SIZE(y_o) 44 m1=m1; m2=mo; mx=mo; IF(PRESENT(msk)) mx=SIZE(msk,1) 45 n1=ni; n2=no; my=no; IF(PRESENT(msk)) my=SIZE(msk,2) 43 46 li=PRESENT(d_i ); IF(li) THEN; m1=SIZE(d_i ,1); n1=SIZE(d_i ,2); END IF 44 47 lo=PRESENT(d_o2); IF(lo) THEN; m2=SIZE(d_o2,1); n2=SIZE(d_o2,2); END IF 45 mi=assert_eq(mi,m1,SIZE(mask,1),TRIM(modname)//" mi") 46 ni=assert_eq(ni,n1,SIZE(mask,2),TRIM(modname)//" ni") 47 mo=assert_eq(mo,m2,SIZE(d_o1,1),TRIM(modname)//" mo") 48 no=assert_eq(no,n2,SIZE(d_o1,2),TRIM(modname)//" no") 48 mi=assert_eq(mi,m1,TRIM(modname)//" mi") 49 ni=assert_eq(ni,n1,TRIM(modname)//" ni") 50 mo=assert_eq(mo,m2,mx,SIZE(d_o1,1),TRIM(modname)//" mo") 51 no=assert_eq(no,n2,my,SIZE(d_o1,2),TRIM(modname)//" no") 52 mask(:,:)=.TRUE.; IF(PRESENT(msk)) mask(:,:)=msk(:,:) 49 53 50 54 !--- COMPUTE CELLS INTERFACES COORDINATES OF OUTPUT GRID … … 67 71 (x_i(ii)-a(io)>thresh.OR.x_i(ii)-b(io)<thresh)) CYCLE 68 72 num_tot(io,jo)=num_tot(io,jo)+1 69 IF(mask(i i,ji)) d_o1(io,jo)=d_o1(io,jo)+inc73 IF(mask(io,jo)) d_o1(io,jo)=d_o1(io,jo)+inc 70 74 IF(.NOT.lo) CYCLE 71 IF(mask(i i,ji)) d_o2(io,jo)=d_o2(io,jo)+inc*inc75 IF(mask(io,jo)) d_o2(io,jo)=d_o2(io,jo)+inc*inc 72 76 END DO 73 77 END DO … … 89 93 IF(found(io,jo)) CYCLE 90 94 ! IF(prt_level>=1) PRINT*, "Problem: point out of domain (i,j)=", io,jo 91 CALL dist_sphe(x_o(io),y_o(jo),x_i,y_i,dist(:,:)) 95 crlo(:)=COS(x_o(io)-x_i(:)) !--- COS of points 1 and 2 angle 96 cpa=COS(y_o(jo)); spa=SIN(y_o(jo)) 97 DO j=1,ni; dist(:,j)=ACOS(spa*SIN(y_i(j))+cpa*COS(y_i(j))*crlo(:)); END DO 92 98 nr=MINLOC(dist(:,:))!; IF(prt_level>=1) PRINT*, "Solution: ", nr 93 99 inc=1.0; IF(li) inc=d_i(nr(1),nr(2)) 94 IF(mask( nr(1),nr(2))) d_o1(io,jo)=inc100 IF(mask(io,jo)) d_o1(io,jo)=inc 95 101 END DO 96 102 END DO … … 250 256 !------------------------------------------------------------------------------- 251 257 252 253 !-------------------------------------------------------------------------------254 !255 SUBROUTINE dist_sphe(rf_lon,rf_lat,rlon,rlat,distance)256 !257 !-------------------------------------------------------------------------------258 ! Author: Laurent Li (december 30th 1996).259 ! Purpose: Compute min. distance (along big circle) between 2 points in degrees.260 !-------------------------------------------------------------------------------261 IMPLICIT NONE262 !-------------------------------------------------------------------------------263 ! Arguments:264 REAL, INTENT(IN) :: rf_lon, rf_lat !--- Reference point coordinates (degrees)265 REAL, INTENT(IN) :: rlon(:), rlat(:)!--- Points longitudes/latitudes (degrees)266 REAL, INTENT(OUT):: distance(SIZE(rlon),SIZE(rlat)) !--- Distance (degrees)267 !-------------------------------------------------------------------------------268 ! Local variables:269 LOGICAL, SAVE :: first=.TRUE.270 REAL :: pa, pb, cpa, cpab, spa, spab, crlo(SIZE(rlon))271 INTEGER :: i, j272 !-------------------------------------------------------------------------------273 IF(first) THEN274 pi=4.0*ATAN(1.0); deg2rad=pi/180.0; first=.FALSE.275 END IF276 crlo(:)=COS((rf_lon-rlon(:))*deg2rad) !--- COS of points 1 and 2 angle277 pa=(90.0-rf_lat)*deg2rad !--- North Pole - Point 1 distance278 cpa=COS(pa); spa=SIN(pa)279 DO j=1,SIZE(rlat)280 pb=(90.0-rlat(j))*deg2rad !--- North Pole - Point 2 distance281 cpab=cpa*COS(pb); spab=spa*SIN(pb)282 distance(:,j)=ACOS(cpab+spab*crlo(:))/deg2rad283 END DO284 285 END SUBROUTINE dist_sphe286 !287 !-------------------------------------------------------------------------------288 289 258 END MODULE grid_atob_m 290 259 !
Note: See TracChangeset
for help on using the changeset viewer.