00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_mg_final_prev_2d_real (grid_id, nlev, &
00012 lstijk, xyz, found, newijk, nc, &
00013 corners1, corners2, corner_shape, nbr_corners, &
00014 tol, ierror)
00015
00016
00017
00018 use PRISM_constants
00019
00020 use PSMILe, dummy_interface => PSMILe_MG_final_prev_2d_real
00021
00022 Implicit none
00023
00024
00025
00026 Integer, Intent (In) :: grid_id
00027
00028
00029
00030 Integer, Intent (In) :: nlev
00031
00032
00033
00034 Integer, Intent (In) :: nc
00035
00036
00037
00038 Integer, Intent (In) :: lstijk (ndim_2d, nc)
00039
00040
00041
00042
00043
00044
00045
00046 Real, Intent (In) :: xyz (ndim_2d, nc)
00047
00048
00049
00050 Integer, Intent (In) :: corner_shape (2, ndim_2d)
00051
00052
00053
00054 Integer, Intent (In) :: nbr_corners
00055
00056
00057
00058
00059 Real, Intent (In) ::
00060 corners1 ( corner_shape(1,1):corner_shape(2,1),
00061 corner_shape(1,2):corner_shape(2,2), nbr_corners)
00062
00063 Real, Intent (In) ::
00064 corners2 ( corner_shape(1,1):corner_shape(2,1),
00065 corner_shape(1,2):corner_shape(2,2), nbr_corners)
00066
00067
00068
00069 Real, Intent (In) :: tol
00070
00071
00072
00073
00074
00075
00076 Integer, Intent (Out) :: found (nc)
00077
00078
00079
00080
00081
00082 Integer, Intent (Out) :: newijk (ndim_2d, nc)
00083
00084
00085
00086 Integer, Intent (Out) :: ierror
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 Integer, Parameter :: ntet = 3
00099
00100 Real, Parameter :: eps = 1.0d-9
00101 Real, Parameter :: rmxeps = 1.0d30
00102 Real, Parameter :: dzero = 0.0
00103
00104 Integer, Parameter :: lev = 1
00105 Integer, Parameter :: levc = 2
00106 Logical, Parameter :: wide = .true.
00107 Logical, Parameter :: small = .false.
00108
00109
00110
00111 Integer :: i, n
00112
00113
00114
00115 Type (Enddef_mg), Pointer :: mg_infos (:)
00116 Integer, Pointer :: ijk0 (:)
00117
00118
00119
00120 Integer :: levd, levdbg, levu, levubg
00121 Integer :: nlev1
00122 Integer :: nold (nc, nlev-1)
00123 Integer :: ijk (ndim_2d, nc, nlev-1)
00124 Integer :: ignore (ndim_2d, nlev-1)
00125
00126
00127
00128 Real :: tol1
00129
00130
00131
00132 Integer :: j, m, nt
00133
00134
00135
00136 Integer, Save :: ijkedg (2, ntet)
00137
00138
00139
00140 Integer :: ind (ndim_2d)
00141 Real :: xyzpnt (ntet, ndim_2d),
00142 xyzref (ntet, ndim_2d)
00143 Real :: xyzedg (ntet, ndim_2d, 2)
00144 Real :: d1, d2
00145 Real :: det (ntet)
00146 Real :: dnorm
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 Character(len=len_cvs_string), save :: mycvs =
00170 '$Id: psmile_mg_final_prev_2d_real.F90,v 1.1.2.2 2008/12/08 18:36:56 ritzdorf Exp $'
00171
00172
00173
00174
00175
00176
00177
00178 data ((ijkedg (j, n), j = 1, 2), n = 1, ntet) &
00179 / 2, 4, 3, 1, 4, 2/
00180
00181
00182
00183
00184
00185
00186 #ifdef VERBOSE
00187 print 9990, trim(ch_id), nc
00188
00189 call psmile_flushstd
00190 #endif /* VERBOSE */
00191
00192 ierror = 0
00193
00194 mg_infos => Grids(grid_id)%mg_infos
00195 ijk0 => Grids(grid_id)%ijk0
00196
00197 nlev1 = nlev - 1
00198 tol1 = tol + 1.0
00199
00200 #ifdef PRISM_ASSERTION
00201 if (levc >= nlev) then
00202 call psmile_assert (__FILE__, __LINE__, 'incorrect level')
00203 endif
00204
00205 if (tol < 0.0) then
00206 call psmile_assert (__FILE__, __LINE__, &
00207 "tol must be >= 0.0")
00208 endif
00209
00210
00211 do i = 1, nc
00212 if (lstijk(1,i)+ijk0(1) < corner_shape(1,1) .or. &
00213 lstijk(1,i)+ijk0(1) > corner_shape(2,1) .or. &
00214 lstijk(2,i)+ijk0(2) < corner_shape(1,2) .or. &
00215 lstijk(2,i)+ijk0(2) > corner_shape(2,2) ) then
00216 exit
00217 endif
00218 end do
00219
00220 if (i <= nc) then
00221 print *, 'i, lstijk', i, lstijk (:, i), ijk0
00222 print *, 'corner_shape', corner_shape
00223 call psmile_assert (__FILE__, __LINE__, &
00224 'wrong index')
00225 endif
00226 #endif
00227
00228 do levd = levc, nlev1
00229 nold (:, levd) = 0
00230 end do
00231
00232
00233
00234
00235 do i = 1, ndim_2d
00236 if (mg_infos(lev )%levdim(i) /= &
00237 mg_infos(levc)%levdim(i) ) then
00238
00239
00240
00241 ijk (:, :, levc) = lstijk (:, :) / 2
00242 else
00243 ijk (:, :, levc) = lstijk (:, :)
00244 endif
00245 end do
00246
00247 do levd = levc+1, nlev1
00248 do i = 1, ndim_2d
00249 if (mg_infos(levd )%levdim(i) /= &
00250 mg_infos(levd-1)%levdim(i) ) then
00251
00252
00253
00254 ijk (i, :, levd) = (ijk (i, :, levd-1) / 4) * 2
00255 else
00256 ijk (i, :, levd) = ijk (i, :, levd-1)
00257 endif
00258 end do
00259 end do
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 loop_n: do n = 1, nc
00281
00282 levdbg = levc
00283
00284
00285 ignore (:, lev) = lstijk (:, n)
00286
00287 do i = 1, ndim_2d
00288 do levd = levc, nlev1
00289 if (mg_infos(levd-1)%levdim(i) > &
00290 mg_infos(levd )%levdim(i)) then
00291 ignore (i, levd) = ignore (i, levd-1) / 2
00292 else
00293 ignore (i, levd) = ignore (i, levd-1)
00294 endif
00295 end do
00296 end do
00297
00298 100 continue
00299
00300 do levd = levdbg, nlev1
00301
00302 call psmile_mg_control_cell_2d_real ( &
00303 mg_infos(levd)%real_arrays%chmin(1)%vector, &
00304 mg_infos(levd)%real_arrays%chmin(2)%vector, &
00305 mg_infos(levd)%real_arrays%chmax(1)%vector, &
00306 mg_infos(levd)%real_arrays%chmax(2)%vector, &
00307 mg_infos(levd)%real_arrays%midp (1)%vector, &
00308 mg_infos(levd)%real_arrays%midp (2)%vector, &
00309 mg_infos(levd)%levdim, &
00310 ijk(1, n, levd), xyz(:,n), nold(n, levd), &
00311 ignore (1, levd), wide, found (n), newijk (:, n))
00312
00313 if (found (n) > 0) then
00314 go to 1990
00315 endif
00316
00317 end do
00318
00319
00320
00321 cycle loop_n
00322
00323
00324
00325
00326
00327 1990 nold (n, levd) = found (n)
00328
00329 levdbg = levd
00330 levubg = levd - 1
00331
00332 nold (n, levubg) = 0
00333
00334 do i = 1, ndim_2d
00335 if (mg_infos(levubg )%levdim(i) > &
00336 mg_infos(levubg+1)%levdim(i)) then
00337 ijk (i, n, levubg) = min (newijk(i,n)*2, &
00338 mg_infos(levubg)%levdim(i))
00339 else
00340 ijk (i, n, levubg) = newijk (i,n)
00341 endif
00342 enddo
00343
00344 1995 continue
00345
00346 do levu = levubg, lev, -1
00347
00348 2000 continue
00349
00350 call psmile_mg_control_cell_2d_real ( &
00351 mg_infos(levu)%real_arrays%chmin(1)%vector, &
00352 mg_infos(levu)%real_arrays%chmin(2)%vector, &
00353 mg_infos(levu)%real_arrays%chmax(1)%vector, &
00354 mg_infos(levu)%real_arrays%chmax(2)%vector, &
00355 mg_infos(levu)%real_arrays%midp (1)%vector, &
00356 mg_infos(levu)%real_arrays%midp (2)%vector, &
00357 mg_infos(levu)%levdim, &
00358 ijk(1, n, levu), xyz(:,n), nold(n, levu), &
00359 ignore (1, levu), small, found(n), newijk (:,n))
00360
00361 if (found(n) == 0) then
00362 if (levu < levd-1) then
00363
00364
00365
00366 levubg = levu + 1
00367 go to 1995
00368 else
00369
00370
00371
00372 go to 100
00373 endif
00374
00375 else if (levu > lev) then
00376
00377 nold (n, levu) = found (n)
00378
00379
00380
00381 nold (n, levu-1) = 0
00382
00383 do i = 1, ndim_2d
00384 if (mg_infos(levu-1)%levdim(i) > &
00385 mg_infos(levu )%levdim(i)) then
00386 ijk (i, n, levu-1) = min (newijk(i,n)*2, &
00387 mg_infos(levu-1)%levdim(i))
00388 else
00389 ijk (i, n, levu-1) = newijk (i,n)
00390 endif
00391 enddo
00392
00393 else
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 ind (:) = newijk (:, n) + ijk0 (1:ndim_2d)
00404
00405 do nt = 1, ntet
00406 xyzref (nt, 1) = corners1 (ind(1), ind(2), nt)
00407 xyzref (nt, 2) = corners2 (ind(1), ind(2), nt)
00408
00409 xyzpnt (nt, 1) = xyz (1, n) - xyzref (nt, 1)
00410 xyzpnt (nt, 2) = xyz (2, n) - xyzref (nt, 2)
00411
00412 do m = 1, 2
00413 xyzedg (nt, 1, m) = corners1 (ind(1), ind(2), &
00414 ijkedg(m, nt)) &
00415 - xyzref (nt, 1)
00416
00417 xyzedg (nt, 2, m) = corners2 (ind(1), ind(2), &
00418 ijkedg(m, nt)) &
00419 - xyzref (nt, 2)
00420 end do
00421 end do
00422
00423
00424
00425
00426
00427 det(:) = xyzedg(:, 1,1)*xyzedg(:, 2,2) &
00428 - xyzedg(:, 1,2)*xyzedg(:, 2,1)
00429
00430 #define ALLOW_DEGRADED_CELL
00431 #ifdef ALLOW_DEGRADED_CELL
00432
00433
00434
00435 do nt = 1, ntet
00436 dnorm = abs(xyzedg(nt,1,1)) + abs(xyzedg(nt,2,1)) + &
00437 abs(xyzedg(nt,1,2)) + abs(xyzedg(nt,2,2))
00438
00439 if (abs(det(nt)) < eps*dnorm*dnorm .or. dnorm == dzero) then
00440 det (nt) = sign (rmxeps, det(nt))
00441 else
00442 det (nt) = 1.0 / det (nt)
00443 endif
00444 end do
00445
00446 #else
00447
00448 loop_n: do nt = 1, ntet
00449 dnorm = abs(xyzedg(nt,1,1)) + abs(xyzedg(nt,2,1)) + &
00450 abs(xyzedg(nt,1,2)) + abs(xyzedg(nt,2,2))
00451
00452 if (abs(det(i, nt)) < eps*dnorm*dnorm .or. &
00453 dnorm(i,nt) == dzero) then
00454 det (i, nt) = dnorm * 1e-25
00455
00456
00457
00458 endif
00459 end do
00460
00461 #ifdef PRINT_DEGRADED_CELL
00462 if (nt < ntet) then
00463
00464
00465
00466 print 9960, trim(ch_id), grid_id, newijk(:, n), &
00467 (corners1(ind(1), ind(2), nt), &
00468 corners2(ind(1), ind(2), nt), nt = 1, nbr_corners)
00469
00470 do nt = 1, ntet
00471 if (abs(det(nt)) < eps) then
00472 print 9950, nt, det (nt), dnorm, &
00473 xyzedg (nt,1, 1), xyzedg (nt,1, 2), &
00474 xyzedg (nt,2, 1), xyzedg (nt,2, 2)
00475 endif
00476 end do
00477
00478 nicht gefunden fnd (i) = .false. versucht, durch
00479 ganz kleine Determinante zu loesen
00480 endif
00481 #endif /* PRINT_DEGRADED_CELL */
00482
00483 det (:) = 1.0 / det (:)
00484
00485 #endif /* ALLOW_DEGRADED_CELL */
00486
00487
00488
00489 do nt = 1, ntet
00490 d1 = (xyzpnt(nt,1)*xyzedg(nt,2,2)- &
00491 xyzpnt(nt,2)*xyzedg(nt,1,2)) * det (nt)
00492 d2 = (xyzpnt(nt,2)*xyzedg(nt,1,1)- &
00493 xyzpnt(nt,1)*xyzedg(nt,2,1)) * det (nt)
00494
00495 if (min(d1, d2) >= -tol .and. &
00496 max(d1,dzero) + max(d2,dzero) <= tol1) exit
00497 end do
00498
00499 if (nt > ntet) then
00500
00501
00502
00503 nold (n, levu) = found (n)
00504
00505 go to 2000
00506 endif
00507 endif
00508 end do
00509
00510 end do loop_n
00511
00512
00513
00514 #ifdef VERBOSE
00515 print 9980, trim(ch_id)
00516
00517 call psmile_flushstd
00518 #endif /* VERBOSE */
00519
00520 return
00521
00522
00523
00524
00525 9990 format (1x, a, ': psmile_mg_final_prev_2d_real: nc', i5)
00526 9980 format (1x, a, ': psmile_mg_final_prev_2d_real: eof')
00527
00528 #ifdef PRINT_DEGRADED_CELL
00529 9960 format (1x, a, ': psmile_MG_final_prev_2d_real: grid id =', i5, &
00530 /1x, ' Grid cell (', i4, ',', i4, &
00531 ') is degraded! Cell coordinates are:', 1p, &
00532 4 (/1x, '(', 1 (e17.9, ','), e17.9, ')'))
00533 9950 format (1x, i1, '-th spawn; det =', 1p, e17.9, ' (', e17.9, &
00534 ') of', 2 (/1x, 2e17.9, ','))
00535 #endif
00536
00537 end subroutine psmile_mg_final_prev_2d_real