prismtrs_apply_weights_2Dcons.F90

Go to the documentation of this file.
00001 !------------------------------------------------------------------------
00002 ! Copyright 2007-2010, CERFACS, Toulouse, France.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 ! !ROUTINE: PRISMTrs_Apply_weights_2Dcons
00008 !
00009 ! !INTERFACE
00010 subroutine prismtrs_apply_weights_2dcons(id_trans_out_size,   &
00011                                   dda_trans_out,       &
00012                                   id_trans_in_size,    &
00013                                   dda_trans_in,        &
00014                                   ida_mask,            &
00015                                   id_nb_links,         &  
00016                                   ida_grid1_add,       &
00017                                   ida_grid2_add,       &
00018                                   id_num_wts,          &
00019                                   dda_wts_map1,        &
00020                                   nbr_fields,          &
00021                                   id_err)
00022 !
00023 ! !USES:
00024 !
00025   USE PRISMDrv, dummy_interface => PRISMTrs_Apply_weights_2Dcons
00026   IMPLICIT NONE
00027 !
00028 ! !PARAMETERS:
00029 !
00030 ! size of the source transient
00031   INTEGER, INTENT (IN)                              :: id_trans_out_size
00032 
00033 ! Nbr of bundle components
00034   INTEGER, INTENT (IN)                              :: nbr_fields
00035 
00036 ! source transient field
00037   DOUBLE PRECISION, DIMENSION(id_trans_out_size*nbr_fields), INTENT(IN) :: dda_trans_out
00038  
00039 ! size of the target transient
00040   INTEGER, INTENT (IN)                              :: id_trans_in_size
00041 
00042 ! target transient mask
00043   INTEGER, DIMENSION(id_trans_in_size), INTENT(IN)       :: ida_mask
00044   
00045 ! number of links involved in the regridding
00046   INTEGER, INTENT (IN)                              :: id_nb_links
00047  
00048 ! source epio address for the links
00049   INTEGER, DIMENSION(id_nb_links), INTENT (IN)      :: ida_grid1_add
00050 
00051 ! target epio address for the links
00052   INTEGER, DIMENSION(id_nb_links), INTENT (IN)      :: ida_grid2_add
00053 
00054 ! Number of weights for 2D conservative remapping
00055   INTEGER, INTENT(in)                               :: id_num_wts
00056 
00057 ! weight for the links
00058   DOUBLE PRECISION, DIMENSION(id_num_wts,id_nb_links), INTENT(IN) :: dda_wts_map1
00059 
00060 !
00061 ! ! RETURN VALUE
00062 !
00063 ! transient out field
00064   DOUBLE PRECISION, DIMENSION(id_trans_in_size*nbr_fields), INTENT (Out) :: dda_trans_in
00065 
00066   INTEGER, INTENT (Out)               :: id_err   ! error value
00067 !
00068 ! !LOCAL VARIABLES
00069 !
00070 
00071 ! epio index of currently processed source cell
00072   INTEGER :: src_cell_idx
00073 ! epio index of currently/previous processed target cell
00074   INTEGER :: tgt_cell_idx, prev_tgt_cell_idx
00075 ! stride used for addressing each single field in the multiple field case
00076   INTEGER :: stride_in, stride_out
00077 ! !DESCRIPTION
00078 ! Subroutine "PRISMTrs_Interp_Apply_weights_2Dcons" performs the 
00079 ! matrix vector computation to get the field on the target grid 
00080 ! for 2D conservative remapping.
00081 !
00082 ! !REVISED HISTORY
00083 !   Date      Programmer   Description
00084 ! ----------  ----------   -----------
00085 ! 16/02/2007  S. Valcke    Creation
00086 ! 06/03/2008  J. Charles   Modifications added for the use of bundle fields
00087 !
00088 ! EOP
00089 !----------------------------------------------------------------------
00090 ! $Id: prismtrs_apply_weights_2Dcons.F90,v 1.1.2.7 2008/06/04 15:48:51 redler Exp $
00091 ! $Author: redler $
00092 !----------------------------------------------------------------------
00093 !
00094 ! Local declarations
00095 !
00096   CHARACTER(LEN=len_cvs_string), SAVE  :: mycvs = 
00097      '$Id: prismtrs_apply_weights_2Dcons.F90,v 1.1.2.7 2008/06/04 15:48:51 redler Exp $'
00098 !
00099   DOUBLE PRECISION :: 
00100      moy_tmp_S, moy_tmp_N,    ! field average at the pole
00101      moy_err_S, moy_err_N,    ! error average at the pole
00102      latpol_N, latpol_S,   
00103      dd_dif
00104 !
00105   DOUBLE PRECISION :: dst_err(id_trans_in_size)
00106 ! 
00107   INTEGER :: ib, ib_bis, i
00108   INTEGER :: compt_S, compt_N  ! number of cells representating a pole
00109 !
00110 ! ---------------------------------------------------------------------
00111 !
00112 #ifdef VERBOSE
00113   PRINT *, '| | | | | | | Enter PRISMTrs_Apply_weights_2Dcons'
00114   call psmile_flushstd
00115 #endif
00116 !
00117   id_err = 0
00118 !
00119 ! 1. For each non masked target point, apply the weights on the source field 
00120 !    to get the target field
00121 !
00122    dda_trans_in(:) = psmile_dundef
00123    stride_in = 0
00124    stride_out = 0
00125    tgt_cell_idx = -1
00126 
00127    DO i = 1, nbr_fields
00128       DO ib_bis = 1, id_nb_links, 5000
00129          DO ib = ib_bis, min(id_nb_links, ib_bis+5000-1)
00130             prev_tgt_cell_idx = tgt_cell_idx
00131             ! get the epio indices for the source and target cell of the current source-target-cell-link
00132             tgt_cell_idx = ida_grid2_add(ib) + stride_in
00133             src_cell_idx = ida_grid1_add(ib) + stride_out
00134 
00135 
00136 
00137 #ifdef PRISM_ASSERTION
00138             ! the target epio address array needs to be sorted. this is required for detecting target
00139             ! cell which have no corresponding source cell
00140             ! the sorting is done in prismtrs_prismtrs_conserv2d_weight.F90 using the routine
00141             ! prismtrs_sort_add
00142             if (tgt_cell_idx < prev_tgt_cell_idx) then
00143                print *, trim(ch_id), 'tgt_cell_idx, prev_tgt_cell_idx', &
00144                                        tgt_cell_idx, prev_tgt_cell_idx
00145                ! TODO: psmile_assert should be moved to psmile_common in order be usable within the driver/transformer
00146 !              call psmile_assert (__FILE__, __LINE__, &
00147 !                                 "source epio address array is not sorted correctly")
00148                print *, "Assertion violation: source epio address array is not sorted correctly"
00149                print *, "file", __FILE__, "line", __LINE__ - 7
00150                call psmile_flushstd
00151                call psmile_abort
00152             endif
00153 #endif
00154 
00155 #ifdef DEBUGX
00156    IF(ida_grid2_add(ib) == 2465) WRITE(88,*) 'In apply_weights_2Dcons'
00157    IF(ida_grid2_add(ib) == 2465) WRITE(88,*) ib,ida_grid2_add(ib), ida_grid1_add(ib),dda_wts_map1(1,ib)
00158    call psmile_flushstd
00159 #endif
00160             ! if the current target cell is touched for the first time => init with zero
00161             IF (prev_tgt_cell_idx .ne. tgt_cell_idx) dda_trans_in(tgt_cell_idx) = 0.0
00162             ! apply the weight for the current source-target-cell-link
00163             dda_trans_in(tgt_cell_idx) = dda_trans_in(tgt_cell_idx) &
00164                   + dda_wts_map1(1,ib) * dda_trans_out(src_cell_idx)
00165          ENDDO
00166       ENDDO
00167       ! set the strides for the next field
00168       stride_in  = stride_in  + id_trans_in_size
00169       stride_out = stride_out + id_trans_out_size
00170    ENDDO
00171   !
00172 !!$  !    Check for line of points at the poles (as done in scriprmp.F)
00173 !!$  !    ------------------------------------------------------------
00174 !!$  !
00175 !!$  !    For the north pole _N and the south pole _S
00176 !!$
00177 !!$  latpol_N = dble_pi*half
00178 !!$  latpol_S = -dble_pi*half
00179 !!$  compt_N = 0
00180 !!$  moy_tmp_N = 0d0
00181 !!$  moy_err_N = 0d0
00182 !!$  compt_S = 0
00183 !!$  moy_tmp_S = 0d0
00184 !!$  moy_err_S = 0d0
00185 !!$  !
00186 !!$  DO ib = 1, id_trans_in_size
00187 !!$    IF (dst_lat(ib) == latpol_N) THEN
00188 !!$        moy_tmp_N = moy_tmp_N + dda_trans_in(ib)
00189 !!$        compt_N = compt_N + 1
00190 !!$    ELSE IF (dst_lat(ib) == latpol_S) THEN
00191 !!$        moy_tmp_S = moy_tmp_S + dda_trans_in(ib)
00192 !!$        compt_S = compt_S + 1
00193 !!$    END IF
00194 !!$  ENDDO
00195 !!$  !
00196 !!$  IF (compt_N/=0) THEN
00197 !!$      moy_tmp_N = moy_tmp_N/compt_N
00198 !!$      DO ib = 1, id_trans_in_size
00199 !!$        IF (dst_lat(ib) == latpol_N) THEN
00200 !!$            dst_err(ib) = abs(moy_tmp_N - dda_trans_in(ib))
00201 !!$            moy_err_N = moy_err_N + dst_err(ib)
00202 !!$            dda_trans_in(ib) = moy_tmp_N
00203 !!$        END IF
00204 !!$      END DO
00205 !!$      moy_err_N = moy_err_N/compt_N
00206 !!$      PRINT*, 'Points at the pole N'
00207 !!$      PRINT*, 'Average value at the pole : ', moy_tmp_N
00208 !!$      PRINT*, 'Average error at the pole : ', moy_err_N
00209 !!$  ELSE
00210 !!$      PRINT*, 'No point at the pole N'
00211 !!$  END IF
00212 !!$  !
00213 !!$  IF (compt_S/=0) THEN
00214 !!$      moy_tmp_S = moy_tmp_S/compt_S
00215 !!$      DO ib = 1, id_trans_in_size
00216 !!$        IF (dst_lat(ib) == latpol_S) THEN
00217 !!$            dst_err(ib) = ABS(moy_tmp_S - dda_trans_in(ib))
00218 !!$            moy_err_S = moy_err_S + dst_err(ib)
00219 !!$            dda_trans_in(ib) = moy_tmp_S
00220 !!$        END IF
00221 !!$      END DO
00222 !!$      moy_err_S = moy_err_S/compt_S
00223 !!$      PRINT*, 'Points at the pole S'
00224 !!$      PRINT*, 'Average value at the pole : ', moy_tmp_S
00225 !!$      PRINT*, 'Average error at the pole : ', moy_err_S
00226 !!$  ELSE
00227 !!$      PRINT*, 'No point at the pole S'
00228 !!$  END IF
00229 !
00230 #ifdef VERBOSE
00231   PRINT *, '| | | | | | | Quit PRISMTrs_Apply_weights_2Dcons'
00232   call psmile_flushstd
00233 #endif
00234 
00235 END SUBROUTINE PRISMTrs_Apply_weights_2Dcons

Generated on 1 Dec 2011 for Oasis4 by  doxygen 1.6.1