00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_bbcells_pole_dble ( &
00012 coords_shape, coords_x, coords_y, &
00013 corner_shape, sub_range, &
00014 chmin_x, chmax_x, chmin_y, chmax_y, &
00015 midp_x, midp_y, pole_array, period, &
00016 ierror)
00017
00018
00019
00020 use psmile, dummy_interface => psmile_bbcells_pole_dble
00021 use psmile_reallocate
00022 use psmile_common, only : ndim_2d, ndim_3d
00023 use psmile_grid, only : psmile_transform_cell_cyclic
00024 use prism, only : prism_undefined
00025
00026 implicit none
00027
00028
00029
00030 integer, intent (in) :: coords_shape (2, ndim_2d)
00031
00032 double precision, intent (in) ::
00033 coords_x(coords_shape(1,1):coords_shape(2,1),
00034 coords_shape(1,2):coords_shape(2,2)),
00035 coords_y(coords_shape(1,1):coords_shape(2,1),
00036 coords_shape(1,2):coords_shape(2,2))
00037
00038 integer, intent (in) :: corner_shape (2, ndim_3d)
00039
00040
00041 integer, intent (in) :: sub_range (2, ndim_2d)
00042
00043
00044 integer, intent (in) :: pole_array(:)
00045
00046 double precision, intent(in) :: period
00047
00048
00049
00050
00051
00052 double precision, intent (inout) :: chmin_x (sub_range(1,1)-1:sub_range(2,1),
00053 sub_range(1,2)-1:sub_range(2,2))
00054
00055 double precision, intent (inout) :: chmax_x (sub_range(1,1)-1:sub_range(2,1),
00056 sub_range(1,2)-1:sub_range(2,2))
00057
00058 double precision, intent (inout) :: chmin_y (sub_range(1,1)-1:sub_range(2,1),
00059 sub_range(1,2)-1:sub_range(2,2))
00060
00061 double precision, intent (inout) :: chmax_y (sub_range(1,1)-1:sub_range(2,1),
00062 sub_range(1,2)-1:sub_range(2,2))
00063
00064 double precision, intent (inout) :: midp_x(sub_range(1,1)-1:sub_range(2,1),
00065 sub_range(1,2)-1:sub_range(2,2))
00066
00067 double precision, intent (inout) :: midp_y(sub_range(1,1)-1:sub_range(2,1),
00068 sub_range(1,2)-1:sub_range(2,2))
00069
00070
00071
00072
00073
00074 integer, intent (out) :: ierror
00075
00076
00077
00078
00079
00080
00081
00082
00083 integer :: n, i, j
00084
00085 integer :: ijk(3)
00086
00087 type(point_dble) :: cell(4), temp_cell(4), midpoint
00088
00089 integer, pointer :: method_pole_array_x(:), method_pole_array_y(:)
00090 integer :: method_pole_array_size
00091 integer :: method_pole_array_allocated_size
00092
00093 integer, parameter :: nerrp = 2
00094 integer :: ierrp (nerrp)
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 Character(len=len_cvs_string), save :: mycvs =
00116 '$Id: psmile_bbcells_pole_dble.F90 2661 2010-10-25 08:39:13Z coquart $'
00117
00118
00119
00120 #ifdef VERBOSE
00121 print 9990, trim(ch_id)
00122
00123 call psmile_flushstd
00124 #endif /* VERBOSE */
00125
00126
00127
00128
00129
00130 ierror = 0
00131 method_pole_array_size = 0
00132 method_pole_array_allocated_size = size(pole_array)
00133 allocate(method_pole_array_x(method_pole_array_allocated_size))
00134 allocate(method_pole_array_y(method_pole_array_allocated_size))
00135 method_pole_array_x = prism_undefined
00136 method_pole_array_y = prism_undefined
00137
00138
00139
00140
00141 #ifdef DEBUG
00142 PRINT *, TRIM(ch_id), 'number of points at pole found in set_corners :', &
00143 SIZE(pole_array)
00144 call psmile_flushstd
00145 #endif
00146 do n = 1, size(pole_array)
00147
00148 ijk = psmile_transform_index_1d_to_3d (pole_array(n), corner_shape)
00149
00150 do i = max (ijk(1)-1, coords_shape(1,1)), min (ijk(1)+1, coords_shape(2,1)-1)
00151
00152 do j = max (ijk(2)-1, coords_shape(1,2)), min (ijk(2)+1, coords_shape(2,2)-1)
00153 cell(1)%x = coords_x(i , j )
00154 cell(2)%x = coords_x(i+1, j )
00155 cell(3)%x = coords_x(i+1, j+1)
00156 cell(4)%x = coords_x(i , j+1)
00157
00158 cell(1)%y = coords_y(i , j )
00159 cell(2)%y = coords_y(i+1, j )
00160 cell(3)%y = coords_y(i+1, j+1)
00161 cell(4)%y = coords_y(i , j+1)
00162
00163 call psmile_transform_cell_cyclic ( cell(:)%x, period, ierror )
00164
00165 if (psmile_cell_covers_pole(cell(:)%x, cell(:)%y, 4)) then
00166
00167
00168 if (.not. any((method_pole_array_x == i) .and. (method_pole_array_y == j))) then
00169
00170 if (method_pole_array_size == method_pole_array_allocated_size) then
00171
00172 method_pole_array_allocated_size = method_pole_array_allocated_size + 8
00173 method_pole_array_x => psmile_realloc(method_pole_array_x, &
00174 method_pole_array_allocated_size)
00175 method_pole_array_y => psmile_realloc(method_pole_array_y, &
00176 method_pole_array_allocated_size)
00177 endif
00178
00179 #if defined(VERBOSE) && defined(DEBUG)
00180 print *, trim(ch_id), ": found pole method cell at", i, j
00181 print "(a, ': x', /, 2f8.2, /, 2f8.2, /, 2f8.2, /, 2f8.2)", trim(ch_id)
00182 PRINT*, 'cell x :',cell(1)%x,cell(2)%x,cell(3)%x,cell(4)%x
00183 PRINT*, 'cell y :',cell(1)%y,cell(2)%y,cell(3)%y,cell(4)%y
00184 #endif
00185
00186 method_pole_array_size = method_pole_array_size + 1
00187 method_pole_array_x(method_pole_array_size) = i
00188 method_pole_array_y(method_pole_array_size) = j
00189 endif
00190 endif
00191 enddo
00192 enddo
00193 enddo
00194
00195
00196
00197 do n = 1, method_pole_array_size
00198
00199 i = method_pole_array_x(n)
00200 j = method_pole_array_y(n)
00201
00202
00203 chmax_x(i, j) = 180.0d0
00204 chmin_x(i, j) = -180.0d0
00205
00206
00207 if (chmax_y(i, j) > 0) then
00208 chmax_y(i, j) = 90.0d0
00209
00210 #if defined(VERBOSE) && defined(DEBUG)
00211 print *, trim(ch_id), ': extending chmax_x to 90'
00212 #endif /* VERBOSE */
00213
00214 else
00215 chmin_y(i, j) = -90.0d0
00216
00217 #if defined(VERBOSE) && defined(DEBUG)
00218 print *, trim(ch_id), ': extending chmin_y to -90'
00219 #endif /* VERBOSE */
00220 endif
00221
00222 cell(1)%x = coords_x(i , j )
00223 cell(2)%x = coords_x(i+1, j )
00224 cell(3)%x = coords_x(i+1, j+1)
00225 cell(4)%x = coords_x(i , j+1)
00226
00227 cell(1)%y = coords_y(i , j )
00228 cell(2)%y = coords_y(i+1, j )
00229 cell(3)%y = coords_y(i+1, j+1)
00230 cell(4)%y = coords_y(i , j+1)
00231
00232 call compute_midpoint(cell, &
00233 midp_x(i, j), midp_y(i, j))
00234
00235 enddo
00236
00237
00238
00239 deallocate (method_pole_array_x, method_pole_array_y)
00240
00241
00242
00243 #ifdef VERBOSE
00244 print 9980, trim(ch_id), ierror
00245
00246 call psmile_flushstd
00247 #endif /* VERBOSE */
00248
00249
00250
00251 9990 format (1x, a, ': psmile_bbcells_pole_dble')
00252 9980 format (1x, a, ': psmile_bbcells_pole_dble: eof ierror =', i3)
00253
00254
00255 contains
00256
00257 subroutine compute_midpoint(cell, midp_x, midp_y)
00258 type(point_dble), intent(in) :: cell(4)
00259 double precision, intent(out) :: midp_x, midp_y
00260 type(point_dble) :: temp_cell(4), temp_midp
00261
00262 #ifdef VERBOSE
00263 print 9970, trim(ch_id), cell(1)%x,cell(1)%y
00264 print 9971, trim(ch_id), cell(2)%x,cell(2)%y
00265 print 9972, trim(ch_id), cell(3)%x,cell(3)%y
00266 print 9973, trim(ch_id), cell(4)%x,cell(4)%y
00267 call psmile_flushstd
00268 #endif /* VERBOSE */
00269
00270 call psmile_transrot_dble(cell(1)%x, cell(1)%y, temp_cell(1)%x, temp_cell(1)%y)
00271 call psmile_transrot_dble(cell(2)%x, cell(2)%y, temp_cell(2)%x, temp_cell(2)%y)
00272 call psmile_transrot_dble(cell(3)%x, cell(3)%y, temp_cell(3)%x, temp_cell(3)%y)
00273 call psmile_transrot_dble(cell(4)%x, cell(4)%y, temp_cell(4)%x, temp_cell(4)%y)
00274
00275 temp_midp%x = sum(temp_cell(:)%x) / 4.0d0
00276 temp_midp%y = sum(temp_cell(:)%y) / 4.0d0
00277
00278 call psmile_transrot_back_dble(midp_x, midp_y, &
00279 temp_midp%x, temp_midp%y)
00280
00281 #ifdef VERBOSE
00282 print 9960, trim(ch_id), midp_x, midp_y
00283 call psmile_flushstd
00284 #endif /* VERBOSE */
00285 9970 format (1x, a, ': psmile_bbcells_pole_dble: computing new midpoint for cell(1) =', 2f8.2)
00286 9971 format (1x, a, ': psmile_bbcells_pole_dble: computing new midpoint for cell(2) =', 2f8.2)
00287 9972 format (1x, a, ': psmile_bbcells_pole_dble: computing new midpoint for cell(3) =', 2f8.2)
00288 9973 format (1x, a, ': psmile_bbcells_pole_dble: computing new midpoint for cell(4) =', 2f8.2)
00289 9960 format (1x, a, ': psmile_bbcells_pole_dble: new midpoint =', 2f8.2)
00290
00291 end subroutine compute_midpoint
00292
00293 function psmile_cell_covers_pole (corners_x, corners_y, num_corners)
00294 double precision, intent(in) :: corners_x(4), corners_y(4)
00295 integer, intent(in) :: num_corners
00296 logical :: psmile_cell_covers_pole
00297 double precision :: angle
00298 integer :: sense, i
00299
00300
00301 if (any(abs(corners_y) == 90)) then
00302 psmile_cell_covers_pole = .true.
00303 return
00304 endif
00305
00306 sense = 0
00307
00308 do i = 1, num_corners - 1
00309 angle = corners_x(i+1) - corners_x(i)
00310 sense = sense + sign(1.0d0,mod(angle-180.0d0,360.0d0)+180.0d0)
00311 enddo
00312
00313 angle = corners_x(1) - corners_x(num_corners)
00314 sense = sense + sign(1.0d0,mod(angle-180.0d0,360.0d0)+180.0d0)
00315
00316 psmile_cell_covers_pole = abs(sense) == num_corners
00317 end function psmile_cell_covers_pole
00318
00319 end subroutine psmile_bbcells_pole_dble