00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine prismtrs_distwght_weight_2d(id_src_size, &
00012 dda_src_lat, &
00013 dda_src_lon, &
00014 ida_src_mask, &
00015 id_tgt_size, &
00016 dda_tgt_lat, &
00017 dda_tgt_lon, &
00018 ida_tgt_mask, &
00019 id_nb_neighbors, &
00020 ida_neighbor_index, &
00021 dda_weights, &
00022 id_err)
00023
00024
00025
00026
00027 USE PRISMDrv, dummy_interface => PRISMTrs_Distwght_weight_2d
00028
00029 IMPLICIT NONE
00030
00031
00032
00033
00034
00035 INTEGER, INTENT (IN) :: id_src_size
00036 INTEGER, INTENT (IN) :: id_tgt_size
00037
00038
00039 DOUBLE PRECISION, DIMENSION(id_src_size) :: dda_src_lat
00040 DOUBLE PRECISION, DIMENSION(id_src_size) :: dda_src_lon
00041 INTEGER, DIMENSION(id_src_size), INTENT (IN) :: ida_src_mask
00042
00043
00044 DOUBLE PRECISION, DIMENSION(id_tgt_size) :: dda_tgt_lat
00045 DOUBLE PRECISION, DIMENSION(id_tgt_size) :: dda_tgt_lon
00046 INTEGER, DIMENSION(id_tgt_size), INTENT (IN) :: ida_tgt_mask
00047
00048
00049 INTEGER, INTENT (IN) :: id_nb_neighbors
00050 INTEGER, DIMENSION(id_tgt_size,id_nb_neighbors), INTENT (IN) :: ida_neighbor_index
00051
00052
00053
00054
00055
00056 DOUBLE PRECISION, DIMENSION(id_tgt_size,id_nb_neighbors), INTENT (Out) :: dda_weights
00057
00058 INTEGER, INTENT (Out) :: id_err
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 CHARACTER(LEN=len_cvs_string), SAVE :: mycvs =
00080 '$Id: prismtrs_distwght_weight_2d.F90 3241 2011-06-23 09:55:11Z coquart $'
00081
00082
00083 INTEGER :: i, ib, nb
00084
00085
00086 DOUBLE PRECISION :: rdistance, dist, arg
00087
00088 DOUBLE PRECISION :: common_grid_range(2)
00089 DOUBLE PRECISION :: shiftSize
00090
00091 #ifndef SX
00092 DOUBLE PRECISION, DIMENSION(id_nb_neighbors) :: dist2v
00093 DOUBLE PRECISION :: plat, plon
00094 DOUBLE PRECISION :: slat, slon, vec_lon
00095 #else
00096 DOUBLE PRECISION, DIMENSION(id_tgt_size,id_nb_neighbors) :: dist2v
00097 DOUBLE PRECISION, DIMENSION(id_tgt_size) :: plon, src_lons, vec_lon
00098 DOUBLE PRECISION, DIMENSION(id_tgt_size) :: splat, splon, cplon, cplat
00099 DOUBLE PRECISION, DIMENSION(id_src_size) :: sslat, sslon, cslon, cslat
00100 INTEGER :: flag(id_tgt_size)
00101 #endif
00102
00103
00104
00105 #ifdef VERBOSE
00106 PRINT *, '| | | | | | | Enter PRISMTrs_Distwght_weight_2d'
00107 call psmile_flushstd
00108 #endif
00109
00110 id_err = 0
00111 dda_weights(:,:) = 0.0d0
00112 common_grid_range(1) = 0.
00113 common_grid_range(2) = dble_pi2
00114 shiftSize = common_grid_range(2) - common_grid_range(1)
00115
00116
00117
00118
00119
00120 DO ib = 1, id_src_size
00121 DO WHILE (dda_src_lon(ib) < common_grid_range(1))
00122 dda_src_lon(ib) = dda_src_lon(ib) + shiftSize
00123 ENDDO
00124 DO WHILE (dda_src_lon(ib) >= common_grid_range(2))
00125 dda_src_lon(ib) = dda_src_lon(ib) - shiftSize
00126 ENDDO
00127 ENDDO
00128 DO ib = 1, id_tgt_size
00129 DO WHILE (dda_tgt_lon(ib) < common_grid_range(1))
00130 dda_tgt_lon(ib) = dda_tgt_lon(ib) + shiftSize
00131 ENDDO
00132 DO WHILE (dda_tgt_lon(ib) >= common_grid_range(2))
00133 dda_tgt_lon(ib) = dda_tgt_lon(ib) - shiftSize
00134 ENDDO
00135 ENDDO
00136
00137
00138
00139
00140 DO ib = 1, id_src_size
00141 IF ( (dda_src_lat(ib) > dble_pih) .OR. (dda_src_lat(ib) < -dble_pih)) THEN
00142 WRITE(*,*) 'Problem :Latitudes of source are greater than +/-90 degrees'
00143 CALL psmile_abort
00144 ENDIF
00145 ENDDO
00146 DO ib = 1, id_tgt_size
00147 IF ( (dda_tgt_lat(ib) > dble_pih) .OR. (dda_tgt_lat(ib) < -dble_pih) ) THEN
00148 WRITE(*,*) 'Problem :Latitudes of target are greater than +/-90 degrees'
00149 CALL psmile_abort
00150 ENDIF
00151 ENDDO
00152
00153 #ifndef SX
00154
00155
00156
00157
00158
00159
00160
00161
00162 DO ib = 1, id_tgt_size
00163
00164 IF (ida_tgt_mask(ib) .eq. 1) THEN
00165
00166
00167
00168 do nb = 1, id_nb_neighbors
00169 if (ida_neighbor_index(ib, nb) <= 0) exit
00170
00171 end do
00172 nb = nb - 1
00173
00174
00175
00176 IF (nb > 0) THEN
00177
00178
00179
00180 plat = dda_tgt_lat(ib)
00181 plon = dda_tgt_lon(ib)
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 DO i = 1, nb
00193 slat = dda_src_lat (ida_neighbor_index(ib, i))
00194 slon = dda_src_lon (ida_neighbor_index(ib, i))
00195
00196 vec_lon = slon - plon
00197 IF (vec_lon > dble_pi) THEN
00198 slon = slon - dble_pi2
00199 ELSE IF (vec_lon < -dble_pi) THEN
00200 slon = slon + dble_pi2
00201 ENDIF
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 arg = SIN(plat)*SIN(slat) + &
00213 COS(plat)*COS(slat) * &
00214 (COS(plon)*COS(slon) + &
00215 SIN(plon)*SIN(slon))
00216 IF (arg < -1.0d0) THEN
00217 arg = -1.0d0
00218 ELSE IF (arg > 1.0d0) THEN
00219 arg = 1.0d0
00220 END IF
00221 dist = ACOS(arg)
00222
00223
00224 dist2v(i) = SQRT(dist**2)
00225 END DO
00226
00227
00228
00229 #ifdef DEBUG
00230 if (ib == 1) print *, 'dist2v', dist2v (1:nb)
00231 #endif
00232 do i = 1, nb
00233 if (dist2v (i) .eq. 0.0d0) exit
00234 end do
00235
00236 if (i <= nb) then
00237
00238 dda_weights(ib,i) = 1.0d0
00239 else
00240
00241 dda_weights(ib,1:nb) = 1.0d0 / dist2v(1:nb)
00242 rdistance = 1.0d0 / SUM (dda_weights(ib,1:nb))
00243 dda_weights(ib,1:nb) = dda_weights(ib,1:nb) * rdistance
00244 endif
00245
00246 END IF
00247
00248 END IF
00249
00250 END DO
00251
00252 #else
00253
00254 flag(:) = 0
00255
00256 DO ib = 1, id_tgt_size
00257
00258 IF (ida_tgt_mask(ib) .EQ. 1) THEN
00259
00260 DO nb = 1, id_nb_neighbors
00261 IF (ida_neighbor_index(ib, nb) > 0) flag(ib)= flag(ib)+1
00262 END DO
00263 END IF
00264
00265 END DO
00266
00267
00268
00269
00270 DO ib = 1, id_src_size
00271 src_lons(ib) = dda_src_lon(ib)
00272 cslat(ib) = cos(dda_src_lat(ib))
00273 sslat(ib) = sin(dda_src_lat(ib))
00274 END DO
00275
00276
00277
00278 DO ib = 1, id_tgt_size
00279 plon(ib) = dda_tgt_lon(ib)
00280 cplat(ib) = cos(dda_tgt_lat(ib))
00281 cplon(ib) = cos(dda_tgt_lon(ib))
00282 splat(ib) = sin(dda_tgt_lat(ib))
00283 splon(ib) = sin(dda_tgt_lon(ib))
00284 END DO
00285
00286 DO nb = 1, id_nb_neighbors
00287 DO ib = 1, id_tgt_size
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 IF ( ida_neighbor_index(ib, nb) > 0 ) THEN
00305
00306
00307 vec_lon(ib) = src_lons (ida_neighbor_index(ib, nb)) - plon(ib)
00308 IF (vec_lon(ib) > dble_pi) THEN
00309 src_lons (ida_neighbor_index(ib, nb))= src_lons (ida_neighbor_index(ib, nb)) - dble_pi2
00310 ELSE IF (vec_lon(ib) < -dble_pi) THEN
00311 src_lons (ida_neighbor_index(ib, nb)) = src_lons (ida_neighbor_index(ib, nb)) + dble_pi2
00312 ENDIF
00313
00314 cslon(ida_neighbor_index(ib, nb)) = COS(src_lons (ida_neighbor_index(ib, nb)))
00315 sslon(ida_neighbor_index(ib, nb)) = SIN(src_lons (ida_neighbor_index(ib, nb)))
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 arg = splat(ib)*sslat(ida_neighbor_index(ib, nb)) + &
00327 cplat(ib)*cslat(ida_neighbor_index(ib, nb)) * &
00328 (cplon(ib)*cslon(ida_neighbor_index(ib, nb)) + &
00329 splon(ib)*sslon(ida_neighbor_index(ib, nb)))
00330 IF (arg < -1.0d0) THEN
00331 arg = -1.0d0
00332 ELSE IF (arg > 1.0d0) THEN
00333 arg = 1.0d0
00334 END IF
00335 dist = ACOS(arg)
00336
00337 dist2v(ib,nb) = ABS(dist**2)
00338 END IF
00339
00340 ENDDO
00341 ENDDO
00342
00343 DO ib = 1, id_tgt_size
00344
00345
00346
00347
00348 DO nb = 1, flag(ib)
00349 IF ( dist2v(ib,nb) == 0.0d0 ) exit
00350 end do
00351
00352 if (nb <= flag(ib)) then
00353 dda_weights(ib,nb) = 1.0d0
00354 else
00355 dda_weights(ib,1:flag(ib)) = 1.0d0 / dist2v(ib,1:flag(ib))
00356 endif
00357 END DO
00358
00359 DO ib = 1, id_tgt_size
00360 IF ( flag(ib) > 0 ) THEN
00361 rdistance = 1.0d0 / SUM (dda_weights(ib,1:id_nb_neighbors))
00362 dda_weights(ib,1:id_nb_neighbors) = dda_weights(ib,1:id_nb_neighbors) * rdistance
00363 ENDIF
00364 END DO
00365 #endif
00366
00367 #ifdef VERBOSE
00368 PRINT *, '| | | | | | | Quit PRISMTrs_Distwght_weight_2d'
00369 call psmile_flushstd
00370 #endif
00371
00372 END SUBROUTINE PRISMTrs_Distwght_weight_2d
00373
00374
00375
00376