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