00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_control_cell_2d_dble (grid_id, &
00012 ic, nc, icdim1, 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_2d_dble
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) :: icdim1
00039
00040
00041
00042 Integer, Intent (In) :: ic (icdim1, ndim_2d)
00043
00044
00045
00046
00047
00048 Integer, Intent (In) :: list (nc)
00049
00050
00051
00052 Integer, Intent (In) :: j
00053
00054
00055
00056 Integer, Intent (In) :: k
00057
00058
00059
00060 Integer, Intent (In) :: shape (2, ndim_3d)
00061
00062
00063
00064
00065 Double Precision, Intent (In) :: coords1 (shape(1,1):shape(2,1),
00066 shape(1,2):shape(2,2),
00067 shape(1,3):shape(2,3))
00068 Double Precision, Intent (In) :: coords2 (shape(1,1):shape(2,1),
00069 shape(1,2):shape(2,2),
00070 shape(1,3):shape(2,3))
00071
00072
00073
00074 Integer, Intent (In) :: corner_shape (2, ndim_2d)
00075
00076
00077
00078 Integer, Intent (In) :: nbr_corners
00079
00080
00081
00082
00083 Double Precision, Intent (In) ::
00084 corners1 ( corner_shape(1,1):corner_shape(2,1),
00085 corner_shape(1,2):corner_shape(2,2), nbr_corners)
00086
00087 Double Precision, Intent (In) ::
00088 corners2 ( corner_shape(1,1):corner_shape(2,1),
00089 corner_shape(1,2):corner_shape(2,2), nbr_corners)
00090
00091
00092
00093 Double Precision, Intent (In) :: tol
00094
00095
00096
00097
00098
00099
00100 Logical, Intent (Out) :: fnd (nc)
00101
00102
00103
00104 Integer, Intent (Out) :: ierror
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 Integer, Parameter :: ntet = 3
00117
00118 Double Precision, Parameter :: eps = 1.0d-9
00119 Double Precision, Parameter :: rmxeps = 1.0d30
00120 Double Precision, Parameter :: dzero = 0.0
00121
00122
00123
00124
00125
00126 Double Precision :: tol1
00127
00128
00129
00130 Integer :: i, jj, m, n
00131
00132
00133
00134 Integer, Save :: ijkedg (2, ntet)
00135
00136
00137
00138 Double Precision :: xyzpnt (nc, ntet, ndim_2d),
00139 xyzref (nc, ntet, ndim_2d)
00140 Double Precision :: xyzedg (nc, ntet, ndim_2d, 2)
00141 Double Precision :: d1, d2
00142 Double Precision :: det (nc, ntet)
00143 Double Precision :: dnorm
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 Character(len=len_cvs_string), save :: mycvs =
00166 '$Id: psmile_control_cell_2d_dble.F90 2927 2011-01-28 14:04:12Z hanke $'
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 data ((ijkedg (jj, n), jj = 1, 2), n = 1, ntet) &
00180 / 2, 4, 3, 1, 4, 2/
00181
00182
00183
00184
00185
00186
00187
00188 #ifdef VERBOSE
00189 print 9990, trim(ch_id), nc
00190
00191 call psmile_flushstd
00192 #endif /* VERBOSE */
00193
00194 #ifdef PRISM_ASSERTION
00195 if (tol < 0.0) then
00196 call psmile_assert (__FILE__, __LINE__, &
00197 "tol must be >= 0.0")
00198 endif
00199
00200
00201 do i = 1, nc
00202 if (ic(i,1) < corner_shape(1,1) .or. ic(i,1) > corner_shape(2,1) .or. &
00203 ic(i,2) < corner_shape(1,2) .or. ic(i,2) > corner_shape(2,2) ) 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 do n = 1, ntet
00222
00223 do i = 1, nc
00224 xyzref (i, n, 1) = corners1 (ic(i,1), ic(i,2), n)
00225 xyzref (i, n, 2) = corners2 (ic(i,1), ic(i,2), n)
00226 end do
00227
00228 xyzpnt (:, n, 1) = coords1 (list(:), j, k) - xyzref (:, n, 1)
00229 xyzpnt (:, n, 2) = coords2 (list(:), j, k) - xyzref (:, n, 2)
00230
00231 do m = 1, 2
00232
00233 do i = 1, nc
00234 xyzedg (i, n, 1, m) = corners1 (ic(i,1), ic(i,2), ijkedg(m, n)) &
00235 - xyzref (i, n, 1)
00236
00237 xyzedg (i, n, 2, m) = corners2 (ic(i,1), ic(i,2), ijkedg(m, n)) &
00238 - xyzref (i, n, 2)
00239 end do
00240 end do
00241 end do
00242
00243
00244
00245
00246
00247 det(:, :) = xyzedg(:, :, 1,1)*xyzedg(:, :, 2,2) &
00248 - xyzedg(:, :, 1,2)*xyzedg(:, :, 2,1)
00249
00250 #ifdef DEBUG_TRACE
00251 if (j == ictl_ind(2)) then
00252
00253 do i = 1, nc
00254 if ( list(i) == ictl_ind(1) ) exit
00255 end do
00256
00257 if (i <= nc) then
00258 print *, 'ictl: i,j', list(i), j, coords1 (list(i), j, k), coords2 (list(i), j, k)
00259 do n = 1, 4
00260 print *, corners1 (ic(i,1), ic(i,2), n), corners2 (ic(i,1), ic(i,2), n)
00261 enddo
00262 print *, '#################################################'
00263 print *, ' i, nc ', i, nc
00264 print *, ' det', det (i, :)
00265 end if
00266 end if
00267 #endif
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.0d0 / 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 corners1(ic(i,1), ic(i,2), 1), &
00313 corners2(ic(i,1), ic(i,2), 1), &
00314 corners1(ic(i,1), ic(i,2), 2), &
00315 corners2(ic(i,1), ic(i,2), 2), &
00316 corners1(ic(i,1), ic(i,2), 3), &
00317 corners2(ic(i,1), ic(i,2), 3), &
00318 corners1(ic(i,1), ic(i,2), 4), &
00319 corners2(ic(i,1), ic(i,2), 4)
00320
00321 do n = 1, ntet
00322 if (abs(det(i, n)) < eps) then
00323 print 9950, n, det (i, n), dnorm, &
00324 xyzedg (i, n,1, 1), xyzedg (i, n,1, 2), &
00325 xyzedg (i, n,2, 1), xyzedg (i, n,2, 2)
00326 endif
00327 end do
00328
00329 nicht gefunden fnd (i) = .false. versucht, durch
00330 ganz kleine Determinante zu loesen
00331 endif
00332 #endif /* PRINT_DEGRADED_CELL */
00333
00334 det (:, :) = 1.0d0 / det (:, :)
00335
00336 #endif /* ALLOW_DEGRADED_CELL */
00337
00338
00339
00340
00341 tol1 = tol + 1.0
00342 fnd (:) = .false.
00343
00344 do n = 1, ntet
00345
00346 do i = 1, nc
00347
00348 d1 = (xyzpnt(i, n,1)*xyzedg(i, n,2,2)- &
00349 xyzpnt(i, n,2)*xyzedg(i, n,1,2)) * det (i, n)
00350 d2 = (xyzpnt(i, n,2)*xyzedg(i, n,1,1)- &
00351 xyzpnt(i, n,1)*xyzedg(i, n,2,1)) * det (i, n)
00352
00353 fnd (i) = fnd (i) .or. &
00354 (min(d1, d2) >= -tol .and. &
00355 max(d1,dzero) + max(d2,dzero) <= tol1)
00356 end do
00357 end do
00358
00359
00360
00361 #ifdef VERBOSE
00362 print 9980, trim(ch_id), count(fnd(:))
00363
00364 call psmile_flushstd
00365 #endif /* VERBOSE */
00366
00367
00368
00369
00370 9990 format (1x, a, ': psmile_control_cell_2d_dble: nc', i5)
00371 9980 format (1x, a, ': psmile_control_cell_2d_dble: eof, suc', i5)
00372
00373 #ifdef PRINT_DEGRADED_CELL
00374 9960 format (1x, a, ': psmile_control_cell_2d_dble: grid id =', i5, &
00375 /1x, ' Grid cell (', i4, ',', i4, &
00376 ') is degraded! Cell coordinates are:', 1p, &
00377 4 (/1x, '(', 1 (e17.9, ','), e17.9, ')'))
00378 9950 format (1x, i1, '-th spawn; det =', 1p, e17.9, ' (', e17.9, &
00379 ') of', 2 (/1x, 2e17.9, ','))
00380 #endif
00381
00382 end subroutine psmile_control_cell_2d_dble