00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine prismtrs_apply_grads( il_src_size, &
00012 dda_trans_out, &
00013 ida_src_mask, &
00014 il_tgt_size, &
00015 dda_trans_in, &
00016 ida_tgt_mask, &
00017 id_nb_neighbors, &
00018 ida_neighbors, &
00019 dda_weights, &
00020 nbr_fields, &
00021 id_err)
00022
00023
00024
00025 USE PRISMDrv, dummy_interface => PRISMTrs_Apply_grads
00026
00027 IMPLICIT NONE
00028
00029
00030
00031
00032
00033 INTEGER, INTENT (IN) :: il_src_size
00034
00035
00036 INTEGER, INTENT (IN) :: nbr_fields
00037
00038
00039 DOUBLE PRECISION, DIMENSION(il_src_size*nbr_fields), INTENT(IN) :: dda_trans_out
00040
00041
00042 INTEGER, DIMENSION(il_src_size), INTENT(IN) :: ida_src_mask
00043
00044
00045 INTEGER, INTENT (IN) :: il_tgt_size
00046
00047
00048 INTEGER, DIMENSION(il_tgt_size), INTENT(IN) :: ida_tgt_mask
00049
00050
00051
00052 INTEGER, INTENT (IN) :: id_nb_neighbors
00053
00054
00055 INTEGER, DIMENSION(il_tgt_size,id_nb_neighbors), INTENT (IN) ::
00056 ida_neighbors
00057 DOUBLE PRECISION, DIMENSION(il_tgt_size,id_nb_neighbors), INTENT(IN) :: dda_weights
00058
00059
00060
00061
00062
00063 DOUBLE PRECISION, DIMENSION(il_tgt_size*nbr_fields), INTENT (Out) :: dda_trans_in
00064
00065 INTEGER, INTENT (Out) :: id_err
00066
00067 DOUBLE PRECISION :: ctrl
00068
00069 DOUBLE PRECISION, DIMENSION(16) :: data
00070 INTEGER, DIMENSION(16) :: tmpmask
00071 DOUBLE PRECISION, DIMENSION(4) :: grad_i
00072 DOUBLE PRECISION, DIMENSION(4) :: grad_j
00073 DOUBLE PRECISION, DIMENSION(4) :: grad_ij
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 CHARACTER(LEN=len_cvs_string), SAVE :: mycvs =
00098 '$Id: prismtrs_apply_grads.F90 2685 2010-10-28 14:05:10Z coquart $'
00099
00100 INTEGER :: ib, ib_bis, i
00101 INTEGER :: il_count_neighbors
00102
00103
00104
00105 #ifdef VERBOSE
00106 PRINT *, '| | | | | | | Enter PRISMTrs_Apply_grads'
00107 call psmile_flushstd
00108 #endif
00109
00110 id_err = 0
00111
00112 IF ( id_nb_neighbors /= 16 ) THEN
00113 PRINT *, &
00114 '| | | | | | | | application of bicubic grads restricted to 16 points.'
00115 PRINT *, &
00116 '| | | | | | | | but number of points is ', id_nb_neighbors
00117
00118 call psmile_abort
00119
00120 ENDIF
00121
00122
00123
00124
00125 dda_trans_in(:) = 0.
00126
00127 DO i = 1, nbr_fields
00128
00129 DO ib = 1, il_tgt_size
00130
00131 ctrl = SUM(dda_weights(ib,:))
00132
00133 #ifdef DEBUGX
00134 IF ( (ib == 30) .or. (ib == 1667) ) THEN
00135 PRINT*, '++++++++++++++++++++++++++++++++++++++++++++++++++'
00136 PRINT*, ' SUM(weights(ib,1:16)) for EPIOT number ib :',ib
00137 PRINT*, '++++++++++++++++++++++++++++++++++++++++++++++++++'
00138 PRINT*, ctrl
00139 ENDIF
00140 #endif
00141
00142 IF (ida_tgt_mask(ib) == 1) THEN
00143
00144 IF ( ctrl < 0.0 ) THEN
00145
00146
00147
00148
00149
00150 il_count_neighbors = 0
00151
00152 DO ib_bis = 1, id_nb_neighbors
00153 IF (ida_neighbors(ib,ib_bis) /= 0) THEN
00154 dda_trans_in(ib+(i-1)*il_tgt_size) = dda_trans_in(ib+(i-1)*il_tgt_size) - &
00155 dda_weights(ib,ib_bis) * &
00156 dda_trans_out(ida_neighbors(ib,ib_bis)+(i-1)*il_src_size)
00157 ELSE
00158 il_count_neighbors = il_count_neighbors + 1
00159 END IF
00160
00161 IF (il_count_neighbors == id_nb_neighbors) &
00162 dda_trans_in(ib+(i-1)*il_tgt_size) = PSMILe_dundef
00163
00164 END DO
00165
00166 ELSE IF ( ctrl > 0 ) THEN
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 do ib_bis = 1, 16
00186 data(ib_bis) = dda_trans_out(ida_neighbors(ib,ib_bis)+(i-1)*il_src_size)
00187 tmpmask(ib_bis) = ida_src_mask (ida_neighbors(ib,ib_bis))
00188 enddo
00189
00190 call gradient ( tmpmask, data, grad_i, grad_j, grad_ij )
00191
00192 dda_trans_in(ib+(i-1)*il_tgt_size) = dda_weights(ib, 1) * dda_trans_out(ida_neighbors(ib, 6)+(i-1)*il_src_size) &
00193 + dda_weights(ib, 5) * dda_trans_out(ida_neighbors(ib, 7)+(i-1)*il_src_size) &
00194 + dda_weights(ib, 9) * dda_trans_out(ida_neighbors(ib,11)+(i-1)*il_src_size) &
00195 + dda_weights(ib,13) * dda_trans_out(ida_neighbors(ib,10)+(i-1)*il_src_size) &
00196
00197 + dda_weights(ib, 2) * grad_i(1) &
00198 + dda_weights(ib, 6) * grad_i(2) &
00199 + dda_weights(ib,10) * grad_i(3) &
00200 + dda_weights(ib,14) * grad_i(4) &
00201
00202 + dda_weights(ib, 3) * grad_j(1) &
00203 + dda_weights(ib, 7) * grad_j(2) &
00204 + dda_weights(ib,11) * grad_j(3) &
00205 + dda_weights(ib,15) * grad_j(4) &
00206
00207 + dda_weights(ib, 4) * grad_ij(1) &
00208 + dda_weights(ib, 8) * grad_ij(2) &
00209 + dda_weights(ib,12) * grad_ij(3) &
00210 + dda_weights(ib,16) * grad_ij(4)
00211
00212
00213 #ifdef DEBUGX
00214 IF ( (ib == 30) .or. (ib == 1667) ) THEN
00215 PRINT*
00216 PRINT*, '++++++++++++++++++++++++++++++++++++++++++++'
00217 PRINT*, 'weights(ib,1:16) for EPIOT number ib :',ib
00218 PRINT*, '++++++++++++++++++++++++++++++++++++++++++++'
00219 PRINT*, dda_weights(ib,1),dda_weights(ib,2),dda_weights(ib,3),dda_weights(ib,4)
00220 PRINT*, dda_weights(ib,5),dda_weights(ib,6),dda_weights(ib,7),dda_weights(ib,8)
00221 PRINT*, dda_weights(ib,9),dda_weights(ib,10),dda_weights(ib,11),dda_weights(ib,12)
00222 PRINT*, dda_weights(ib,13),dda_weights(ib,14),dda_weights(ib,15),dda_weights(ib,16)
00223 PRINT*, '++++++++++++++++++++++++++++++++++++++++++++'
00224 PRINT*, 'gradi,gradj,gradij for EPIOT number ib :',ib
00225 PRINT*, '++++++++++++++++++++++++++++++++++++++++++++'
00226 PRINT*, grad_i(1),grad_i(2),grad_i(3),grad_i(4)
00227 PRINT*, grad_j(1),grad_j(2),grad_j(3),grad_j(4)
00228 PRINT*, grad_ij(1),grad_ij(2),grad_ij(3),grad_ij(4)
00229 PRINT*
00230 ENDIF
00231 #endif
00232
00233 ELSE
00234
00235 dda_trans_in(ib+(i-1)*il_tgt_size) = PSMILe_dundef
00236
00237 ENDIF
00238
00239 ELSE
00240
00241
00242
00243 dda_trans_in(ib+(i-1)*il_tgt_size) = PSMILe_dundef
00244
00245 END IF
00246
00247 END DO
00248
00249 END DO
00250
00251 #ifdef VERBOSE
00252 PRINT *, '| | | | | | | Quit PRISMTrs_Apply_grads'
00253 call psmile_flushstd
00254 #endif
00255
00256 END SUBROUTINE PRISMTrs_Apply_grads
00257
00258
00259
00260 subroutine gradient (mask, data, grad_i, grad_j, grad_ij )
00261
00262 implicit none
00263
00264 double precision :: grad_i (1:4)
00265 double precision :: grad_j (1:4)
00266 double precision :: grad_ij (1:4)
00267 double precision :: data (1:16)
00268
00269 double precision :: weight, weight_i, weight_j
00270
00271 double precision :: grad_jp1
00272 double precision :: grad_jm1
00273
00274 integer :: index (1:4)
00275 integer :: mask(16)
00276
00277 integer :: i, ip1, im1, jp1, jm1
00278
00279 integer :: index_jp1 (1:4)
00280 integer :: index_jm1 (1:4)
00281
00282
00283 data index / 6, 7, 11, 10 /
00284
00285 data index_jp1 / 10, 11, 15, 14 /
00286 data index_jm1 / 2, 3, 7, 6 /
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 do i = 1, 4
00306
00307 ip1 = index(i)+1
00308 im1 = index(i)-1
00309
00310 weight = 0.5d0
00311
00312 if ( mask(ip1) == 1 .or. mask(im1) == 1 ) then
00313 if ( mask(index(i)+1) /= 1 ) then
00314 ip1 = index(i)
00315 weight = 1.0d0
00316 else if ( mask(index(i)-1) /= 1 ) then
00317 im1 = index(i)
00318 weight = 1.0d0
00319 endif
00320 grad_i(i) = weight * ( data(ip1) - data(im1) )
00321 else
00322 grad_i(i) = 0.0d0
00323 endif
00324
00325 enddo
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 do i = 1, 4
00346
00347 jp1 = index(i)+4
00348 jm1 = index(i)-4
00349
00350 weight = 0.5d0
00351
00352 if ( mask(jp1) == 1 .or. mask(jm1) == 1 ) then
00353 if ( mask(index(i)+4) /= 1 ) then
00354 jp1 = index(i)
00355 weight = 1.0d0
00356 else if ( mask(index(i)-4) /= 1 ) then
00357 jm1 = index(i)
00358 weight = 1.0d0
00359 endif
00360 grad_j(i) = weight * ( data(jp1) - data(jm1) )
00361 else
00362 grad_j(i) = 0.0d0
00363 endif
00364
00365 enddo
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 weight_j = 0.5d0
00394 grad_ij = 0.0d0
00395
00396 do i = 1, 4
00397
00398 ip1 = index_jp1(i)+1
00399 im1 = index_jp1(i)-1
00400
00401 weight_i = 0.5d0
00402 grad_jp1 = 0.0d0
00403
00404 if ( mask(index_jp1(i)+1) == 1 .or. mask(index_jp1(i)-1) == 1 ) then
00405 if ( mask(index_jp1(i)+1) /= 1 .and. mask(index_jp1(i)) == 1 ) then
00406 ip1 = index_jp1(i)
00407 weight_i = 1.0d0
00408 else if ( mask(index_jp1(i)-1) /= 1 .and. mask(index_jp1(i)) == 1 ) then
00409 im1 = index_jp1(i)
00410 weight_i = 1.0d0
00411 else
00412 weight_i = 0.0d0
00413 endif
00414 grad_jp1 = weight_i * ( data(ip1) - data(im1) )
00415 endif
00416
00417 ip1 = index_jm1(i)+1
00418 im1 = index_jm1(i)-1
00419
00420 weight_i = 0.5d0
00421 grad_jm1 = 0.0d0
00422
00423 if ( mask(index_jm1(i)+1) == 1 .or. mask(index_jm1(i)-1) == 1 ) then
00424 if ( mask(index_jm1(i)+1) /= 1 .and. mask(index_jm1(i)) == 1 ) then
00425 ip1 = index_jm1(i)
00426 weight_i = 1.0d0
00427 else if ( mask(index_jm1(i)-1) /= 1 .and. mask(index_jm1(i)) == 1 ) then
00428 im1 = index_jm1(i)
00429 weight_i = 1.0d0
00430 else
00431 weight_i = 0.0d0
00432 endif
00433 grad_jm1 = weight_i * ( data(ip1) - data(im1) )
00434 endif
00435
00436 if ( grad_jp1 /= 0.0d0 .and. grad_jm1 /= 0.0d0 ) then
00437 grad_ij(i) = weight_j * ( grad_jp1 - grad_jm1 )
00438 endif
00439
00440 enddo
00441
00442 end subroutine gradient