00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 subroutine prismtrs_gauswght_weight_3d(id_src_size, &
00011 dda_src_lat, &
00012 dda_src_lon, &
00013 dda_src_z, &
00014 ida_src_mask, &
00015 id_tgt_size, &
00016 dda_tgt_lat, &
00017 dda_tgt_lon, &
00018 dda_tgt_z, &
00019 ida_tgt_mask, &
00020 dd_gaus_var, &
00021 id_nb_neighbors, &
00022 ida_neighbor_index, &
00023 dda_weights, &
00024 id_err)
00025
00026
00027
00028
00029 USE PRISMDrv, dummy_interface => PRISMTrs_Gauswght_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 DOUBLE PRECISION, INTENT (IN) :: dd_gaus_var
00056
00057
00058 INTEGER, INTENT (IN) :: id_nb_neighbors
00059 INTEGER, DIMENSION(id_tgt_size,id_nb_neighbors), INTENT (IN) :: ida_neighbor_index
00060
00061
00062
00063
00064
00065 DOUBLE PRECISION, DIMENSION(id_tgt_size,id_nb_neighbors), INTENT (Out) :: dda_weights
00066
00067 INTEGER, INTENT (Out) :: id_err
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 CHARACTER(LEN=len_cvs_string), SAVE :: mycvs =
00089 '$Id: prismtrs_gauswght_weight_3d.F90 2963 2011-02-17 14:52:53Z coquart $'
00090
00091
00092 DOUBLE PRECISION, PARAMETER :: a = 6400.0
00093
00094
00095 INTEGER :: ib, ib_bis
00096
00097
00098 DOUBLE PRECISION, DIMENSION(8) :: src_lats
00099 DOUBLE PRECISION, DIMENSION(8) :: src_lons
00100 DOUBLE PRECISION, DIMENSION(8) :: src_zs
00101 DOUBLE PRECISION, DIMENSION(8) :: vec_lon
00102 DOUBLE PRECISION :: common_grid_range(2)
00103 DOUBLE PRECISION :: shiftSize
00104
00105
00106 DOUBLE PRECISION :: plat, plon, pz, slat, slon, sz
00107
00108
00109 DOUBLE PRECISION :: arg
00110 DOUBLE PRECISION, DIMENSION(id_tgt_size) :: distance
00111 DOUBLE PRECISION, DIMENSION(id_tgt_size,id_nb_neighbors) :: dist
00112
00113
00114
00115 #ifdef VERBOSE
00116 PRINT *, '| | | | | | | Enter PRISMTrs_Gauswght_weight_3d'
00117 call psmile_flushstd
00118 #endif
00119
00120 id_err = 0
00121 dda_weights(:,:) = 0.0d0
00122 common_grid_range(1) = -dble_pi
00123 common_grid_range(2) = dble_pi
00124 shiftSize = common_grid_range(2) - common_grid_range(1)
00125
00126
00127
00128
00129
00130 DO ib = 1, id_src_size
00131 DO WHILE (dda_src_lon(ib) < common_grid_range(1))
00132 dda_src_lon(ib) = dda_src_lon(ib) + shiftSize
00133 ENDDO
00134 DO WHILE (dda_src_lon(ib) >= common_grid_range(2))
00135 dda_src_lon(ib) = dda_src_lon(ib) - shiftSize
00136 ENDDO
00137 ENDDO
00138 DO ib = 1, id_tgt_size
00139 DO WHILE (dda_tgt_lon(ib) < common_grid_range(1))
00140 dda_tgt_lon(ib) = dda_tgt_lon(ib) + shiftSize
00141 ENDDO
00142 DO WHILE (dda_tgt_lon(ib) >= common_grid_range(2))
00143 dda_tgt_lon(ib) = dda_tgt_lon(ib) - shiftSize
00144 ENDDO
00145 ENDDO
00146
00147
00148
00149
00150 DO ib = 1, id_src_size
00151 IF ( (dda_src_lat(ib) > dble_pih) .OR. (dda_src_lat(ib) < -dble_pih)) THEN
00152 WRITE(*,*) 'Problem :Latitudes of source are greater than +/-90 degrees'
00153 CALL psmile_abort
00154 ENDIF
00155 ENDDO
00156 DO ib = 1, id_tgt_size
00157 IF ( (dda_tgt_lat(ib) > dble_pih) .OR. (dda_tgt_lat(ib) < -dble_pih) ) THEN
00158 WRITE(*,*) 'Problem :Latitudes of target are greater than +/-90 degrees'
00159 CALL psmile_abort
00160 ENDIF
00161 ENDDO
00162
00163
00164
00165 DO ib = 1, id_tgt_size
00166
00167 IF (ida_tgt_mask(ib) .EQ. 1) THEN
00168
00169
00170 plat = dda_tgt_lat(ib)
00171 plon = dda_tgt_lon(ib)
00172 pz = dda_tgt_z(ib)
00173
00174
00175
00176
00177 DO ib_bis = 1, id_nb_neighbors
00178
00179 IF (ida_neighbor_index(ib, ib_bis) > 0) THEN
00180
00181 src_zs (ib_bis) = dda_src_z (ida_neighbor_index(ib, ib_bis))
00182 src_lats (ib_bis) = &
00183 dda_src_lat (ida_neighbor_index(ib, ib_bis))
00184 src_lons (ib_bis) = &
00185 dda_src_lon (ida_neighbor_index(ib, ib_bis))
00186
00187 vec_lon(ib_bis) = src_lons (ib_bis) - plon
00188 IF (vec_lon(ib_bis) > dble_pi) THEN
00189 src_lons (ib_bis)= src_lons (ib_bis) - dble_pi2
00190 ELSE IF (vec_lon(ib_bis) < -dble_pi) THEN
00191 src_lons (ib_bis) = src_lons (ib_bis) + dble_pi2
00192
00193 ENDIF
00194
00195 ENDIF
00196 END DO
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 distance = 0.
00208 DO ib_bis = 1, id_nb_neighbors
00209
00210 IF (ida_neighbor_index(ib, ib_bis) > 0) THEN
00211
00212 slat = src_lats(ib_bis)
00213 slon = src_lons(ib_bis)
00214 sz = src_zs(ib_bis)
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 arg = SIN(plat)*SIN(slat) + &
00226 COS(plat)*COS(slat) * &
00227 (COS(plon)*COS(slon) + &
00228 SIN(plon)*SIN(slon))
00229 IF (arg < -1.0d0) THEN
00230 arg = -1.0d0
00231 ELSE IF (arg > 1.0d0) THEN
00232 arg = 1.0d0
00233 END IF
00234 dist(ib,ib_bis) = (a + pz)*ACOS (arg)
00235
00236
00237 dist(ib,ib_bis) = SQRT(dist(ib,ib_bis)**2 + (pz-sz)**2)
00238 ENDIF
00239 ENDDO
00240
00241 DO ib_bis = 1, id_nb_neighbors
00242 IF (ida_neighbor_index(ib, ib_bis) > 0) THEN
00243 distance(ib) = distance(ib) + dist(ib,ib_bis)
00244 ENDIF
00245 END DO
00246
00247 distance(ib)=distance(ib)/id_nb_neighbors
00248 distance(ib)=dd_gaus_var*distance(ib)*distance(ib)
00249
00250 DO ib_bis = 1, id_nb_neighbors
00251 IF (ida_neighbor_index(ib, ib_bis) > 0) THEN
00252 dda_weights(ib,ib_bis) = &
00253 EXP(.5*dist(ib,ib_bis)*dist(ib,ib_bis)/distance(ib))
00254 dda_weights(ib,ib_bis) = 1./dda_weights(ib,ib_bis)
00255 ENDIF
00256 ENDDO
00257
00258 distance(ib) = 0.
00259 DO ib_bis = 1, id_nb_neighbors
00260 IF (ida_neighbor_index(ib, ib_bis) > 0) THEN
00261 distance(ib) = distance(ib) + dda_weights(ib,ib_bis)
00262 ENDIF
00263 END DO
00264
00265 DO ib_bis = 1, id_nb_neighbors
00266 IF (ida_neighbor_index(ib, ib_bis) > 0) THEN
00267 dda_weights(ib,ib_bis) = dda_weights(ib,ib_bis)/distance(ib)
00268 ENDIF
00269 ENDDO
00270
00271 ENDIF
00272
00273 ENDDO
00274
00275
00276 #ifdef VERBOSE
00277 PRINT *, '| | | | | | | Quit PRISMTrs_Gauswght_weight_3d'
00278 call psmile_flushstd
00279 #endif
00280
00281 END SUBROUTINE PRISMTrs_Gauswght_weight_3d
00282
00283
00284
00285