00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_neigh_trili_3d ( &
00012 grid_valid_shape, interpolation_mode, cyclic, &
00013 srcloc, nloc, neighbors_3d, num_neigh, ierror)
00014
00015
00016
00017 use PRISM_constants
00018
00019 use PSMILe, dummy_interface => PSMILe_Neigh_trili_3d
00020
00021 implicit none
00022
00023
00024
00025 Integer, Intent (In) :: nloc
00026
00027
00028
00029 Integer, Intent (In) :: srcloc (ndim_3d, nloc)
00030
00031
00032
00033 Integer, Intent (In) :: grid_valid_shape (2, ndim_3d)
00034
00035
00036
00037 Integer, Intent (In) :: interpolation_mode
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 Logical, Intent (In) :: cyclic (ndim_3d)
00048
00049
00050
00051 Integer, Intent (In) :: num_neigh
00052
00053
00054
00055
00056
00057 Integer, Intent (Out) :: neighbors_3d (ndim_3d, nloc, num_neigh)
00058
00059
00060
00061 Integer, Intent (Out) :: ierror
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 Integer, Parameter :: n_corners_3d = 2 * 2 * 2
00075 Integer, Parameter :: n_corners_2d = 2 * 2
00076 Integer, Parameter :: n_corners_1d = 2
00077
00078
00079
00080
00081
00082 Integer :: i, j, n
00083 Integer :: n_corners
00084
00085
00086
00087 Integer, Save :: ijkstd (ndim_3d, 2:n_corners_3d)
00088 Integer :: ijkctl (ndim_3d, 2:n_corners_3d)
00089
00090 Integer :: length (ndim_3d)
00091 Integer :: nca (ndim_3d)
00092
00093
00094
00095 Integer, parameter :: nerrp = 2
00096 Integer :: ierrp (nerrp)
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 Character(len=len_cvs_string), save :: mycvs =
00123 '$Id: psmile_neigh_trili_3d.F90 2687 2010-10-28 15:15:52Z coquart $'
00124
00125
00126
00127
00128
00129 #ifdef FORTRAN_ORDER
00130 data ((ijkstd (i, n), i=1,ndim_3d), n = 2, n_corners_3d) &
00131 / 1, 0, 0, &
00132 0, 1, 0, 1, 1, 0, &
00133 0, 0, 1, 1, 0, 1, &
00134 0, 1, 1, 1, 1, 1/
00135
00136 #else
00137
00138 data ((ijkstd (i, n), i=1,ndim_3d), n = 2, n_corners_3d) &
00139 / 1, 0, 0, &
00140 1, 1, 0, 0, 1, 0, &
00141 0, 0, 1, 1, 0, 1, &
00142 1, 1, 1, 0, 1, 1/
00143 #endif
00144
00145 data nca /n_corners_1d, n_corners_2d, n_corners_3d/
00146
00147
00148
00149
00150
00151 #ifdef VERBOSE
00152 print 9990, trim(ch_id)
00153 call psmile_flushstd
00154 #endif /* VERBOSE */
00155
00156
00157
00158 if (interpolation_mode < 1 .or. interpolation_mode > ndim_3d) then
00159 ierrp (1) = interpolation_mode
00160 ierror = PRISM_Error_Internal
00161
00162 call psmile_error ( ierror, 'unsupported interpolation mode in psmile_neigh_trili', &
00163 ierrp, 1, __FILE__, __LINE__ )
00164 return
00165 endif
00166
00167
00168
00169 ierror = 0
00170
00171 n_corners = nca (interpolation_mode)
00172
00173 length (1:ndim_3d) = grid_valid_shape(2,1:ndim_3d) - &
00174 grid_valid_shape(1,1:ndim_3d) + 1
00175
00176 #ifdef PRISM_ASSERTION
00177
00178
00179
00180 if (num_neigh < n_corners) then
00181 print 9970, trim(ch_id), num_neigh, n_corners
00182 call psmile_assert (__FILE__, __LINE__, &
00183 'Number of neighbors is insufficient')
00184 endif
00185
00186
00187
00188
00189
00190
00191 do i = 1, nloc
00192
00193 if (srcloc(1,i) < grid_valid_shape(1,1)-1 .or. &
00194 srcloc(1,i) > grid_valid_shape(2,1) .or. &
00195 srcloc(2,i) < grid_valid_shape(1,2)-1 .or. &
00196 srcloc(2,i) > grid_valid_shape(2,2) .or. &
00197 srcloc(3,i) < grid_valid_shape(1,3)-1 .or. &
00198 srcloc(3,i) > grid_valid_shape(2,3)) exit
00199 end do
00200
00201 if (i <= nloc) then
00202 print *, "Incorrect index in i", i, srcloc (:, i)
00203 print *, grid_valid_shape
00204 call psmile_assert (__FILE__, __LINE__, &
00205 'wrong index')
00206 endif
00207 #endif
00208
00209
00210
00211
00212
00213 ijkctl = ijkstd
00214
00215 do j = 1, ndim_3d
00216 if (length(j) == 1) ijkctl (j, :) = 0
00217 end do
00218
00219
00220
00221
00222 #define TRANSF_SUP_2D_INTERP
00223
00224 #ifdef TRANSF_SUP_2D_INTERP
00225
00226
00227
00228
00229 neighbors_3d (:, 1:nloc, 1) = srcloc (:, 1:nloc)
00230 #else
00231
00232 if ( n_corners == N_CORNERS_2D ) then
00233
00234
00235
00236 do j = 1, ndim_2d
00237 if (cyclic (j) .or. length(j) == 1) then
00238 neighbors_3d (j, :, 1) = srcloc (j, :)
00239 else
00240
00241 do i = 1, nloc
00242 neighbors_3d (j, i, 1) = min (srcloc (j, i), &
00243 grid_valid_shape(2,j)-1)
00244 end do
00245
00246 endif
00247 end do
00248
00249
00250
00251 neighbors_3d (3, :, 1) = srcloc (3, :)
00252
00253 else
00254
00255 do j = 1, ndim_3d
00256 if (cyclic (j) .or. length(j) == 1) then
00257 neighbors_3d (j, :, 1) = srcloc (j, :)
00258 else
00259
00260 do i = 1, nloc
00261 neighbors_3d (j, i, 1) = min (srcloc (j, i), &
00262 grid_valid_shape(2,j)-1)
00263 end do
00264 endif
00265 end do
00266
00267 endif
00268
00269 #endif /* TRANSF_SUP_2D_INTERP */
00270
00271 do n = 2, n_corners
00272
00273 do i = 1, nloc
00274
00275 neighbors_3d (:, i, n) = neighbors_3d (:, i, 1) + ijkctl (:, n)
00276 end do
00277 end do
00278
00279
00280
00281 do j = 1, ndim_3d
00282 if (cyclic(j) .and. length(j) > 1) then
00283
00284 do n = 1, n_corners
00285
00286 do i = 1, nloc
00287 if (neighbors_3d (j, i, n) < grid_valid_shape(1,j)) then
00288 neighbors_3d (j, i, n) = &
00289 neighbors_3d (j, i, n) + length (j)
00290
00291 else if ( neighbors_3d (j, i, n) > grid_valid_shape(2,j)) then
00292 neighbors_3d (j, i, n) = &
00293 neighbors_3d (j, i, n) - length (j)
00294 endif
00295 end do
00296 end do
00297 endif
00298 end do
00299
00300
00301
00302 #ifdef VERBOSE
00303 print 9980, trim(ch_id)
00304
00305 call psmile_flushstd
00306 #endif /* VERBOSE */
00307
00308
00309
00310 9990 format (1x, a, ': psmile_neigh_trili_3d')
00311 9980 format (1x, a, ': psmile_neigh_trili_3d: eof')
00312
00313 #ifdef PRISM_ASSERTION
00314 9970 format (1x, a, ': number of neighbors', i2, '; expected at least', i2)
00315 #endif
00316
00317 end subroutine psmile_neigh_trili_3d