00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_mg_method_gauss2_dble (method_id, search_range, &
00012 tgt_shape, tgt_coords_x, &
00013 tgt_coords_y, loc_fnd_shape, &
00014 found, loc, virtual_cell, &
00015 ierror)
00016
00017
00018
00019 use PRISM_constants
00020 use psmile, dummy => psmile_mg_method_gauss2_dble
00021 use psmile_geometry, only : point_is_in_quadrangle
00022 use psmile_grid, only : common_grid_range, psmile_transform_cell_cyclic
00023 use psmile_grid_reduced_gauss
00024 #ifdef DEBUG_TRACE
00025 use psmile_debug_trace
00026 #endif
00027
00028 implicit none
00029
00030
00031
00032 integer, intent (in) :: method_id
00033
00034 integer, intent (in) :: search_range (2, ndim_3d)
00035
00036
00037 integer, intent (in) :: loc_fnd_shape (2, ndim_3d)
00038
00039
00040
00041 integer, intent (in) :: tgt_shape (2, ndim_3d)
00042
00043
00044
00045
00046 double precision, intent (in) :: tgt_coords_x (tgt_shape(1,1):tgt_shape(2,1),
00047 tgt_shape(1,2):tgt_shape(2,2),
00048 tgt_shape(1,3):tgt_shape(2,3)),
00049 tgt_coords_y (tgt_shape(1,1):tgt_shape(2,1),
00050 tgt_shape(1,2):tgt_shape(2,2),
00051 tgt_shape(1,3):tgt_shape(2,3))
00052
00053
00054
00055
00056
00057 integer, intent (inout) :: found (loc_fnd_shape(1,1):loc_fnd_shape(2,1),
00058 loc_fnd_shape(1,2):loc_fnd_shape(2,2),
00059 loc_fnd_shape(1,3):loc_fnd_shape(2,3))
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 integer, intent (inout) :: loc (loc_fnd_shape(1,1):loc_fnd_shape(2,1),
00074 loc_fnd_shape(1,2):loc_fnd_shape(2,2),
00075 loc_fnd_shape(1,3):loc_fnd_shape(2,3))
00076
00077
00078
00079
00080
00081
00082
00083 integer, intent (out) :: virtual_cell (loc_fnd_shape(1,1):loc_fnd_shape(2,1),
00084 loc_fnd_shape(1,2):loc_fnd_shape(2,2),
00085 loc_fnd_shape(1,3):loc_fnd_shape(2,3))
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 integer, intent (out) :: ierror
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 integer, parameter :: val_coupler = -1
00113
00114
00115
00116 integer, pointer :: local_1d_stencil_lookup(:,:)
00117
00118 integer :: i, j, k, n, n_end
00119
00120 integer :: not_found
00121
00122 double precision, pointer :: src_coords_x(:),
00123 src_coords_y(:)
00124
00125
00126
00127 integer, pointer :: local_coords_shape(:,:)
00128 integer :: num_local_points, num_remote_points, num_global_lats
00129
00130 integer, pointer :: curr_stencil(:)
00131 integer :: curr_stencil_idx
00132 integer :: curr_3d_base_idx(ndim_3d)
00133 type(point_dble) :: method_cell (4), point
00134 double precision :: grid_extent
00135 integer :: grid_id
00136
00137 integer, allocatable :: loc_3d(:,:,:,:)
00138
00139 integer, parameter :: n_to_stencil_base_idx(9) = (/1,2,3, 5,6,7,
00140 9,10,11/)
00141 integer, parameter :: stencil_idx_to_virtual_cell(16) = (/1,2,3,-1,
00142 4,0,6,-1,
00143 7,8,9,-1,
00144 -1,-1,-1,-1/)
00145
00146 #ifdef DEBUG_TRACE
00147
00148
00149
00150 logical :: debug_trace
00151 type(point_dble) :: debug_point
00152 character (len=*), parameter :: out_prefix = "ictl psmile_mg_method_gauss2_dble:"
00153 #endif
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 Character(len=len_cvs_string), save :: mycvs =
00178 '$Id: psmile_mg_method_gauss2_dble.F90 3248 2011-06-23 13:03:19Z coquart $'
00179
00180
00181 #ifdef VERBOSE
00182 print 9990, trim(ch_id)
00183
00184 call psmile_flushstd
00185 #endif /* VERBOSE */
00186
00187
00188
00189 ierror = 0
00190
00191 grid_id = methods(method_id)%grid_id
00192 local_1d_stencil_lookup => &
00193 grids(grid_id)%reduced_gauss_data%local_1d_stencil_lookup
00194 num_global_lats = &
00195 size (grids(grid_id)%reduced_gauss_data%nbr_points_per_lat)
00196 not_found = - (grids(grid_id)%nlev + 2)
00197 local_coords_shape => Methods(method_id)%coords_pointer%coords_shape
00198
00199
00200 num_local_points = local_coords_shape(2,1) - local_coords_shape(1,1)
00201 if (associated (grids(grid_id)%reduced_gauss_data%remote_index)) then
00202 num_remote_points = size (grids(grid_id)%reduced_gauss_data%remote_index)
00203 else
00204 num_remote_points = 0
00205 endif
00206
00207
00208
00209 if (num_remote_points <= 0) then
00210
00211 src_coords_x => Methods(method_id)%coords_pointer%coords_dble(1)%vector
00212 src_coords_y => Methods(method_id)%coords_pointer%coords_dble(2)%vector
00213 else
00214
00215
00216 allocate (src_coords_x(local_coords_shape(1,1):local_coords_shape(2,1)+num_remote_points), &
00217 src_coords_y(local_coords_shape(1,1):local_coords_shape(2,1)+num_remote_points), &
00218 stat = ierror)
00219
00220 if ( ierror > 0 ) then
00221 call psmile_error (PRISM_Error_Alloc, 'src_coords_x and src_coords_y', (/ierror, &
00222 2*(local_coords_shape(2,1)-local_coords_shape(1,1)+1+num_remote_points)/), &
00223 2, __FILE__, __LINE__ )
00224 return
00225 endif
00226
00227 src_coords_x(local_coords_shape(1,1):local_coords_shape(2,1)) = &
00228 Methods(method_id)%coords_pointer%coords_dble(1)%vector
00229 src_coords_y(local_coords_shape(1,1):local_coords_shape(2,1)) = &
00230 Methods(method_id)%coords_pointer%coords_dble(2)%vector
00231
00232 src_coords_x(local_coords_shape(2,1)+1:local_coords_shape(2,1)+num_remote_points) = &
00233 Methods(method_id)%gauss2_dble(1)%vector
00234 src_coords_y(local_coords_shape(2,1)+1:local_coords_shape(2,1)+num_remote_points) = &
00235 Methods(method_id)%gauss2_dble(2)%vector
00236 endif
00237
00238
00239 virtual_cell(:,:,:) = 0
00240
00241
00242 grid_extent = common_grid_range(2,1) - common_grid_range(1,1)
00243
00244
00245 allocate (loc_3d(ndim_3d, loc_fnd_shape(1,1):loc_fnd_shape(2,1), &
00246 loc_fnd_shape(1,2):loc_fnd_shape(2,2), &
00247 loc_fnd_shape(1,3):loc_fnd_shape(2,3)))
00248
00249 loc_3d(:,:,:,:) = reshape (psmile_gauss_local_1d_to_3d(grid_id, &
00250 reshape(loc, (/size(loc)/)), &
00251 size(loc)), &
00252 (/ndim_3d, size(loc,1), size(loc,2), size(loc,3)/))
00253
00254 do i = search_range(1, 1), search_range(2,1)
00255 do j = search_range(1, 2), search_range(2,2)
00256 do k = search_range(1, 3), search_range(2,3)
00257 #ifdef DEBUG_TRACE
00258 if (i == ictl_ind(1) .and. j == ictl_ind(2)) then
00259 print *, out_prefix, ' ictl_ind', &
00260 ictl_ind (1:ndim_2d), ' old found = ', &
00261 found (ictl_ind(1),ictl_ind(2),search_range(1,3)), &
00262 ', old loc =', loc (ictl_ind(1),ictl_ind(2),search_range(1,3))
00263 debug_trace = .true.
00264 else
00265 debug_trace = .false.
00266 endif
00267 #endif
00268
00269 if (found (i,j,k) == 1) then
00270
00271 point%x = tgt_coords_x (i,j,k)
00272 point%y = tgt_coords_y (i,j,k)
00273
00274 curr_stencil => local_1d_stencil_lookup(:, loc (i,j,k))
00275 curr_3d_base_idx(:) = loc_3d (:,i,j,k)
00276
00277 #ifdef DEBUG_TRACE
00278 if (debug_trace) then
00279 print '(2(1x,a),2f8.2)', out_prefix, 'point to be searched: ', point
00280 debug_point = point
00281 endif
00282 #endif
00283
00284
00285 if (curr_3d_base_idx(2) == 1) then
00286 n = 4
00287 else
00288 n = 1
00289 endif
00290
00291
00292 if (curr_3d_base_idx(2) == num_global_lats - 1) then
00293 n_end = 6
00294 else
00295 n_end = 9
00296 endif
00297
00298
00299 do n = n, n_end
00300
00301 curr_stencil_idx = n_to_stencil_base_idx(n)
00302
00303
00304 method_cell = get_method_cell (curr_stencil_idx, curr_stencil, &
00305 curr_3d_base_idx(2))
00306
00307
00308 do while (point%x < minval (method_cell(:)%x))
00309 point%x = point%x + grid_extent
00310 enddo
00311 do while (point%x > maxval (method_cell(:)%x))
00312 point%x = point%x - grid_extent
00313 enddo
00314
00315 #ifdef DEBUG_TRACE
00316 if (debug_trace) then
00317 if (debug_point%x /= point%x) then
00318 print '(2(1x,a),/,2f8.2)', out_prefix, &
00319 "point coordinates were adjusted to method cell range:", point
00320 debug_point = point
00321 endif
00322 endif
00323 #endif
00324
00325
00326 if (point_is_in_quadrangle (point, method_cell)) then
00327
00328 found (i,j,k) = val_coupler
00329 exit
00330 endif
00331 enddo
00332
00333
00334 if (found (i,j,k) == val_coupler) then
00335 #ifdef DEBUG_TRACE
00336 if (debug_trace) then
00337 print *, out_prefix, ' found matching cell'
00338 endif
00339 #endif
00340
00341 virtual_cell (i,j,k) = &
00342 stencil_idx_to_virtual_cell(curr_stencil_idx)
00343 #ifdef DEBUG_TRACE
00344 if (virtual_cell (i,j,k) /= 0) then
00345
00346
00347 if (debug_trace) then
00348 print *, out_prefix, ' cell is a virtual cell at stencil idx', &
00349 curr_stencil_idx, 'virt. cell idx', virtual_cell (i,j,k)
00350 endif
00351 endif
00352 #endif
00353 else
00354 found (i,j,k) = not_found
00355 endif
00356 endif
00357 enddo
00358 enddo
00359 enddo
00360
00361
00362 deallocate (loc_3d)
00363 if (num_remote_points > 0) deallocate (src_coords_x, src_coords_y)
00364
00365 #ifdef VERBOSE
00366 print 9980, trim(ch_id)
00367
00368 call psmile_flushstd
00369 #endif /* VERBOSE */
00370
00371
00372
00373 9990 format (1x, a, ': psmile_mg_method_gauss2_dble:')
00374 9980 format (1x, a, ': psmile_mg_method_gauss2_dble: eof')
00375
00376 contains
00377
00378
00379
00380
00381
00382 function get_method_cell(idx, stencil, g_latitude_idx)
00383
00384 integer, intent (in) :: idx, stencil(16), g_latitude_idx
00385
00386 type (point_dble) :: get_method_cell(4)
00387
00388 type (point_dble) :: method_cell(4)
00389 integer, parameter :: neighbours(3,16) =
00390 reshape ((/ 2, 6, 5, 3, 7, 6, 4, 8, 7, -1,-1,-1,
00391 6,10, 9, 7,11,10, 8,12,11, -1,-1,-1,
00392 10,14,13, 11,15,14, 12,16,15, -1,-1,-1,
00393 -1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1/),
00394 (/3,16/))
00395
00396 integer, parameter :: latitude_off(16) = (/-1,-1,-1, 0,
00397 0, 0, 0, 0,
00398 1, 1, 1, 0,
00399 0, 0, 0, 0/)
00400
00401 #ifdef DEBUG_TRACE
00402 if (debug_trace) then
00403 print *, out_prefix, ' stencil =', stencil
00404 print *, out_prefix, ' stencil idx =', idx
00405 print *, out_prefix, ' generating method cell with indices:', &
00406 stencil(idx), stencil(neighbours(:,idx))
00407 endif
00408 #endif
00409
00410 method_cell(1)%x = src_coords_x(stencil(idx))
00411
00412
00413
00414 method_cell(2)%x = src_coords_x(stencil(neighbours(1,idx)))
00415
00416
00417 method_cell(3)%x = src_coords_x(stencil(neighbours(2,idx)))
00418
00419
00420 method_cell(4)%x = src_coords_x(stencil(neighbours(3,idx)))
00421
00422
00423 if (g_latitude_idx + latitude_off(idx) == 1) then
00424
00425 method_cell(1:2)%y = dsign (90.d0, src_coords_y(stencil(idx)))
00426
00427 #ifdef DEBUG_TRACE
00428 if (debug_trace) then
00429 print *, out_prefix, ' extending method cell to pole'
00430 endif
00431 #endif
00432 else
00433
00434 method_cell(1)%y = src_coords_y(stencil(idx))
00435 method_cell(2)%y = src_coords_y(stencil(neighbours(1,idx)))
00436 endif
00437
00438
00439 if (g_latitude_idx + latitude_off(idx) == num_global_lats - 1) then
00440
00441 method_cell(3:4)%y = dsign (90.d0, src_coords_y(stencil(idx)))
00442
00443 #ifdef DEBUG_TRACE
00444 if (debug_trace) then
00445 print *, out_prefix, ' extending method cell to pole'
00446 endif
00447 #endif
00448 else
00449
00450 method_cell(3)%y = src_coords_y(stencil(neighbours(2,idx)))
00451 method_cell(4)%y = src_coords_y(stencil(neighbours(3,idx)))
00452 endif
00453
00454 #ifdef DEBUG_TRACE
00455 if (debug_trace) then
00456 print "(2(1x,a),4(/,2f8.2))", out_prefix, 'generated method cell:', &
00457 method_cell
00458 endif
00459 #endif
00460
00461
00462 call psmile_transform_cell_cyclic(method_cell(:)%x, grid_extent, ierror)
00463
00464 #ifdef DEBUG_TRACE
00465 if (debug_trace) then
00466 print "(2(1x,a),4(/,2f8.2))", &
00467 out_prefix, 'after cyclic transformation:', method_cell
00468 endif
00469 #endif
00470
00471 get_method_cell = method_cell
00472
00473 end function get_method_cell
00474
00475 end subroutine psmile_mg_method_gauss2_dble