[532] | 1 | MODULE cpl_oasis3 |
---|
| 2 | !!====================================================================== |
---|
| 3 | !! *** MODULE cpl_oasis *** |
---|
| 4 | !! Coupled O/A : coupled ocean-atmosphere case using OASIS3 V. prism_2_4 |
---|
| 5 | !! special case: NEMO OPA/LIM coupled to ECHAM5 |
---|
| 6 | !!===================================================================== |
---|
| 7 | !! History : |
---|
[1281] | 8 | !! 9.0 ! 04-06 (R. Redler, NEC Laboratories Europe, St Augustin, Germany) Original code |
---|
| 9 | !! " " ! 04-11 (R. Redler, NEC Laboratories Europe; N. Keenlyside, W. Park, IFM-GEOMAR, Kiel, Germany) revision |
---|
[532] | 10 | !! " " ! 04-11 (V. Gayler, MPI M&D) Grid writing |
---|
| 11 | !! " " ! 05-08 (R. Redler, W. Park) frld initialization, paral(2) revision |
---|
| 12 | !! " " ! 05-09 (R. Redler) extended to allow for communication over root only |
---|
| 13 | !! " " ! 06-01 (W. Park) modification of physical part |
---|
| 14 | !! " " ! 06-02 (R. Redler, W. Park) buffer array fix for root exchange |
---|
| 15 | !!---------------------------------------------------------------------- |
---|
| 16 | #if defined key_oasis3 |
---|
| 17 | !!---------------------------------------------------------------------- |
---|
| 18 | !! 'key_oasis3' coupled Ocean/Atmosphere via OASIS3 |
---|
| 19 | !!---------------------------------------------------------------------- |
---|
| 20 | !!---------------------------------------------------------------------- |
---|
| 21 | !! cpl_prism_init : initialization of coupled mode communication |
---|
| 22 | !! cpl_prism_define : definition of grid and fields |
---|
[1218] | 23 | !! cpl_prism_snd : snd out fields in coupled mode |
---|
| 24 | !! cpl_prism_rcv : receive fields in coupled mode |
---|
[532] | 25 | !! cpl_prism_finalize : finalize the coupled mode communication |
---|
| 26 | !!---------------------------------------------------------------------- |
---|
[1218] | 27 | USE mod_prism_proto ! OASIS3 prism module |
---|
| 28 | USE mod_prism_def_partition_proto! OASIS3 prism module for partitioning |
---|
| 29 | USE mod_prism_put_proto ! OASIS3 prism module for snding |
---|
| 30 | USE mod_prism_get_proto ! OASIS3 prism module for receiving |
---|
| 31 | USE par_oce ! ocean parameters |
---|
[532] | 32 | USE dom_oce ! ocean space and time domain |
---|
| 33 | USE in_out_manager ! I/O manager |
---|
[1218] | 34 | USE lbclnk ! ocean lateral boundary conditions (or mpp link) |
---|
[532] | 35 | IMPLICIT NONE |
---|
[1218] | 36 | PRIVATE |
---|
[532] | 37 | ! |
---|
[1218] | 38 | LOGICAL, PUBLIC, PARAMETER :: lk_cpl = .TRUE. ! coupled flag |
---|
[1698] | 39 | INTEGER, PUBLIC :: OASIS_Rcv = 1 ! return code if received field |
---|
| 40 | INTEGER, PUBLIC :: OASIS_idle = 0 ! return code if nothing done by oasis |
---|
[1218] | 41 | INTEGER :: ncomp_id ! id returned by prism_init_comp |
---|
| 42 | INTEGER :: nerror ! return error code |
---|
[532] | 43 | |
---|
[1218] | 44 | INTEGER, PARAMETER :: nmaxfld=40 ! Maximum number of coupling fields |
---|
| 45 | |
---|
| 46 | TYPE, PUBLIC :: FLD_CPL ! Type for coupling field information |
---|
| 47 | LOGICAL :: laction ! To be coupled or not |
---|
| 48 | CHARACTER(len = 8) :: clname ! Name of the coupling field |
---|
| 49 | CHARACTER(len = 1) :: clgrid ! Grid type |
---|
| 50 | REAL(wp) :: nsgn ! Control of the sign change |
---|
| 51 | INTEGER :: nid ! Id of the field |
---|
| 52 | END TYPE FLD_CPL |
---|
[532] | 53 | |
---|
[1218] | 54 | TYPE(FLD_CPL), DIMENSION(nmaxfld), PUBLIC :: srcv, ssnd ! Coupling fields |
---|
[532] | 55 | |
---|
| 56 | REAL(wp), DIMENSION(:,:), ALLOCATABLE :: exfld ! Temporary buffer for receiving |
---|
| 57 | |
---|
| 58 | !! Routine accessibility |
---|
| 59 | PUBLIC cpl_prism_init |
---|
| 60 | PUBLIC cpl_prism_define |
---|
[1218] | 61 | PUBLIC cpl_prism_snd |
---|
| 62 | PUBLIC cpl_prism_rcv |
---|
[532] | 63 | PUBLIC cpl_prism_finalize |
---|
| 64 | |
---|
| 65 | !!---------------------------------------------------------------------- |
---|
| 66 | !! OPA 9.0 , LOCEAN-IPSL (2006) |
---|
[1218] | 67 | !! $Header$ |
---|
[2160] | 68 | !! Software governed by the CeCILL licence (NEMOGCM/License_CeCILL.txt) |
---|
[532] | 69 | !!---------------------------------------------------------------------- |
---|
| 70 | |
---|
| 71 | CONTAINS |
---|
| 72 | |
---|
[1226] | 73 | SUBROUTINE cpl_prism_init (kl_comm) |
---|
[532] | 74 | |
---|
| 75 | !!------------------------------------------------------------------- |
---|
| 76 | !! *** ROUTINE cpl_prism_init *** |
---|
| 77 | !! |
---|
| 78 | !! ** Purpose : Initialize coupled mode communication for ocean |
---|
| 79 | !! exchange between AGCM, OGCM and COUPLER. (OASIS3 software) |
---|
| 80 | !! |
---|
| 81 | !! ** Method : OASIS3 MPI communication |
---|
| 82 | !!-------------------------------------------------------------------- |
---|
[1226] | 83 | INTEGER, INTENT( OUT ) :: kl_comm ! local communicator of the model |
---|
| 84 | !!-------------------------------------------------------------------- |
---|
[1218] | 85 | |
---|
[1579] | 86 | ! WARNING: No write in numout in this routine |
---|
| 87 | !============================================ |
---|
| 88 | |
---|
[532] | 89 | !------------------------------------------------------------------ |
---|
| 90 | ! 1st Initialize the PRISM system for the application |
---|
| 91 | !------------------------------------------------------------------ |
---|
[1218] | 92 | CALL prism_init_comp_proto ( ncomp_id, 'oceanx', nerror ) |
---|
| 93 | IF ( nerror /= PRISM_Ok ) & |
---|
| 94 | CALL prism_abort_proto (ncomp_id, 'cpl_prism_init', 'Failure in prism_init_comp_proto') |
---|
[532] | 95 | |
---|
| 96 | !------------------------------------------------------------------ |
---|
| 97 | ! 3rd Get an MPI communicator for OPA local communication |
---|
| 98 | !------------------------------------------------------------------ |
---|
| 99 | |
---|
[1226] | 100 | CALL prism_get_localcomm_proto ( kl_comm, nerror ) |
---|
[1218] | 101 | IF ( nerror /= PRISM_Ok ) & |
---|
| 102 | CALL prism_abort_proto (ncomp_id, 'cpl_prism_init','Failure in prism_get_localcomm_proto' ) |
---|
[532] | 103 | |
---|
| 104 | END SUBROUTINE cpl_prism_init |
---|
| 105 | |
---|
| 106 | |
---|
[1226] | 107 | SUBROUTINE cpl_prism_define (krcv, ksnd) |
---|
[532] | 108 | |
---|
| 109 | !!------------------------------------------------------------------- |
---|
| 110 | !! *** ROUTINE cpl_prism_define *** |
---|
| 111 | !! |
---|
| 112 | !! ** Purpose : Define grid and field information for ocean |
---|
| 113 | !! exchange between AGCM, OGCM and COUPLER. (OASIS3 software) |
---|
| 114 | !! |
---|
| 115 | !! ** Method : OASIS3 MPI communication |
---|
| 116 | !!-------------------------------------------------------------------- |
---|
[1226] | 117 | INTEGER, INTENT( IN ) :: krcv, ksnd ! Number of received and sent coupling fields |
---|
| 118 | ! |
---|
[1218] | 119 | INTEGER :: id_part |
---|
[532] | 120 | INTEGER :: paral(5) ! OASIS3 box partition |
---|
[1218] | 121 | INTEGER :: ishape(2,2) ! shape of arrays passed to PSMILe |
---|
| 122 | INTEGER :: ji ! local loop indicees |
---|
[532] | 123 | !! |
---|
| 124 | !!-------------------------------------------------------------------- |
---|
[1218] | 125 | |
---|
[532] | 126 | IF(lwp) WRITE(numout,*) |
---|
| 127 | IF(lwp) WRITE(numout,*) 'cpl_prism_define : initialization in coupled ocean/atmosphere case' |
---|
| 128 | IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~~~' |
---|
| 129 | IF(lwp) WRITE(numout,*) |
---|
| 130 | |
---|
| 131 | ! |
---|
| 132 | ! ... Define the shape for the area that excludes the halo |
---|
| 133 | ! For serial configuration (key_mpp_mpi not being active) |
---|
| 134 | ! nl* is set to the global values 1 and jp*glo. |
---|
| 135 | ! |
---|
[1218] | 136 | ishape(:,1) = (/ 1, nlei-nldi+1 /) |
---|
| 137 | ishape(:,2) = (/ 1, nlej-nldj+1 /) |
---|
[532] | 138 | ! |
---|
| 139 | ! ... Allocate memory for data exchange |
---|
| 140 | ! |
---|
[1218] | 141 | ALLOCATE(exfld(nlei-nldi+1, nlej-nldj+1), stat = nerror) |
---|
| 142 | IF (nerror > 0) THEN |
---|
| 143 | CALL prism_abort_proto ( ncomp_id, 'cpl_prism_define', 'Failure in allocating exfld') |
---|
[532] | 144 | RETURN |
---|
| 145 | ENDIF |
---|
| 146 | ! |
---|
[1218] | 147 | ! ----------------------------------------------------------------- |
---|
| 148 | ! ... Define the partition |
---|
| 149 | ! ----------------------------------------------------------------- |
---|
| 150 | |
---|
| 151 | paral(1) = 2 ! box partitioning |
---|
| 152 | paral(2) = jpiglo * (nldj-1+njmpp-1) + (nldi-1+nimpp-1) ! NEMO lower left corner global offset |
---|
| 153 | paral(3) = nlei-nldi+1 ! local extent in i |
---|
| 154 | paral(4) = nlej-nldj+1 ! local extent in j |
---|
| 155 | paral(5) = jpiglo ! global extent in x |
---|
| 156 | |
---|
| 157 | IF( ln_ctl ) THEN |
---|
| 158 | WRITE(numout,*) ' multiexchg: paral (1:5)', paral |
---|
| 159 | WRITE(numout,*) ' multiexchg: jpi, jpj =', jpi, jpj |
---|
| 160 | WRITE(numout,*) ' multiexchg: nldi, nlei, nimpp =', nldi, nlei, nimpp |
---|
| 161 | WRITE(numout,*) ' multiexchg: nldj, nlej, njmpp =', nldj, nlej, njmpp |
---|
| 162 | ENDIF |
---|
| 163 | |
---|
| 164 | CALL prism_def_partition_proto ( id_part, paral, nerror ) |
---|
[532] | 165 | ! |
---|
[1218] | 166 | ! ... Announce send variables. |
---|
[532] | 167 | ! |
---|
[1226] | 168 | DO ji = 1, ksnd |
---|
[1218] | 169 | IF ( ssnd(ji)%laction ) THEN |
---|
| 170 | CALL prism_def_var_proto (ssnd(ji)%nid, ssnd(ji)%clname, id_part, (/ 2, 0/), & |
---|
| 171 | & PRISM_Out , ishape , PRISM_REAL, nerror) |
---|
| 172 | IF ( nerror /= PRISM_Ok ) THEN |
---|
| 173 | WRITE(numout,*) 'Failed to define transient ', ji, TRIM(ssnd(ji)%clname) |
---|
| 174 | CALL prism_abort_proto ( ssnd(ji)%nid, 'cpl_prism_define', 'Failure in prism_def_var') |
---|
[532] | 175 | ENDIF |
---|
[1218] | 176 | ENDIF |
---|
| 177 | END DO |
---|
| 178 | ! |
---|
| 179 | ! ... Announce received variables. |
---|
| 180 | ! |
---|
[1226] | 181 | DO ji = 1, krcv |
---|
[1218] | 182 | IF ( srcv(ji)%laction ) THEN |
---|
| 183 | CALL prism_def_var_proto ( srcv(ji)%nid, srcv(ji)%clname, id_part, (/ 2, 0/), & |
---|
| 184 | & PRISM_In , ishape , PRISM_REAL, nerror) |
---|
| 185 | IF ( nerror /= PRISM_Ok ) THEN |
---|
| 186 | WRITE(numout,*) 'Failed to define transient ', ji, TRIM(srcv(ji)%clname) |
---|
| 187 | CALL prism_abort_proto ( srcv(ji)%nid, 'cpl_prism_define', 'Failure in prism_def_var') |
---|
[532] | 188 | ENDIF |
---|
[1218] | 189 | ENDIF |
---|
| 190 | END DO |
---|
| 191 | |
---|
[532] | 192 | !------------------------------------------------------------------ |
---|
[1218] | 193 | ! End of definition phase |
---|
[532] | 194 | !------------------------------------------------------------------ |
---|
[1218] | 195 | |
---|
| 196 | CALL prism_enddef_proto(nerror) |
---|
| 197 | IF ( nerror /= PRISM_Ok ) CALL prism_abort_proto ( ncomp_id, 'cpl_prism_define', 'Failure in prism_enddef') |
---|
| 198 | |
---|
[532] | 199 | END SUBROUTINE cpl_prism_define |
---|
[1218] | 200 | |
---|
| 201 | |
---|
| 202 | SUBROUTINE cpl_prism_snd( kid, kstep, pdata, kinfo ) |
---|
[532] | 203 | |
---|
| 204 | !!--------------------------------------------------------------------- |
---|
[1218] | 205 | !! *** ROUTINE cpl_prism_snd *** |
---|
[532] | 206 | !! |
---|
| 207 | !! ** Purpose : - At each coupling time-step,this routine sends fields |
---|
| 208 | !! like sst or ice cover to the coupler or remote application. |
---|
| 209 | !!---------------------------------------------------------------------- |
---|
| 210 | !! * Arguments |
---|
| 211 | !! |
---|
[1218] | 212 | INTEGER, INTENT( IN ) :: kid ! variable intex in the array |
---|
| 213 | INTEGER, INTENT( OUT ) :: kinfo ! OASIS3 info argument |
---|
| 214 | INTEGER, INTENT( IN ) :: kstep ! ocean time-step in seconds |
---|
| 215 | REAL(wp), DIMENSION(jpi,jpj), INTENT( IN ) :: pdata |
---|
[532] | 216 | !! |
---|
| 217 | !! |
---|
| 218 | !!-------------------------------------------------------------------- |
---|
| 219 | ! |
---|
[1218] | 220 | ! snd data to OASIS3 |
---|
[532] | 221 | ! |
---|
[1227] | 222 | CALL prism_put_proto ( ssnd(kid)%nid, kstep, pdata(nldi:nlei, nldj:nlej), kinfo ) |
---|
[1218] | 223 | |
---|
| 224 | IF ( ln_ctl ) THEN |
---|
| 225 | IF ( kinfo == PRISM_Sent .OR. kinfo == PRISM_ToRest .OR. & |
---|
| 226 | & kinfo == PRISM_SentOut .OR. kinfo == PRISM_ToRestOut ) THEN |
---|
| 227 | WRITE(numout,*) '****************' |
---|
| 228 | WRITE(numout,*) 'prism_put_proto: Outgoing ', ssnd(kid)%clname |
---|
| 229 | WRITE(numout,*) 'prism_put_proto: ivarid ', ssnd(kid)%nid |
---|
| 230 | WRITE(numout,*) 'prism_put_proto: kstep ', kstep |
---|
| 231 | WRITE(numout,*) 'prism_put_proto: info ', kinfo |
---|
| 232 | WRITE(numout,*) ' - Minimum value is ', MINVAL(pdata) |
---|
| 233 | WRITE(numout,*) ' - Maximum value is ', MAXVAL(pdata) |
---|
| 234 | WRITE(numout,*) ' - Sum value is ', SUM(pdata) |
---|
| 235 | WRITE(numout,*) '****************' |
---|
| 236 | ENDIF |
---|
| 237 | ENDIF |
---|
| 238 | END SUBROUTINE cpl_prism_snd |
---|
[532] | 239 | |
---|
| 240 | |
---|
[1218] | 241 | SUBROUTINE cpl_prism_rcv( kid, kstep, pdata, kinfo ) |
---|
[532] | 242 | |
---|
| 243 | !!--------------------------------------------------------------------- |
---|
[1218] | 244 | !! *** ROUTINE cpl_prism_rcv *** |
---|
[532] | 245 | !! |
---|
| 246 | !! ** Purpose : - At each coupling time-step,this routine receives fields |
---|
| 247 | !! like stresses and fluxes from the coupler or remote application. |
---|
| 248 | !!---------------------------------------------------------------------- |
---|
[1218] | 249 | INTEGER, INTENT( IN ) :: kid ! variable intex in the array |
---|
| 250 | INTEGER, INTENT( IN ) :: kstep ! ocean time-step in seconds |
---|
| 251 | REAL(wp), DIMENSION(jpi,jpj), INTENT( INOUT ) :: pdata ! IN to keep the value if nothing is done |
---|
| 252 | INTEGER, INTENT( OUT ) :: kinfo ! OASIS3 info argument |
---|
[532] | 253 | !! |
---|
[1218] | 254 | LOGICAL :: llaction |
---|
| 255 | !!-------------------------------------------------------------------- |
---|
[532] | 256 | ! |
---|
[1218] | 257 | ! receive local data from OASIS3 on every process |
---|
| 258 | ! |
---|
| 259 | CALL prism_get_proto ( srcv(kid)%nid, kstep, exfld, kinfo ) |
---|
[532] | 260 | |
---|
[1218] | 261 | llaction = .false. |
---|
| 262 | IF( kinfo == PRISM_Recvd .OR. kinfo == PRISM_FromRest .OR. & |
---|
| 263 | kinfo == PRISM_RecvOut .OR. kinfo == PRISM_FromRestOut ) llaction = .TRUE. |
---|
[532] | 264 | |
---|
[1218] | 265 | IF ( ln_ctl ) WRITE(numout,*) "llaction, kinfo, kstep, ivarid: " , llaction, kinfo, kstep, srcv(kid)%nid |
---|
[532] | 266 | |
---|
[1218] | 267 | IF ( llaction ) THEN |
---|
[532] | 268 | |
---|
[1698] | 269 | kinfo = OASIS_Rcv |
---|
[1227] | 270 | pdata(nldi:nlei, nldj:nlej) = exfld(:,:) |
---|
[1218] | 271 | |
---|
| 272 | !--- Fill the overlap areas and extra hallows (mpp) |
---|
| 273 | !--- check periodicity conditions (all cases) |
---|
| 274 | CALL lbc_lnk( pdata, srcv(kid)%clgrid, srcv(kid)%nsgn ) |
---|
| 275 | |
---|
| 276 | IF ( ln_ctl ) THEN |
---|
[532] | 277 | WRITE(numout,*) '****************' |
---|
[1218] | 278 | WRITE(numout,*) 'prism_get_proto: Incoming ', srcv(kid)%clname |
---|
| 279 | WRITE(numout,*) 'prism_get_proto: ivarid ' , srcv(kid)%nid |
---|
| 280 | WRITE(numout,*) 'prism_get_proto: kstep', kstep |
---|
| 281 | WRITE(numout,*) 'prism_get_proto: info ', kinfo |
---|
| 282 | WRITE(numout,*) ' - Minimum value is ', MINVAL(pdata) |
---|
| 283 | WRITE(numout,*) ' - Maximum value is ', MAXVAL(pdata) |
---|
| 284 | WRITE(numout,*) ' - Sum value is ', SUM(pdata) |
---|
[532] | 285 | WRITE(numout,*) '****************' |
---|
| 286 | ENDIF |
---|
[1218] | 287 | |
---|
[1698] | 288 | ELSE |
---|
| 289 | kinfo = OASIS_idle |
---|
[532] | 290 | ENDIF |
---|
| 291 | |
---|
[1218] | 292 | END SUBROUTINE cpl_prism_rcv |
---|
[532] | 293 | |
---|
| 294 | |
---|
| 295 | SUBROUTINE cpl_prism_finalize |
---|
| 296 | |
---|
| 297 | !!--------------------------------------------------------------------- |
---|
| 298 | !! *** ROUTINE cpl_prism_finalize *** |
---|
| 299 | !! |
---|
| 300 | !! ** Purpose : - Finalizes the coupling. If MPI_init has not been |
---|
| 301 | !! called explicitly before cpl_prism_init it will also close |
---|
| 302 | !! MPI communication. |
---|
| 303 | !!---------------------------------------------------------------------- |
---|
| 304 | |
---|
| 305 | DEALLOCATE(exfld) |
---|
[1218] | 306 | CALL prism_terminate_proto ( nerror ) |
---|
[532] | 307 | |
---|
[1218] | 308 | END SUBROUTINE cpl_prism_finalize |
---|
[532] | 309 | |
---|
[1218] | 310 | #else |
---|
[532] | 311 | |
---|
[1218] | 312 | !!---------------------------------------------------------------------- |
---|
| 313 | !! Default case Forced Ocean/Atmosphere |
---|
| 314 | !!---------------------------------------------------------------------- |
---|
| 315 | !! Empty module |
---|
| 316 | !!---------------------------------------------------------------------- |
---|
| 317 | USE in_out_manager ! I/O manager |
---|
| 318 | LOGICAL, PUBLIC, PARAMETER :: lk_cpl = .FALSE. !: coupled flag |
---|
| 319 | PUBLIC cpl_prism_init |
---|
| 320 | PUBLIC cpl_prism_finalize |
---|
[532] | 321 | |
---|
[1218] | 322 | CONTAINS |
---|
[532] | 323 | |
---|
[1226] | 324 | SUBROUTINE cpl_prism_init (kl_comm) |
---|
| 325 | INTEGER, INTENT( OUT ) :: kl_comm ! local communicator of the model |
---|
| 326 | kl_comm = -1 |
---|
[1218] | 327 | WRITE(numout,*) 'cpl_prism_init: Error you sould not be there...' |
---|
| 328 | END SUBROUTINE cpl_prism_init |
---|
[532] | 329 | |
---|
[1218] | 330 | SUBROUTINE cpl_prism_finalize |
---|
| 331 | WRITE(numout,*) 'cpl_prism_finalize: Error you sould not be there...' |
---|
[532] | 332 | END SUBROUTINE cpl_prism_finalize |
---|
| 333 | |
---|
| 334 | #endif |
---|
| 335 | |
---|
| 336 | END MODULE cpl_oasis3 |
---|