Oasis3 4.0.2
|
00001 module mod_prism_put_proto 00002 #include "psmile_os.h" 00003 00004 interface prism_put_proto 00005 00006 #ifndef __NO_4BYTE_REALS 00007 module procedure prism_put_proto_r14 00008 module procedure prism_put_proto_r24 00009 #endif 00010 module procedure prism_put_proto_r18, & 00011 prism_put_proto_r28 00012 00013 end interface 00014 00015 contains 00016 #ifndef __NO_4BYTE_REALS 00017 SUBROUTINE prism_put_proto_r14(id_port_id,kstep,rd_field,kinfo) 00018 ! 00019 ! 00020 !* *** PRISM_put *** PRISM 1.0 00021 ! 00022 ! purpose: 00023 ! -------- 00024 ! give pfield to Oasis or models connected to port id_port_id at the 00025 ! time kstep 00026 ! 00027 ! interface: 00028 ! ---------- 00029 ! id_port_id : port number of the field 00030 ! kstep : current time in seconds 00031 ! rd_field : buffer of reals 00032 ! kinfo : output status 00033 ! 00034 ! lib mp: 00035 ! ------- 00036 ! mpi-1 00037 ! 00038 ! author: 00039 ! ------- 00040 ! Arnaud Caubel - Fecit (08/02 - created from CLIM_Export) 00041 ! 00042 ! modified: 00043 ! --------- 00044 ! Reiner Vogelsang, SGI, 27 April 2003 00045 ! - Screening of 4 byte real interfaces in case a of dbl4 compilation. 00046 ! File has to be preprocessed with -D__SXdbl4. 00047 ! S. Legutke, MPI-HH M&D, 13 May 2003 00048 ! - return PRISM_Sent if a field was received 00049 ! S. Valcke, CERFACS, 24/10/2004: Added GSIP 00050 ! ---------------------------------------------------------------- 00051 USE mod_prism_proto 00052 USE mod_comprism_proto 00053 USE mathelp_psmile 00054 #if defined use_comm_GSIP 00055 USE mod_gsip_model 00056 #endif 00057 IMPLICIT NONE 00058 #if defined use_comm_MPI1 || defined use_comm_MPI2 00059 #include <mpif.h> 00060 #endif 00061 ! ---------------------------------------------------------------- 00062 INTEGER (kind=ip_intwp_p) kstep, kinfo, id_port_id 00063 REAL(kind=ip_single_p), DIMENSION(myport(4,id_port_id)) :: rd_field 00064 ! ---------------------------------------------------------------- 00065 INTEGER (kind=ip_intwp_p) il_newtime 00066 INTEGER (kind=ip_intwp_p) info, ib 00067 INTEGER (kind=ip_intwp_p) isend, ip, iport, ilk, iseg, is, ilgb 00068 INTEGER (kind=ip_intwp_p) imod, itid, itag, il_len, ioff, ityp, ibyt 00069 INTEGER (kind=ip_intwp_p) iposbuf 00070 INTEGER (kind=ip_intwp_p) :: il_nbopp, il_nbin, il_nbout 00071 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbopp_max = 10 00072 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbindex=1 00073 INTEGER (kind=ip_intwp_p) :: il_nindex(ip_nbindex) 00074 REAL(kind=ip_single_p) :: rl_tmp_scal(ip_nbopp_max) 00075 REAL(kind=ip_single_p),PARAMETER :: ip_missing_val=1.e20 00076 REAL(kind=ip_single_p), DIMENSION(myport(4,id_port_id)) :: rl_field_aux 00077 CHARACTER(len=80) :: cl_topps, cl_str 00078 CHARACTER(len=7) :: cl_tmp_topp, cl_tmp_sopp(ip_nbopp_max) 00079 #ifdef use_comm_GSIP 00080 INTEGER(kind=ip_intwp_p) :: il_rst, il_ren, il_errgsip 00081 INTEGER :: mgi_write 00082 #endif 00083 #ifdef balance 00084 CHARACTER(8) :: date 00085 CHARACTER(10) :: time 00086 CHARACTER(5) :: zone 00087 INTEGER(kind=ip_intwp_p) ,DIMENSION(8) :: values 00088 REAL(kind=ip_double_p):: millisec 00089 REAL(kind=ip_double_p):: sec_date 00090 #endif 00091 ! ---------------------------------------------------------------- 00092 ! 00093 #ifdef __VERBOSE 00094 WRITE(nulprt,*) ' ' 00095 WRITE(nulprt,*) '| | | Entering prism_put_proto_r14 for field ',id_port_id 00096 call flush(nulprt) 00097 #endif 00098 ! 00099 rl_field_aux(:)=0 00100 cl_tmp_sopp(:)=' ' 00101 il_nindex(:)=0 00102 rl_tmp_scal(:)=0 00103 ! 00104 !* 0. Entering 00105 ! ----------- 00106 ! 00107 kinfo = PRISM_Ok 00108 IF (ip_realwp_p == ip_double_p) CALL prism_abort_proto (0,'prism_put_proto', & 00109 'STOP -- PSMILe compiled with double precision REAL; prism_put_proto_r14 should not be called') 00110 lg_dgfield = .false. 00111 ! 00112 !* 1. check for this port in my list 00113 ! --------------------------------- 00114 ! 00115 isend = 0 00116 iport = -1 00117 ! Test if the field is defined in the namcouple and if its coupling period 00118 ! is not greater than the time of the simulation. 00119 IF (ig_def_freq(id_port_id) .eq. 0.or. & 00120 ig_def_freq(id_port_id) .gt. ig_ntime) THEN 00121 GOTO 1010 00122 ENDIF 00123 ! 00124 ! 00125 ! if a field exported at a certain time should match an import 00126 ! at a time+lag, add the lag here; the lag is given by the user 00127 ! in the namcouple at the end of the field 2nd line. 00128 IF (myport(1,id_port_id).eq.CLIM_Out) THEN 00129 iport=id_port_id 00130 il_newtime = kstep + ig_def_lag(iport) 00131 ENDIF 00132 00133 IF (iport.lt.0) THEN 00134 kinfo = CLIM_BadPort 00135 WRITE(nulprt,FMT='(A,A)') & 00136 'Put - WARNING - Invalid port out: ', & 00137 cports(id_port_id) 00138 GO TO 1010 00139 ENDIF 00140 ! 00141 ! If the user indicated in the namcouple that the field must be 00142 ! accumulated or averaged (keyword 'AVERAGE' or 'ACCUMUL' at the 00143 ! end of the field 2nd line), do the local transformations. 00144 ! 00145 IF (ig_def_trans(iport) .EQ. ip_instant) THEN 00146 cl_str = 'inst(ident(X))' 00147 rg_field_trans(1:myport(4,id_port_id),iport) = rd_field (:) 00148 ELSEIF (ig_def_trans(iport) .eq. ip_average .or. & 00149 ig_def_trans(iport) .EQ. ip_accumul .OR. & 00150 ig_def_trans(iport) .EQ. ip_min .OR. & 00151 ig_def_trans(iport) .EQ. ip_max) THEN 00152 IF (ig_number(iport) .EQ. 0) rg_field_trans(:,iport) = 0 00153 il_nbin = myport(4,iport) 00154 il_nbout = il_nbin 00155 cl_topps = 'ave, inst, t_sum, t_min, t_max' 00156 IF (ig_def_trans(iport) .EQ. ip_average) THEN 00157 cl_str = 'ave(ident(X))' 00158 ELSEIF (ig_def_trans(iport) .EQ. ip_accumul) THEN 00159 cl_str = 't_sum(ident(X))' 00160 ELSEIF (ig_def_trans(iport) .EQ. ip_min) THEN 00161 cl_str = 't_min(ident(X))' 00162 ELSEIF (ig_def_trans(iport) .EQ. ip_max) THEN 00163 cl_str = 't_max(ident(X))' 00164 ENDIF 00165 CALL buildop (cl_str,cl_topps,cl_tmp_topp,ip_nbopp_max, & 00166 ip_missing_val,cl_tmp_sopp,rl_tmp_scal,il_nbopp) 00167 00168 CALL mathop (cl_tmp_sopp(1), il_nbin, rd_field, ip_missing_val, & 00169 ip_nbindex, il_nindex, rl_tmp_scal(1), il_nbout, & 00170 rl_field_aux) 00171 00172 IF ((cl_tmp_topp(:LEN_TRIM(cl_tmp_topp)) .NE. 'inst')) & 00173 CALL moycum(cl_tmp_topp, il_nbin, rg_field_trans(:,iport), & 00174 rl_field_aux, ig_number(iport)) 00175 ig_number(iport) = ig_number(iport) + 1 00176 IF (MOD(il_newtime,ig_def_freq(iport)) .EQ. 0) THEN 00177 ig_number(iport) = 0 00178 DO ib = 1, myport(4,iport) 00179 rd_field(ib) = rg_field_trans(ib,iport) 00180 ENDDO 00181 ENDIF 00182 kinfo = PRISM_LocTrans 00183 ENDIF 00184 ! 00185 !* Test if field must be written to restart file i.e. 00186 !* - current time is time at the end of simulation + 00187 !* - lag of current field is greater 0 00188 ! 00189 IF (il_newtime.EQ.ig_ntime.AND.ig_def_lag(iport).GT.0) THEN 00190 IF (ig_def_state(iport) .ne. ip_output) THEN 00191 ! 00192 !* Note: A model can have several restart files but same restart 00193 !* file can't be used by different models 00194 ! 00195 IF (mydist(CLIM_Strategy,iport) .eq. CLIM_Serial) THEN 00196 CALL write_filer4(rd_field,cports(iport),iport) 00197 ELSE 00198 CALL write_file_parar4(rd_field,cports(iport),iport) 00199 ENDIF 00200 kinfo = PRISM_ToRest 00201 ENDIF 00202 ! Test if the current time is a coupling (or I/O) time 00203 IF (MOD(il_newtime,ig_def_freq(iport)).EQ.0) THEN 00204 00205 #if !defined key_noIO 00206 !* If the user indicated in the namcouple that the field is 00207 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 00208 !* at the end of the field 1st line), do the writing to file here, e.g.: 00209 IF (ig_def_state(iport) .EQ. ip_output ) THEN 00210 CALL psmile_write_4(iport,rd_field,il_newtime) 00211 kinfo = PRISM_Output 00212 ELSEIF (ig_def_state(iport) .eq. ip_expout .or. & 00213 ig_def_state(iport) .EQ. ip_ignout) THEN 00214 CALL psmile_write_4(iport,rd_field,il_newtime) 00215 kinfo = PRISM_ToRestOut 00216 ENDIF 00217 #endif 00218 ENDIF 00219 ELSE 00220 ! Test if the current time is a coupling (or I/O) time 00221 IF (MOD(il_newtime,ig_def_freq(iport)).EQ.0) THEN 00222 ! 00223 #if !defined key_noIO 00224 !* If the user indicated in the namcouple that the field is 00225 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 00226 !* at the end of the field 1st line), do the writing to file here, e.g.: 00227 IF (ig_def_state(iport) .EQ. ip_output .OR. & 00228 ig_def_state(iport) .EQ. ip_expout .OR. & 00229 ig_def_state(iport) .EQ. ip_ignout) THEN 00230 CALL psmile_write_4(iport,rd_field,il_newtime) 00231 kinfo = PRISM_Output 00232 ENDIF 00233 #endif 00234 !* 00235 !* If the user indicated in the namcouple that the field is 00236 !* a coupling field (keyword EXPORTED','EXPOUT','IGNORED' or 'IGNOUT' 00237 !* at the end of the field 1st line),do the export here. 00238 !* 00239 IF (ig_def_state(iport) .EQ. ip_expout .OR. & 00240 ig_def_state(iport) .eq. ip_exported .or. & 00241 ig_def_state(iport) .eq. ip_ignored .or. & 00242 ig_def_state(iport) .eq. ip_ignout .or. & 00243 ig_def_state(iport) .eq. ip_auxilary) THEN 00244 00245 ! 00246 !* check for connected ports (in) 00247 ! ------------------------------ 00248 ! 00249 ! #slo - Output reduced using option -D__SILENT in Cppflags_libs.h: 00250 #ifdef __VERBOSE 00251 WRITE(nulprt,FMT='(A,A)') 'Put - ', cports(iport) 00252 CALL FLUSH(nulprt) 00253 #endif 00254 ! 00255 ityp = myport(2,iport) 00256 ibyt = myport(3,iport) 00257 #ifdef balance 00258 CALL date_and_time(date,time,zone,values) 00259 millisec=values(8) 00260 sec_date=millisec/1000+values(7)+values(6)*60+& 00261 values(5)*3600+values(3)*86400 00262 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 00263 'Balance: ',cports(iport),'Before MPI put ',sec_date 00264 #endif 00265 ! 00266 DO ip=1,myport(5,iport) 00267 ! 00268 ilk = myport(5+ip,iport) 00269 imod = mylink(1,ilk) 00270 itid = mylink(2,ilk) 00271 itag = mylink(3,ilk) - il_newtime / ig_frqmin 00272 iseg = mylink(4,ilk) 00273 ! 00274 #if defined use_comm_MPI1 || defined use_comm_MPI2 00275 ilgb = 0 00276 iposbuf = 0 00277 DO is=1,iseg 00278 ioff = mylink(4+2*is-1,ilk) * 2 + 1 00279 il_len = mylink(4+2*is,ilk) 00280 ! 00281 IF ( ityp .EQ. PRISM_Real ) THEN 00282 CALL MPI_Pack ( rd_field(ioff), il_len, & 00283 MPI_REAL,pkwork_field, ig_maxtype_field, iposbuf, & 00284 mpi_comm, info ) 00285 ELSE 00286 WRITE(nulprt,*)'Put - pb type incorrect ', ityp 00287 kinfo = CLIM_BadType 00288 GO TO 1010 00289 ENDIF 00290 ilgb = ilgb + il_len 00291 ENDDO 00292 IF (info.ne.0 .or. ilgb*ibyt .gt. ig_maxtype_field) THEN 00293 kinfo = CLIM_Pack 00294 #ifdef __VERBOSE 00295 WRITE(nulprt,FMT='(A,I3,I8,A)') & 00296 'Put - pb pack<mpi ',info,ilgb*ibyt,'>' 00297 CALL FLUSH(nulprt) 00298 #endif 00299 ELSE 00300 !* 00301 IF (lg_clim_bsend) THEN 00302 !* Buffered send 00303 !* -> if fields are not sent and received in the same order, and 00304 !* and on architectures on which MPI_Send is not implemented with a 00305 !* mailbox (e.g. NEC SX5) 00306 !* 00307 CALL MPI_BSend ( pkwork_field, iposbuf, & 00308 MPI_PACKED, itid, itag, mpi_comm, info ) 00309 ELSE 00310 !* 00311 !* Standard blocking send: To be used 00312 !* -> if fields are necessarily sent and received in the same order, 00313 !* -> or on architectures on which MPI_Send is implemented with a 00314 !* mailbox (e.g. VPPs); in this case, make sure that your mailbox 00315 !* size is large enough. 00316 ! 00317 CALL MPI_Send ( pkwork_field, iposbuf, & 00318 MPI_PACKED, itid, itag, mpi_comm, info ) 00319 ! 00320 ENDIF 00321 ! 00322 IF (info.eq.CLIM_ok) THEN 00323 isend = isend + 1 00324 nbsend = nbsend + ilgb * ibyt 00325 #ifdef __VERBOSE 00326 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A,I6,A)') & 00327 'Put - <dest:',imod, & 00328 '> <step:',il_newtime, & 00329 '> <len:',ilgb, & 00330 '> <type:',ibyt, & 00331 '> <tag:',itag, & 00332 '> <comm:',mpi_comm,'>' 00333 CALL FLUSH(nulprt) 00334 #endif 00335 ELSE 00336 kinfo = CLIM_Pvm 00337 #ifdef __VERBOSE 00338 WRITE(nulprt,FMT='(A,I3,A)') & 00339 'Put - pb send <mpi ',info,'>' 00340 CALL FLUSH(nulprt) 00341 #endif 00342 ENDIF 00343 ENDIF 00344 #elif defined use_comm_GSIP 00345 if (myport(5,iport) .ne. 1) CALL prism_abort_proto & 00346 (0,'prism_put_proto', 'STOP -- only one send to Oasis, myport(5,iport) should be 1') 00347 if (imod .ne. 0) CALL prism_abort_proto & 00348 (0,'prism_get_proto', 'STOP -- if sent to Oasis, imod should be 0') 00349 if (itid .ne. 1) CALL prism_abort_proto & 00350 (0,'prism_get_proto', 'STOP -- if sent to Oasis, itid should be 1') 00351 ! 00352 ! Fill pkworkps with segments of rd_field 00353 ilgb = 0 00354 il_rst = 0 00355 il_ren = 0 00356 DO is=1,iseg 00357 ioff = mylink(4+2*is-1,ilk) + 1 00358 il_len = mylink(4+2*is,ilk) 00359 il_rst = il_ren + 1 00360 il_ren = il_rst + il_len - 1 00361 pkworkps(il_rst:il_ren) = rd_field(ioff:ioff+il_len-1) 00362 ! 00363 ilgb = ilgb + il_len 00364 ENDDO 00365 IF (ilgb .GT. ig_CLIMmax) THEN 00366 WRITE(UNIT = nulprt,FMT = *) & 00367 '1- prism_put_proto - error :', il_errgsip 00368 CALL prism_abort_proto (0, 'prism_put_proto', & 00369 'STOP - sum of segments greater than pkworkps size') 00370 ENDIF 00371 ! 00372 ! Write the field in channel to Oasis (no DIRECT communication) 00373 il_errgsip = mgi_write (ig_gsipw, pkworkps, ig_CLIMmax, 'R') 00374 IF (il_errgsip .GE. 0) THEN 00375 WRITE(UNIT = nulprt,FMT = *) & 00376 'prism_put_proto - pkworkps written OK:', il_errgsip 00377 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)') & 00378 'Put - <dest:',imod, '> <step:',kstep,'> <len:', & 00379 ilgb, '> <type:',ibyt, '> <noproc:',itid,'>' 00380 isend = isend + 1 00381 ELSE 00382 WRITE(UNIT = nulprt,FMT = *) & 00383 '2- prism_put_proto - error :', il_errgsip 00384 CALL flush(nulprt) 00385 CALL prism_abort_proto (0, 'prism_put_proto', & 00386 'STOP - pkworkps not written OK)') 00387 ENDIF 00388 #endif 00389 ! 00390 ENDDO 00391 #ifdef balance 00392 CALL date_and_time(date,time,zone,values) 00393 millisec=values(8) 00394 sec_date=millisec/1000+values(7)+values(6)*60+& 00395 values(5)*3600+values(3)*86400 00396 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 00397 'Balance: ',cports(iport),'After MPI put ',sec_date 00398 #endif 00399 ! 00400 IF (kinfo .EQ. PRISM_Output) THEN 00401 kinfo = PRISM_SentOut 00402 ELSE 00403 kinfo = PRISM_Sent 00404 ENDIF 00405 00406 #ifdef __VERBOSE 00407 WRITE(nulprt,FMT='(A,I3,A)') & 00408 'Put r14- ',isend,' fields exported' 00409 CALL FLUSH(nulprt) 00410 #endif 00411 ENDIF 00412 ENDIF 00413 ENDIF 00414 ! 00415 ! ---------------------------------------------------------------- 00416 ! 00417 1010 CONTINUE 00418 ! 00419 #ifdef __VERBOSE 00420 WRITE(nulprt,*)'| | | Leaving routine prism_put_proto_r14' 00421 WRITE(nulprt,*) ' ' 00422 CALL FLUSH(nulprt) 00423 #endif 00424 ! 00425 RETURN 00426 END SUBROUTINE prism_put_proto_r14 00427 #endif 00428 SUBROUTINE prism_put_proto_r18(id_port_id,kstep,rd_field,kinfo) 00429 ! 00430 !* *** PRISM_put *** PRISM 1.0 00431 ! 00432 ! purpose: 00433 ! -------- 00434 ! give rd_field to Oasis or models connected to port id_port_id at the 00435 ! time kstep 00436 ! 00437 ! interface: 00438 ! ---------- 00439 ! id_port_id : port number of the field 00440 ! kstep : current time in seconds 00441 ! rd_field : buffer of reals 00442 ! kinfo : output status 00443 ! 00444 ! lib mp: 00445 ! ------- 00446 ! mpi-1 or mpi-2 or gsip 00447 ! 00448 ! author: 00449 ! ------- 00450 ! Arnaud Caubel - Fecit (08/02 - created from CLIM_Export) 00451 ! S. Valcke, CERFACS, 24/10/2004: Added GSIP 00452 ! ---------------------------------------------------------------- 00453 USE mod_kinds_model 00454 USE mod_prism_proto 00455 USE mod_comprism_proto 00456 USE mathelp_psmile 00457 #if defined use_comm_GSIP 00458 USE mod_gsip_model 00459 #endif 00460 IMPLICIT NONE 00461 #if defined use_comm_MPI1 || defined use_comm_MPI2 00462 #include <mpif.h> 00463 #endif 00464 ! ---------------------------------------------------------------- 00465 INTEGER (kind=ip_intwp_p) kstep, kinfo, id_port_id 00466 REAL(kind=ip_double_p), DIMENSION(myport(4,id_port_id)) :: rd_field 00467 ! ---------------------------------------------------------------- 00468 INTEGER (kind=ip_intwp_p) il_newtime 00469 INTEGER (kind=ip_intwp_p) info 00470 INTEGER (kind=ip_intwp_p) isend, ip, iport, ilk, iseg, is, ilgb, & 00471 imod, itid, itag, il_len, ioff, ityp, ibyt 00472 INTEGER (kind=ip_intwp_p) iposbuf 00473 INTEGER (kind=ip_intwp_p) :: ib, il_nbopp, il_nbin, il_nbout 00474 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbopp_max = 10 00475 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbindex=1 00476 INTEGER (kind=ip_intwp_p) :: il_nindex(ip_nbindex) 00477 REAL(kind=ip_double_p) :: rl_tmp_scal(ip_nbopp_max) 00478 REAL(kind=ip_double_p),PARAMETER :: ip_missing_val=1.e20 00479 REAL(kind=ip_double_p), DIMENSION(myport(4,id_port_id)) :: rl_field_aux 00480 CHARACTER(len=80) :: cl_topps, cl_str 00481 CHARACTER(len=7) :: cl_tmp_topp, cl_tmp_sopp(ip_nbopp_max) 00482 #ifdef use_comm_GSIP 00483 INTEGER(kind=ip_intwp_p) :: il_rst, il_ren, il_errgsip 00484 INTEGER :: mgi_write 00485 #endif 00486 #ifdef balance 00487 CHARACTER(8) :: date 00488 CHARACTER(10) :: time 00489 CHARACTER(5) :: zone 00490 INTEGER(kind=ip_intwp_p) ,DIMENSION(8) :: values 00491 REAL(kind=ip_double_p):: millisec 00492 REAL(kind=ip_double_p):: sec_date 00493 #endif 00494 ! ---------------------------------------------------------------- 00495 ! 00496 #ifdef __VERBOSE 00497 WRITE(nulprt,*) ' ' 00498 WRITE(nulprt,*) '| | | Entering prism_put_proto_r18 for field ',id_port_id 00499 call flush(nulprt) 00500 #endif 00501 ! 00502 rl_field_aux(:)=0 00503 cl_tmp_sopp(:)=' ' 00504 il_nindex(:)=0 00505 rl_tmp_scal(:)=0 00506 ! 00507 !* 0. Entering 00508 ! ----------- 00509 ! 00510 kinfo = PRISM_Ok 00511 IF (ip_realwp_p == ip_single_p) CALL prism_abort_proto (0,'prism_put_proto', & 00512 'STOP -- PSMILe compiled with single precision REAL; prism_put_proto_r18 should not be called') 00513 lg_dgfield = .true. 00514 ! 00515 !* 1. check for this port in my list 00516 ! --------------------------------- 00517 ! 00518 isend = 0 00519 iport = -1 00520 ! 00521 ! Test if the field is defined in the namcouple and if its coupling period 00522 ! is not greater than the time of the simulation. 00523 IF (ig_def_freq(id_port_id) .eq. 0.or. & 00524 ig_def_freq(id_port_id) .gt. ig_ntime) THEN 00525 GOTO 1010 00526 ENDIF 00527 ! 00528 ! if a field exported at a certain time should match an import 00529 ! at a time+lag, add the lag here; the lag is given by the user 00530 ! in the namcouple at the end of the field 2nd line. 00531 IF (myport(1,id_port_id).eq.CLIM_Out) THEN 00532 iport=id_port_id 00533 il_newtime = kstep + ig_def_lag(iport) 00534 ENDIF 00535 00536 IF (iport.LT.0) THEN 00537 kinfo = CLIM_BadPort 00538 WRITE(nulprt,FMT='(A,A)') & 00539 'Put - WARNING - Invalid port out: ', & 00540 cports(id_port_id) 00541 GO TO 1010 00542 ENDIF 00543 ! 00544 ! If the user indicated in the namcouple that the field must be 00545 ! accumulated or averaged (keyword 'AVERAGE' or 'ACCUMUL' at the 00546 ! end of the field 2nd line), do the local transformations. 00547 ! 00548 IF (ig_def_trans(iport) .EQ. ip_instant) THEN 00549 cl_str = 'inst(ident(X))' 00550 dg_field_trans(1:myport(4,id_port_id),iport) = rd_field (:) 00551 ELSEIF (ig_def_trans(iport) .eq. ip_average .or. & 00552 ig_def_trans(iport) .EQ. ip_accumul .OR. & 00553 ig_def_trans(iport) .EQ. ip_min .OR. & 00554 ig_def_trans(iport) .EQ. ip_max) THEN 00555 IF (ig_number(iport) .EQ. 0) dg_field_trans(:,iport) = 0 00556 il_nbin = myport(4,iport) 00557 il_nbout = il_nbin 00558 cl_topps = 'ave, inst, t_sum, t_min, t_max' 00559 IF (ig_def_trans(iport) .EQ. ip_average) THEN 00560 cl_str = 'ave(ident(X))' 00561 ELSEIF (ig_def_trans(iport) .EQ. ip_accumul) THEN 00562 cl_str = 't_sum(ident(X))' 00563 ELSEIF (ig_def_trans(iport) .EQ. ip_min) THEN 00564 cl_str = 't_min(ident(X))' 00565 ELSEIF (ig_def_trans(iport) .EQ. ip_max) THEN 00566 cl_str = 't_max(ident(X))' 00567 ENDIF 00568 CALL buildop (cl_str,cl_topps,cl_tmp_topp,ip_nbopp_max, & 00569 ip_missing_val,cl_tmp_sopp,rl_tmp_scal,il_nbopp) 00570 00571 CALL mathop (cl_tmp_sopp(1), il_nbin, rd_field, ip_missing_val, & 00572 ip_nbindex, il_nindex, rl_tmp_scal(1), il_nbout, & 00573 rl_field_aux) 00574 00575 IF ((cl_tmp_topp(:LEN_TRIM(cl_tmp_topp)) .NE. 'inst')) & 00576 CALL moycum(cl_tmp_topp, il_nbin, dg_field_trans(:,iport), & 00577 rl_field_aux, ig_number(iport)) 00578 ig_number(iport) = ig_number(iport) + 1 00579 IF (MOD(il_newtime,ig_def_freq(iport)) .EQ. 0) THEN 00580 ig_number(iport) = 0 00581 DO ib = 1, myport(4,iport) 00582 rd_field(ib) = dg_field_trans(ib,iport) 00583 ENDDO 00584 ENDIF 00585 kinfo = PRISM_LocTrans 00586 ENDIF 00587 ! 00588 !* Test if field must be written to restart file i.e. 00589 !* - current time is time at the end of simulation + 00590 !* - lag of current field is greater 0 00591 ! 00592 IF (il_newtime.eq.ig_ntime.and.ig_def_lag(iport).gt.0) THEN 00593 IF (ig_def_state(iport) .ne. ip_output) THEN 00594 ! 00595 !* Note: A model can have several restart files but same restart 00596 !* file can't be used by different models 00597 ! 00598 IF (mydist(CLIM_Strategy,iport) .eq. CLIM_Serial) THEN 00599 CALL write_filer8(rd_field,cports(iport),iport) 00600 ELSE 00601 CALL write_file_parar8(rd_field,cports(iport),iport) 00602 ENDIF 00603 kinfo = PRISM_ToRest 00604 ENDIF 00605 ! Test if the current time is a coupling (or I/O) time 00606 IF (MOD(il_newtime,ig_def_freq(iport)).EQ.0) THEN 00607 00608 #if !defined key_noIO 00609 !* If the user indicated in the namcouple that the field is 00610 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 00611 !* at the end of the field 1st line), do the writing to file here, e.g.: 00612 IF (ig_def_state(iport) .EQ. ip_output ) THEN 00613 CALL psmile_write_8(iport,rd_field,il_newtime) 00614 kinfo = PRISM_Output 00615 ELSEIF (ig_def_state(iport) .eq. ip_expout .or. & 00616 ig_def_state(iport) .EQ. ip_ignout) THEN 00617 CALL psmile_write_8(iport,rd_field,il_newtime) 00618 kinfo = PRISM_ToRestOut 00619 ENDIF 00620 #endif 00621 ENDIF 00622 ELSE 00623 00624 ! Test if the current time is a coupling (or I/O) time 00625 IF (mod(il_newtime,ig_def_freq(iport)).eq.0) THEN 00626 ! 00627 #if !defined key_noIO 00628 !* If the user indicated in the namcouple that the field is 00629 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 00630 !* at the end of the field 1st line), do the writing to file here, e.g.: 00631 IF (ig_def_state(iport) .eq. ip_output .or. & 00632 ig_def_state(iport) .eq. ip_expout .or. & 00633 ig_def_state(iport) .eq. ip_ignout) THEN 00634 call psmile_write_8(iport,rd_field,il_newtime) 00635 kinfo = PRISM_Output 00636 ENDIF 00637 #endif 00638 !* 00639 !* If the user indicated in the namcouple that the field is 00640 !* a coupling field (keyword EXPORTED','EXPOUT','IGNORED' or 'IGNOUT' 00641 !* at the end of the field 1st line),do the export here. 00642 !* 00643 IF (ig_def_state(iport) .eq. ip_expout .or. & 00644 ig_def_state(iport) .eq. ip_exported .or. & 00645 ig_def_state(iport) .eq. ip_ignored .or. & 00646 ig_def_state(iport) .eq. ip_ignout .or. & 00647 ig_def_state(iport) .eq. ip_auxilary) THEN 00648 00649 ! 00650 !* check for connected ports (in) 00651 ! ------------------------------ 00652 ! 00653 #ifdef __VERBOSE 00654 WRITE(nulprt,FMT='(A,A)') 'Put - ', cports(iport) 00655 CALL FLUSH(nulprt) 00656 #endif 00657 ! 00658 ityp = myport(2,iport) 00659 ibyt = myport(3,iport) 00660 #ifdef balance 00661 CALL date_and_time(date,time,zone,values) 00662 millisec=values(8) 00663 sec_date=millisec/1000+values(7)+values(6)*60+& 00664 values(5)*3600+values(3)*86400 00665 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 00666 'Balance: ',cports(iport),'Before MPI put ',sec_date 00667 #endif 00668 ! 00669 DO ip=1,myport(5,iport) 00670 ! 00671 ilk = myport(5+ip,iport) 00672 ! imod is the distant model number 00673 imod = mylink(1,ilk) 00674 ! itid is the distant local process number 00675 itid = mylink(2,ilk) 00676 itag = mylink(3,ilk) - il_newtime / ig_frqmin 00677 iseg = mylink(4,ilk) 00678 ! 00679 #if defined use_comm_MPI1 || defined use_comm_MPI2 00680 ilgb = 0 00681 iposbuf = 0 00682 DO is=1,iseg 00683 ioff = mylink(4+2*is-1,ilk) + 1 00684 il_len = mylink(4+2*is,ilk) 00685 ! 00686 IF ( ityp .EQ. PRISM_Real ) THEN 00687 CALL MPI_Pack ( rd_field(ioff), il_len, & 00688 MPI_DOUBLE_PRECISION, pkwork_field, & 00689 ig_maxtype_field, iposbuf, & 00690 mpi_comm, info ) 00691 ELSE 00692 WRITE(nulprt,*)'Put - pb type incorrect ', ityp 00693 kinfo = CLIM_BadType 00694 GO TO 1010 00695 ENDIF 00696 ilgb = ilgb + il_len 00697 ENDDO 00698 IF (info.ne.0 .or. ilgb*ibyt .gt. ig_maxtype_field) THEN 00699 kinfo = CLIM_Pack 00700 WRITE(nulprt,FMT='(A,I3,I8,A)') & 00701 'Put - pb pack<mpi ',info,ilgb*ibyt,'>' 00702 ELSE 00703 IF (lg_clim_bsend) THEN 00704 !* 00705 !* Buffered send 00706 !* -> if fields are not sent and received in the same order, and 00707 !* and on architectures on which MPI_Send is not implemented with a 00708 !* mailbox (e.g. NEC SX5) 00709 !* 00710 CALL MPI_BSend ( pkwork_field, iposbuf, & 00711 MPI_PACKED, itid, itag, mpi_comm, info ) 00712 ELSE 00713 !* 00714 !* Standard blocking send: To be used 00715 !* -> if fields are necessarily sent and received in the same order, 00716 !* -> or on architectures on which MPI_Send is implemented with a 00717 !* mailbox (e.g. VPPs); in this case, make sure that your mailbox 00718 !* size is large enough. 00719 ! 00720 CALL MPI_Send ( pkwork_field, iposbuf, & 00721 MPI_PACKED, itid, itag, mpi_comm, info ) 00722 ! 00723 ENDIF 00724 ! 00725 IF (info.eq.CLIM_ok) THEN 00726 isend = isend + 1 00727 nbsend = nbsend + ilgb * ibyt 00728 #ifdef __VERBOSE 00729 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)') & 00730 'Put - <dest:',imod, & 00731 '> <step:',il_newtime, & 00732 '> <len:',ilgb, & 00733 '> <type:',ibyt, & 00734 '> <tag:',itag,'>' 00735 CALL FLUSH(nulprt) 00736 #endif 00737 ELSE 00738 kinfo = CLIM_Pvm 00739 #ifdef __VERBOSE 00740 WRITE(nulprt,FMT='(A,I3,A)') & 00741 'Put - pb send <mpi ',info,'>' 00742 CALL FLUSH(nulprt) 00743 #endif 00744 ENDIF 00745 ENDIF 00746 #elif defined use_comm_GSIP 00747 if (myport(5,iport) .ne. 1) CALL prism_abort_proto & 00748 (0,'prism_put_proto', 'STOP -- only one send to Oasis, myport(5,iport) should be 1') 00749 if (imod .ne. 0) CALL prism_abort_proto & 00750 (0,'prism_get_proto', 'STOP -- if sent to Oasis, imod should be 0') 00751 if (itid .ne. 1) CALL prism_abort_proto & 00752 (0,'prism_get_proto', 'STOP -- if sent to Oasis, itid should be 1') 00753 ! 00754 ! Fill pkworkps with segments of rd_field 00755 ilgb = 0 00756 il_rst = 0 00757 il_ren = 0 00758 DO is=1,iseg 00759 ioff = mylink(4+2*is-1,ilk) + 1 00760 il_len = mylink(4+2*is,ilk) 00761 il_rst = il_ren + 1 00762 il_ren = il_rst + il_len - 1 00763 pkworkps(il_rst:il_ren) = rd_field(ioff:ioff+il_len-1) 00764 ! 00765 ilgb = ilgb + il_len 00766 ENDDO 00767 IF (ilgb .GT. ig_CLIMmax) THEN 00768 WRITE(UNIT = nulprt,FMT = *) & 00769 '1- prism_put_proto - error :', il_errgsip 00770 CALL prism_abort_proto (0, 'prism_put_proto', & 00771 'STOP - sum of segments greater than pkworkps size') 00772 ENDIF 00773 ! 00774 ! Write the field in channel to Oasis (no DIRECT communication) 00775 il_errgsip = mgi_write (ig_gsipw, pkworkps, ig_CLIMmax, 'D') 00776 IF (il_errgsip .GE. 0) THEN 00777 WRITE(UNIT = nulprt,FMT = *) & 00778 'prism_put_proto - pkworkps written OK:', il_errgsip 00779 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)') & 00780 'Put - <dest:',imod, '> <step:',kstep,'> <len:', & 00781 ilgb, '> <type:',ibyt, '> <noproc:',itid,'>' 00782 isend = isend + 1 00783 ELSE 00784 WRITE(UNIT = nulprt,FMT = *) & 00785 '2- prism_put_proto - error :', il_errgsip 00786 CALL prism_abort_proto (0, 'prism_put_proto', & 00787 'STOP - pkworkps not written OK)') 00788 ENDIF 00789 #endif 00790 ENDDO 00791 #ifdef balance 00792 CALL date_and_time(date,time,zone,values) 00793 millisec=values(8) 00794 sec_date=millisec/1000+values(7)+values(6)*60+& 00795 values(5)*3600+values(3)*86400 00796 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 00797 'Balance: ',cports(iport),'After MPI put ',sec_date 00798 #endif 00799 ! 00800 IF (kinfo .EQ. PRISM_Output) THEN 00801 kinfo = PRISM_SentOut 00802 ELSE 00803 kinfo = PRISM_Sent 00804 ENDIF 00805 00806 #ifdef __VERBOSE 00807 WRITE(nulprt,FMT='(A,I3,A)') & 00808 'Put r18- ',isend,' fields exported' 00809 call flush(nulprt) 00810 #endif 00811 ENDIF 00812 ENDIF 00813 ENDIF 00814 ! 00815 ! ---------------------------------------------------------------- 00816 ! 00817 1010 CONTINUE 00818 #ifdef __VERBOSE 00819 WRITE(nulprt,*)'| | | Leaving routine prism_put_proto_r18' 00820 WRITE(nulprt,*) ' ' 00821 CALL FLUSH(nulprt) 00822 #endif 00823 RETURN 00824 END SUBROUTINE prism_put_proto_r18 00825 #ifndef __NO_4BYTE_REALS 00826 SUBROUTINE prism_put_proto_r24(id_port_id,kstep,rd_field_2d,kinfo) 00827 ! 00828 !* *** PRISM_put *** PRISM 1.0 00829 ! 00830 ! purpose: 00831 ! -------- 00832 ! give pfield to Oasis or models connected to port id_port_id at the 00833 ! time kstep 00834 ! 00835 ! interface: 00836 ! ---------- 00837 ! id_port_id : port number of the field 00838 ! kstep : current time in seconds 00839 ! rd_field : buffer of reals 00840 ! kinfo : output status 00841 ! 00842 ! lib mp: 00843 ! ------- 00844 ! mpi-1 00845 ! 00846 ! author: 00847 ! ------- 00848 ! Arnaud Caubel - Fecit (08/02 - created from CLIM_Export) 00849 ! S. Valcke, CERFACS, 24/10/2004: Added GSIP 00850 ! ---------------------------------------------------------------- 00851 USE mod_kinds_model 00852 USE mod_prism_proto 00853 USE mod_comprism_proto 00854 USE mathelp_psmile 00855 #if defined use_comm_GSIP 00856 USE mod_gsip_model 00857 #endif 00858 IMPLICIT NONE 00859 #if defined use_comm_MPI1 || defined use_comm_MPI2 00860 #include <mpif.h> 00861 #endif 00862 ! ---------------------------------------------------------------- 00863 INTEGER (kind=ip_intwp_p) kstep, kinfo, id_port_id 00864 REAL(kind=ip_single_p), DIMENSION(:,:) :: rd_field_2d 00865 ! ---------------------------------------------------------------- 00866 REAL(kind=ip_single_p), DIMENSION(myport(4,id_port_id)) :: rd_field 00867 00868 INTEGER (kind=ip_intwp_p) il_newtime 00869 INTEGER (kind=ip_intwp_p) info, ib 00870 INTEGER (kind=ip_intwp_p) isend, ip, iport, ilk, iseg, is, ilgb 00871 INTEGER (kind=ip_intwp_p) imod, itid, itag, il_len, ioff, ityp, ibyt 00872 INTEGER (kind=ip_intwp_p) iposbuf 00873 INTEGER (kind=ip_intwp_p) :: il_nbopp, il_nbin, il_nbout 00874 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbopp_max = 10 00875 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbindex=1 00876 INTEGER (kind=ip_intwp_p) :: il_nindex(ip_nbindex) 00877 REAL(kind=ip_single_p) :: rl_tmp_scal(ip_nbopp_max) 00878 REAL(kind=ip_single_p),PARAMETER :: ip_missing_val=1.e20 00879 REAL(kind=ip_single_p), DIMENSION(myport(4,id_port_id)) :: rl_field_aux 00880 CHARACTER(len=80) :: cl_topps, cl_str 00881 CHARACTER(len=7) :: cl_tmp_topp, cl_tmp_sopp(ip_nbopp_max) 00882 #ifdef use_comm_GSIP 00883 INTEGER(kind=ip_intwp_p) :: il_rst, il_ren, il_errgsip 00884 INTEGER :: mgi_write 00885 #endif 00886 #ifdef balance 00887 CHARACTER(8) :: date 00888 CHARACTER(10) :: time 00889 CHARACTER(5) :: zone 00890 INTEGER(kind=ip_intwp_p) ,DIMENSION(8) :: values 00891 REAL(kind=ip_double_p):: millisec 00892 REAL(kind=ip_double_p):: sec_date 00893 #endif 00894 ! ---------------------------------------------------------------- 00895 ! 00896 #ifdef __VERBOSE 00897 WRITE(nulprt,*) ' ' 00898 WRITE(nulprt,*) '| | | Entering prism_put_proto_r24 for field ',id_port_id 00899 call flush(nulprt) 00900 #endif 00901 ! 00902 rl_field_aux(:)=0 00903 cl_tmp_sopp(:)=' ' 00904 il_nindex(:)=0 00905 rl_tmp_scal(:)=0 00906 ! 00907 !* 0. Entering 00908 ! ----------- 00909 ! 00910 kinfo = PRISM_Ok 00911 IF (ip_realwp_p == ip_double_p) CALL prism_abort_proto (0,'prism_put_proto', & 00912 'STOP -- PSMILe compiled with double precision REAL; prism_put_proto_r24 should not be called') 00913 lg_dgfield = .false. 00914 ! 00915 !* 1. check for this port in my list 00916 ! --------------------------------- 00917 ! 00918 isend = 0 00919 iport = -1 00920 ! 00921 ! 00922 ! Test if the field is defined in the namcouple and if its coupling period 00923 ! is not greater than the time of the simulation. 00924 IF (ig_def_freq(id_port_id) .eq. 0 .or. & 00925 ig_def_freq(id_port_id) .gt. ig_ntime) THEN 00926 GOTO 1010 00927 ENDIF 00928 ! if a field exported at a certain time should match an import 00929 ! at a time+lag, add the lag here; the lag is given by the user 00930 ! in the namcouple at the end of the field 2nd line. 00931 IF (myport(1,id_port_id).eq.CLIM_Out) THEN 00932 iport=id_port_id 00933 il_newtime = kstep + ig_def_lag(iport) 00934 ENDIF 00935 00936 IF (iport.lt.0) THEN 00937 kinfo = CLIM_BadPort 00938 WRITE(nulprt,FMT='(A,A)') & 00939 'Put - WARNING - Invalid port out: ', & 00940 cports(id_port_id) 00941 GO TO 1010 00942 ENDIF 00943 ! 00944 ! Reshape 2d field 00945 ! 00946 rd_field(1:myport(4,id_port_id)) = RESHAPE (rd_field_2d(:,:), & 00947 (/myport(4,id_port_id)/)) 00948 ! 00949 ! If the user indicated in the namcouple that the field must be 00950 ! accumulated or averaged (keyword 'AVERAGE' or 'ACCUMUL' at the 00951 ! end of the field 2nd line), do the local transformations. 00952 ! 00953 IF (ig_def_trans(iport) .EQ. ip_instant) THEN 00954 cl_str = 'inst(ident(X))' 00955 rg_field_trans(1:myport(4,id_port_id),iport) = rd_field (:) 00956 ELSEIF (ig_def_trans(iport) .eq. ip_average .or. & 00957 ig_def_trans(iport) .EQ. ip_accumul .OR. & 00958 ig_def_trans(iport) .EQ. ip_min .OR. & 00959 ig_def_trans(iport) .EQ. ip_max) THEN 00960 IF (ig_number(iport) .EQ. 0) rg_field_trans(:,iport) = 0 00961 il_nbin = myport(4,iport) 00962 il_nbout = il_nbin 00963 cl_topps = 'ave, inst, t_sum, t_min, t_max' 00964 IF (ig_def_trans(iport) .EQ. ip_average) THEN 00965 cl_str = 'ave(ident(X))' 00966 ELSEIF (ig_def_trans(iport) .EQ. ip_accumul) THEN 00967 cl_str = 't_sum(ident(X))' 00968 ELSEIF (ig_def_trans(iport) .EQ. ip_min) THEN 00969 cl_str = 't_min(ident(X))' 00970 ELSEIF (ig_def_trans(iport) .EQ. ip_max) THEN 00971 cl_str = 't_max(ident(X))' 00972 ENDIF 00973 CALL buildop (cl_str,cl_topps,cl_tmp_topp,ip_nbopp_max, & 00974 ip_missing_val,cl_tmp_sopp,rl_tmp_scal,il_nbopp) 00975 00976 CALL mathop (cl_tmp_sopp(1), il_nbin, rd_field, ip_missing_val, & 00977 ip_nbindex, il_nindex, rl_tmp_scal(1), il_nbout, & 00978 rl_field_aux) 00979 00980 IF ((cl_tmp_topp(:LEN_TRIM(cl_tmp_topp)) .NE. 'inst')) & 00981 CALL moycum(cl_tmp_topp, il_nbin, rg_field_trans(:,iport), & 00982 rl_field_aux, ig_number(iport)) 00983 ig_number(iport) = ig_number(iport) + 1 00984 IF (MOD(il_newtime,ig_def_freq(iport)) .EQ. 0) THEN 00985 ig_number(iport) = 0 00986 DO ib = 1, myport(4,iport) 00987 rd_field(ib) = rg_field_trans(ib,iport) 00988 ENDDO 00989 ENDIF 00990 kinfo = PRISM_LocTrans 00991 ENDIF 00992 ! 00993 !* Test if field must be written to restart file i.e. 00994 !* - current time is time at the end of simulation + 00995 !* - lag of current field is greater 0 00996 ! 00997 IF (il_newtime.eq.ig_ntime.and.ig_def_lag(iport).gt.0) THEN 00998 IF (ig_def_state(iport) .ne. ip_output) THEN 00999 ! 01000 !* Note: A model can have several restart files but same restart 01001 !* file can't be used by different models 01002 ! 01003 IF (mydist(CLIM_Strategy,iport) .eq. CLIM_Serial) THEN 01004 CALL write_filer4(rd_field,cports(iport),iport) 01005 ELSE 01006 CALL write_file_parar4(rd_field,cports(iport),iport) 01007 ENDIF 01008 kinfo = PRISM_ToRest 01009 ENDIF 01010 ! Test if the current time is a coupling (or I/O) time 01011 IF (mod(il_newtime,ig_def_freq(iport)).eq.0) THEN 01012 01013 #if !defined key_noIO 01014 !* If the user indicated in the namcouple that the field is 01015 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 01016 !* at the end of the field 1st line), do the writing to file here, e.g.: 01017 IF (ig_def_state(iport) .EQ. ip_output ) THEN 01018 CALL psmile_write_4(iport,rd_field,il_newtime) 01019 kinfo = PRISM_Output 01020 ELSEIF (ig_def_state(iport) .eq. ip_expout .or. & 01021 ig_def_state(iport) .EQ. ip_ignout) THEN 01022 CALL psmile_write_4(iport,rd_field,il_newtime) 01023 kinfo = PRISM_ToRestOut 01024 ENDIF 01025 #endif 01026 ENDIF 01027 ELSE 01028 ! Test if the current time is a coupling (or I/O) time 01029 IF (mod(il_newtime,ig_def_freq(iport)).eq.0) THEN 01030 ! 01031 #if !defined key_noIO 01032 !* If the user indicated in the namcouple that the field is 01033 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 01034 !* at the end of the field 1st line), do the writing to file here, e.g.: 01035 IF (ig_def_state(iport) .EQ. ip_output .OR. & 01036 ig_def_state(iport) .eq. ip_expout .or. & 01037 ig_def_state(iport) .EQ. ip_ignout) THEN 01038 CALL psmile_write_4(iport,rd_field,il_newtime) 01039 kinfo = PRISM_Output 01040 ENDIF 01041 #endif 01042 !* 01043 !* If the user indicated in the namcouple that the field is 01044 !* a coupling field (keyword EXPORTED','EXPOUT','IGNORED' or 'IGNOUT' 01045 !* at the end of the field 1st line),do the export here. 01046 !* 01047 IF (ig_def_state(iport) .eq. ip_expout .or. & 01048 ig_def_state(iport) .eq. ip_exported .or. & 01049 ig_def_state(iport) .eq. ip_ignored .or. & 01050 ig_def_state(iport) .eq. ip_ignout .or. & 01051 ig_def_state(iport) .eq. ip_auxilary) THEN 01052 ! 01053 !* check for connected ports (in) 01054 ! ------------------------------ 01055 ! 01056 #ifdef __VERBOSE 01057 WRITE(nulprt,FMT='(A,A)') 'Put - ', cports(iport) 01058 #endif 01059 ! 01060 ityp = myport(2,iport) 01061 ibyt = myport(3,iport) 01062 ! 01063 #ifdef balance 01064 CALL date_and_time(date,time,zone,values) 01065 millisec=values(8) 01066 sec_date=millisec/1000+values(7)+values(6)*60+& 01067 values(5)*3600+values(3)*86400 01068 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 01069 'Balance: ',cports(iport),'Before MPI put ',sec_date 01070 #endif 01071 DO ip=1,myport(5,iport) 01072 ! 01073 ilk = myport(5+ip,iport) 01074 imod = mylink(1,ilk) 01075 itid = mylink(2,ilk) 01076 itag = mylink(3,ilk) - il_newtime / ig_frqmin 01077 iseg = mylink(4,ilk) 01078 ! 01079 #if defined use_comm_MPI1 || defined use_comm_MPI2 01080 ilgb = 0 01081 iposbuf = 0 01082 DO is=1,iseg 01083 ioff = mylink(4+2*is-1,ilk) * 2 + 1 01084 il_len = mylink(4+2*is,ilk) 01085 ! 01086 IF ( ityp .EQ. PRISM_Real ) THEN 01087 CALL MPI_Pack ( rd_field(ioff), il_len, & 01088 MPI_REAL,pkwork_field, ig_maxtype_field, iposbuf, & 01089 mpi_comm, info ) 01090 ELSE 01091 WRITE(nulprt,*)'Put - pb type incorrect ', ityp 01092 kinfo = CLIM_BadType 01093 GO TO 1010 01094 ENDIF 01095 ilgb = ilgb + il_len 01096 ENDDO 01097 IF (info.ne.0 .or. ilgb*ibyt .gt. ig_maxtype_field) THEN 01098 kinfo = CLIM_Pack 01099 WRITE(nulprt,FMT='(A,I3,I8,A)') & 01100 'Put - pb pack<mpi ',info,ilgb*ibyt,'>' 01101 ELSE 01102 IF (lg_clim_bsend) THEN 01103 !* 01104 !* Buffered send 01105 !* -> if fields are not sent and received in the same order, and 01106 !* and on architectures on which MPI_Send is not implemented with a 01107 !* mailbox (e.g. NEC SX5) 01108 !* 01109 CALL MPI_BSend ( pkwork_field, iposbuf, MPI_PACKED, & 01110 itid, itag, mpi_comm, info ) 01111 ELSE 01112 !* 01113 !* Standard blocking send: To be used 01114 !* -> if fields are necessarily sent and received in the same order, 01115 !* -> or on architectures on which MPI_Send is implemented with a 01116 !* mailbox (e.g. VPPs); in this case, make sure that your mailbox 01117 !* size is large enough. 01118 ! 01119 CALL MPI_Send ( pkwork_field, iposbuf, MPI_PACKED, & 01120 itid, itag, mpi_comm, info ) 01121 ! 01122 ENDIF 01123 ! 01124 IF (info.eq.CLIM_ok) THEN 01125 isend = isend + 1 01126 nbsend = nbsend + ilgb * ibyt 01127 #ifdef __VERBOSE 01128 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)') & 01129 'Put - <dest:',imod, & 01130 '> <step:',il_newtime, & 01131 '> <len:',ilgb, & 01132 '> <type:',ibyt, & 01133 '> <tag:',itag,'>' 01134 #endif 01135 ELSE 01136 kinfo = CLIM_Pvm 01137 WRITE(nulprt,FMT='(A,I3,A)') & 01138 'Put - pb send <mpi ',info,'>' 01139 ENDIF 01140 ENDIF 01141 ! 01142 #elif defined use_comm_GSIP 01143 if (myport(5,iport) .ne. 1) CALL prism_abort_proto & 01144 (0,'prism_put_proto', 'STOP -- only one send to Oasis, myport(5,iport) should be 1') 01145 if (imod .ne. 0) CALL prism_abort_proto & 01146 (0,'prism_get_proto', 'STOP -- if sent to Oasis, imod should be 0') 01147 if (itid .ne. 1) CALL prism_abort_proto & 01148 (0,'prism_get_proto', 'STOP -- if sent to Oasis, itid should be 1') 01149 ! 01150 ! Fill pkworkps with segments of rd_field 01151 ilgb = 0 01152 il_rst = 0 01153 il_ren = 0 01154 DO is=1,iseg 01155 ioff = mylink(4+2*is-1,ilk) + 1 01156 il_len = mylink(4+2*is,ilk) 01157 il_rst = il_ren + 1 01158 il_ren = il_rst + il_len - 1 01159 pkworkps(il_rst:il_ren) = rd_field(ioff:ioff+il_len-1) 01160 ! 01161 ilgb = ilgb + il_len 01162 ENDDO 01163 IF (ilgb .GT. ig_CLIMmax) THEN 01164 WRITE(UNIT = nulprt,FMT = *) & 01165 '1- prism_put_proto - error :', il_errgsip 01166 CALL prism_abort_proto (0, 'prism_put_proto', & 01167 'STOP - sum of segments greater than pkworkps size') 01168 ENDIF 01169 ! 01170 ! Write the field in channel to Oasis (no DIRECT communication) 01171 il_errgsip = mgi_write (ig_gsipw, pkworkps, ig_CLIMmax, 'R') 01172 IF (il_errgsip .GE. 0) THEN 01173 WRITE(UNIT = nulprt,FMT = *) & 01174 'prism_put_proto - pkworkps written OK:', il_errgsip 01175 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)') & 01176 'Put - <dest:',imod, '> <step:',kstep,'> <len:', & 01177 ilgb, '> <type:',ibyt, '> <noproc:',itid,'>' 01178 isend = isend + 1 01179 ELSE 01180 WRITE(UNIT = nulprt,FMT = *) & 01181 '2- prism_put_proto - error :', il_errgsip 01182 CALL prism_abort_proto (0, 'prism_put_proto', & 01183 'STOP - pkworkps not written OK)') 01184 ENDIF 01185 #endif 01186 ENDDO 01187 #ifdef balance 01188 CALL date_and_time(date,time,zone,values) 01189 millisec=values(8) 01190 sec_date=millisec/1000+values(7)+values(6)*60+& 01191 values(5)*3600+values(3)*86400 01192 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 01193 'Balance: ',cports(iport),'After MPI put ',sec_date 01194 #endif 01195 ! 01196 IF (kinfo .EQ. PRISM_Output) THEN 01197 kinfo = PRISM_SentOut 01198 ELSE 01199 kinfo = PRISM_Sent 01200 ENDIF 01201 01202 #ifdef __VERBOSE 01203 WRITE(nulprt,FMT='(A,I3,A)') & 01204 'Put r24- ',isend,' fields exported' 01205 CALL FLUSH(nulprt) 01206 #endif 01207 ENDIF 01208 ENDIF 01209 ENDIF 01210 ! 01211 ! ---------------------------------------------------------------- 01212 ! 01213 1010 CONTINUE 01214 ! 01215 #ifdef __VERBOSE 01216 WRITE(nulprt,*)'| | | Leaving routine prism_put_proto_r24' 01217 WRITE(nulprt,*) ' ' 01218 CALL FLUSH(nulprt) 01219 #endif 01220 ! 01221 RETURN 01222 END SUBROUTINE prism_put_proto_r24 01223 #endif 01224 SUBROUTINE prism_put_proto_r28(id_port_id,kstep,rd_field_2d,kinfo) 01225 ! 01226 !* *** PRISM_put *** PRISM 1.0 01227 ! 01228 ! purpose: 01229 ! -------- 01230 ! give rd_field to Oasis or models connected to port id_port_id at the 01231 ! time kstep 01232 ! 01233 ! interface: 01234 ! ---------- 01235 ! id_port_id : port number of the field 01236 ! kstep : current time in seconds 01237 ! rd_field : buffer of reals 01238 ! kinfo : output status 01239 ! 01240 ! lib mp: 01241 ! ------- 01242 ! mpi-1 01243 ! 01244 ! author: 01245 ! ------- 01246 ! Arnaud Caubel - Fecit (08/02 - created from CLIM_Export) 01247 ! S. Valcke, CERFACS, 24/10/2004: Added GSIP 01248 ! ---------------------------------------------------------------- 01249 USE mod_kinds_model 01250 USE mod_prism_proto 01251 USE mod_comprism_proto 01252 USE mathelp_psmile 01253 #if defined use_comm_GSIP 01254 USE mod_gsip_model 01255 #endif 01256 IMPLICIT NONE 01257 #if defined use_comm_MPI1 || defined use_comm_MPI2 01258 #include <mpif.h> 01259 #endif 01260 ! ---------------------------------------------------------------- 01261 INTEGER (kind=ip_intwp_p) kstep, kinfo, id_port_id 01262 REAL(kind=ip_double_p), DIMENSION(:,:) :: rd_field_2d 01263 ! ---------------------------------------------------------------- 01264 REAL(kind=ip_double_p), DIMENSION(myport(4,id_port_id)) :: rd_field 01265 INTEGER (kind=ip_intwp_p) il_newtime 01266 INTEGER (kind=ip_intwp_p) info 01267 INTEGER (kind=ip_intwp_p) isend, ip, iport, ilk, iseg, is, ilgb, & 01268 imod, itid, itag, il_len, ioff, ityp, ibyt 01269 INTEGER (kind=ip_intwp_p) iposbuf 01270 INTEGER (kind=ip_intwp_p) :: ib, il_nbopp, il_nbin, il_nbout 01271 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbopp_max = 10 01272 INTEGER (kind=ip_intwp_p), PARAMETER :: ip_nbindex=1 01273 INTEGER (kind=ip_intwp_p) :: il_nindex(ip_nbindex) 01274 REAL(kind=ip_double_p) :: rl_tmp_scal(ip_nbopp_max) 01275 REAL(kind=ip_double_p),PARAMETER :: ip_missing_val=1.e20 01276 REAL(kind=ip_double_p), DIMENSION(myport(4,id_port_id)) :: rl_field_aux 01277 CHARACTER(len=80) :: cl_topps, cl_str 01278 CHARACTER(len=7) :: cl_tmp_topp, cl_tmp_sopp(ip_nbopp_max) 01279 #ifdef use_comm_GSIP 01280 INTEGER(kind=ip_intwp_p) :: il_rst, il_ren, il_errgsip 01281 INTEGER :: mgi_write 01282 #endif 01283 #ifdef balance 01284 CHARACTER(8) :: date 01285 CHARACTER(10) :: time 01286 CHARACTER(5) :: zone 01287 INTEGER(kind=ip_intwp_p) ,DIMENSION(8) :: values 01288 REAL(kind=ip_double_p):: millisec 01289 REAL(kind=ip_double_p):: sec_date 01290 #endif 01291 ! ---------------------------------------------------------------- 01292 ! 01293 #ifdef __VERBOSE 01294 WRITE(nulprt,*) ' ' 01295 WRITE(nulprt,*) '| | | Entering prism_put_proto_r28 for field ',id_port_id 01296 call flush(nulprt) 01297 #endif 01298 ! 01299 rl_field_aux(:)=0 01300 cl_tmp_sopp(:)=' ' 01301 il_nindex(:)=0 01302 rl_tmp_scal(:)=0 01303 ! 01304 !* 0. Entering 01305 ! ----------- 01306 ! 01307 kinfo = PRISM_Ok 01308 IF (ip_realwp_p == ip_single_p) CALL prism_abort_proto (0,'prism_put_proto', & 01309 'STOP -- PSMILe compiled with single precision REAL; prism_put_proto_r28 should not be called') 01310 lg_dgfield = .true. 01311 ! 01312 !* 1. check for this port in my list 01313 ! --------------------------------- 01314 ! 01315 isend = 0 01316 iport = -1 01317 ! 01318 ! 01319 ! Test if the field is defined in the namcouple and if its coupling period 01320 ! is not greater than the time of the simulation. 01321 IF (ig_def_freq(id_port_id) .eq. 0 .or. & 01322 ig_def_freq(id_port_id) .gt. ig_ntime) THEN 01323 GOTO 1010 01324 ENDIF 01325 ! if a field exported at a certain time should match an import 01326 ! at a time+lag, add the lag here; the lag is given by the user 01327 ! in the namcouple at the end of the field 2nd line. 01328 IF (myport(1,id_port_id).eq.CLIM_Out) THEN 01329 iport=id_port_id 01330 il_newtime = kstep + ig_def_lag(iport) 01331 ENDIF 01332 IF (iport.lt.0) THEN 01333 kinfo = CLIM_BadPort 01334 WRITE(nulprt,FMT='(A,A)') & 01335 'Put - WARNING - Invalid port out: ', & 01336 cports(id_port_id) 01337 GO TO 1010 01338 ENDIF 01339 ! 01340 ! Reshape the 2d field 01341 ! 01342 rd_field(1:myport(4,id_port_id)) = RESHAPE (rd_field_2d(:,:), & 01343 (/myport(4,id_port_id)/)) 01344 ! 01345 ! If the user indicated in the namcouple that the field must be 01346 ! accumulated or averaged (keyword 'AVERAGE' or 'ACCUMUL' at the 01347 ! end of the field 2nd line), do the local transformations. 01348 ! 01349 IF (ig_def_trans(iport) .EQ. ip_instant) THEN 01350 cl_str = 'inst(ident(X))' 01351 dg_field_trans(1:myport(4,id_port_id),iport) = rd_field (:) 01352 ELSEIF (ig_def_trans(iport) .EQ. ip_average .OR. & 01353 ig_def_trans(iport) .EQ. ip_accumul .OR. & 01354 ig_def_trans(iport) .EQ. ip_min .OR. & 01355 ig_def_trans(iport) .EQ. ip_max) THEN 01356 IF (ig_number(iport) .EQ. 0) dg_field_trans(:,iport) = 0 01357 il_nbin = myport(4,iport) 01358 il_nbout = il_nbin 01359 cl_topps = 'ave, inst, t_sum, t_min, t_max' 01360 IF (ig_def_trans(iport) .EQ. ip_average) THEN 01361 cl_str = 'ave(ident(X))' 01362 ELSEIF (ig_def_trans(iport) .EQ. ip_accumul) THEN 01363 cl_str = 't_sum(ident(X))' 01364 ELSEIF (ig_def_trans(iport) .EQ. ip_min) THEN 01365 cl_str = 't_min(ident(X))' 01366 ELSEIF (ig_def_trans(iport) .EQ. ip_max) THEN 01367 cl_str = 't_max(ident(X))' 01368 ENDIF 01369 CALL buildop (cl_str,cl_topps,cl_tmp_topp,ip_nbopp_max, & 01370 ip_missing_val,cl_tmp_sopp,rl_tmp_scal,il_nbopp) 01371 01372 CALL mathop (cl_tmp_sopp(1), il_nbin, rd_field, ip_missing_val, & 01373 ip_nbindex, il_nindex, rl_tmp_scal(1), il_nbout, & 01374 rl_field_aux) 01375 01376 IF ((cl_tmp_topp(:LEN_TRIM(cl_tmp_topp)) .NE. 'inst')) & 01377 CALL moycum(cl_tmp_topp, il_nbin, dg_field_trans(:,iport), & 01378 rl_field_aux, ig_number(iport)) 01379 ig_number(iport) = ig_number(iport) + 1 01380 IF (MOD(il_newtime,ig_def_freq(iport)) .EQ. 0) THEN 01381 ig_number(iport) = 0 01382 DO ib = 1, myport(4,iport) 01383 rd_field(ib) = dg_field_trans(ib,iport) 01384 ENDDO 01385 ENDIF 01386 kinfo = PRISM_LocTrans 01387 ENDIF 01388 ! 01389 !* Test if field must be written to restart file i.e. 01390 !* - current time is time at the end of simulation + 01391 !* - lag of current field is greater from 0 01392 ! 01393 IF (il_newtime.eq.ig_ntime.and.ig_def_lag(iport).gt.0) THEN 01394 IF (ig_def_state(iport) .ne. ip_output) THEN 01395 ! 01396 !* Note: A model can have several restart files but same restart 01397 !* file can't be used by different models 01398 ! 01399 IF (mydist(CLIM_Strategy,iport) .eq. CLIM_Serial) THEN 01400 CALL write_filer8(rd_field,cports(iport),iport) 01401 ELSE 01402 CALL write_file_parar8(rd_field,cports(iport),iport) 01403 ENDIF 01404 kinfo = PRISM_ToRest 01405 ENDIF 01406 ! Test if the current time is a coupling (or I/O) time 01407 IF (MOD(il_newtime,ig_def_freq(iport)).EQ.0) THEN 01408 01409 #if !defined key_noIO 01410 !* If the user indicated in the namcouple that the field is 01411 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 01412 !* at the end of the field 1st line), do the writing to file here, e.g.: 01413 IF (ig_def_state(iport) .EQ. ip_output ) THEN 01414 CALL psmile_write_8(iport,rd_field,il_newtime) 01415 kinfo = PRISM_Output 01416 ELSEIF (ig_def_state(iport) .eq. ip_expout .or. & 01417 ig_def_state(iport) .EQ. ip_ignout) THEN 01418 CALL psmile_write_8(iport,rd_field,il_newtime) 01419 kinfo = PRISM_ToRestOut 01420 ENDIF 01421 ! IF (ig_def_state(iport) .EQ. ip_output .OR. & 01422 ! ig_def_state(iport) .eq. ip_expout .or. & 01423 ! ig_def_state(iport) .EQ. ip_ignout) THEN 01424 ! CALL psmile_write_8(iport,rd_field,il_newtime) 01425 ! kinfo = PRISM_ToRestOut 01426 ! ENDIF 01427 #endif 01428 ENDIF 01429 ELSE 01430 01431 ! Test if the current time is a coupling (or I/O) time 01432 IF (mod(il_newtime,ig_def_freq(iport)).eq.0) THEN 01433 ! 01434 #if !defined key_noIO 01435 !* If the user indicated in the namcouple that the field is 01436 !* a field output-to-file (keyword 'OUTPUT', 'IGNOUT' or 'EXPOUT' 01437 !* at the end of the field 1st line), do the writing to file here, e.g.: 01438 IF (ig_def_state(iport) .EQ. ip_output .OR. & 01439 ig_def_state(iport) .eq. ip_expout .or. & 01440 ig_def_state(iport) .eq. ip_ignout) THEN 01441 call psmile_write_8(iport,rd_field,il_newtime) 01442 kinfo = PRISM_Output 01443 ENDIF 01444 #endif 01445 !* 01446 !* If the user indicated in the namcouple that the field is 01447 !* a coupling field (keyword EXPORTED','EXPOUT','IGNORED' or 'IGNOUT' 01448 !* at the end of the field 1st line),do the export here. 01449 !* 01450 IF (ig_def_state(iport) .eq. ip_expout .or. & 01451 ig_def_state(iport) .eq. ip_exported .or. & 01452 ig_def_state(iport) .eq. ip_ignored .or. & 01453 ig_def_state(iport) .eq. ip_ignout .or. & 01454 ig_def_state(iport) .eq. ip_auxilary) THEN 01455 ! 01456 !* check for connected ports (in) 01457 ! ------------------------------ 01458 ! 01459 #ifdef __VERBOSE 01460 WRITE(nulprt,FMT='(A,A)') 'Put - ', cports(iport) 01461 CALL FLUSH(nulprt) 01462 #endif 01463 ! 01464 ityp = myport(2,iport) 01465 ibyt = myport(3,iport) 01466 ! 01467 #ifdef balance 01468 CALL date_and_time(date,time,zone,values) 01469 millisec=values(8) 01470 sec_date=millisec/1000+values(7)+values(6)*60+& 01471 values(5)*3600+values(3)*86400 01472 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 01473 'Balance: ',cports(iport),'Before MPI put ',sec_date 01474 #endif 01475 DO ip=1,myport(5,iport) 01476 ! 01477 ilk = myport(5+ip,iport) 01478 imod = mylink(1,ilk) 01479 itid = mylink(2,ilk) 01480 itag = mylink(3,ilk) - il_newtime / ig_frqmin 01481 iseg = mylink(4,ilk) 01482 ! 01483 #if defined use_comm_MPI1 || defined use_comm_MPI2 01484 ilgb = 0 01485 iposbuf = 0 01486 DO is=1,iseg 01487 ioff = mylink(4+2*is-1,ilk) + 1 01488 il_len = mylink(4+2*is,ilk) 01489 ! 01490 IF ( ityp .EQ. PRISM_Real ) THEN 01491 CALL MPI_Pack(rd_field(ioff),il_len, & 01492 MPI_DOUBLE_PRECISION, & 01493 pkwork_field, ig_maxtype_field, iposbuf, & 01494 mpi_comm, info ) 01495 ELSE 01496 WRITE(nulprt,*)'Put - pb type incorrect ', ityp 01497 kinfo = CLIM_BadType 01498 GO TO 1010 01499 ENDIF 01500 ilgb = ilgb + il_len 01501 ENDDO 01502 IF (info.ne.0 .or. ilgb*ibyt .gt. ig_maxtype_field) THEN 01503 kinfo = CLIM_Pack 01504 WRITE(nulprt,FMT='(A,I3,I8,A)') & 01505 'Put - pb pack<mpi ',info,ilgb*ibyt,'>' 01506 ELSE 01507 IF (lg_clim_bsend) THEN 01508 !* 01509 !* Buffered send 01510 !* -> if fields are not sent and received in the same order, and 01511 !* and on architectures on which MPI_Send is not implemented with a 01512 !* mailbox (e.g. NEC SX5) 01513 !* 01514 CALL MPI_BSend ( pkwork_field, iposbuf, & 01515 MPI_PACKED, itid, itag, mpi_comm, info ) 01516 ELSE 01517 !* 01518 !* Standard blocking send: To be used 01519 !* -> if fields are necessarily sent and received in the same order, 01520 !* -> or on architectures on which MPI_Send is implemented with a 01521 !* mailbox (e.g. VPPs); in this case, make sure that your mailbox 01522 !* size is large enough. 01523 ! 01524 CALL MPI_Send ( pkwork_field, iposbuf, & 01525 MPI_PACKED, itid, itag, mpi_comm, info ) 01526 ! 01527 ENDIF 01528 ! 01529 IF (info.eq.CLIM_ok) THEN 01530 isend = isend + 1 01531 nbsend = nbsend + ilgb * ibyt 01532 #ifdef __VERBOSE 01533 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)') & 01534 'Put - <dest:',imod, & 01535 '> <step:',il_newtime, & 01536 '> <len:',ilgb, & 01537 '> <type:',ibyt, & 01538 '> <tag:',itag,'>' 01539 call flush(nulprt) 01540 #endif 01541 ELSE 01542 kinfo = CLIM_Pvm 01543 WRITE(nulprt,FMT='(A,I3,A)') & 01544 'Put - pb send <mpi ',info,'>' 01545 ENDIF 01546 ENDIF 01547 ! 01548 #elif defined use_comm_GSIP 01549 if (myport(5,iport) .ne. 1) CALL prism_abort_proto & 01550 (0,'prism_put_proto', 'STOP -- only one send to Oasis, myport(5,iport) should be 1') 01551 if (imod .ne. 0) CALL prism_abort_proto & 01552 (0,'prism_get_proto', 'STOP -- if sent to Oasis, imod should be 0') 01553 if (itid .ne. 1) CALL prism_abort_proto & 01554 (0,'prism_get_proto', 'STOP -- if sent to Oasis, itid should be 1') 01555 ! 01556 ! Fill pkworkps with segments of rd_field 01557 ilgb = 0 01558 il_rst = 0 01559 il_ren = 0 01560 DO is=1,iseg 01561 ioff = mylink(4+2*is-1,ilk) + 1 01562 il_len = mylink(4+2*is,ilk) 01563 il_rst = il_ren + 1 01564 il_ren = il_rst + il_len - 1 01565 pkworkps(il_rst:il_ren) = rd_field(ioff:ioff+il_len-1) 01566 ! 01567 ilgb = ilgb + il_len 01568 ENDDO 01569 IF (ilgb .GT. ig_CLIMmax) THEN 01570 WRITE(UNIT = nulprt,FMT = *) & 01571 '1- prism_put_proto - error :', il_errgsip 01572 CALL prism_abort_proto (0, 'prism_put_proto', & 01573 'STOP - sum of segments greater than pkworkps size') 01574 ENDIF 01575 ! 01576 ! Write the field in channel to Oasis (no DIRECT communication) 01577 il_errgsip = mgi_write (ig_gsipw, pkworkps, ig_CLIMmax, 'D') 01578 IF (il_errgsip .GE. 0) THEN 01579 WRITE(UNIT = nulprt,FMT = *) & 01580 'prism_put_proto - pkworkps written OK:', il_errgsip 01581 WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)') & 01582 'Put - <dest:',imod, '> <step:',kstep,'> <len:', & 01583 ilgb, '> <type:',ibyt, '> <noproc:',itid,'>' 01584 isend = isend + 1 01585 ELSE 01586 WRITE(UNIT = nulprt,FMT = *) & 01587 '2- prism_put_proto - error :', il_errgsip 01588 CALL prism_abort_proto (0, 'prism_put_proto', & 01589 'STOP - pkworkps not written OK)') 01590 ENDIF 01591 #endif 01592 ENDDO 01593 #ifdef balance 01594 CALL date_and_time(date,time,zone,values) 01595 millisec=values(8) 01596 sec_date=millisec/1000+values(7)+values(6)*60+& 01597 values(5)*3600+values(3)*86400 01598 WRITE(nulprt, FMT='(A,A,A,F11.3)') & 01599 'Balance: ',cports(iport),'After MPI put ',sec_date 01600 #endif 01601 ! 01602 IF (kinfo .EQ. PRISM_Output) THEN 01603 kinfo = PRISM_SentOut 01604 ELSE 01605 kinfo = PRISM_Sent 01606 ENDIF 01607 01608 #ifdef __VERBOSE 01609 WRITE(nulprt,FMT='(A,I3,A)') & 01610 'Put r28 - ',isend,' fields exported' 01611 CALL FLUSH(nulprt) 01612 #endif 01613 ENDIF 01614 ENDIF 01615 ENDIF 01616 ! 01617 ! ---------------------------------------------------------------- 01618 ! 01619 1010 CONTINUE 01620 ! 01621 #ifdef __VERBOSE 01622 WRITE(nulprt,*)'| | | Leaving routine prism_put_proto_r28' 01623 WRITE(nulprt,*) ' ' 01624 CALL FLUSH(nulprt) 01625 #endif 01626 ! 01627 RETURN 01628 END SUBROUTINE prism_put_proto_r28 01629 01630 end module mod_prism_put_proto 01631