Changeset 8736


Ignore:
Timestamp:
2024-11-28T16:29:18+01:00 (3 hours ago)
Author:
jan.polcher
Message:

Backporting of Cassini projection and other improvements of the curvilinear grids to ORCHIDEE2.2. The code in the Trunk remains the reference.

Location:
branches/ORCHIDEE_2_2/ORCHIDEE
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/ORCHIDEE_2_2/ORCHIDEE/src_driver/forcing_tools.f90

    r8606 r8736  
    36263626             CALL grid_tolola(i_orig+0.5, j_orig-0.5, corners_loc(i,j,2,1), corners_loc(i,j,2,2))  
    36273627             CALL grid_tolola(i_orig-0.5, j_orig-0.5, corners_loc(i,j,3,1), corners_loc(i,j,3,2))  
    3628              CALL grid_tolola(i_orig-0.5, j_orig-0.5, corners_loc(i,j,4,1), corners_loc(i,j,4,2))  
     3628             CALL grid_tolola(i_orig-0.5, j_orig+0.5, corners_loc(i,j,4,1), corners_loc(i,j,4,2))  
    36293629              
    36303630             coslat = MAX( COS(lat_glo(i_orig,j_orig) * pi/180. ), mincos )  
  • branches/ORCHIDEE_2_2/ORCHIDEE/src_global/grid.f90

    r8712 r8736  
    1  
     1!! 
    22!! This module define variables for the grid to gathered points. 
    33!! 
    4 !! @call sechiba_main 
    5 !! @Version : $Revision$, $Date$ 
    6 !!  
    7 !< $HeadURL$ 
    8 !< $Date$ 
    9 !< $Revision$ 
     4!! $HeadURL$ 
     5!! $Date$ 
     6!! $Revision$ 
    107!! 
    118!! @author Marie-Alice Foujols, Jan Polcher and Martial Mancip 
     
    3128  USE mod_orchidee_para_var 
    3229  USE mod_orchidee_transfert_para 
     30   
    3331  USE haversine 
    3432  USE module_llxy 
     
    117115  ! 
    118116  type (proj_info), SAVE, dimension(1:MAX_DOMAINS) :: proj_stack 
     117!$OMP THREADPRIVATE(proj_stack) 
    119118  ! 
    120119  real(r_std), SAVE, ALLOCATABLE, DIMENSION(:,:)   :: dxwrf, dywrf 
    121   ! 
     120!$OMP THREADPRIVATE(dxwrf, dywrf) 
     121  ! 
     122  ! Full projected grid. It is needed to replace the information in the grid file which could 
     123  ! have been computed with anotehr Earth radius 
     124  ! 
     125  REAL(r_std), ALLOCATABLE, DIMENSION (:,:), SAVE   :: lon_proj, lat_proj 
     126!$OMP THREADPRIVATE(lon_proj, lat_proj) 
    122127  ! 
    123128  INTERFACE grid_tolola 
     
    742747    REAL(r_std)                :: dx, dy, dtx, dty, coslat 
    743748    REAL(r_std), ALLOCATABLE, DIMENSION (:)    :: LON, LAT 
     749    REAL(r_std), ALLOCATABLE, DIMENSION (:,:)  :: LON_MAT, LAT_MAT 
    744750    REAL(r_std), ALLOCATABLE, DIMENSION (:,:)  :: mapfac_x, mapfac_y 
     751    REAL(r_std)                :: lon_test, lat_test, a, b 
     752    REAL(r_std)                :: maxerr=-10000000., minerr=10000000., d, xp, xg, yp, yg, zp, zg 
     753    LOGICAL                    :: checkgrid=.TRUE. 
    745754    ! 
    746755    ! 
     
    769778    iret = NF90_GET_ATT(fid, NF90_GLOBAL, "DX", user_dxkm) 
    770779    iret = NF90_GET_ATT(fid, NF90_GLOBAL, "DY", user_dykm) 
    771     ! 
    772780    user_dlat = user_dykm/(R_Earth * pi * 2.0 / 360.0) 
    773781    user_dlon = user_dxkm/(R_Earth * pi * 2.0 / 360.0) 
     
    775783    iret = NF90_GET_ATT(fid, NF90_GLOBAL, "POLE_LON", user_lon0) 
    776784    iret = NF90_GET_ATT(fid, NF90_GLOBAL, "POLE_LAT", user_lat0) 
    777  
    778      
     785    ! 
     786    ! Get one line or the full grid from file for test purposes 
     787    ! 
     788    iret = NF90_inq_VARID(fid, "XLONG_M",lonid) 
     789    iret = NF90_inq_VARID(fid, "XLAT_M",latid) 
     790    iret = NF90_INQUIRE_VARIABLE(fid, lonid, dimids = dimIDs) 
     791    iret = NF90_INQUIRE_DIMENSION(fid, dimIDs(1), len = numLons) 
     792    iret = NF90_INQUIRE_DIMENSION(fid, dimIDs(2), len = numLats) 
    779793    ! 
    780794    IF ( current_proj == PROJ_LATLON ) THEN 
    781795       ! 
    782        iret = NF90_inq_VARID(fid, "XLONG_M",lonid) 
    783        iret = NF90_INQUIRE_VARIABLE(fid, lonid, dimids = dimIDs) 
    784        iret = NF90_INQUIRE_DIMENSION(fid, dimIDs(1), len = numLons) 
    785        iret = NF90_INQUIRE_DIMENSION(fid, dimIDs(2), len = numLats) 
    786796       ALLOCATE(LON(numLons)) 
    787797       iret = NF90_GET_VAR(fid, lonid, LON(:), start = (/ 1, 1, 1 /), count = (/ numLons, 1, 1 /)) 
    788         
    789798       iret = NF90_inq_VARID(fid, "XLAT_M",latid) 
    790799       ALLOCATE(LAT(numLats)) 
    791800       iret = NF90_GET_VAR(fid, latid, LAT(:), start = (/ 1, 1, 1 /), count = (/ 1, numLats, 1 /)) 
    792         
    793801       user_dlon = (LON(numLons) - LON(1)) / (numLons - 1) 
    794802       user_dlat = (LAT(numLats) - LAT(1)) / (numLats - 1) 
    795         
    796        DEALLOCATE(LON,LAT) 
    797  
     803    ELSE 
     804       ! 
     805       ALLOCATE(LON_MAT(numLons,numLats)) 
     806       iret = NF90_GET_VAR(fid, lonid, LON_MAT) 
     807       ALLOCATE(LAT_MAT(numLons,numLats)) 
     808       iret = NF90_GET_VAR(fid, latid, LAT_MAT) 
    798809    ENDIF 
    799810    ! Unable to know from where to get the information 
     
    815826    ALLOCATE(dxwrf(iim,jjm)) 
    816827    ALLOCATE(dywrf(iim,jjm)) 
     828    ALLOCATE(lon_proj(iim,jjm)) 
     829    ALLOCATE(lat_proj(iim,jjm))  
    817830    ! 
    818831    varname = "MAPFAC_MX" 
     
    858871        
    859872    else if (current_proj == PROJ_CASSINI) then 
    860        CALL rotate_coords(user_known_lat, user_known_lon, proj_known_lat, & 
    861             proj_known_lon, user_lat0, user_lon0, user_stand_lon, -1) 
    862        CALL map_set(current_proj, proj_stack(idom), & 
    863             loninc=user_dlon, & 
    864             latinc=user_dlat, & 
    865             lat1=user_known_lat, & 
    866             lon1=user_known_lon, & 
    867             lat0=user_lat0 ,& 
    868             lon0=user_lon0 ,& 
    869             knowni=user_known_x, & 
    870             knownj=user_known_y, & 
    871             stdlon=user_stand_lon, & 
    872             r_earth=R_Earth) 
    873  
     873                   CALL map_set(current_proj, proj_stack(idom),      & 
     874            latinc   = user_dlon,                        & 
     875            loninc   = user_dlat,                        & 
     876            lat1     = user_known_lat,                   & 
     877            lon1     = user_known_lon,                   & 
     878            lat0     = user_lat0,                        & 
     879            lon0     = user_lon0,                        & 
     880            knowni   = user_known_x,                     & 
     881            knownj   = user_known_y,                     & 
     882            stdlon   = user_stand_lon) 
     883        
    874884    else if (current_proj == PROJ_LC) then 
    875885       call map_set(current_proj, proj_stack(idom), & 
     
    938948          ! 
    939949          IF (proj_stack(idom)%code /= PROJ_LATLON ) THEN 
    940              dx = proj_stack(idom)%dx 
    941              ! Some projections in WRF do not store dy, in that case dy=dx. 
    942              IF ( proj_stack(idom)%dy > 0 ) THEN 
    943                 dy = proj_stack(idom)%dy 
     950             IF ( proj_stack(idom)%dx > 0 ) THEN 
     951                dx = proj_stack(idom)%dx 
     952                ! Some projections in WRF do not store dy, in that case dy=dx. 
     953                IF ( proj_stack(idom)%dy > 0 ) THEN 
     954                   dy = proj_stack(idom)%dy 
     955                ELSE 
     956                   dy = proj_stack(idom)%dx 
     957                ENDIF 
    944958             ELSE 
    945                 dy = proj_stack(idom)%dx 
     959                dx = user_dxkm 
     960                dy = user_dykm 
    946961             ENDIF 
    947962             dxwrf(i,j) = dx/mapfac_x(i,j) 
     
    963978    ENDDO 
    964979    ! 
     980    ! Compute full projected grid 
     981    ! 
     982    DO i=1,iim 
     983       DO j=1,jjm 
     984          CALL grid_tolola(i*1.0, j*1.0, lon_proj(i,j), lat_proj(i,j)) 
     985       ENDDO 
     986    ENDDO 
     987    ! 
     988    ! verify projection 
     989    ! 
     990    IF ( checkgrid  .AND. current_proj .NE. PROJ_LATLON ) THEN 
     991       DO i=1,iim 
     992          DO j=1,jjm 
     993             d = haversine_distance(lon_proj(i,j), lat_proj(i,j), LON_MAT(i,j), LAT_MAT(i,j)) 
     994             minerr=MIN(abs(d),minerr) 
     995             maxerr=MAX(abs(d),maxerr) 
     996          ENDDO 
     997       ENDDO 
     998       WRITE(*,*) "grid_initproj : Coordinate error range ", minerr, " < [m] < ", maxerr 
     999       IF ( maxerr > 1000 ) THEN 
     1000          WRITE(*,*) "grid_initproj : The projected grid is different from the one found in grid.nc" 
     1001          WRITE(*,*) "grid_initproj : This can be explained by a difference in Earth radius :" 
     1002          WRITE(*,*) "grid_initproj : ORCHIDEE's Earth radius : ", R_Earth 
     1003          WRITE(*,*) "grid_initproj : WRF's Earth radius (for instance) : 6370000." 
     1004          !!           
     1005          !!  Assume that in this projection the central point of the grid 
     1006          !!  is only affected by the radius of the Earth 
     1007          !! 
     1008          i=INT(iim/2.) 
     1009          j=INT(jjm/2.) 
     1010          ! 
     1011          CALL grid_tolola(i*1.0, j*1.0, lon_test, lat_test) 
     1012          xp=COS(lat_test * pi/180.)*COS(lon_test * pi/180.) 
     1013          xg=COS(LAT_MAT(i,j) * pi/180.)*COS(LON_MAT(i,j) * pi/180.) 
     1014          yp=COS(lat_test * pi/180.)*SIN(lon_test * pi/180.) 
     1015          yg=COS(LAT_MAT(i,j) * pi/180.)*SIN(LON_MAT(i,j) * pi/180.) 
     1016          zp=SIN(lat_test * pi/180.) 
     1017          zg=SIN(LAT_MAT(i,j) * pi/180.) 
     1018          WRITE(*,*) "grid_initproj : Radius of grid file at mid-point : ", (R_Earth*xg/xp + R_Earth*yg/yp + R_Earth*zg/zp)/3. 
     1019          ! 
     1020       ENDIF 
     1021    ENDIF 
     1022    ! 
     1023    ! 
     1024    ! 
     1025    IF ( ALLOCATED(LON) ) DEALLOCATE(LON) 
     1026    IF ( ALLOCATED(LAT) ) DEALLOCATE(LAT) 
     1027    IF ( ALLOCATED(LON_MAT) ) DEALLOCATE(LON_MAT) 
     1028    IF ( ALLOCATED(LAT_MAT) ) DEALLOCATE(LAT_MAT) 
     1029    ! 
    9651030  END SUBROUTINE grid_initproj 
    9661031! 
Note: See TracChangeset for help on using the changeset viewer.