00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_control_cell_gauss2_real (grid_id, &
00012 ic, nc, list, j, k, &
00013 coords1, coords2, shape, &
00014 corners1, corners2, corner_shape, nbr_corners, &
00015 tol, fnd, ierror)
00016
00017
00018
00019 use PRISM_constants
00020
00021 use PSMILe, dummy_interface => PSMILe_Control_cell_gauss2_real
00022 #ifdef DEBUG_TRACE
00023 use psmile_debug_trace
00024 #endif
00025
00026 Implicit none
00027
00028
00029
00030 Integer, Intent (In) :: grid_id
00031
00032
00033
00034 Integer, Intent (In) :: nc
00035
00036
00037
00038 Integer, Intent (In) :: ic (nc)
00039
00040
00041
00042
00043 Integer, Intent (In) :: list (nc)
00044
00045
00046
00047 Integer, Intent (In) :: j
00048
00049
00050
00051 Integer, Intent (In) :: k
00052
00053
00054
00055
00056 Integer, Intent (In) :: shape (2, ndim_3d)
00057
00058
00059
00060
00061 Real, Intent (In) ::
00062 coords1 (shape(1,1):shape(2,1), shape(1,2):shape(2,2),
00063 shape(1,3):shape(2,3))
00064
00065 Real, Intent (In) ::
00066 coords2 (shape(1,1):shape(2,1), shape(1,2):shape(2,2),
00067 shape(1,3):shape(2,3))
00068
00069
00070
00071 Integer, Intent (In) :: corner_shape (2, ndim_2d)
00072
00073
00074
00075 Integer, Intent (In) :: nbr_corners
00076
00077
00078
00079
00080 Real, Intent (In) ::
00081 corners1 ( corner_shape(1,1):corner_shape(2,1), nbr_corners)
00082
00083
00084
00085 Real, Intent (In) ::
00086 corners2 ( corner_shape(1,1):corner_shape(2,1), nbr_corners)
00087
00088
00089
00090 Real, Intent (In) :: tol
00091
00092
00093
00094
00095
00096
00097 Logical, Intent (Out) :: fnd (nc)
00098
00099
00100
00101 Integer, Intent (Out) :: ierror
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 Integer, Parameter :: ntet = 3
00114
00115 Real, Parameter :: eps = 1.0d-9
00116 Real, Parameter :: rmxeps = 1.0d30
00117 Real, Parameter :: dzero = 0.0
00118
00119
00120
00121
00122
00123 Real :: tol1
00124
00125
00126
00127 Integer :: i, jj, m, n
00128
00129
00130
00131 Integer, Save :: ijkedg (2, ntet)
00132
00133
00134
00135 Real :: xyzpnt (nc, ntet, ndim_2d),
00136 xyzref (nc, ntet+1, ndim_2d)
00137 Real :: xyzedg (nc, ntet, ndim_2d, 2)
00138 Real :: d1, d2
00139 Real :: det (nc, ntet)
00140 Real :: dnorm
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 Character(len=len_cvs_string), save :: mycvs =
00167 '$Id: psmile_control_cell_gauss2_real.F90 2927 2011-01-28 14:04:12Z hanke $'
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 data ((ijkedg (jj, n), jj = 1, 2), n = 1, ntet) &
00181 / 2, 4, 3, 1, 4, 2/
00182
00183
00184
00185
00186
00187
00188
00189 #ifdef VERBOSE
00190 print 9990, trim(ch_id), nc
00191
00192 call psmile_flushstd
00193 #endif /* VERBOSE */
00194
00195 #ifdef PRISM_ASSERTION
00196 if (tol < 0.0) then
00197 call psmile_assert (__FILE__, __LINE__, &
00198 "tol must be >= 0.0")
00199 endif
00200
00201
00202 do i = 1, nc
00203 if (ic(i) < corner_shape(1,1) .or. ic(i) > corner_shape(2,1) ) then
00204 exit
00205 endif
00206 end do
00207
00208 if (i <= nc) then
00209 print *, 'i, ic', i, ic(i)
00210 print *, 'corner_shape', corner_shape
00211 call psmile_assert (__FILE__, __LINE__, &
00212 'wrong index')
00213 endif
00214 #endif
00215
00216 ierror = 0
00217
00218
00219
00220
00221 xyzref (:, 1, 1) = corners1 (ic(:), 1)
00222 xyzref (:, 1, 2) = corners2 (ic(:), 1)
00223
00224 xyzref (:, 2, 1) = corners1 (ic(:), 2)
00225 xyzref (:, 2, 2) = xyzref (:, 1, 2)
00226
00227 xyzref (:, 3, 1) = xyzref (:, 2, 1)
00228 xyzref (:, 3, 2) = corners2 (ic(:), 2)
00229
00230 xyzref (:, 4, 1) = xyzref (:, 1, 1)
00231 xyzref (:, 4, 2) = xyzref (:, 3, 2)
00232
00233 #ifdef DEBUG_TRACE
00234 do i = 1, nc
00235 if ( list(i) == ictl_ind(1) .and. j == ictl_ind(2) ) then
00236 print *, 'Search coords ', &
00237 coords1(list(i),j,shape(1,3)), coords2(list(i),j,shape(1,3))
00238 print *, 'Corners: '
00239 print *, ' C1 : ', xyzref (i, 1, 1), xyzref (i, 1, 2)
00240 print *, ' C2 : ', xyzref (i, 2, 1), xyzref (i, 2, 2)
00241 print *, ' C3 : ', xyzref (i, 3, 1), xyzref (i, 3, 2)
00242 print *, ' C4 : ', xyzref (i, 4, 1), xyzref (i, 4, 2)
00243 endif
00244 enddo
00245 #endif
00246 do n = 1, ntet
00247 xyzpnt (:, n, 1) = coords1 (list(:), j, k) - xyzref (:, n, 1)
00248 xyzpnt (:, n, 2) = coords2 (list(:), j, k) - xyzref (:, n, 2)
00249
00250 do m = 1, 2
00251
00252 do i = 1, nc
00253 xyzedg (i, n, 1, m) = xyzref (i, ijkedg(m, n), 1) &
00254 - xyzref (i, n, 1)
00255
00256 xyzedg (i, n, 2, m) = xyzref (i, ijkedg(m, n), 2) &
00257 - xyzref (i, n, 2)
00258 end do
00259 end do
00260 end do
00261
00262
00263
00264
00265
00266 det(:, :) = xyzedg(:, :, 1,1)*xyzedg(:, :, 2,2) &
00267 - xyzedg(:, :, 1,2)*xyzedg(:, :, 2,1)
00268
00269 #define ALLOW_DEGRADED_CELL
00270 #ifdef ALLOW_DEGRADED_CELL
00271
00272
00273
00274 do n = 1, ntet
00275
00276 do i = 1, nc
00277 dnorm = abs(xyzedg(i, n,1,1)) + abs(xyzedg(i, n,2,1)) + &
00278 abs(xyzedg(i, n,1,2)) + abs(xyzedg(i, n,2,2))
00279
00280 if (abs(det(i, n)) < eps*dnorm*dnorm .or. dnorm == dzero) then
00281 det (i, n) = sign (rmxeps, det(i, n))
00282 else
00283 det (i, n) = 1.0 / det (i, n)
00284 endif
00285 end do
00286 end do
00287
00288 #else
00289
00290 loop_n: do n = 1, ntet
00291
00292 do i = 1, nc
00293 dnorm = abs(xyzedg(i, n,1,1)) + abs(xyzedg(i, n,2,1)) + &
00294 abs(xyzedg(i, n,1,2)) + abs(xyzedg(i, n,2,2))
00295
00296 if (abs(det(i, n)) < eps*dnorm*dnorm .or. &
00297 dnorm(i,n) == dzero) then
00298 det (i, n) = dnorm * 1e-25
00299
00300
00301
00302 endif
00303 end do
00304 end do
00305
00306 #ifdef PRINT_DEGRADED_CELL
00307 if (n < ntet) then
00308
00309
00310
00311 print 9960, trim(ch_id), grid_id, ic (i), &
00312 (xyzref (i, n, 1), xyzref (i, n, 2), n = 1, 4)
00313
00314 do n = 1, ntet
00315 if (abs(det(i, n)) < eps) then
00316 print 9950, n, det (i, n), dnorm, &
00317 xyzedg (i, n,1, 1), xyzedg (i, n,1, 2), &
00318 xyzedg (i, n,2, 1), xyzedg (i, n,2, 2)
00319 endif
00320 end do
00321
00322 nicht gefunden fnd (i) = .false. versucht, durch
00323 ganz kleine Determinante zu loesen
00324 endif
00325 #endif /* PRINT_DEGRADED_CELL */
00326
00327 det (:, :) = 1.0 / det (:, :)
00328
00329 #endif /* ALLOW_DEGRADED_CELL */
00330
00331
00332
00333
00334 tol1 = tol + 1.0
00335 fnd (:) = .false.
00336
00337 do n = 1, ntet
00338
00339 do i = 1, nc
00340
00341 d1 = (xyzpnt(i, n,1)*xyzedg(i, n,2,2)- &
00342 xyzpnt(i, n,2)*xyzedg(i, n,1,2)) * det (i, n)
00343 d2 = (xyzpnt(i, n,2)*xyzedg(i, n,1,1)- &
00344 xyzpnt(i, n,1)*xyzedg(i, n,2,1)) * det (i, n)
00345
00346 fnd (i) = fnd (i) .or. &
00347 (min(d1, d2) >= -tol .and. &
00348 max(d1,dzero) + max(d2,dzero) <= tol1)
00349 end do
00350 end do
00351
00352
00353
00354 #ifdef VERBOSE
00355 print 9980, trim(ch_id), count(fnd(:))
00356
00357 call psmile_flushstd
00358 #endif /* VERBOSE */
00359
00360
00361
00362
00363 9990 format (1x, a, ': psmile_control_cell_gauss2_real: nc', i5)
00364 9980 format (1x, a, ': psmile_control_cell_gauss2_real: eof, suc', i5)
00365
00366 #ifdef PRINT_DEGRADED_CELL
00367 9960 format (1x, a, ': psmile_control_cell_gauss2_real: grid id =', i5, &
00368 /1x, ' Grid cell (', i4,
00369 ') is degraded! Cell coordinates are:', 1p, &
00370 4 (/1x, '(', 1 (e17.9, ','), e17.9, ')'))
00371 9950 format (1x, i1, '-th spawn; det =', 1p, e17.9, ' (', e17.9, &
00372 ') of', 2 (/1x, 2e17.9, ','))
00373 #endif
00374
00375 end subroutine psmile_control_cell_gauss2_real