00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 subroutine psmile_apply_user_data(ierror)
00027
00028 use psmile_user_data, only : grid_data, point_data, &
00029 mask_data, var_data, &
00030 grid_id_map, point_id_map, &
00031 mask_id_map, var_id_map, &
00032 get_grid_type, get_comp_id, &
00033 generate_partition_data, &
00034 partition_data_available, &
00035 reducedgrid_map_available
00036 use psmile_multimap, only : add_pair, get_num_values, &
00037 get_values, init_multimap
00038 use psmile_common, only : ch_id, ndim_1d, ndim_2d, ndim_3d
00039 use psmile_grid, only : PRISM_Gaussreduced_regvrt, &
00040 PRISM_Gaussreduced_sigmavrt, &
00041 PRISM_Gridless, &
00042 get_size_of_shape
00043 use prism_constants, only : PRISM_Error_Grid, prism_undefined
00044 use psmile, only : Grids, &
00045 psmile_def_grid, &
00046 psmile_def_partition, &
00047 psmile_reducedgrid_map, &
00048 psmile_set_corners_3d_double, &
00049 psmile_set_corners_3d_real, &
00050 psmile_set_mask, &
00051 psmile_set_points_gridless, &
00052 psmile_set_points_3d_double, &
00053 psmile_set_points_3d_real, &
00054 psmile_def_var
00055
00056 implicit none
00057
00058 integer, intent (out) :: ierror
00059
00060 integer :: i, j
00061 integer :: grid_type, grid_id
00062 integer :: psmile_id
00063 integer :: size_of_shape(2)
00064 integer, allocatable :: block_start_index(:), block_extent(:), grid_extent(:)
00065 integer, allocatable :: block_valid_shape(:, :)
00066 integer, allocatable :: grid_ids(:)
00067
00068 integer, allocatable :: point_ids(:), mask_ids(:)
00069 integer :: num_blocks
00070
00071 integer :: block_actual_shape (2, ndim_3d)
00072 integer :: grid_actual_shape (2, ndim_3d)
00073
00074 #ifdef VERBOSE
00075 print 9990, trim(ch_id)
00076 call psmile_flushstd
00077 #endif /* VERBOSE */
00078
00079 ierror = 0
00080
00081 if (associated (grid_data)) then
00082
00083
00084 do i = 1, size(grid_data)
00085
00086 grid_type = get_grid_type (i)
00087
00088
00089
00090
00091 if (grid_type == PRISM_Gaussreduced_regvrt .or.&
00092 grid_type == PRISM_Gaussreduced_sigmavrt .or. &
00093 grid_type == PRISM_Gridless) then
00094
00095 call psmile_def_grid (psmile_id, &
00096 grid_data(i)%grid_name, &
00097 grid_data(i)%comp_id, &
00098 grid_data(i)%grid_valid_shape, &
00099 grid_data(i)%grid_type, &
00100 ierror)
00101
00102 call add_pair(grid_id_map, i, psmile_id)
00103
00104 if (.not. partition_data_available (i)) then
00105
00106 ierror = PRISM_Error_Grid
00107
00108 call psmile_error (PRISM_Error_Grid, 'partition information is missing', &
00109 (/psmile_id, get_comp_id(i), grid_type/), 3, &
00110 __FILE__, __LINE__ )
00111 else
00112
00113 call psmile_def_partition(psmile_id, size (grid_data(i)%partition_array, 1), &
00114 grid_data(i)%partition_array(:, :), &
00115 grid_data(i)%extent_array(:, :), &
00116 ierror)
00117 endif
00118
00119
00120
00121 if (grid_type == PRISM_Gaussreduced_regvrt .or. &
00122 grid_type == PRISM_Gaussreduced_sigmavrt) then
00123
00124 if (.not. reducedgrid_map_available(i)) then
00125
00126 ierror = PRISM_Error_Grid
00127
00128 call psmile_error (PRISM_Error_Grid, 'prism_reducedgrid_map was not called', &
00129 (/psmile_id, get_comp_id(i), grid_type/), 3, &
00130 __FILE__, __LINE__ )
00131 else
00132
00133 call psmile_reducedgrid_map (psmile_id, &
00134 size (grid_data(i)%nbr_points_per_lat, 1), &
00135 grid_data(i)%nbr_points_per_lat, ierror)
00136 endif
00137
00138
00139 if (associated (grid_data(i)%corners%st_array_dble)) then
00140
00141
00142
00143
00144 call psmile_set_corners_3d_double (psmile_id, &
00145 grid_data(i)%nbr_corners, &
00146 grid_data(i)%corners%actual_shape, &
00147 grid_data(i)%corners%st_array_dble, &
00148 grid_data(i)%corners%nd_array_dble, &
00149 grid_data(i)%corners%rd_array_dble, &
00150 ierror)
00151 else
00152
00153 call psmile_set_corners_3d_real (psmile_id, &
00154 grid_data(i)%nbr_corners, &
00155 grid_data(i)%corners%actual_shape, &
00156 grid_data(i)%corners%st_array_real, &
00157 grid_data(i)%corners%nd_array_real, &
00158 grid_data(i)%corners%rd_array_real, &
00159 ierror)
00160
00161 endif
00162 endif
00163 else
00164
00165 size_of_shape = get_size_of_shape(grid_data(i)%grid_type)
00166
00167 allocate (block_start_index(size_of_shape(2)), &
00168 block_extent(size_of_shape(2)), &
00169 grid_extent(size_of_shape(2)), &
00170 block_valid_shape(size_of_shape(1), &
00171 size_of_shape(2)))
00172
00173 block_start_index = grid_data(i)%grid_valid_shape(1,:)
00174
00175 grid_extent = grid_data(i)%grid_valid_shape(2,:) - &
00176 grid_data(i)%grid_valid_shape(1,:) + 1
00177
00178 if (.not. partition_data_available (i)) then
00179
00180
00181 call generate_partition_data(i)
00182 endif
00183
00184
00185 do j = 1, size(grid_data(i)%partition_array, 1)
00186
00187 block_valid_shape(1,:) = block_start_index
00188 block_valid_shape(2,:) = block_start_index + &
00189 grid_data(i)%extent_array(j, :) - 1
00190
00191 block_extent = grid_data(i)%extent_array(j,:)
00192
00193 call psmile_def_grid (psmile_id, &
00194 grid_data(i)%grid_name, &
00195 grid_data(i)%comp_id, &
00196 block_valid_shape, &
00197 grid_data(i)%grid_type, &
00198 ierror)
00199
00200 call add_pair(grid_id_map, i, psmile_id)
00201
00202
00203 call psmile_def_partition(psmile_id, 1, &
00204 grid_data(i)%partition_array(j, :), &
00205 grid_data(i)%extent_array(j, :), &
00206 ierror)
00207
00208
00209 if (associated (grid_data(i)%corners%st_array_dble)) then
00210
00211
00212
00213
00214 call psmile_set_corners_3d_double (psmile_id, &
00215 grid_data(i)%nbr_corners, &
00216 grid_data(i)%corners%actual_shape, &
00217 grid_data(i)%corners%st_array_dble, &
00218 grid_data(i)%corners%nd_array_dble, &
00219 grid_data(i)%corners%rd_array_dble, &
00220 ierror)
00221 else
00222
00223 call psmile_set_corners_3d_real (psmile_id, &
00224 grid_data(i)%nbr_corners, &
00225 grid_data(i)%corners%actual_shape, &
00226 grid_data(i)%corners%st_array_real, &
00227 grid_data(i)%corners%nd_array_real, &
00228 grid_data(i)%corners%rd_array_real, &
00229 ierror)
00230 endif
00231
00232 where (get_varying_dimension(block_extent, grid_extent, size_of_shape(2)))
00233
00234 block_start_index = block_start_index + block_extent
00235 end where
00236
00237 enddo
00238
00239 deallocate (block_start_index, block_extent, block_valid_shape, grid_extent)
00240
00241 endif
00242 enddo
00243
00244 allocate (grid_ids(get_max_num_blocks_per_grid ()), &
00245 point_ids(get_max_num_blocks_per_grid ()), &
00246 mask_ids(get_max_num_blocks_per_grid ()))
00247
00248 endif
00249
00250 if (associated (mask_data)) then
00251
00252
00253 do i = 1, size (mask_data)
00254
00255 if (associated (mask_data(i)%mask)) then
00256
00257 num_blocks = get_num_values (grid_id_map, mask_data(i)%grid_id)
00258
00259 grid_ids(1:num_blocks) = get_values(grid_id_map, mask_data(i)%grid_id, &
00260 num_blocks)
00261
00262 size_of_shape = get_size_of_shape (grid_data(mask_data(i)%grid_id)%grid_type)
00263
00264
00265 grid_actual_shape = 1
00266 grid_actual_shape(:,1:size_of_shape(2)) = mask_data(i)%mask_actual_shape
00267
00268
00269 do j = 1, num_blocks
00270
00271
00272 block_actual_shape = 1
00273 block_actual_shape(:,1:size_of_shape(2)) = &
00274 get_block_actual_shape (mask_data(i)%mask_actual_shape, &
00275 Grids(grid_ids(j))%grid_shape, &
00276 grid_data(mask_data(i)%grid_id)%grid_valid_shape, &
00277 size_of_shape(2))
00278
00279 call psmile_set_mask (psmile_id, grid_ids (j), block_actual_shape, &
00280 get_sub_block_3d (mask_data(i)%mask, grid_actual_shape, block_actual_shape), &
00281 .true., ierror)
00282
00283 call add_pair (mask_id_map, i, psmile_id)
00284
00285 enddo
00286 endif
00287 enddo
00288 endif
00289
00290 if (associated (point_data)) then
00291
00292
00293 do i = 1, size (point_data)
00294
00295 num_blocks = get_num_values (grid_id_map, point_data(i)%grid_id)
00296
00297 grid_ids(1:num_blocks) = get_values(grid_id_map, point_data(i)%grid_id, &
00298 num_blocks)
00299
00300
00301 do j = 1, num_blocks
00302
00303
00304 if (get_grid_type(point_data(i)%grid_id) == PRISM_Gridless) then
00305
00306 call psmile_set_points_gridless(psmile_id, point_data(i)%name, &
00307 grid_ids(j), .true., ierror)
00308 else
00309
00310
00311 if (associated (point_data(i)%points%st_array_dble)) then
00312
00313 call psmile_set_points_3d_double (psmile_id, point_data(i)%name, grid_ids(j), &
00314 point_data(i)%points%actual_shape, &
00315 point_data(i)%points%st_array_dble, &
00316 point_data(i)%points%nd_array_dble, &
00317 point_data(i)%points%rd_array_dble, .true., ierror)
00318 else
00319
00320 call psmile_set_points_3d_real (psmile_id, point_data(i)%name, grid_ids(j), &
00321 point_data(i)%points%actual_shape, &
00322 point_data(i)%points%st_array_real, &
00323 point_data(i)%points%nd_array_real, &
00324 point_data(i)%points%rd_array_real, .true., ierror)
00325 endif
00326 endif
00327
00328 call add_pair (point_id_map, i, psmile_id)
00329
00330 enddo
00331 enddo
00332 endif
00333
00334 if (associated (var_data)) then
00335
00336
00337 do i = 1, size (var_data)
00338
00339 grid_id = point_data(var_data(i)%point_id)%grid_id
00340 num_blocks = get_num_values (grid_id_map, grid_id)
00341
00342
00343 grid_ids(1:num_blocks) = get_values(grid_id_map, grid_id, num_blocks)
00344 point_ids(1:num_blocks) = get_values(point_id_map, var_data(i)%point_id, &
00345 num_blocks)
00346
00347 if (var_data(i)%mask_id /= prism_undefined) then
00348
00349 mask_ids(1:num_blocks) = get_values(mask_id_map, var_data(i)%mask_id, &
00350 num_blocks)
00351
00352 else
00353 mask_ids(1:num_blocks) = prism_undefined
00354 endif
00355
00356
00357 do j = 1, num_blocks
00358
00359 call psmile_def_var (psmile_id, var_data(i)%var_name, &
00360 grid_ids(j), &
00361 point_ids(j), &
00362 mask_ids(j), &
00363 (/size (var_data(i)%var_actual_shape, 2),0/), &
00364 var_data(i)%var_actual_shape, &
00365 var_data(i)%var_type, ierror)
00366
00367 call add_pair (var_id_map, i, psmile_id)
00368
00369 enddo
00370 enddo
00371 endif
00372
00373 if (allocated (grid_ids)) deallocate (grid_ids)
00374
00375 #ifdef VERBOSE
00376 print 9980, trim(ch_id), ierror
00377 call psmile_flushstd
00378 #endif /* VERBOSE */
00379
00380 9990 format (1x, a, ': psmile_apply_user_data: ')
00381 9980 format (1x, a, ': psmile_apply_user_data: eof ierror =', i5)
00382
00383 contains
00384
00385
00386
00387 function get_varying_dimension(block_extent, grid_extent, ndim)
00388
00389 integer, intent(in) :: ndim
00390 integer, intent(in) :: block_extent(ndim), grid_extent(ndim)
00391 logical :: get_varying_dimension(ndim)
00392
00393 get_varying_dimension = block_extent /= grid_extent
00394
00395 #ifdef PRISM_ASSERTION
00396 if (count (get_varying_dimension) > 1) then
00397 print *, "block extent", block_extent
00398 print *, "grid extent", grid_extent
00399 call psmile_assert (__FILE__, __LINE__, &
00400 "more than one varying dimension")
00401 endif
00402 #endif
00403 end function get_varying_dimension
00404
00405
00406
00407 function get_max_num_blocks_per_grid ()
00408
00409 integer :: get_max_num_blocks_per_grid
00410 integer :: i
00411
00412 get_max_num_blocks_per_grid = 1
00413
00414 do i = 1, size (grid_data)
00415
00416 get_max_num_blocks_per_grid = max (get_max_num_blocks_per_grid, &
00417 get_num_values(grid_id_map, i))
00418 enddo
00419
00420 end function get_max_num_blocks_per_grid
00421
00422
00423
00424 function get_block_actual_shape (grid_actual_shape, block_valid_shape, grid_valid_shape, ndim)
00425
00426 integer, intent (in) :: ndim
00427 integer, intent (in) :: grid_actual_shape (2, ndim),
00428 block_valid_shape (2, ndim),
00429 grid_valid_shape (2, ndim)
00430
00431 integer :: get_block_actual_shape (2, ndim)
00432
00433 where (block_valid_shape(2,:) == grid_valid_shape(2,:))
00434 get_block_actual_shape(2,:) = max (block_valid_shape(2,:), grid_actual_shape(2,:))
00435 elsewhere
00436 get_block_actual_shape(2,:) = block_valid_shape(2,:)
00437 end where
00438
00439 where (block_valid_shape(1,:) == grid_valid_shape(1,:))
00440 get_block_actual_shape(1,:) = min (block_valid_shape(1,:), grid_actual_shape(1,:))
00441 elsewhere
00442 get_block_actual_shape(1,:) = block_valid_shape(1,:)
00443 end where
00444
00445 end function
00446
00447
00448
00449 function get_sub_block_3d (src, src_shape, sub_block_shape)
00450
00451 integer, intent (in) :: src_shape (2, ndim_3d),
00452 sub_block_shape (2, ndim_3d)
00453 logical, intent (in) :: src (src_shape(1,1):src_shape(2,1),
00454 src_shape(1,2):src_shape(2,2),
00455 src_shape(1,3):src_shape(2,3))
00456
00457 logical :: get_sub_block_3d (sub_block_shape(1,1):sub_block_shape(2,1),
00458 sub_block_shape(1,2):sub_block_shape(2,2),
00459 sub_block_shape(1,3):sub_block_shape(2,3))
00460
00461 get_sub_block_3d = src(sub_block_shape(1,1):sub_block_shape(2,1), &
00462 sub_block_shape(1,2):sub_block_shape(2,2), &
00463 sub_block_shape(1,3):sub_block_shape(2,3))
00464
00465 end function get_sub_block_3d
00466
00467 end subroutine psmile_apply_user_data