New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
Changeset 3849 for branches/2011/DEV_r2739_STFC_dCSE/NEMOGCM/NEMO/OPA_SRC/LBC/partition_mod.F90 – NEMO

Ignore:
Timestamp:
2013-03-26T11:45:16+01:00 (11 years ago)
Author:
trackstand2
Message:

Merge branch 'partitioner'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2011/DEV_r2739_STFC_dCSE/NEMOGCM/NEMO/OPA_SRC/LBC/partition_mod.F90

    r3837 r3849  
    11MODULE partition_mod 
    2    USE par_oce, ONLY: jpni, jpnj, jpi, jpj, jpim1, jpjm1, jpij, & 
     2   USE par_oce, ONLY: jpni, jpnj, jpnij, jpi, jpj, jpim1, jpjm1, jpij, & 
    33                      jpreci, jprecj, jpk, jpkm1, jperio, jpiglo, jpjglo 
    44   USE dom_oce, ONLY: ln_zco, nbondi, nbondj, nidom, npolj, & 
     
    1818   USE lib_mpp,        ONLY: mppsize, mppsync, mpi_comm_opa,                & 
    1919                             MAX_FACTORS, xfactors, yfactors, nn_pttrim,    & 
    20                              nn_cpnode 
     20                             nn_cpnode, nn_readpart 
    2121#endif 
    2222   USE lib_mpp,        ONLY: ctl_stop, ctl_warn 
     
    3434                                                 ! (1 for ocean, 0 for land) 
    3535                                                 ! set in nemogcm.F90 
    36    INTEGER, SAVE, ALLOCATABLE, DIMENSION(:,:), TARGET :: ibotlevel ! Holds the bottom level of the ocean at each grid point - used for trimming halos in z direction 
     36   ! Holds the bottom level of the ocean at each grid point - used for  
     37   ! trimming halos in z direction 
     38   INTEGER, SAVE, ALLOCATABLE, DIMENSION(:,:), TARGET :: ibotlevel  
    3739 
    3840   ! Parameters for the cost function used when evaluating different  
     
    7577   PUBLIC imask, ibotlevel, smooth_global_bathy, global_bot_level, partition_mask_alloc 
    7678   PUBLIC mpp_init3, partition_rk, partition_mca_rk, write_partition_map 
     79   PUBLIC read_partition, write_partition 
    7780 
    7881CONTAINS 
     
    292295      CALL mpp_init_ioipsl() 
    293296 
     297      ! Write this partition to file in the format that the code can 
     298      ! read 
     299      CALL write_partition() 
     300 
    294301      ! ARPDBG - test comms setup 
    295302      CALL mpp_test_comms(imask, ibotlevel) 
     
    396403#if defined key_mpp_mpi 
    397404 
    398       ! IMPORTANT: Set the number of PEs to partition over (mapcomm_mod  
    399       ! module variable) 
    400       nprocp = mppsize 
    401  
    402405#if defined PARTIT_DEBUG 
    403406      IF(lwp)WRITE(*,*) 'ARPDBG partition_rk: jpn{i,j} = ',jpni,jpnj 
     
    478481       ! set that here 
    479482       myinst = narea - 1 
    480  
    481        ! IMPORTANT: set the number of PEs to partition over (mapcomm_mod  
    482        ! module variable) 
    483        nprocp = mppsize 
    484483 
    485484       ! Factorise the total number of MPI processes that we have 
     
    682681      jpni = nprocx 
    683682      jpnj = nprocy 
     683      jpnij = jpni*jpnj 
    684684 
    685685      IF (lwp) THEN 
     
    13881388 
    13891389 
    1390    SUBROUTINE finish_partition() 
    1391       USE mapcomm_mod, ONLY: ielb,ieub,pielb,pjelb,pieub,pjeub, & 
    1392                              iesub,jesub,jeub,ilbext,iubext,jubext, & 
     1390   SUBROUTINE finish_partition(fromFile) 
     1391      USE mapcomm_mod, ONLY: ielb,ieub,pielb,pjelb,pieub,pjeub,          & 
     1392                             iesub,jesub,jeub,ilbext,iubext,jubext,      & 
    13931393                             jlbext,pnactive,piesub,pjesub,jelb,pilbext, & 
    1394                              piubext, pjlbext, pjubext, & 
     1394                             piubext, pjlbext, pjubext,                  & 
    13951395                             trimmed, nidx,eidx,sidx,widx 
    13961396      IMPLICIT NONE 
     1397      LOGICAL, INTENT(in), OPTIONAL :: fromFile 
     1398      ! Locals 
    13971399      INTEGER :: iproc, ierr 
    1398  
    1399       ! Set the external boundary flags before boundaries are 
    1400       ! altered by the trimming process and it becomes more difficult 
    1401       ! to recognize which were the external boundaries. 
     1400      LOGICAL :: lFromFile 
     1401 
     1402      ! Check to see whether we're dealing with a partion that has been 
     1403      ! read from file. If we are then there are some things we don't 
     1404      ! calculate here. 
     1405      lFromFile = .FALSE. 
     1406      IF( PRESENT(fromFile) ) lFromFile = fromFile 
     1407 
     1408      IF(.NOT. lFromFile)THEN 
     1409         ! Set the external boundary flags before boundaries are 
     1410         ! altered by the trimming process and it becomes more difficult 
     1411         ! to recognize which were the external boundaries. 
    14021412       
    1403       DO iproc=1, nprocp, 1 
    1404            pilbext(iproc) = pielb(iproc).EQ.1 
    1405            piubext(iproc) = pieub(iproc).EQ.jpiglo 
    1406            pjlbext(iproc) = pjelb(iproc).EQ.1 
    1407            pjubext(iproc) = pjeub(iproc).EQ.jpjglo 
    1408         ENDDO 
    1409  
    1410       ! Trim off redundant rows and columns containing all land. 
    1411         IF(.NOT. ALLOCATED(trimmed) )THEN 
    1412            ALLOCATE(trimmed(4,nprocp), Stat=ierr) 
    1413            IF(ierr /= 0)THEN 
    1414               CALL ctl_stop('STOP',    & 
    1415                             'Failed to allocate memory for domain trimming') 
    1416            END IF 
    1417         END IF 
     1413         DO iproc=1, nprocp, 1 
     1414            pilbext(iproc) = pielb(iproc).EQ.1 
     1415            piubext(iproc) = pieub(iproc).EQ.jpiglo 
     1416            pjlbext(iproc) = pjelb(iproc).EQ.1 
     1417            pjubext(iproc) = pjeub(iproc).EQ.jpjglo 
     1418         ENDDO 
     1419 
     1420         ! Trim off redundant rows and columns containing all land. 
     1421         IF(.NOT. ALLOCATED(trimmed) )THEN 
     1422            ALLOCATE(trimmed(4,nprocp), Stat=ierr) 
     1423            IF(ierr /= 0)THEN 
     1424               CALL ctl_stop('STOP',    & 
     1425                             'Failed to allocate memory for domain trimming') 
     1426            END IF 
     1427         END IF 
    14181428 
    14191429#if defined key_mpp_mpi 
     
    14301440        ENDIF 
    14311441#else 
    1432         trimmed(1:4,1:nprocp) = .FALSE. 
    1433 #endif 
    1434  
    1435         ! Lower boundary (long.) of sub-domain, GLOBAL coords 
    1436         ! before correction for global halos 
    1437         nimpp = pielb(narea) 
    1438  
    1439         ! Is the domain on an external LONGITUDE boundary? 
    1440         nbondi = 0 
    1441         ilbext = pilbext(narea) 
    1442         IF(ilbext)THEN 
    1443            nbondi = -1 
    1444         END IF 
    1445  
    1446         IF( (.NOT. ilbext) .OR. (ilbext .AND. trimmed(widx,narea)) )THEN 
    1447            ! It isn't, which means we must shift its lower boundary by 
    1448            ! -jpreci to allow for the overlap of this domain with its 
    1449            ! westerly neighbour. 
    1450            nimpp = nimpp - jpreci 
    1451         END IF 
    1452  
    1453         iubext = piubext(narea) 
    1454         IF(iubext)THEN 
    1455            nbondi = 1 
    1456            IF(ilbext)nbondi = 2 ! Both East and West boundaries are at  
    1457                                 ! edges of global domain 
    1458         END IF 
    1459  
    1460         ! Set local values for limits in global coords of the sub-domain  
    1461         ! owned by this process. 
    1462         ielb   = pielb (narea) 
    1463         ieub   = pieub (narea) 
    1464         iesub  = piesub(narea) 
    1465  
    1466         jpi  = iesub + 2*jpreci ! jpi is the same for all domains - this is 
    1467                                 ! what original decomposition did 
    1468         nlci = jpi 
    1469  
    1470         ! If the domain is at the edge of the model domain and a cyclic  
    1471         ! East-West b.c. is in effect then it already incorporates one  
    1472         ! extra halo column (because of the way the model domain itself is 
    1473         ! set-up). If we've trimmed-off dry rows and columns then, even if 
    1474         ! a domain is on the model boundary, it may still need a halo so 
    1475         ! we add one. 
    1476         IF( nbondi == -1 .AND. (.NOT. trimmed(widx,narea))  )THEN 
     1442         trimmed(1:4,1:nprocp) = .FALSE. 
     1443#endif 
     1444      END IF ! not read from file 
     1445 
     1446      ! Lower boundary (long.) of sub-domain, GLOBAL coords 
     1447      ! before correction for global halos 
     1448      nimpp = pielb(narea) 
     1449 
     1450      ! Is the domain on an external LONGITUDE boundary? 
     1451      nbondi = 0 
     1452      ilbext = pilbext(narea) 
     1453      IF(ilbext)THEN 
     1454         nbondi = -1 
     1455      END IF 
     1456 
     1457      IF( (.NOT. ilbext) .OR. (ilbext .AND. trimmed(widx,narea)) )THEN 
     1458         ! It isn't, which means we must shift its lower boundary by 
     1459         ! -jpreci to allow for the overlap of this domain with its 
     1460         ! westerly neighbour. 
     1461         nimpp = nimpp - jpreci 
     1462      END IF 
     1463 
     1464      iubext = piubext(narea) 
     1465      IF(iubext)THEN 
     1466         nbondi = 1 
     1467         IF(ilbext)nbondi = 2 ! Both East and West boundaries are at  
     1468                              ! edges of global domain 
     1469      END IF 
     1470 
     1471      ! Set local values for limits in global coords of the sub-domain  
     1472      ! owned by this process. 
     1473      ielb   = pielb (narea) 
     1474      ieub   = pieub (narea) 
     1475      iesub  = piesub(narea) 
     1476 
     1477      jpi  = iesub + 2*jpreci ! jpi is the same for all domains - this is 
     1478                              ! what original decomposition did 
     1479      nlci = jpi 
     1480 
     1481      ! If the domain is at the edge of the model domain and a cyclic  
     1482      ! East-West b.c. is in effect then it already incorporates one  
     1483      ! extra halo column (because of the way the model domain itself is 
     1484      ! set-up). If we've trimmed-off dry rows and columns then, even if 
     1485      ! a domain is on the model boundary, it may still need a halo so 
     1486      ! we add one. 
     1487      IF( nbondi == -1 .AND. (.NOT. trimmed(widx,narea))  )THEN 
    14771488           ! Western boundary 
    14781489           ! First column of global domain is actually a halo but NEMO 
     
    15471558        nlcj = jpj 
    15481559 
    1549 ! Unlike the East-West boundaries, the global domain does not include 
    1550 ! halo (rows) at the Northern and Southern edges. In fact, there is no 
    1551 ! cyclic boundary condition in the North-South direction so there are no 
    1552 ! halos at all at the edges of the global domain. 
     1560      ! Unlike the East-West boundaries, the global domain does not include 
     1561      ! halo (rows) at the Northern and Southern edges. In fact, there is no 
     1562      ! cyclic boundary condition in the North-South direction so there are no 
     1563      ! halos at all at the edges of the global domain. 
    15531564      IF( nbondj == -1 .AND. (.NOT. trimmed(sidx,narea)) )THEN 
    15541565         ! Southern edge 
     
    27722783    END SUBROUTINE global_bot_level 
    27732784 
     2785 
     2786    SUBROUTINE read_partition(ierr) 
     2787      USE par_oce, ONLY: jpni, jpnj, jpnij 
     2788      USE mapcomm_mod, ONLY: eidx, widx, sidx, nidx, trimmed, & 
     2789                             pilbext, piubext, pjlbext, pjubext 
     2790      IMPLICIT none 
     2791      INTEGER, INTENT(out) :: ierr 
     2792      ! Locals 
     2793      INTEGER, PARAMETER :: funit = 1099 
     2794      INTEGER :: idom, ndom 
     2795      CHARACTER(len=200) :: linein 
     2796      !====================================================================== 
     2797 
     2798      ierr = 0 
     2799 
     2800      OPEN(UNIT=funit, file='partition.dat', status='OLD', & 
     2801           ACTION='READ', IOSTAT=ierr) 
     2802      IF(ierr /= 0)THEN 
     2803         CALL ctl_warn('read_partition: failed to read partitioning from file - will calculate it instead.') 
     2804         RETURN 
     2805      END IF 
     2806 
     2807      ! Number of procs in x and y 
     2808      CALL read_next_line(funit, linein, ierr) 
     2809      READ(linein,FMT=*) jpni, jpnj 
     2810 
     2811      ! Store their product 
     2812      jpnij = jpni*jpnj 
     2813 
     2814      ! Check that the implied number of PEs matches that 
     2815      ! in our MPI world 
     2816      ndom = jpni*jpnj 
     2817      IF(ndom /= mppsize)THEN 
     2818         CALL ctl_stop('STOP', & 
     2819                       'read_partition: no. of PEs specified in partition.dat does not match no. of PEs in use by this job.') 
     2820      END IF 
     2821 
     2822      ! Read the description of each sub-domain 
     2823      domains: DO idom = 1, ndom, 1 
     2824 
     2825         ! Coordinates of bottom-left (SW) corner of domain 
     2826         CALL read_next_line(funit, linein, ierr) 
     2827         READ(linein,FMT=*) pielb(idom), pjelb(idom) 
     2828         ! Top-right (NE) corner 
     2829         CALL read_next_line(funit, linein, ierr) 
     2830         READ(linein,FMT=*) pieub(idom), pjeub(idom) 
     2831         ! Whether this domain has external boundaries and has been trimmed 
     2832         CALL read_next_line(funit, linein, ierr) 
     2833         READ(linein,FMT=*) pilbext(idom), trimmed(widx,idom) 
     2834         CALL read_next_line(funit, linein, ierr) 
     2835         READ(linein,FMT=*) piubext(idom), trimmed(eidx,idom) 
     2836         CALL read_next_line(funit, linein, ierr) 
     2837         READ(linein,FMT=*) pjlbext(idom), trimmed(sidx,idom) 
     2838         CALL read_next_line(funit, linein, ierr) 
     2839         READ(linein,FMT=*) pjubext(idom), trimmed(nidx,idom) 
     2840 
     2841         piesub(idom) = pieub(idom) - pielb(idom) + 1 
     2842         pjesub(idom) = pjeub(idom) - pjelb(idom) + 1 
     2843 
     2844      END DO domains 
     2845 
     2846      ! All done - close the file 
     2847      CLOSE(UNIT=funit) 
     2848 
     2849      CALL finish_partition(fromFile=.TRUE.) 
     2850 
     2851    END SUBROUTINE read_partition 
     2852 
     2853    !=================================================================== 
     2854 
     2855    SUBROUTINE write_partition 
     2856      USE par_oce, ONLY: jpni, jpnj 
     2857      USE mapcomm_mod, ONLY: eidx, widx, sidx, nidx, trimmed,    & 
     2858                             pjubext, pjlbext, piubext, pilbext, & 
     2859                             pielb, pieub, pjelb, pjeub 
     2860      IMPLICIT none 
     2861      INTEGER, PARAMETER :: funit = 1099 
     2862      INTEGER :: ierr 
     2863      INTEGER :: idom 
     2864 
     2865      ! Only PE 0 (narea==1) writes this file 
     2866      IF(narea /= 1) RETURN 
     2867 
     2868      OPEN(UNIT=funit, file='partition.dat.new', status='REPLACE', & 
     2869           ACTION='WRITE', IOSTAT=ierr) 
     2870      IF(ierr /= 0)THEN 
     2871         CALL ctl_warn('write_partition: failed to write partition description to file.') 
     2872         RETURN 
     2873      END IF 
     2874      WRITE(UNIT=funit,FMT="('#  jpni  jpnj')") 
     2875      WRITE(UNIT=funit,FMT="(I5,1x,I5)") jpni, jpnj 
     2876 
     2877      DO idom = 1, mppsize, 1 
     2878         WRITE(UNIT=funit,FMT="('# Domain: ',I5)") idom 
     2879         IF(idom==1)WRITE(UNIT=funit,FMT="('# Lower bounds: x  y')") 
     2880         WRITE(UNIT=funit,FMT="(I5,1x,I5)") pielb(idom), pjelb(idom) 
     2881         IF(idom==1)WRITE(UNIT=funit,FMT="('# Upper bounds: x  y')") 
     2882         WRITE(UNIT=funit,FMT="(I5,1x,I5)") pieub(idom), pjeub(idom) 
     2883         IF(idom==1)WRITE(UNIT=funit,FMT="('# x: Lower bound external, trimmed')") 
     2884         WRITE(UNIT=funit,FMT="(L5,1x,L5)") pilbext(idom), trimmed(widx,idom) 
     2885         IF(idom==1)WRITE(UNIT=funit,FMT="('# x: Upper bound external, trimmed')") 
     2886         WRITE(UNIT=funit,FMT="(L5,1x,L5)") piubext(idom), trimmed(eidx,idom) 
     2887         IF(idom==1)WRITE(UNIT=funit,FMT="('# y: Lower bound external, trimmed')") 
     2888         WRITE(UNIT=funit,FMT="(L5,1x,L5)") pjlbext(idom), trimmed(sidx,idom) 
     2889         IF(idom==1)WRITE(UNIT=funit,FMT="('# y: Upper bound external, trimmed')") 
     2890         WRITE(UNIT=funit,FMT="(L5,1x,L5)") pjubext(idom), trimmed(nidx,idom) 
     2891      END DO 
     2892 
     2893      CLOSE(UNIT=funit) 
     2894 
     2895    END SUBROUTINE write_partition 
     2896 
     2897    SUBROUTINE read_next_line(funit, linein, ierr) 
     2898      IMPLICIT none 
     2899      !!------------------------------------------------------------------ 
     2900      INTEGER,            INTENT( in) :: funit  ! Unit no. to read 
     2901      CHARACTER(len=200), INTENT(out) :: linein ! String containing next 
     2902                                                ! non-comment line in file 
     2903      INTEGER,            INTENT(out) :: ierr   ! Error flag (0==OK) 
     2904      !!------------------------------------------------------------------ 
     2905 
     2906      ierr = 0 
     2907 
     2908      READ(UNIT=funit,FMT="(200A)") linein 
     2909 
     2910      ! Comment lines begin with '#'. Skip those plus any blank 
     2911      ! lines... 
     2912      DO WHILE( INDEX( TRIM(ADJUSTL(linein)),'#') /= 0 .OR. & 
     2913                LEN_TRIM(linein) == 0 ) 
     2914         READ(UNIT=funit,FMT="(200A)") linein    
     2915      END DO 
     2916 
     2917      WRITE(*,*)'returning linein >>'//linein//'<<' 
     2918 
     2919    END SUBROUTINE read_next_line 
     2920 
    27742921END MODULE partition_mod 
Note: See TracChangeset for help on using the changeset viewer.