00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 integer function getTrCode(shiftCount)
00018 integer, intent(in) :: shiftCount(2)
00019 integer :: i
00020
00021 getTrCode = 0
00022 do i = 2, 1, -1
00023 getTrCode = ishft(getTrCode, 4)
00024 if (shiftCount(i) < 0) getTrCode = ibset(getTrCode,3)
00025 getTrCode = getTrCode + abs(shiftCount(i))
00026 enddo
00027 end function getTrCode
00028
00029
00030 function getShiftCount(tr_code)
00031 integer, intent(in) :: tr_code
00032 integer :: getShiftCount(2)
00033 integer :: i, code
00034
00035 code = tr_code
00036 do i = 1, 2
00037 getShiftCount(i) = iand(code,7)
00038 if (btest(code,3)) getShiftCount(i) = -1 * getShiftCount(i)
00039 code = ishft(code, -4)
00040 enddo
00041 end function getShiftCount
00042
00043 subroutine psmile_transform_extent_cyclic (grid_type, extent, &
00044 transformed, tr_codes, n_trans, ierror)
00045
00046
00047
00048 use psmile_common, only : psmile_float_kind, ndim_3d, ch_id
00049 use psmile_grid, dummy_interface => psmile_transform_extent_cyclic
00050
00051 implicit none
00052
00053
00054
00055
00056
00057 integer, intent (in) :: grid_type
00058
00059 real (psmile_float_kind), intent (in) :: extent (2, ndim_3d)
00060
00061
00062
00063
00064 real (psmile_float_kind), intent (out) :: transformed (2, ndim_3d,
00065 max_num_trans_parts)
00066
00067
00068 integer, intent (out) :: tr_codes (max_num_trans_parts)
00069
00070 integer, intent (out) :: n_trans
00071
00072
00073
00074 integer, intent (out) :: ierror
00075
00076
00077
00078
00079
00080 integer :: i, j
00081
00082
00083 logical :: isCyclic (2)
00084
00085 integer :: splitCount
00086
00087 integer :: shiftCount(2, max_num_trans_parts)
00088
00089 real (psmile_float_kind) :: shiftSize(2)
00090
00091 integer, external :: getTrCode
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 #ifdef VERBOSE
00108 print 9990, trim(ch_id), extent
00109 call psmile_flushstd
00110 #endif /* VERBOSE */
00111
00112
00113
00114
00115
00116 isCyclic(1) = any(grids_cyclic_in_first_dim == grid_type)
00117 isCyclic(2) = any(grids_cyclic_in_second_dim == grid_type)
00118
00119
00120 shiftSize = common_grid_range(2,1:2) - common_grid_range(1,1:2)
00121 shiftCount = 0
00122 tr_codes(:) = 0
00123 transformed(:,:,:) = 0
00124 ierror = 0
00125
00126 #ifdef PRISM_ASSERTION
00127
00128
00129
00130 do i = 1, 2
00131 if (isCyclic(i)) then
00132 if ((extent(2,i) - extent(1,i)) > &
00133 2*(common_grid_range(2,i) - common_grid_range(1,i))) then
00134 print *, 'index, extent(:,index)', i, extent(:,i)
00135 print *, 'range is bigger than expected range: ', &
00136 2*(common_grid_range(2,i) - common_grid_range(1,i))
00137 call psmile_assert (__FILE__, __LINE__, &
00138 'extent is too big')
00139 endif
00140 if (extent (1, i) < 7 * common_grid_range(1,i) .or. &
00141 extent (2, i) > 7 * common_grid_range(2,i)) then
00142 print *, 'index, extent', i, extent (1, i), extent (2, i)
00143 print *, 'range expected', 7 * common_grid_range(1,i), &
00144 7 * common_grid_range(2,i)
00145 call psmile_assert (__FILE__, __LINE__, &
00146 'extent is out of expected range')
00147 endif
00148 if (extent (1, i) > extent (2, i)) then
00149 print *, 'index, extent', i, extent (1, i), extent (2, i)
00150 call psmile_assert (__FILE__, __LINE__, &
00151 'upper and lower bound do not match')
00152 endif
00153 endif
00154 enddo
00155
00156 #endif
00157
00158 transformed(:, :, 1) = extent(:,:)
00159
00160
00161
00162
00163
00164 do i = 1, 2
00165 if (isCyclic(i)) then
00166
00167
00168
00169
00170 do while (transformed(1, i, 1) < common_grid_range(1,i))
00171 shiftCount(i,1) = shiftCount(i,1) + 1
00172 transformed(:,i, 1) = transformed(:,i, 1) + &
00173 shiftSize(i)
00174 enddo
00175
00176 do while (transformed(1, i, 1) >= common_grid_range(2,i))
00177 shiftCount(i,1) = shiftCount(i,1) - 1
00178 transformed(:,i, 1) = transformed(:,i, 1) - &
00179 shiftSize(i)
00180 enddo
00181 endif
00182 enddo
00183
00184 n_trans = 1
00185
00186 tr_codes(1) = getTrCode(shiftCount)
00187
00188
00189
00190
00191
00192 do i = 1, 2
00193 if (isCyclic(i)) then
00194
00195
00196 splitCount = 0
00197
00198
00199 do while (transformed (2, i, 1 + splitCount * n_trans) > common_grid_range(2,i))
00200
00201
00202
00203 transformed(:,:,1+(splitCount+1)*n_trans:(splitCount+2)*n_trans) = &
00204 transformed(:,:,1+splitCount*n_trans:(splitCount+1)*n_trans)
00205 shiftCount(:,1+(splitCount+1)*n_trans:(splitCount+2)*n_trans) = &
00206 shiftCount(:,1+splitCount*n_trans:(splitCount+1)*n_trans)
00207
00208
00209 transformed(2,i,1+splitCount*n_trans:(splitCount+1)*n_trans) = &
00210 common_grid_range(2,i)
00211
00212
00213
00214 transformed(2,i,1+(splitCount+1)*n_trans:(splitCount+2)*n_trans) = &
00215 transformed(2,i,1+(splitCount+1)*n_trans:(splitCount+2)*n_trans) - &
00216 shiftSize(i)
00217 shiftCount(i,1+(splitCount+1)*n_trans:(splitCount+2)*n_trans) = &
00218 shiftCount(i,1+(splitCount+1)*n_trans:(splitCount+2)*n_trans) - 1
00219
00220
00221 transformed(1,i,1+(splitCount+1)*n_trans:(splitCount+2)*n_trans) = &
00222 common_grid_range(1,i)
00223
00224
00225 do j = 1+(splitCount+1)*n_trans, (splitCount+2)*n_trans
00226 tr_codes(j) = getTrCode(shiftCount(:,j))
00227 enddo
00228
00229
00230 splitCount = splitCount + 1
00231 enddo
00232
00233
00234 n_trans = n_trans * (1 + splitCount)
00235 endif
00236 enddo
00237
00238 #ifdef VERBOSE
00239 print 9980, trim(ch_id), ierror, n_trans
00240 call psmile_flushstd
00241 #endif /* VERBOSE */
00242
00243 #ifdef VERBOSE
00244
00245 9990 format (1x, a, ': psmile_transform_extent_cyclic: extent', 6e13.6)
00246 9980 format (1x, a, ': psmile_transform_extent_cyclic: eof ierror =', i3, &
00247 '; n_trans =', i2)
00248
00249 #endif /* VERBOSE */
00250 end subroutine psmile_Transform_extent_cyclic
00251
00252
00253
00254 subroutine psmile_transform_extent_back (tr_codes, &
00255 extents, transformed, n_trans, ierror)
00256
00257
00258
00259 use psmile_common, only : psmile_float_kind, ndim_3d, ch_id
00260 use psmile_grid, dummy_interface => psmile_transform_extent_back
00261
00262 implicit none
00263
00264
00265
00266
00267 integer, intent (in) :: n_trans
00268
00269 integer, intent (in) :: tr_codes (n_trans)
00270
00271 real (psmile_float_kind), intent (in) :: extents (2, ndim_3d, n_trans)
00272
00273
00274
00275
00276 real (psmile_float_kind), intent (out) :: transformed (2, ndim_3d,
00277 n_trans)
00278
00279
00280
00281 integer, intent (out) :: ierror
00282
00283
00284
00285
00286 integer :: i
00287
00288
00289 integer :: shiftCount (2)
00290
00291 integer :: shiftSize(2)
00292
00293 interface
00294 function getShiftCount(tr_code)
00295 integer, intent(in) :: tr_code
00296 integer :: getShiftCount(2)
00297 end function getShiftCount
00298 end interface
00299
00300
00301
00302
00303
00304
00305 #ifdef VERBOSE
00306 print 9990, trim(ch_id), n_trans
00307 call psmile_flushstd
00308 #endif /* VERBOSE */
00309
00310 ierror = 0
00311 transformed = extents
00312
00313 shiftSize = common_grid_range(2,1:2) - common_grid_range(1,1:2)
00314
00315 #ifdef PRISM_ASSERTION
00316
00317
00318
00319 if (any(tr_codes(:) > 255)) then
00320 call psmile_assert (__FILE__, __LINE__, &
00321 'invalid transformation code')
00322 endif
00323 #endif
00324
00325 do i = 1, n_trans
00326 shiftCount = getShiftCount(tr_codes(i))
00327 transformed(1, 1:2, i) = extents(1,1:2,i) + &
00328 shiftCount * shiftSize * (-1.0)
00329 transformed(2, 1:2, i) = extents(2,1:2,i) + &
00330 shiftCount * shiftSize * (-1.0)
00331 enddo
00332
00333 #ifdef VERBOSE
00334 print 9980, trim(ch_id), ierror
00335 call psmile_flushstd
00336 #endif /* VERBOSE */
00337
00338
00339
00340
00341 #ifdef VERBOSE
00342
00343 9990 format (1x, a, ': psmile_transform_extent_back: n_trans', i5)
00344 9980 format (1x, a, ': psmile_transform_extent_back: eof ierror =', i3)
00345
00346 #endif /* VERBOSE */
00347
00348 end subroutine psmile_transform_extent_back
00349
00350
00351
00352 subroutine psmile_transform_coords_db_re (tr_code_to, tr_code_from, &
00353 coords_data_dble, coords_data_real, &
00354 coords_size, datatype, ierror)
00355
00356
00357
00358 use prism_constants
00359 use psmile_common, only : dble_vector, real_vector, &
00360 ndim_3d, ch_id, MPI_REAL, &
00361 MPI_DOUBLE_PRECISION
00362 use psmile_grid, dummy_interface => psmile_transform_coords_db_re
00363
00364 implicit none
00365
00366
00367
00368
00369 integer, intent (in) :: tr_code_to
00370
00371
00372 integer, intent (in) :: tr_code_from
00373
00374 integer, intent (in) :: coords_size (ndim_3d)
00375
00376 integer, intent (in) :: datatype
00377
00378
00379
00380
00381 type (dble_vector), intent(inout), optional :: coords_data_dble (ndim_3d)
00382 type (real_vector), intent(inout), optional :: coords_data_real (ndim_3d)
00383
00384
00385
00386
00387
00388
00389 integer, intent (out) :: ierror
00390
00391
00392
00393
00394 integer :: i
00395
00396
00397 integer :: shiftCount (2)
00398
00399 integer :: shiftSize(2)
00400
00401 interface
00402 function getShiftCount(tr_code)
00403 integer, intent(in) :: tr_code
00404 integer :: getShiftCount(2)
00405 end function getShiftCount
00406 end interface
00407
00408
00409
00410
00411
00412
00413
00414 #ifdef VERBOSE
00415 print 9990, trim(ch_id), tr_code_to, tr_code_from
00416 call psmile_flushstd
00417 #endif /* VERBOSE */
00418
00419 #ifdef PRISM_ASSERTION
00420
00421
00422
00423 if (present(coords_data_dble) .eqv. present(coords_data_real)) then
00424 print *, 'coords_data_dble and coords_data_real are both', &
00425 ' provided or both are missing'
00426 call psmile_assert (__FILE__, __LINE__, &
00427 'wrong input data')
00428 endif
00429 if ((present(coords_data_dble).and.(datatype==MPI_DOUBLE_PRECISION)) .eqv. &
00430 (present(coords_data_real).and.(datatype==MPI_REAL))) then
00431 print *, 'provided data and datatype do not match'
00432 call psmile_assert (__FILE__, __LINE__, &
00433 'wrong input data')
00434 endif
00435 #endif
00436
00437 ierror = 0
00438
00439 if (tr_code_to /= tr_code_from) then
00440
00441
00442 shiftSize = common_grid_range(2,1:2) - common_grid_range(1,1:2)
00443
00444
00445
00446 shiftCount = getShiftCount(tr_code_from)
00447
00448
00449
00450
00451
00452 shiftCount = shiftCount - getShiftCount(tr_code_to)
00453
00454
00455 do i = 1, 2
00456 select case (datatype)
00457 case (MPI_DOUBLE_PRECISION)
00458 coords_data_dble(i)%vector(1:coords_size(i)) = &
00459 coords_data_dble(i)%vector(1:coords_size(i)) + &
00460 shiftCount(i) * shiftSize(i)
00461 case (MPI_REAL)
00462 coords_data_real(i)%vector(1:coords_size(i)) = &
00463 coords_data_real(i)%vector(1:coords_size(i)) + &
00464 shiftCount(i) * shiftSize(i)
00465 end select
00466 enddo
00467 endif
00468
00469 #ifdef VERBOSE
00470 print 9980, trim(ch_id), ierror
00471 call psmile_flushstd
00472 #endif /* VERBOSE */
00473
00474 #ifdef VERBOSE
00475 9990 format (1x, a, ': psmile_transform_coords_db_re: ', 2i5)
00476 9980 format (1x, a, ': psmile_transform_coords_db_re: eof ierror =', i3)
00477 #endif /* VERBOSE */
00478 end subroutine psmile_transform_coords_db_re