|
|
◆ grid_transform_compute()
| recursive subroutine grid_transform_class::grid_transform_compute |
( |
type(grid_transform), intent(in), target |
this, |
|
|
real, dimension(:,:,:), intent(in) |
field_in, |
|
|
real, dimension(:,:,:), intent(out) |
field_out, |
|
|
type(vol7d_var), intent(in), optional |
var, |
|
|
real, dimension(:,:,:), intent(in), optional, target |
coord_3d_in, |
|
|
logical, dimension(:), intent(in), optional |
zlist |
|
) |
| |
|
private |
Compute the output data array from input data array according to the defined transformation.
The grid_transform object this must have been properly initialised, so that it contains all the information needed for computing the transformation. This is the grid-to-grid and grid-to-sparse points version. In the case of grid-to-sparse points transformation, the output argument is still a 2-d array with shape (np,1), which may have to be reshaped and assigned to the target 1-d array after the subroutine call by means of the RESHAPE() intrinsic function.
- Parametri
-
| [in] | this | grid_transformation object |
| [in] | field_in | input array |
| [out] | field_out | output array |
| [in] | var | physical variable to be interpolated, if provided, some ad-hoc algorithms may be used where possible |
| [in] | coord_3d_in | input vertical coordinate for vertical interpolation, if not provided by other means |
| [in] | zlist | list of levels actually present in input volume, if provided, levels marked as .FALSE. will not be interpolated regardless of their content (optimisation to avoid interpolating missing data) |
Definizione alla linea 3157 del file grid_transform_class.F90.
3159 ELSE IF (this%trans%sub_type == 'stddev' .OR. & 3160 this%trans%sub_type == 'stddevnm1') THEN 3162 IF (this%trans%sub_type == 'stddev') THEN 3168 navg = this%trans%box_info%npx*this%trans%box_info%npy 3170 IF (.NOT.lzlist(k)) cycle 3172 DO j = 1, this%inny - this%trans%box_info%npy + 1, this%trans%box_info%npy 3173 je = j+this%trans%box_info%npy-1 3176 DO i = 1, this%innx - this%trans%box_info%npx + 1, this%trans%box_info%npx 3177 ie = i+this%trans%box_info%npx-1 3179 field_out(ii,jj,k) = stat_stddev( & 3180 reshape(field_in(i:ie,j:je,k),(/navg/)), nm1=nm1) 3185 ELSE IF (this%trans%sub_type == 'max') THEN 3187 IF (.NOT.lzlist(k)) cycle 3189 DO j = 1, this%inny - this%trans%box_info%npy + 1, this%trans%box_info%npy 3190 je = j+this%trans%box_info%npy-1 3193 DO i = 1, this%innx - this%trans%box_info%npx + 1, this%trans%box_info%npx 3194 ie = i+this%trans%box_info%npx-1 3196 navg = count(field_in(i:ie,j:je,k) /= rmiss) 3198 field_out(ii,jj,k) = maxval(field_in(i:ie,j:je,k), & 3199 mask=(field_in(i:ie,j:je,k) /= rmiss)) 3205 ELSE IF (this%trans%sub_type == 'min') THEN 3207 IF (.NOT.lzlist(k)) cycle 3209 DO j = 1, this%inny - this%trans%box_info%npy + 1, this%trans%box_info%npy 3210 je = j+this%trans%box_info%npy-1 3213 DO i = 1, this%innx - this%trans%box_info%npx + 1, this%trans%box_info%npx 3214 ie = i+this%trans%box_info%npx-1 3216 navg = count(field_in(i:ie,j:je,k) /= rmiss) 3218 field_out(ii,jj,k) = minval(field_in(i:ie,j:je,k), & 3219 mask=(field_in(i:ie,j:je,k) /= rmiss)) 3225 ELSE IF (this%trans%sub_type == 'percentile') THEN 3227 navg = this%trans%box_info%npx*this%trans%box_info%npy 3229 IF (.NOT.lzlist(k)) cycle 3231 DO j = 1, this%inny - this%trans%box_info%npy + 1, this%trans%box_info%npy 3232 je = j+this%trans%box_info%npy-1 3235 DO i = 1, this%innx - this%trans%box_info%npx + 1, this%trans%box_info%npx 3236 ie = i+this%trans%box_info%npx-1 3238 field_out(ii:ii,jj,k) = stat_percentile( & 3239 reshape(field_in(i:ie,j:je,k),(/navg/)), & 3240 (/ REAL(this%trans%stat_info%percentile)/)) 3245 ELSE IF (this%trans%sub_type == 'frequency') THEN 3248 IF (.NOT.lzlist(k)) cycle 3250 DO j = 1, this%inny - this%trans%box_info%npy + 1, this%trans%box_info%npy 3251 je = j+this%trans%box_info%npy-1 3254 DO i = 1, this%innx - this%trans%box_info%npx + 1, this%trans%box_info%npx 3255 ie = i+this%trans%box_info%npx-1 3257 navg = count(field_in(i:ie,j:je,k) /= rmiss) 3259 field_out(ii,jj,k) = sum(interval_info_valid( & 3260 this%trans%interval_info, field_in(i:ie,j:je,k)), & 3261 mask=(field_in(i:ie,j:je,k) /= rmiss))/navg 3269 ELSE IF (this%trans%trans_type == 'inter') THEN 3271 IF (this%trans%sub_type == 'near') THEN 3274 IF (.NOT.lzlist(k)) cycle 3275 DO j = 1, this%outny 3276 DO i = 1, this%outnx 3278 IF (c_e(this%inter_index_x(i,j))) field_out(i,j,k) = & 3279 field_in(this%inter_index_x(i,j),this%inter_index_y(i,j),k) 3285 ELSE IF (this%trans%sub_type == 'bilin') THEN 3288 IF (.NOT.lzlist(k)) cycle 3289 DO j = 1, this%outny 3290 DO i = 1, this%outnx 3292 IF (c_e(this%inter_index_x(i,j))) THEN 3294 z1=field_in(this%inter_index_x(i,j),this%inter_index_y(i,j),k) 3295 z2=field_in(this%inter_index_x(i,j)+1,this%inter_index_y(i,j),k) 3296 z3=field_in(this%inter_index_x(i,j)+1,this%inter_index_y(i,j)+1,k) 3297 z4=field_in(this%inter_index_x(i,j),this%inter_index_y(i,j)+1,k) 3299 IF (c_e(z1) .AND. c_e(z2) .AND. c_e(z3) .AND. c_e(z4)) THEN 3301 x1=this%inter_x(this%inter_index_x(i,j),this%inter_index_y(i,j)) 3302 y1=this%inter_y(this%inter_index_x(i,j),this%inter_index_y(i,j)) 3303 x3=this%inter_x(this%inter_index_x(i,j)+1,this%inter_index_y(i,j)+1) 3304 y3=this%inter_y(this%inter_index_x(i,j)+1,this%inter_index_y(i,j)+1) 3306 xp=this%inter_xp(i,j) 3307 yp=this%inter_yp(i,j) 3309 field_out(i,j,k) = hbilin(z1,z2,z3,z4,x1,y1,x3,y3,xp,yp) 3317 ELSE IF (this%trans%sub_type == 'shapiro_near') THEN 3319 IF (.NOT.lzlist(k)) cycle 3320 DO j = 1, this%outny 3321 DO i = 1, this%outnx 3323 IF (c_e(this%inter_index_x(i,j))) THEN 3325 IF(this%inter_index_x(i,j)-1>0) THEN 3326 z(1) = field_in(this%inter_index_x(i,j)-1,this%inter_index_y(i,j) ,k) 3330 IF(this%inter_index_x(i,j)+1<=this%outnx) THEN 3331 z(3)=field_in(this%inter_index_x(i,j)+1,this%inter_index_y(i,j) ,k) 3335 IF(this%inter_index_y(i,j)+1<=this%outny) THEN 3336 z(2)=field_in(this%inter_index_x(i,j) ,this%inter_index_y(i,j)+1,k) 3340 IF(this%inter_index_y(i,j)-1>0) THEN 3341 z(4)=field_in(this%inter_index_x(i,j), this%inter_index_y(i,j)-1,k) 3345 field_out(i,j,k) = shapiro(z,field_in(this%inter_index_x(i,j),this%inter_index_y(i,j),k)) 3354 ELSE IF (this%trans%trans_type == 'intersearch') THEN 3357 likethis%trans%trans_type = 'inter' 3358 CALL grid_transform_compute(likethis, field_in, field_out, var, coord_3d_in, zlist) 3359 CALL getenv( 'LIBSIM_DISABLEOPTSEARCH', env_var) 3360 optsearch = len_trim(env_var) == 0 3363 IF (.NOT.lzlist(k)) cycle 3364 IF ((.NOT.all(c_e(field_out(:,:,k)))) .AND. (any(c_e(field_in(:,:,k))))) THEN 3365 DO j = 1, this%outny 3366 DO i = 1, this%outnx 3367 IF (.NOT.c_e(field_out(i,j,k))) THEN 3371 ix = this%inter_index_x(i,j) 3372 iy = this%inter_index_y(i,j) 3373 DO s = 0, max(this%innx, this%inny) 3375 DO m = iy-s, iy+s, max(2*s, 1) 3376 IF (m < 1 .OR. m > this%inny) cycle 3377 DO l = max(1, ix-s), min(this%innx, ix+s) 3378 disttmp = (this%inter_xp(i,j) - this%inter_x(l,m))**2 + (this%inter_yp(i,j) - this%inter_y(l,m))**2 3379 IF (c_e(field_in(l,m,k))) THEN 3380 IF (disttmp < dist) THEN 3382 field_out(i,j,k) = field_in(l,m,k) 3384 ELSE IF (disttmp == dist) THEN 3385 field_out(i,j,k) = field_out(i,j,k) + field_in(l,m,k) 3386 nearcount = nearcount + 1 3389 IF (disttmp < dist) farenough = .false. 3392 DO m = max(1, iy-s+1), min(this%inny, iy+s-1) 3393 DO l = ix-s, ix+s, 2*s 3394 IF (l < 1 .OR. l > this%innx) cycle 3395 disttmp = (this%inter_xp(i,j) - this%inter_x(l,m))**2 + (this%inter_yp(i,j) - this%inter_y(l,m))**2 3396 IF (c_e(field_in(l,m,k))) THEN 3397 IF (disttmp < dist) THEN 3399 field_out(i,j,k) = field_in(l,m,k) 3401 ELSE IF (disttmp == dist) THEN 3402 field_out(i,j,k) = field_out(i,j,k) + field_in(l,m,k) 3403 nearcount = nearcount + 1 3406 IF (disttmp < dist) farenough = .false. 3409 IF (s > 0 .AND. farenough) EXIT 3414 IF (c_e(field_in(l,m,k))) THEN 3415 disttmp = (this%inter_xp(i,j) - this%inter_x(l,m))**2 + (this%inter_yp(i,j) - this%inter_y(l,m))**2 3416 IF (disttmp < dist) THEN 3418 field_out(i,j,k) = field_in(l,m,k) 3420 ELSE IF (disttmp == dist) THEN 3421 field_out(i,j,k) = field_out(i,j,k) + field_in(l,m,k) 3422 nearcount = nearcount + 1 3429 IF (nearcount > 1) field_out(i,j,k) = field_out(i,j,k)/nearcount 3436 ELSE IF (this%trans%trans_type == 'boxinter' & 3437 .OR. this%trans%trans_type == 'polyinter' & 3438 .OR. this%trans%trans_type == 'maskinter') THEN 3440 IF (this%trans%sub_type == 'average') THEN 3442 IF (vartype == var_dir360) THEN 3444 IF (.NOT.lzlist(k)) cycle 3445 DO j = 1, this%outny 3446 DO i = 1, this%outnx 3447 field_out(i,j,k) = find_prevailing_direction(field_in(:,:,k), & 3449 mask=this%inter_index_x(:,:) == i .AND. this%inter_index_y(:,:) == j) 3455 ALLOCATE(nval(this%outnx, this%outny)) 3456 field_out(:,:,:) = 0.0 3458 IF (.NOT.lzlist(k)) cycle 3462 IF (c_e(this%inter_index_x(i,j)) .AND. c_e(field_in(i,j,k))) THEN 3463 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) = & 3464 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) + & 3466 nval(this%inter_index_x(i,j),this%inter_index_y(i,j)) = & 3467 nval(this%inter_index_x(i,j),this%inter_index_y(i,j)) + 1 3471 WHERE (nval(:,:) /= 0) 3472 field_out(:,:,k) = field_out(:,:,k)/nval(:,:) 3474 field_out(:,:,k) = rmiss 3480 ELSE IF (this%trans%sub_type == 'stddev' .OR. & 3481 this%trans%sub_type == 'stddevnm1') THEN 3483 IF (this%trans%sub_type == 'stddev') THEN 3489 IF (.NOT.lzlist(k)) cycle 3490 DO j = 1, this%outny 3491 DO i = 1, this%outnx 3493 field_out(i:i,j,k) = stat_stddev( & 3494 reshape(field_in(:,:,k), (/ SIZE(field_in(:,:,k))/)), & 3495 mask=reshape((this%inter_index_x == i .AND. & 3496 this%inter_index_y == j), (/ SIZE(field_in(:,:,k))/)), nm1=nm1) 3501 ELSE IF (this%trans%sub_type == 'max') THEN 3504 IF (.NOT.lzlist(k)) cycle 3507 IF (c_e(this%inter_index_x(i,j)) .AND. c_e(field_in(i,j,k))) THEN 3508 IF (c_e(field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k))) THEN 3509 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) = & 3510 max(field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k), & 3513 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) = & 3522 ELSE IF (this%trans%sub_type == 'min') THEN 3525 IF (.NOT.lzlist(k)) cycle 3528 IF (c_e(this%inter_index_x(i,j)) .AND. c_e(field_in(i,j,k))) THEN 3529 IF (c_e(field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k))) THEN 3530 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) = & 3531 min(field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k), & 3534 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) = & 3542 ELSE IF (this%trans%sub_type == 'percentile') THEN 3545 IF (.NOT.lzlist(k)) cycle 3546 DO j = 1, this%outny 3547 DO i = 1, this%outnx 3549 field_out(i:i,j,k) = stat_percentile( & 3550 reshape(field_in(:,:,k), (/ SIZE(field_in(:,:,k))/)), & 3551 (/ REAL(this%trans%stat_info%percentile)/), & 3552 mask=reshape((this%inter_index_x == i .AND. & 3553 this%inter_index_y == j), (/ SIZE(field_in(:,:,k))/))) 3558 ELSE IF (this%trans%sub_type == 'frequency') THEN 3560 ALLOCATE(nval(this%outnx, this%outny)) 3562 IF (.NOT.lzlist(k)) cycle 3563 field_out(:,:,k) = 0.0 3567 IF (c_e(this%inter_index_x(i,j)) .AND. c_e(field_in(i,j,k))) THEN 3568 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) = & 3569 field_out(this%inter_index_x(i,j),this%inter_index_y(i,j),k) + & 3570 interval_info_valid(this%trans%interval_info, field_in(i,j,k)) 3571 nval(this%inter_index_x(i,j),this%inter_index_y(i,j)) = & 3572 nval(this%inter_index_x(i,j),this%inter_index_y(i,j)) + 1 3576 WHERE (nval(:,:) /= 0) 3577 field_out(:,:,k) = field_out(:,:,k)/nval(:,:) 3579 field_out(:,:,k) = rmiss 3586 ELSE IF (this%trans%trans_type == 'stencilinter') THEN 3587 np = SIZE(this%stencil,1)/2 3588 ns = SIZE(this%stencil) 3590 IF (this%trans%sub_type == 'average') THEN 3592 IF (vartype == var_dir360) THEN 3594 IF (.NOT.lzlist(k)) cycle 3595 DO j = 1, this%outny 3596 DO i = 1, this%outnx 3597 IF (c_e(this%inter_index_x(i,j))) THEN 3598 i1 = this%inter_index_x(i,j) - np 3599 i2 = this%inter_index_x(i,j) + np 3600 j1 = this%inter_index_y(i,j) - np 3601 j2 = this%inter_index_y(i,j) + np 3602 field_out(i,j,k) = find_prevailing_direction(field_in(i1:i2,j1:j2,k), & 3604 mask=this%stencil(:,:)) 3615 IF (.NOT.lzlist(k)) cycle 3616 DO j = 1, this%outny 3617 DO i = 1, this%outnx 3618 IF (c_e(this%inter_index_x(i,j))) THEN 3619 i1 = this%inter_index_x(i,j) - np 3620 i2 = this%inter_index_x(i,j) + np 3621 j1 = this%inter_index_y(i,j) - np 3622 j2 = this%inter_index_y(i,j) + np 3623 n = count(field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:)) 3625 field_out(i,j,k) = sum(field_in(i1:i2,j1:j2,k), & 3626 mask=field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:))/n 3635 ELSE IF (this%trans%sub_type == 'stddev' .OR. & 3636 this%trans%sub_type == 'stddevnm1') THEN 3638 IF (this%trans%sub_type == 'stddev') THEN 3647 IF (.NOT.lzlist(k)) cycle 3648 DO j = 1, this%outny 3649 DO i = 1, this%outnx 3650 IF (c_e(this%inter_index_x(i,j))) THEN 3651 i1 = this%inter_index_x(i,j) - np 3652 i2 = this%inter_index_x(i,j) + np 3653 j1 = this%inter_index_y(i,j) - np 3654 j2 = this%inter_index_y(i,j) + np 3656 field_out(i:i,j,k) = stat_stddev( & 3657 reshape(field_in(i1:i2,j1:j2,k), (/ns/)), & 3658 mask=reshape(field_in(i1:i2,j1:j2,k) /= rmiss .AND. & 3659 this%stencil(:,:), (/ns/)), nm1=nm1) 3666 ELSE IF (this%trans%sub_type == 'max') THEN 3671 IF (.NOT.lzlist(k)) cycle 3672 DO j = 1, this%outny 3673 DO i = 1, this%outnx 3674 IF (c_e(this%inter_index_x(i,j))) THEN 3675 i1 = this%inter_index_x(i,j) - np 3676 i2 = this%inter_index_x(i,j) + np 3677 j1 = this%inter_index_y(i,j) - np 3678 j2 = this%inter_index_y(i,j) + np 3679 n = count(field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:)) 3681 field_out(i,j,k) = maxval(field_in(i1:i2,j1:j2,k), & 3682 mask=field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:)) 3690 ELSE IF (this%trans%sub_type == 'min') THEN 3695 IF (.NOT.lzlist(k)) cycle 3696 DO j = 1, this%outny 3697 DO i = 1, this%outnx 3698 IF (c_e(this%inter_index_x(i,j))) THEN 3699 i1 = this%inter_index_x(i,j) - np 3700 i2 = this%inter_index_x(i,j) + np 3701 j1 = this%inter_index_y(i,j) - np 3702 j2 = this%inter_index_y(i,j) + np 3703 n = count(field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:)) 3705 field_out(i,j,k) = minval(field_in(i1:i2,j1:j2,k), & 3706 mask=field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:)) 3714 ELSE IF (this%trans%sub_type == 'percentile') THEN 3719 IF (.NOT.lzlist(k)) cycle 3720 DO j = 1, this%outny 3721 DO i = 1, this%outnx 3722 IF (c_e(this%inter_index_x(i,j))) THEN 3723 i1 = this%inter_index_x(i,j) - np 3724 i2 = this%inter_index_x(i,j) + np 3725 j1 = this%inter_index_y(i,j) - np 3726 j2 = this%inter_index_y(i,j) + np 3728 field_out(i:i,j,k) = stat_percentile( & 3729 reshape(field_in(i1:i2,j1:j2,k), (/ns/)), & 3730 (/ REAL(this%trans%stat_info%percentile)/), & 3731 mask=reshape(field_in(i1:i2,j1:j2,k) /= rmiss .AND. & 3732 this%stencil(:,:), (/ns/))) 3739 ELSE IF (this%trans%sub_type == 'frequency') THEN 3744 IF (.NOT.lzlist(k)) cycle 3745 DO j = 1, this%outny 3746 DO i = 1, this%outnx 3747 IF (c_e(this%inter_index_x(i,j))) THEN 3748 i1 = this%inter_index_x(i,j) - np 3749 i2 = this%inter_index_x(i,j) + np 3750 j1 = this%inter_index_y(i,j) - np 3751 j2 = this%inter_index_y(i,j) + np 3752 n = count(field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:)) 3754 field_out(i,j,k) = sum(interval_info_valid( & 3755 this%trans%interval_info, field_in(i1:i2,j1:j2,k)), & 3756 mask=field_in(i1:i2,j1:j2,k) /= rmiss .AND. this%stencil(:,:))/n 3766 ELSE IF (this%trans%trans_type == 'maskgen') THEN 3769 WHERE(c_e(this%inter_index_x(:,:))) 3770 field_out(:,:,k) = REAL(this%inter_index_x(:,:)) 3774 ELSE IF (this%trans%trans_type == 'metamorphosis') THEN 3776 IF (this%trans%sub_type == 'all') THEN 3778 field_out(:,:,:) = reshape(field_in(:,:,:), (/this%outnx,this%outny,innz/)) 3780 ELSE IF (this%trans%sub_type == 'coordbb' .OR. this%trans%sub_type == 'poly' & 3781 .OR. this%trans%sub_type == 'mask' .OR. this%trans%sub_type == 'index') THEN 3784 IF (.NOT.lzlist(k)) cycle 3786 field_out(:,1,k) = pack(field_in(:,:,k), c_e(this%point_index(:,:))) 3789 ELSE IF (this%trans%sub_type == 'maskvalid' .OR. & 3790 this%trans%sub_type == 'maskinvalid') THEN 3793 IF (.NOT.lzlist(k)) cycle 3794 WHERE (this%point_mask(:,:)) 3795 field_out(:,:,k) = field_in(:,:,k) 3799 ELSE IF (this%trans%sub_type == 'lemaskinvalid') THEN 3802 IF (.NOT.lzlist(k)) cycle 3803 WHERE (c_e(field_in(:,:,k)) .AND. field_in(:,:,k) > this%val_mask(:,:)) 3804 field_out(:,:,k) = field_in(:,:,k) 3806 field_out(:,:,k) = rmiss 3810 ELSE IF (this%trans%sub_type == 'ltmaskinvalid') THEN 3813 IF (.NOT.lzlist(k)) cycle 3814 WHERE (c_e(field_in(:,:,k)) .AND. field_in(:,:,k) >= this%val_mask(:,:)) 3815 field_out(:,:,k) = field_in(:,:,k) 3817 field_out(:,:,k) = rmiss 3821 ELSE IF (this%trans%sub_type == 'gemaskinvalid') THEN 3824 IF (.NOT.lzlist(k)) cycle 3825 WHERE (c_e(field_in(:,:,k)) .AND. field_in(:,:,k) < this%val_mask(:,:)) 3826 field_out(:,:,k) = field_in(:,:,k) 3828 field_out(:,:,k) = rmiss 3832 ELSE IF (this%trans%sub_type == 'gtmaskinvalid') THEN 3835 IF (.NOT.lzlist(k)) cycle 3836 WHERE (c_e(field_in(:,:,k)) .AND. field_in(:,:,k) <= this%val_mask(:,:)) 3837 field_out(:,:,k) = field_in(:,:,k) 3839 field_out(:,:,k) = rmiss 3843 ELSE IF (this%trans%sub_type == 'setinvalidto') THEN 3846 IF (.NOT.lzlist(k)) cycle 3847 WHERE (c_e(field_in(:,:,k))) 3848 field_out(:,:,k) = field_in(:,:,k) 3850 field_out(:,:,k) = this%val1 3854 ELSE IF (this%trans%sub_type == 'settoinvalid') THEN 3855 IF (c_e(this%val1) .AND. c_e(this%val2)) THEN 3856 WHERE (c_e(field_in(:,:,:)) .AND. field_in(:,:,:) > this%val1 & 3857 .AND. field_in(:,:,:) <= this%val2) 3858 field_out(:,:,:) = rmiss 3860 field_out(:,:,:) = field_in(:,:,:) 3862 ELSE IF (c_e(this%val1)) THEN 3863 WHERE (c_e(field_in(:,:,:)) .AND. field_in(:,:,:) > this%val1) 3864 field_out(:,:,:) = rmiss 3866 field_out(:,:,:) = field_in(:,:,:) 3868 ELSE IF (c_e(this%val2)) THEN 3869 WHERE (c_e(field_in(:,:,:)) .AND. field_in(:,:,:) <= this%val2) 3870 field_out(:,:,:) = rmiss 3872 field_out(:,:,:) = field_in(:,:,:) 3877 ELSE IF (this%trans%trans_type == 'vertint') THEN 3879 IF (this%trans%sub_type == 'linear') THEN 3881 alloc_coord_3d_in_act = .false. 3882 IF ( ASSOCIATED(this%inter_index_z)) THEN 3885 IF (c_e(this%inter_index_z(k))) THEN 3886 z1 = REAL(this%inter_zp(k)) 3887 z2 = REAL(1.0D0 - this%inter_zp(k)) 3888 SELECT CASE(vartype) 3893 IF (c_e(field_in(i,j,this%inter_index_z(k))) .AND. & 3894 c_e(field_in(i,j,this%inter_index_z(k)+1))) THEN 3895 field_out(i,j,k) = & 3896 interp_var_360(field_in(i,j,this%inter_index_z(k)), & 3897 field_in(i,j,this%inter_index_z(k)+1), z1, z2) 3905 IF (c_e(field_in(i,j,this%inter_index_z(k))) .AND. & 3906 c_e(field_in(i,j,this%inter_index_z(k)+1)) .AND. & 3907 field_in(i,j,this%inter_index_z(k)) > 0. .AND. & 3908 field_in(i,j,this%inter_index_z(k)+1) > 0.) THEN 3909 field_out(i,j,k) = exp( & 3910 log(field_in(i,j,this%inter_index_z(k)))*z2 + & 3911 log(field_in(i,j,this%inter_index_z(k)+1))*z1) 3919 IF (c_e(field_in(i,j,this%inter_index_z(k))) .AND. & 3920 c_e(field_in(i,j,this%inter_index_z(k)+1))) THEN 3921 field_out(i,j,k) = & 3922 field_in(i,j,this%inter_index_z(k))*z2 + & 3923 field_in(i,j,this%inter_index_z(k)+1)*z1 3935 IF ( ALLOCATED(this%coord_3d_in)) THEN 3936 coord_3d_in_act => this%coord_3d_in 3938 CALL l4f_category_log(this%category,l4f_debug, & 3939 "Using external vertical coordinate for vertint") 3942 IF ( PRESENT(coord_3d_in)) THEN 3944 CALL l4f_category_log(this%category,l4f_debug, & 3945 "Using internal vertical coordinate for vertint") 3947 IF (this%dolog) THEN 3948 ALLOCATE(coord_3d_in_act( SIZE(coord_3d_in,1), & 3949 SIZE(coord_3d_in,2), SIZE(coord_3d_in,3))) 3950 alloc_coord_3d_in_act = .true. 3951 WHERE (c_e(coord_3d_in) .AND. coord_3d_in > 0.0) 3952 coord_3d_in_act = log(coord_3d_in) 3954 coord_3d_in_act = rmiss 3957 coord_3d_in_act => coord_3d_in 3960 CALL l4f_category_log(this%category,l4f_error, & 3961 "Missing internal and external vertical coordinate for vertint") 3967 inused = SIZE(coord_3d_in_act,3) 3968 IF (inused < 2) RETURN 3972 IF (.NOT.c_e(this%vcoord_out(k))) cycle 3976 DO kk = 1, max(inused-kkcache-1, kkcache) 3978 kkdown = kkcache - kk + 1 3980 IF (kkdown >= 1) THEN 3981 IF (this%vcoord_out(k) >= & 3982 min(coord_3d_in_act(i,j,kkdown), coord_3d_in_act(i,j,kkdown+1)) .AND. & 3983 this%vcoord_out(k) < & 3984 max(coord_3d_in_act(i,j,kkdown), coord_3d_in_act(i,j,kkdown+1))) THEN 3987 kfound = kkcache + this%levshift 3991 IF (kkup < inused) THEN 3992 IF (this%vcoord_out(k) >= & 3993 min(coord_3d_in_act(i,j,kkup), coord_3d_in_act(i,j,kkup+1)) .AND. & 3994 this%vcoord_out(k) < & 3995 max(coord_3d_in_act(i,j,kkup), coord_3d_in_act(i,j,kkup+1))) THEN 3998 kfound = kkcache + this%levshift 4005 IF (c_e(kfound)) THEN 4006 IF (c_e(field_in(i,j,kfound)) .AND. c_e(field_in(i,j,kfound+1))) THEN 4007 z1 = REAL((this%vcoord_out(k) - coord_3d_in_act(i,j,kfoundin))/ & 4008 (coord_3d_in_act(i,j,kfoundin+1) - coord_3d_in_act(i,j,kfoundin))) 4010 SELECT CASE(vartype) 4013 field_out(i,j,k) = & 4014 interp_var_360(field_in(i,j,kfound), field_in(i,j,kfound+1), z1, z2) 4016 field_out(i,j,k) = exp(log(field_in(i,j,kfound))*z2 + & 4017 log(field_in(i,j,kfound+1))*z1) 4020 field_out(i,j,k) = field_in(i,j,kfound)*z2 + field_in(i,j,kfound+1)*z1 4029 IF (alloc_coord_3d_in_act) DEALLOCATE(coord_3d_in_act) 4032 ELSE IF (this%trans%sub_type == 'linearsparse') THEN 4035 IF (.NOT. ASSOCIATED(this%vcoord_in) .AND. .NOT. PRESENT(coord_3d_in)) THEN 4036 CALL l4f_category_log(this%category,l4f_error, & 4037 "linearsparse interpolation, no input vert coord available") 4041 ALLOCATE(coord_in(innz),val_in(innz),mask_in(innz)) 4045 IF ( ASSOCIATED(this%vcoord_in)) THEN 4046 mask_in = c_e(field_in(i,j,this%levshift+1:this%levshift+this%levused)) & 4047 .AND. c_e(this%vcoord_in(:)) 4049 mask_in = c_e(field_in(i,j,this%levshift+1:this%levshift+this%levused)) & 4050 .AND. c_e(coord_3d_in(i,j,:)) 4053 IF (vartype == var_press) THEN 4054 mask_in(:) = mask_in(:) .AND. & 4055 (field_in(i,j,this%levshift+1:this%levshift+this%levused) > 0.0d0) 4057 inused = count(mask_in) 4058 IF (inused > 1) THEN 4059 IF ( ASSOCIATED(this%vcoord_in)) THEN 4060 coord_in(1:inused) = pack(this%vcoord_in(:), mask=mask_in) 4062 coord_in(1:inused) = pack(coord_3d_in(i,j,:), mask=mask_in) 4064 IF (vartype == var_press) THEN 4065 val_in(1:inused) = log(pack( & 4066 field_in(i,j,this%levshift+1:this%levshift+this%levused), & 4069 val_in(1:inused) = pack( & 4070 field_in(i,j,this%levshift+1:this%levshift+this%levused), & 4077 DO kk = 1, max(inused-kkcache-1, kkcache) 4079 kkdown = kkcache - kk + 1 4081 IF (kkdown >= 1) THEN 4082 IF (this%vcoord_out(k) >= & 4083 min(coord_in(kkdown), coord_in(kkdown+1)) .AND. & 4084 this%vcoord_out(k) < & 4085 max(coord_in(kkdown), coord_in(kkdown+1))) THEN 4092 IF (kkup < inused) THEN 4093 IF (this%vcoord_out(k) >= & 4094 min(coord_in(kkup), coord_in(kkup+1)) .AND. & 4095 this%vcoord_out(k) < & 4096 max(coord_in(kkup), coord_in(kkup+1))) THEN 4106 IF (c_e(kfound)) THEN 4107 z1 = REAL((this%vcoord_out(k) - coord_in(kfound-1))/ & 4108 (coord_in(kfound) - coord_in(kfound-1))) 4110 IF (vartype == var_dir360) THEN 4111 field_out(i,j,k) = & 4112 interp_var_360(val_in(kfound-1), val_in(kfound), z1, z2) 4113 ELSE IF (vartype == var_press) THEN 4114 field_out(i,j,k) = exp(val_in(kfound-1)*z2 + val_in(kfound)*z1) 4116 field_out(i,j,k) = val_in(kfound-1)*z2 + val_in(kfound)*z1 4126 DEALLOCATE(coord_in,val_in) 4131 ELSE IF (this%trans%trans_type == '' .OR. this%trans%trans_type == 'none') THEN 4133 field_out(:,:,:) = field_in(:,:,:) 4143 FUNCTION interp_var_360(v1, v2, w1, w2) 4144 REAL, INTENT(in) :: v1, v2, w1, w2 4145 REAL :: interp_var_360 4149 IF (abs(v1 - v2) > 180.) THEN 4157 interp_var_360 = modulo(lv1*w2 + lv2*w1, 360.) 4159 interp_var_360 = v1*w2 + v2*w1 4162 END FUNCTION interp_var_360 4165 RECURSIVE FUNCTION find_prevailing_direction(v1, l, h, res, mask) RESULT(prev) 4166 REAL, INTENT(in) :: v1(:,:) 4167 REAL, INTENT(in) :: l, h, res 4168 LOGICAL, INTENT(in), OPTIONAL :: mask(:,:) 4176 IF ((h - l) <= res) THEN 4181 IF ( PRESENT(mask)) THEN 4182 nl = count(v1 >= l .AND. v1 < m .AND. mask) 4183 nh = count(v1 >= m .AND. v1 < h .AND. mask) 4185 nl = count(v1 >= l .AND. v1 < m) 4186 nh = count(v1 >= m .AND. v1 < h) 4189 prev = find_prevailing_direction(v1, m, h, res) 4190 ELSE IF (nl > nh) THEN 4191 prev = find_prevailing_direction(v1, l, m, res) 4192 ELSE IF (nl == 0 .AND. nh == 0) THEN 4198 END FUNCTION find_prevailing_direction 4201 END SUBROUTINE grid_transform_compute 4209 SUBROUTINE grid_transform_v7d_grid_compute(this, field_in, field_out, var, & 4211 TYPE(grid_transform), INTENT(in) :: this 4212 REAL, INTENT(in) :: field_in(:,:) 4213 REAL, INTENT(out):: field_out(:,:,:) 4214 TYPE(vol7d_var), INTENT(in), OPTIONAL :: var 4215 REAL, INTENT(in), OPTIONAL, TARGET :: coord_3d_in(:,:,:) 4217 real, allocatable :: field_in_p(:),x_in_p(:),y_in_p(:) 4218 INTEGER :: inn_p, ier, k 4219 INTEGER :: innx, inny, innz, outnx, outny, outnz 4222 call l4f_category_log(this%category,l4f_debug, "start v7d_grid_transform_compute") 4225 field_out(:,:,:) = rmiss 4227 IF (.NOT.this%valid) THEN 4228 call l4f_category_log(this%category,l4f_error, & 4229 "refusing to perform a non valid transformation") 4234 innx = SIZE(field_in,1); inny = 1; innz = SIZE(field_in,2) 4235 outnx = SIZE(field_out,1); outny = SIZE(field_out,2); outnz = SIZE(field_out,3) 4238 IF (this%trans%trans_type == 'vertint') THEN 4240 IF (innz /= this%innz) THEN 4241 CALL l4f_category_log(this%category,l4f_error, "vertical interpolation") 4242 CALL l4f_category_log(this%category,l4f_error, "inconsistent input shape: "//& 4243 t2c(this%innz)// " /= "//t2c(innz)) 4248 IF (outnz /= this%outnz) THEN 4249 CALL l4f_category_log(this%category,l4f_error, "vertical interpolation") 4250 CALL l4f_category_log(this%category,l4f_error, "inconsistent output shape: "//& 4251 t2c(this%outnz)// " /= "//t2c(outnz)) 4256 IF (innx /= outnx .OR. inny /= outny) THEN 4257 CALL l4f_category_log(this%category,l4f_error, "vertical interpolation") 4258 CALL l4f_category_log(this%category,l4f_error, "inconsistent hor. sizes: "//& 4259 t2c(innx)// ","//t2c(inny)// " /= "//& 4260 t2c(outnx)// ","//t2c(outny)) 4267 IF (innx /= this%innx .OR. inny /= this%inny) THEN 4268 CALL l4f_category_log(this%category,l4f_error, "horizontal interpolation") 4269 CALL l4f_category_log(this%category,l4f_error, "inconsistent input shape: "//& 4270 t2c(this%innx)// ","//t2c(this%inny)// " /= "//& 4271 t2c(innx)// ","//t2c(inny)) 4276 IF (outnx /= this%outnx .OR. outny /= this%outny) THEN 4277 CALL l4f_category_log(this%category,l4f_error, "horizontal interpolation") 4278 CALL l4f_category_log(this%category,l4f_error, "inconsistent output shape: "//& 4279 t2c(this%outnx)// ","//t2c(this%outny)// " /= "//& 4280 t2c(outnx)// ","//t2c(outny)) 4285 IF (innz /= outnz) THEN 4286 CALL l4f_category_log(this%category,l4f_error, "horizontal interpolation") 4287 CALL l4f_category_log(this%category,l4f_error, "inconsistent vert. sizes: "//& 4288 t2c(innz)// " /= "//t2c(outnz)) 4296 call l4f_category_log(this%category,l4f_debug, & 4297 "start grid_transform_v7d_grid_compute "//trim(this%trans%trans_type)// ':'// & 4298 trim(this%trans%sub_type)) 4301 IF (this%trans%trans_type == 'inter') THEN 4303 IF (this%trans%sub_type == 'linear') THEN 4305 #ifdef HAVE_LIBNGMATH 4307 ALLOCATE(field_in_p(innx*inny), x_in_p(innx*inny), y_in_p(innx*inny)) 4309 inn_p = count(c_e(field_in(:,k))) 4311 CALL l4f_category_log(this%category,l4f_info, & 4312 "Number of sparse data points: "//t2c(inn_p)// ','//t2c( SIZE(field_in(:,k)))) 4316 field_in_p(1:inn_p) = pack(field_in(:,k), c_e(field_in(:,k))) 4317 x_in_p(1:inn_p) = pack(this%inter_xp(:,1), c_e(field_in(:,k))) 4318 y_in_p(1:inn_p) = pack(this%inter_yp(:,1), c_e(field_in(:,k))) 4320 IF (.NOT.this%trans%extrap) THEN 4321 CALL nnseti( 'ext', 0) 4322 CALL nnsetr( 'nul', rmiss) 4325 CALL natgrids(inn_p, x_in_p, y_in_p, field_in_p, & 4326 this%outnx, this%outny, REAL(this%inter_x(:,1)), & 4327 REAL(this%inter_y(1,:)), field_out(1,1,k), ier) 4330 CALL l4f_category_log(this%category,l4f_error, & 4331 "Error code from NCAR natgrids: "//t2c(ier)) 4337 CALL l4f_category_log(this%category,l4f_info, & 4338 "insufficient data in gridded region to triangulate") 4342 DEALLOCATE(field_in_p, x_in_p, y_in_p) 4345 CALL l4f_category_log(this%category,l4f_error, & 4346 "libsim compiled without NATGRIDD (ngmath ncarg library)") 4353 ELSE IF (this%trans%trans_type == 'boxinter' .OR. & 4354 this%trans%trans_type == 'polyinter' .OR. & 4355 this%trans%trans_type == 'vertint' .OR. & 4356 this%trans%trans_type == 'metamorphosis') THEN 4358 CALL compute(this, & 4359 reshape(field_in, (/ SIZE(field_in,1), 1, SIZE(field_in,2)/)), field_out, var, & 4364 END SUBROUTINE grid_transform_v7d_grid_compute 4379 ELEMENTAL FUNCTION hbilin (z1,z2,z3,z4,x1,y1,x3,y3,xp,yp) RESULT(zp) 4380 REAL, INTENT(in) :: z1,z2,z3,z4 4381 DOUBLE PRECISION, INTENT(in):: x1,y1 4382 DOUBLE PRECISION, INTENT(in):: x3,y3 4383 DOUBLE PRECISION, INTENT(in):: xp,yp 4390 p2 = REAL((yp-y1)/(y3-y1)) 4391 p1 = REAL((xp-x1)/(x3-x1))
|