Ignore:
Timestamp:
07/15/14 18:15:39 (10 years ago)
Author:
dubos
Message:

New dyn/phys interface - halo points not passed to physics any more (cleanup follows)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • codes/icosagcm/trunk/src/physics_interface.f90

    r196 r213  
    55  PRIVATE 
    66 
    7   TYPE :: physics_inout 
    8      ! Input 
     7  INTEGER :: nb_extra_physics_2D, nb_extra_physics_3D 
     8 
     9  TYPE t_physics_inout 
     10     ! Input, time-independent 
    911     INTEGER :: ngrid 
    1012     REAL(rstd) :: dt_phys 
    11      REAL(rstd), DIMENSION(:), POINTER :: lon, lat 
     13     REAL(rstd), DIMENSION(:), POINTER :: Ai, lon, lat, phis 
     14     ! Input, time-dependent 
    1215     REAL(rstd), DIMENSION(:,:), POINTER :: p, Temp, ulon, ulat 
    1316     REAL(rstd), DIMENSION(:,:,:), POINTER :: q 
     
    1821     REAL(rstd), DIMENSION(:,:), POINTER :: extra_2D 
    1922     REAL(rstd), DIMENSION(:,:,:), POINTER :: extra_3D 
    20   END TYPE physics_inout 
    21  
    22   PUBLIC :: physics_inout 
     23  END TYPE t_physics_inout 
     24 
     25!------------------------ (new interface) -------------------------- 
     26! physics_inout is used to exchange information with physics 
     27! Field ngrid is initialized by physics.f90/init_physics. Its other fields 
     28! must be defined by XX/init_physics (where XX =  e.g. physics_dcmip.f90)  
     29! by either pointing to internal data of the physics package 
     30! or by a specific allocation 
     31! size : (ngrid), (ngrid,llm) except p(ngrid,llm+1), (ngrid,llm,nqtot)  
     32 
     33  TYPE(t_physics_inout), SAVE :: physics_inout 
     34  
     35!------------------------ (new interface) -------------------------- 
     36! pack_info contains indices used by pack/unpack routines 
     37! to pack together the data of all the domains managed by the MPI process 
     38! It is initialized by physics.f90/init_physics  
     39  TYPE t_pack_info 
     40     INTEGER :: ngrid, & ! number of non-halo points in that domain 
     41          nseg ! number of segments (contigous parts) in that domain 
     42     ! size and start of each segment : ij domain index, k packed index 
     43     INTEGER, ALLOCATABLE :: n(:), ij(:), k(:) 
     44  END TYPE t_pack_info 
     45 
     46  TYPE(t_pack_info), ALLOCATABLE, SAVE :: pack_info(:) 
     47   
     48  INTERFACE pack_field 
     49     MODULE PROCEDURE pack_2D 
     50     MODULE PROCEDURE pack_3D 
     51     MODULE PROCEDURE pack_4D 
     52  END INTERFACE pack_field 
     53 
     54  INTERFACE unpack_field 
     55     MODULE PROCEDURE unpack_2D 
     56     MODULE PROCEDURE unpack_3D 
     57     MODULE PROCEDURE unpack_4D 
     58  END INTERFACE unpack_field 
     59 
     60  INTERFACE pack_domain 
     61     MODULE PROCEDURE pack_domain_2D 
     62     MODULE PROCEDURE pack_domain_3D 
     63     MODULE PROCEDURE pack_domain_4D 
     64  END INTERFACE pack_domain 
     65 
     66  INTERFACE unpack_domain 
     67     MODULE PROCEDURE unpack_domain_2D 
     68     MODULE PROCEDURE unpack_domain_3D 
     69     MODULE PROCEDURE unpack_domain_4D 
     70  END INTERFACE unpack_domain 
     71 
     72  PUBLIC :: nb_extra_physics_2D, nb_extra_physics_3D, & 
     73       t_physics_inout, physics_inout, & 
     74       t_pack_info, pack_info, init_pack_before, init_pack_after, & 
     75       pack_domain, pack_field, unpack_domain, unpack_field, & 
     76       garbage_3D 
     77 
     78CONTAINS 
     79   
     80    SUBROUTINE init_pack_before 
     81    USE icosa 
     82    IMPLICIT NONE 
     83    INTEGER :: ind, offset 
     84    !$OMP MASTER 
     85    offset=0 
     86    ALLOCATE(pack_info(ndomain)) 
     87    DO ind=1,ndomain 
     88       CALL swap_dimensions(ind) 
     89       CALL swap_geometry(ind) 
     90       CALL count_segments(domain(ind)%own, pack_info(ind)) 
     91       pack_info(ind)%k = pack_info(ind)%k + offset 
     92       offset = offset + pack_info(ind)%ngrid 
     93    END DO 
     94    physics_inout%ngrid = offset 
     95    !$OMP END MASTER 
     96    !$OMP BARRIER 
     97  END SUBROUTINE init_pack_before 
     98 
     99  SUBROUTINE count_segments(own, info) 
     100    USE icosa 
     101    IMPLICIT NONE 
     102    LOGICAL, DIMENSION(:,:) :: own 
     103    TYPE(t_pack_info) :: info 
     104 
     105    INTEGER, DIMENSION(jjm) :: n 
     106    INTEGER :: ngrid, nseg, i, j, jj, k 
     107    INTEGER, PARAMETER :: method=4 
     108    SELECT CASE(method) 
     109    CASE(1) ! Copy all points, including halo (works) 
     110       info%nseg=1 
     111       info%ngrid=iim*jjm 
     112       ALLOCATE(info%n(1)) 
     113       ALLOCATE(info%ij(1)) 
     114       ALLOCATE(info%k(1)) 
     115       info%n(1)=iim*jjm 
     116       info%ij(1)=1 
     117       info%k(1)=1 
     118    CASE(2) ! Copy all points, including halo, one at a time (works, slow ?) 
     119       info%nseg=iim*jjm 
     120       info%ngrid=iim*jjm 
     121       ALLOCATE(info%n(iim*jjm)) 
     122       ALLOCATE(info%ij(iim*jjm)) 
     123       ALLOCATE(info%k(iim*jjm)) 
     124       DO jj=1,iim*jjm 
     125          info%n(jj) =1 
     126          info%ij(jj)=jj 
     127          info%k(jj) =jj 
     128       END DO 
     129    CASE(3) ! Copy non-halo points only, one at a time (works, slow ?) 
     130       n=COUNT(own,1) 
     131       ngrid=SUM(n) 
     132       info%ngrid=ngrid 
     133       info%nseg=ngrid 
     134       ALLOCATE(info%n(ngrid)) 
     135       ALLOCATE(info%ij(ngrid)) 
     136       ALLOCATE(info%k(ngrid)) 
     137       jj=1 
     138       DO j=1,jjm 
     139          DO i=1,iim 
     140             IF(own(i,j)) THEN 
     141                info%n(jj)=1 
     142                info%k(jj)=jj 
     143                info%ij(jj) = iim*(j-1)+i 
     144                jj=jj+1 
     145             END IF 
     146          END DO 
     147       END DO 
     148        
     149    CASE DEFAULT ! Copy non-halo points only, as contiguous segments (works) 
     150       n=0 
     151       n=COUNT(own,1) 
     152       ngrid=SUM(n) 
     153       info%ngrid=ngrid 
     154       nseg=COUNT(n>0) 
     155       info%nseg=nseg 
     156       ALLOCATE(info%n(nseg)) 
     157       ALLOCATE(info%ij(nseg)) 
     158       ALLOCATE(info%k(nseg)) 
     159 
     160       jj=1 
     161       k=1 
     162       DO j=1,jjm 
     163          IF(n(j)>0) THEN 
     164             ! find first .TRUE. value in own(:,j) 
     165             DO i=1,iim 
     166                IF(own(i,j)) THEN 
     167                   info%n(jj)=n(j) 
     168                   info%k(jj)=k 
     169                   info%ij(jj) = iim*(j-1)+i 
     170                   IF(COUNT(own(i:i+n(j)-1,j)) /= n(j)) STOP 
     171                   EXIT 
     172                END IF 
     173             END DO 
     174             k = k + n(j) 
     175             jj=jj+1 
     176          END IF 
     177       END DO 
     178 
     179       IF(k-1/=ngrid) THEN 
     180          PRINT *, 'Total number of grid points inconsistent', k-1, ngrid 
     181          STOP 
     182       END IF 
     183       IF(jj-1/=nseg) THEN 
     184          PRINT *, 'Number of segments inconsistent', jj-1, nseg 
     185          STOP 
     186       END IF 
     187 
     188    END SELECT 
     189     
     190    PRINT *, 'count_segments', info%nseg, info%ngrid, SUM(info%n), COUNT(own), iim*jjm 
     191  END SUBROUTINE count_segments 
     192 
     193  SUBROUTINE init_pack_after 
     194    USE icosa 
     195    IMPLICIT NONE 
     196    INTEGER :: ind, offset 
     197    DO ind=1,ndomain 
     198       IF (.NOT. assigned_domain(ind)) CYCLE 
     199       CALL swap_dimensions(ind) 
     200       CALL swap_geometry(ind) 
     201       CALL pack_domain_2D(pack_info(ind), Ai, physics_inout%Ai) 
     202       CALL pack_lonlat(pack_info(ind)) 
     203    END DO 
     204  END SUBROUTINE init_pack_after 
     205 
     206  SUBROUTINE pack_lonlat(info) 
     207    USE icosa 
     208    IMPLICIT NONE 
     209    TYPE(t_pack_info) :: info 
     210    REAL(rstd) :: lon(iim*jjm), lat(iim*jjm) 
     211    INTEGER :: ij 
     212    DO ij=1,iim*jjm 
     213       CALL xyz2lonlat(xyz_i(ij,:),lon(ij),lat(ij))  
     214    ENDDO 
     215    CALL pack_domain_2D(info, lon, physics_inout%lon) 
     216    CALL pack_domain_2D(info, lat, physics_inout%lat) 
     217  END SUBROUTINE pack_lonlat 
     218 
     219!-------------------------------- Pack / Unpack 2D --------------------------- 
     220 
     221  SUBROUTINE pack_2D(f_2D, packed) 
     222    USE icosa 
     223    IMPLICIT NONE 
     224    TYPE(t_field),POINTER :: f_2D(:) 
     225    REAL(rstd)            :: packed(:) 
     226    REAL(rstd), POINTER   :: loc(:) 
     227    INTEGER :: ind 
     228    DO ind=1,ndomain 
     229       IF (.NOT. assigned_domain(ind)) CYCLE 
     230       loc = f_2D(ind) 
     231       CALL pack_domain_2D(pack_info(ind), loc, packed) 
     232    END DO 
     233  END SUBROUTINE pack_2D 
     234 
     235  SUBROUTINE unpack_2D(f_2D, packed)  
     236    USE icosa 
     237    IMPLICIT NONE 
     238    TYPE(t_field),POINTER :: f_2D(:) 
     239    REAL(rstd)            :: packed(:) 
     240    REAL(rstd), POINTER   :: loc(:) 
     241    INTEGER :: ind 
     242    DO ind=1,ndomain 
     243       IF (.NOT. assigned_domain(ind)) CYCLE 
     244       loc = f_2D(ind) 
     245       CALL unpack_domain_2D(pack_info(ind), loc, packed) 
     246    END DO 
     247  END SUBROUTINE unpack_2D 
     248 
     249  SUBROUTINE pack_domain_2D(info, loc, glob) 
     250    USE icosa 
     251    IMPLICIT NONE 
     252    TYPE(t_pack_info) :: info 
     253    REAL(rstd), DIMENSION(:) :: loc, glob 
     254    INTEGER :: jj,n,k,ij 
     255    DO jj=1, info%nseg 
     256       n = info%n(jj)-1 
     257       ij = info%ij(jj) 
     258       k = info%k(jj) 
     259       glob(k:k+n) = loc(ij:ij+n) 
     260    END DO 
     261  END SUBROUTINE pack_domain_2D 
     262 
     263  SUBROUTINE unpack_domain_2D(info, loc, glob) 
     264    IMPLICIT NONE 
     265    TYPE(t_pack_info) :: info 
     266    REAL(rstd), DIMENSION(:) :: loc, glob 
     267    INTEGER :: jj,n,k,ij 
     268    DO jj=1, info%nseg 
     269       n = info%n(jj)-1 
     270       ij = info%ij(jj) 
     271       k = info%k(jj) 
     272       loc(ij:ij+n) = glob(k:k+n) 
     273    END DO 
     274  END SUBROUTINE unpack_domain_2D 
     275 
     276!-------------------------------- Pack / Unpack 3D --------------------------- 
     277 
     278  SUBROUTINE pack_3D(f_3D, packed) 
     279    USE icosa 
     280    IMPLICIT NONE 
     281    TYPE(t_field),POINTER :: f_3D(:) 
     282    REAL(rstd)            :: packed(:,:) 
     283    REAL(rstd), POINTER   :: loc(:,:) 
     284    INTEGER :: ind 
     285    DO ind=1,ndomain 
     286       IF (.NOT. assigned_domain(ind)) CYCLE 
     287       loc = f_3D(ind) 
     288       CALL pack_domain_3D(pack_info(ind), loc, packed) 
     289    END DO 
     290  END SUBROUTINE pack_3D 
     291 
     292  SUBROUTINE unpack_3D(f_3D, packed)  
     293    USE icosa 
     294    IMPLICIT NONE 
     295    TYPE(t_field),POINTER :: f_3D(:) 
     296    REAL(rstd)            :: packed(:,:) 
     297    REAL(rstd), POINTER   :: loc(:,:) 
     298    INTEGER :: ind 
     299    DO ind=1,ndomain 
     300       IF (.NOT. assigned_domain(ind)) CYCLE 
     301       loc = f_3D(ind) 
     302       CALL unpack_domain_3D(pack_info(ind), loc, packed) 
     303    END DO 
     304  END SUBROUTINE unpack_3D 
     305 
     306  SUBROUTINE pack_domain_3D(info, loc, glob) 
     307    IMPLICIT NONE 
     308    TYPE(t_pack_info) :: info 
     309    REAL(rstd), DIMENSION(:,:) :: loc, glob 
     310    INTEGER :: jj,n,k,ij 
     311    DO jj=1, info%nseg 
     312       n = info%n(jj)-1 
     313       ij = info%ij(jj) 
     314       k = info%k(jj) 
     315       glob(k:k+n,:) = loc(ij:ij+n,:) 
     316    END DO 
     317  END SUBROUTINE pack_domain_3D 
     318 
     319  SUBROUTINE unpack_domain_3D(info, loc, glob) 
     320    IMPLICIT NONE 
     321    TYPE(t_pack_info) :: info 
     322    REAL(rstd), DIMENSION(:,:) :: loc, glob 
     323    INTEGER :: jj,n,k,ij 
     324    DO jj=1, info%nseg 
     325       n = info%n(jj)-1 
     326       ij = info%ij(jj) 
     327       k = info%k(jj) 
     328       loc(ij:ij+n,:) = glob(k:k+n,:) 
     329    END DO     
     330  END SUBROUTINE unpack_domain_3D 
     331 
     332  SUBROUTINE garbage_3D(loc,own) 
     333    USE icosa 
     334    IMPLICIT NONE 
     335    LOGICAL :: own(iim,jjm) 
     336    REAL(rstd) :: loc(iim*jjm,llm) 
     337    INTEGER :: i,j,ij 
     338    ! write garbage in non-owned points 
     339    DO j=1,jjm 
     340       DO i=1,iim 
     341          IF(.NOT.own(i,j)) THEN 
     342             ij=iim*(j-1)+i 
     343             loc(ij,:)=-1e30 
     344          END IF 
     345       END DO 
     346    END DO    
     347  END SUBROUTINE garbage_3D 
     348 
     349!-------------------------------- Pack / Unpack 4D --------------------------- 
     350 
     351  SUBROUTINE pack_4D(f_4D, packed) 
     352    USE icosa 
     353    IMPLICIT NONE 
     354    TYPE(t_field),POINTER :: f_4D(:) 
     355    REAL(rstd)            :: packed(:,:,:) 
     356    REAL(rstd), POINTER   :: loc(:,:,:) 
     357    INTEGER :: ind 
     358    DO ind=1,ndomain 
     359       IF (.NOT. assigned_domain(ind)) CYCLE 
     360       loc = f_4D(ind) 
     361       CALL pack_domain_4D(pack_info(ind), loc, packed) 
     362    END DO 
     363  END SUBROUTINE pack_4D 
     364 
     365  SUBROUTINE unpack_4D(f_4D, packed)  
     366    USE icosa 
     367    IMPLICIT NONE 
     368    TYPE(t_field),POINTER :: f_4D(:) 
     369    REAL(rstd)            :: packed(:,:,:) 
     370    REAL(rstd), POINTER   :: loc(:,:,:) 
     371    INTEGER :: ind 
     372    DO ind=1,ndomain 
     373       IF (.NOT. assigned_domain(ind)) CYCLE 
     374       loc = f_4D(ind) 
     375       CALL unpack_domain_4D(pack_info(ind), loc, packed) 
     376    END DO 
     377  END SUBROUTINE unpack_4D 
     378 
     379  SUBROUTINE pack_domain_4D(info, loc, glob) 
     380    IMPLICIT NONE 
     381    TYPE(t_pack_info) :: info 
     382    REAL(rstd), DIMENSION(:,:,:) :: loc, glob 
     383    INTEGER :: jj,n,k,ij 
     384    DO jj=1, info%nseg 
     385       n = info%n(jj)-1 
     386       ij = info%ij(jj) 
     387       k = info%k(jj) 
     388       glob(k:k+n,:,:) = loc(ij:ij+n,:,:) 
     389    END DO 
     390  END SUBROUTINE pack_domain_4D 
     391 
     392  SUBROUTINE unpack_domain_4D(info, loc, glob) 
     393    IMPLICIT NONE 
     394    TYPE(t_pack_info) :: info 
     395    REAL(rstd), DIMENSION(:,:,:) :: loc, glob 
     396    INTEGER :: jj,n,k,ij 
     397    DO jj=1, info%nseg 
     398       n = info%n(jj)-1 
     399       ij = info%ij(jj) 
     400       k = info%k(jj) 
     401       loc(ij:ij+n,:,:) = glob(k:k+n,:,:) 
     402    END DO 
     403  END SUBROUTINE unpack_domain_4D 
    23404 
    24405END MODULE physics_interface_mod 
Note: See TracChangeset for help on using the changeset viewer.