prismtrs_drv_exchange_util.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2008-2010, DKRZ, Hamburg, Germany.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !
00006 ! !DESCRIPTION
00007 ! Subroutines "prismdrv_[enqueue,dequeue]_in_[field,sum]_*" handle memory
00008 ! managment for the trans_in_fields and global sums buffered by 
00009 ! the driver
00010 !
00011 ! !REVISED HISTORY
00012 !   Date      Programmer   Description
00013 ! ----------  ----------   -----------
00014 ! 30/11/2009  M. Hanke     Creation
00015 
00016 subroutine prismtrs_enqueue_in_field_dble(field, field_size, exchange_id, ierror)
00017    use PRISMDrv, dummy_interface => prismtrs_enqueue_in_field_dble
00018    implicit none
00019    
00020    integer, intent(in)       :: field_size  ! size of the field * nbr_fields
00021    double precision, intent(in) 
00022                              :: field(field_size)! data that needs to be added to
00023                                             ! the array of fields
00024    integer, intent(in)       :: exchange_id ! exchange id...
00025    integer, intent(out)      :: ierror
00026 
00027    double precision, pointer :: field_array(:) ! array that contains all fields,
00028                                                ! which are waiting to be received 
00029                                                ! by a prism_get
00030    integer                   :: status         ! number of fields - 1 that are
00031                                                ! currently in the array
00032    integer                   :: allocated_fields ! number of fields, that would
00033                                                ! fit into allocated memory
00034    double precision, pointer :: temp(:)        ! temporary variable for memory allocation
00035 
00036    integer                   :: ierrp(2)
00037 
00038 ! Initialisation
00039    status           = Drv_Exchanges(exchange_id)%trans_in_status
00040    allocated_fields = Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_fields
00041 
00042 
00043 ! If there is not enough memory allocated for another additional field
00044 
00045    if (status .eq. allocated_fields+1) then
00046 
00047       allocate(temp(field_size*(allocated_fields+1)), stat=ierror)
00048       if (ierror > 0) then
00049          ierrp (1) = ierror
00050          ierrp (2) = field_size*(allocated_fields+1)
00051          call psmile_error_common ( PRISM_Error_Alloc, 'enqueue_in_field', &
00052                                     ierrp, 2, __FILE__, __LINE__ )
00053 
00054          return
00055       endif
00056 
00057       ! copy old field array into new array (if there is data)
00058       if (allocated_fields .gt.0) then
00059          temp(1:field_size*allocated_fields) = &
00060             Drv_Exchanges(exchange_id)%trans_in_field_dble
00061          deallocate(Drv_Exchanges(exchange_id)%trans_in_field_dble, stat=ierror)
00062          if (ierror > 0) then
00063             ierrp (1) = ierror
00064             call psmile_error_common(PRISM_Error_Dealloc,'enqueue_in_field',&
00065                                        ierrp, 1, __FILE__, __LINE__ )
00066             return
00067          endif
00068       endif
00069 
00070       Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_fields&
00071                 = allocated_fields +1
00072 
00073       ! set new field array
00074       Drv_Exchanges(exchange_id)%trans_in_field_dble => temp
00075 
00076    else if (status .gt. allocated_fields+1) then ! this should never happen
00077 
00078       ierrp (1) = status
00079       ierrp (2) = allocated_fields
00080       call psmile_error_common(PRISM_Error_Arg, 'enqueue_in_field_dble', &
00081                       ierrp, 1, __FILE__, __LINE__ )
00082       return
00083    endif
00084 
00085    field_array => Drv_Exchanges(exchange_id)%trans_in_field_dble
00086 
00087 !  copy new field into field array
00088    field_array(field_size*(status-1)+1: &
00089                field_size*status) = &
00090                field
00091 
00092 end subroutine prismtrs_enqueue_in_field_dble
00093 
00094 subroutine prismtrs_enqueue_in_field_real(field, field_size, exchange_id, ierror)
00095    use PRISMDrv, dummy_interface => prismtrs_enqueue_in_field_real
00096    implicit none
00097    
00098    integer, intent(in)       :: field_size  ! size of the field * nbr_fields
00099    real, intent(in)          :: field(field_size)! data that needs to be added to
00100                                             ! the array of fields
00101    integer, intent(in)       :: exchange_id ! exchange id...
00102    integer, intent(out)      :: ierror
00103 
00104    real, pointer             :: field_array(:) ! array that contains all fields,
00105                                                ! which are waiting to be received 
00106                                                ! by a prism_get
00107    integer                   :: status         ! number of fields - 1 that are
00108                                                ! currently in the array
00109    integer                   :: allocated_fields ! number of fields, that would
00110                                                ! fit into allocated memory
00111    real, pointer             :: temp(:)        ! temporary variable for memory allocation
00112 
00113    integer                   :: ierrp(2)
00114 
00115 ! Initialisation
00116    status           = Drv_Exchanges(exchange_id)%trans_in_status
00117    allocated_fields = Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_fields
00118 
00119 ! If there is not enough memory allocated for another additional field
00120    if (status .eq. allocated_fields+1) then
00121 
00122       allocate(temp(field_size*(allocated_fields+1)), stat=ierror)
00123       if (ierror > 0) then
00124          ierrp (1) = ierror
00125          ierrp (2) = field_size*(allocated_fields+1)
00126          call psmile_error_common ( PRISM_Error_Alloc, 'enqueue_in_field', &
00127                                     ierrp, 2, __FILE__, __LINE__ )
00128 
00129          return
00130       endif
00131 
00132       ! copy old field array into new array (if there is data)
00133       if (allocated_fields .gt.0) then
00134          temp(1:field_size*allocated_fields) = &
00135             Drv_Exchanges(exchange_id)%trans_in_field_real
00136          deallocate(Drv_Exchanges(exchange_id)%trans_in_field_real, stat=ierror)
00137          if (ierror > 0) then
00138             ierrp (1) = ierror
00139             call psmile_error_common(PRISM_Error_Dealloc,'enqueue_in_field',&
00140                                     ierrp, 1, __FILE__, __LINE__ )
00141             return
00142          endif
00143       endif
00144 
00145       Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_fields&
00146                 = allocated_fields +1
00147       ! set new field array
00148       Drv_Exchanges(exchange_id)%trans_in_field_real => temp
00149 
00150    else if (status .gt. allocated_fields+1) then ! this should never happen
00151 
00152       ierrp (1) = status
00153       ierrp (2) = allocated_fields
00154       call psmile_error_common(PRISM_Error_Arg, 'enqueue_in_field_real', &
00155                       ierrp, 1, __FILE__, __LINE__ )
00156       return
00157    endif
00158 
00159    field_array => Drv_Exchanges(exchange_id)%trans_in_field_real
00160 
00161 !  copy new field into field array
00162    field_array(field_size*(status-1)+1: &
00163                field_size*status) = &
00164                field
00165 
00166 end subroutine prismtrs_enqueue_in_field_real
00167 
00168 subroutine prismtrs_enqueue_in_field_int(field, field_size, exchange_id, ierror)
00169    use PRISMDrv, dummy_interface => prismtrs_enqueue_in_field_int
00170    implicit none
00171    
00172    integer, intent(in)       :: field_size  ! size of the field * nbr_fields
00173    integer, intent(in)       :: field(field_size)! data that needs to be added to
00174                                             ! the array of fields
00175    integer, intent(in)       :: exchange_id ! exchange id...
00176    integer, intent(out)      :: ierror
00177 
00178    integer, pointer          :: field_array(:) ! array that contains all fields,
00179                                                ! which are waiting to be received 
00180                                                ! by a prism_get
00181    integer                   :: status         ! number of fields - 1 that are
00182                                                ! currently in the array
00183    integer                   :: allocated_fields ! number of fields, that would
00184                                                ! fit into allocated memory
00185    integer, pointer          :: temp(:)        ! temporary variable for memory allocation
00186 
00187    integer                   :: ierrp(2)
00188 
00189 ! Initialisation
00190    status           = Drv_Exchanges(exchange_id)%trans_in_status
00191    allocated_fields = Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_fields
00192 
00193 ! If there is not enough memory allocated for another additional field
00194    if (status .eq. allocated_fields+1) then
00195 
00196       allocate(temp(field_size*(allocated_fields+1)), stat=ierror)
00197       if (ierror > 0) then
00198          ierrp (1) = ierror
00199          ierrp (2) = field_size*(allocated_fields+1)
00200          call psmile_error_common ( PRISM_Error_Alloc, 'enqueue_in_field', &
00201                                     ierrp, 2, __FILE__, __LINE__ )
00202 
00203          return
00204       endif
00205 
00206       ! copy old field array into new array (if there is data)
00207       if (allocated_fields .gt.0) then
00208          temp(1:field_size*allocated_fields) = &
00209             Drv_Exchanges(exchange_id)%trans_in_field_int
00210          deallocate(Drv_Exchanges(exchange_id)%trans_in_field_int, stat=ierror)
00211          if (ierror > 0) then
00212             ierrp (1) = ierror
00213             call psmile_error_common(PRISM_Error_Dealloc,'enqueue_in_field',&
00214                                        ierrp, 1, __FILE__, __LINE__ )
00215             return
00216          endif
00217       endif
00218 
00219       Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_fields&
00220                 = allocated_fields +1
00221 
00222       ! set new field array
00223       Drv_Exchanges(exchange_id)%trans_in_field_int => temp
00224 
00225    else if (status .gt. allocated_fields+1) then ! this should never happen
00226 
00227       ierrp (1) = status
00228       ierrp (2) = allocated_fields
00229       call psmile_error_common(PRISM_Error_Arg, 'enqueue_in_field_int', &
00230                       ierrp, 1, __FILE__, __LINE__ )
00231       return
00232    endif
00233 
00234    field_array => Drv_Exchanges(exchange_id)%trans_in_field_int
00235 
00236 !  copy new field into field array
00237    field_array(field_size*(status-1)+1: &
00238                field_size*status) = &
00239                field
00240 
00241 end subroutine prismtrs_enqueue_in_field_int
00242 
00243 subroutine prismtrs_dequeue_in_field_dble(field_size, exchange_id, ierror)
00244    use PRISMDrv, dummy_interface => prismtrs_dequeue_in_field_dble
00245    implicit none
00246    
00247    integer, intent(in)       :: field_size  ! size of the field * nbr_fields
00248    integer, intent(in)       :: exchange_id ! exchange id...
00249    integer, intent(out)      :: ierror
00250 
00251    double precision, pointer :: field_array(:) ! array that contains all fields,
00252                                                ! which are waiting to be received 
00253                                                ! by a prism_get
00254    integer                   :: status         ! number of fields - 1 that are
00255                                                ! currently in the array
00256    integer                   :: i
00257    integer                   :: ierrp(2)
00258 
00259 ! Initialisation
00260    status      =  Drv_Exchanges(exchange_id)%trans_in_status
00261    field_array => Drv_Exchanges(exchange_id)%trans_in_field_dble
00262 
00263 !  if there are still other fields in the array that need to be received by a prism_get
00264    do i=1, status
00265       field_array((i-1)*field_size+1:i*field_size) =&
00266          field_array(i*field_size+1:(i+1)*field_size)
00267    end do
00268 end subroutine prismtrs_dequeue_in_field_dble
00269 
00270 subroutine prismtrs_dequeue_in_field_real(field_size, exchange_id, ierror)
00271    use PRISMDrv, dummy_interface => prismtrs_dequeue_in_field_real
00272    implicit none
00273    
00274    integer, intent(in)       :: field_size  ! size of the field * nbr_fields
00275    integer, intent(in)       :: exchange_id ! exchange id...
00276    integer, intent(out)      :: ierror
00277 
00278    real, pointer             :: field_array(:) ! array that contains all fields,
00279                                                ! which are waiting to be received 
00280                                                ! by a prism_get
00281    integer                   :: status         ! number of fields - 1 that are
00282                                                ! currently in the array
00283    integer                   :: i
00284    integer                   :: ierrp(2)
00285 
00286 ! Initialisation
00287    status      =  Drv_Exchanges(exchange_id)%trans_in_status
00288    field_array => Drv_Exchanges(exchange_id)%trans_in_field_real
00289 
00290 !  if there are still other fields in the array that need to be received by a prism_get
00291    do i=1, status
00292       field_array((i-1)*field_size+1:i*field_size) =&
00293          field_array(i*field_size+1:(i+1)*field_size)
00294    end do
00295 end subroutine prismtrs_dequeue_in_field_real
00296 
00297 subroutine prismtrs_dequeue_in_field_int(field_size, exchange_id, ierror)
00298    use PRISMDrv, dummy_interface => prismtrs_dequeue_in_field_int
00299    implicit none
00300    
00301    integer, intent(in)       :: field_size  ! size of the field * nbr_fields
00302    integer, intent(in)       :: exchange_id ! exchange id...
00303    integer, intent(out)      :: ierror
00304 
00305    integer, pointer          :: field_array(:) ! array that contains all fields,
00306                                                ! which are waiting to be received 
00307                                                ! by a prism_get
00308    integer                   :: status         ! number of fields - 1 that are
00309                                                ! currently in the array
00310    integer                   :: i
00311    integer                   :: ierrp(2)
00312 
00313 ! Initialisation
00314    status      =  Drv_Exchanges(exchange_id)%trans_in_status
00315    field_array => Drv_Exchanges(exchange_id)%trans_in_field_int
00316 
00317 !  if there are still other fields in the array that need to be received by a prism_get
00318    do i=1, status
00319       field_array((i-1)*field_size+1:i*field_size) =&
00320          field_array(i*field_size+1:(i+1)*field_size)
00321    end do
00322 end subroutine prismtrs_dequeue_in_field_int
00323 
00324 subroutine prismtrs_enqueue_glob_sum_dble(global_sum, nbr_fields, exchange_id, ierror)
00325    use PRISMDrv, dummy_interface => prismtrs_enqueue_glob_sum_dble
00326    implicit none
00327 
00328    integer, intent(in)       :: nbr_fields  ! number of fields(one sum per field)
00329    double complex, intent(in):: global_sum(nbr_fields)
00330                                             ! global sum of the field
00331    integer, intent(in)       :: exchange_id ! exchange id...
00332    integer, intent(out)      :: ierror
00333 
00334    double complex, pointer   :: sum_array(:)   ! array that contains all sums,
00335                                                ! which are waiting to be received 
00336                                                ! by a prism_get
00337    integer                   :: status         ! number of fields - 1 that are
00338                                                ! currently in the array
00339    integer                   :: allocated_sums ! number of sums, that would
00340                                                ! fit into allocated memory
00341    double complex, pointer   :: temp(:)        ! temporary variable for memory allocation
00342 
00343    integer                   :: ierrp(2)
00344 
00345 ! Initialisation
00346    status           = Drv_Exchanges(exchange_id)%trans_in_status
00347    allocated_sums = Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_sums
00348 
00349 ! If there is not enough memory allocated for another additional global sum
00350    if (status .eq. allocated_sums+1) then
00351 
00352       allocate(temp((allocated_sums+1)*nbr_fields), stat=ierror)
00353       if (ierror > 0) then
00354          ierrp (1) = ierror
00355          ierrp (2) = (allocated_sums+1)*nbr_fields
00356          call psmile_error_common ( PRISM_Error_Alloc, 'enqueue_glob_sum', &
00357                                     ierrp, 2, __FILE__, __LINE__ )
00358 
00359          return
00360       endif
00361 
00362       ! copy old sum array into new array (if there is data)
00363       if (allocated_sums .gt.0) then
00364          temp(1:allocated_sums*nbr_fields) =&
00365             Drv_Exchanges(exchange_id)%global_sum_dble
00366 
00367          deallocate(Drv_Exchanges(exchange_id)%global_sum_dble, stat=ierror)
00368          if (ierror > 0) then
00369             ierrp (1) = ierror
00370             call psmile_error_common(PRISM_Error_Dealloc,'enqueue_glob_sum',&
00371                                     ierrp, 1, __FILE__, __LINE__ )
00372             return
00373          endif
00374       endif
00375 
00376       Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_sums&
00377                 = allocated_sums +1
00378 
00379       ! set new field array
00380       Drv_Exchanges(exchange_id)%global_sum_dble => temp
00381 
00382    else if (status .gt. allocated_sums+1) then ! this should never happen
00383 
00384       ierrp (1) = status
00385       ierrp (2) = allocated_sums
00386       call psmile_error_common(PRISM_Error_Arg, 'enqueue_glob_sum', &
00387                       ierrp, 1, __FILE__, __LINE__ )
00388       return
00389    endif
00390 
00391    sum_array => Drv_Exchanges(exchange_id)%global_sum_dble
00392 !  copy new field into field array
00393    sum_array((status-1)*nbr_fields+1:&
00394               status*nbr_fields) = global_sum
00395 
00396 end subroutine prismtrs_enqueue_glob_sum_dble
00397 
00398 subroutine prismtrs_enqueue_glob_sum_int(global_sum, nbr_fields, exchange_id, ierror)
00399    use PRISMDrv, dummy_interface => prismtrs_enqueue_glob_sum_int
00400    implicit none
00401 
00402    integer, intent(in)       :: nbr_fields  ! number of fields(one sum per field)
00403    integer, intent(in)       :: global_sum(nbr_fields)
00404                                             ! global sum of the field
00405    integer, intent(in)       :: exchange_id ! exchange id...
00406    integer, intent(out)      :: ierror
00407 
00408    integer, pointer          :: sum_array(:)   ! array that contains all sums,
00409                                                ! which are waiting to be received 
00410                                                ! by a prism_get
00411    integer                   :: status         ! number of fields - 1 that are
00412                                                ! currently in the array
00413    integer                   :: allocated_sums ! number of sums, that would
00414                                                ! fit into allocated memory
00415    integer, pointer          :: temp(:)        ! temporary variable for memory allocation
00416 
00417    integer                   :: ierrp(2)
00418 
00419 ! Initialisation
00420    status           = Drv_Exchanges(exchange_id)%trans_in_status
00421    allocated_sums = Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_sums
00422 
00423 ! If there is not enough memory allocated for another additional global sum
00424    if (status .eq. allocated_sums+1) then
00425 
00426       allocate(temp((allocated_sums+1)*nbr_fields), stat=ierror)
00427       if (ierror > 0) then
00428          ierrp (1) = ierror
00429          ierrp (2) = (allocated_sums+1)*nbr_fields
00430          call psmile_error_common ( PRISM_Error_Alloc, 'enqueue_glob_sum', &
00431                                     ierrp, 2, __FILE__, __LINE__ )
00432 
00433          return
00434       endif
00435 
00436       ! copy old sum array into new array (if there is data)
00437       if (allocated_sums .gt.0) then
00438          temp(1:allocated_sums*nbr_fields) =&
00439             Drv_Exchanges(exchange_id)%global_sum_int
00440 
00441          deallocate(Drv_Exchanges(exchange_id)%global_sum_dble, stat=ierror)
00442          if (ierror > 0) then
00443             ierrp (1) = ierror
00444             call psmile_error_common(PRISM_Error_Dealloc,'enqueue_glob_sum',&
00445                                     ierrp, 1, __FILE__, __LINE__ )
00446             return
00447          endif
00448       endif
00449 
00450       Drv_Exchanges(exchange_id)%trans_in_nbr_allocated_sums&
00451                 = allocated_sums +1
00452 
00453       ! set new field array
00454       Drv_Exchanges(exchange_id)%global_sum_int => temp
00455 
00456    else if (status .gt. allocated_sums+1) then ! this should never happen
00457 
00458       ierrp (1) = status
00459       ierrp (2) = allocated_sums
00460       call psmile_error_common(PRISM_Error_Arg, 'enqueue_glob_sum', &
00461                       ierrp, 1, __FILE__, __LINE__ )
00462       return
00463    endif
00464 
00465    sum_array => Drv_Exchanges(exchange_id)%global_sum_int
00466 !  copy new field into field array
00467    sum_array((status-1)*nbr_fields+1:&
00468               status*nbr_fields) = global_sum
00469 
00470 end subroutine prismtrs_enqueue_glob_sum_int
00471 
00472 subroutine prismtrs_dequeue_glob_sum_dble(nbr_fields, exchange_id, ierror)
00473    use PRISMDrv, dummy_interface => prismtrs_dequeue_glob_sum_dble
00474    implicit none
00475 
00476    integer, intent(in)       :: nbr_fields
00477    integer, intent(in)       :: exchange_id ! exchange id...
00478    integer, intent(out)      :: ierror
00479 
00480    double complex, pointer   :: sum_array(:)   ! array that contains all sums,
00481                                                ! which are waiting to be received 
00482                                                ! by a prism_get
00483    integer                   :: status         ! number of fields - 1 that are
00484                                                ! currently in the array
00485    integer                   :: ierrp(2)
00486 
00487 !  Initialisation
00488    status    =  Drv_Exchanges(exchange_id)%trans_in_status
00489    sum_array => Drv_Exchanges(exchange_id)%global_sum_dble
00490 
00491 !  if there are still other sums in the array copy which still need to be processes,
00492 !  copy them to an index which is lower by -1
00493    if (status > 0) sum_array(1:status*nbr_fields) = sum_array(nbr_fields+1:(status+1)*nbr_fields)
00494 
00495 end subroutine prismtrs_dequeue_glob_sum_dble
00496 
00497 subroutine prismtrs_dequeue_glob_sum_int(nbr_fields, exchange_id, ierror)
00498    use PRISMDrv, dummy_interface => prismtrs_dequeue_glob_sum_int
00499    implicit none
00500 
00501    integer, intent(in)       :: nbr_fields
00502    integer, intent(in)       :: exchange_id ! exchange id...
00503    integer, intent(out)      :: ierror
00504 
00505    integer, pointer          :: sum_array(:)   ! array that contains all sums,
00506                                                ! which are waiting to be received 
00507                                                ! by a prism_get
00508    integer                   :: status         ! number of fields - 1 that are
00509                                                ! currently in the array
00510    integer                   :: ierrp(2)
00511 
00512 !  Initialisation
00513    status    =  Drv_Exchanges(exchange_id)%trans_in_status
00514    sum_array => Drv_Exchanges(exchange_id)%global_sum_int
00515 
00516 !  if there are still other sums in the array copy which still need to be processes,
00517 !  copy them to an index which is lower by -1
00518    if (status > 0) sum_array(1:status*nbr_fields) = sum_array(nbr_fields+1:(status+1)*nbr_fields)
00519 
00520 end subroutine prismtrs_dequeue_glob_sum_int
00521 
00522 subroutine prismdrv_init_Drv_Exchange(exchange_id)
00523    use PRISMDrv, dummy_interface => prismdrv_init_Drv_Exchange
00524    implicit none
00525 
00526    integer, intent(in) :: exchange_id
00527 
00528    type(Drv_Exchange), pointer  :: exchange
00529 
00530    exchange => Drv_Exchanges(exchange_id)
00531 
00532    exchange%epio_id = PSMILe_trans_unset
00533    exchange%interp_status = PSMILe_trans_notbegun
00534    exchange%transf_id = PSMILe_trans_unset
00535    exchange%transf_status = PSMILe_trans_notbegun
00536    exchange%trans_in_request = PSMILe_trans_notrequested
00537    exchange%trans_in_status = 0
00538    exchange%trans_in_nbr_allocated_fields = 0
00539    exchange%trans_in_nbr_allocated_sums = 0
00540 
00541    Nullify(exchange%trans_in_field_dble)
00542    Nullify(exchange%trans_in_field_real)
00543    Nullify(exchange%trans_in_field_int)
00544 
00545    Nullify(exchange%global_sum_dble)
00546    Nullify(exchange%global_sum_int)
00547 
00548 end subroutine prismdrv_init_Drv_Exchange

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1