00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011       subroutine psmile_mg_method_3d_real (                &
00012                            comp_info, nlev,                &
00013                            found, loc, range,              &
00014                            coords1, coords2, coords3,      &
00015                            shape, control,                 &
00016                            method_id,                      &
00017                            x_coords, y_coords, z_coords,   &
00018                            coords_shape,                   &
00019                            grid_valid_shape, cyclic,       &
00020                            chmin1, chmin2, chmin3,         &
00021                            chmax1, chmax2, chmax3,         &
00022                            midp1,  midp2,  midp3,          &
00023                            tol, ierror)
00024 
00025 
00026 
00027       use PRISM_constants
00028 
00029       use PSMILe, dummy_interface => PSMILe_mg_method_3d_real
00030 
00031       implicit none
00032 
00033 
00034 
00035       Type (Enddef_comp), Intent (In) :: comp_info
00036 
00037 
00038 
00039 
00040       Integer,          Intent (In)   :: nlev
00041 
00042 
00043 
00044       Integer,          Intent (In)   :: range (2, ndim_3d)
00045 
00046 
00047 
00048       Integer,          Intent (In)   :: shape (2, ndim_3d)
00049 
00050 
00051 
00052 
00053       Integer,          Intent (InOut) :: found (range(1,1):range(2,1), 
00054                                                  range(1,2):range(2,2), 
00055                                                  range(1,3):range(2,3))
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069       Integer,          Intent (InOut) :: loc   (ndim_3d,               
00070                                                  range(1,1):range(2,1), 
00071                                                  range(1,2):range(2,2), 
00072                                                  range(1,3):range(2,3))
00073 
00074 
00075 
00076 
00077       Real, Intent (In)               :: coords1 (shape(1,1):shape(2,1), 
00078                                                   shape(1,2):shape(2,2), 
00079                                                   shape(1,3):shape(2,3))
00080       Real, Intent (In)               :: coords2 (shape(1,1):shape(2,1), 
00081                                                   shape(1,2):shape(2,2), 
00082                                                   shape(1,3):shape(2,3))
00083       Real, Intent (In)               :: coords3 (shape(1,1):shape(2,1), 
00084                                                   shape(1,2):shape(2,2), 
00085                                                   shape(1,3):shape(2,3))
00086 
00087 
00088 
00089       Integer,          Intent (In)   :: control (2, ndim_3d)
00090 
00091 
00092 
00093 
00094       Integer,          Intent (In)   :: method_id
00095 
00096 
00097 
00098       Integer,          Intent (In)   :: coords_shape (2, ndim_3d)
00099 
00100 
00101 
00102       Real, Intent (In)               :: x_coords(coords_shape(1,1): 
00103                                                   coords_shape(2,1), 
00104                                                   coords_shape(1,2): 
00105                                                   coords_shape(2,2), 
00106                                                   coords_shape(1,3): 
00107                                                   coords_shape(2,3))
00108       Real, Intent (In)               :: y_coords(coords_shape(1,1): 
00109                                                   coords_shape(2,1), 
00110                                                   coords_shape(1,2): 
00111                                                   coords_shape(2,2), 
00112                                                   coords_shape(1,3): 
00113                                                   coords_shape(2,3))
00114       Real, Intent (In)               :: z_coords(coords_shape(1,1): 
00115                                                   coords_shape(2,1), 
00116                                                   coords_shape(1,2): 
00117                                                   coords_shape(2,2), 
00118                                                   coords_shape(1,3): 
00119                                                   coords_shape(2,3))
00120 
00121 
00122 
00123       Integer,          Intent (In)   :: grid_valid_shape (2, ndim_3d)
00124 
00125 
00126 
00127 
00128 
00129       Logical,          Intent (In)   :: cyclic (ndim_3d)
00130 
00131 
00132 
00133       Real, Intent (In)               :: chmin1 (grid_valid_shape(1,1)-1: 
00134                                                  grid_valid_shape(2,1),   
00135                                                  grid_valid_shape(1,2)-1: 
00136                                                  grid_valid_shape(2,2),   
00137                                                  grid_valid_shape(1,3)-1: 
00138                                                  grid_valid_shape(2,3))
00139       Real, Intent (In)               :: chmin2 (grid_valid_shape(1,1)-1: 
00140                                                  grid_valid_shape(2,1),   
00141                                                  grid_valid_shape(1,2)-1: 
00142                                                  grid_valid_shape(2,2),   
00143                                                  grid_valid_shape(1,3)-1: 
00144                                                  grid_valid_shape(2,3))
00145       Real, Intent (In)               :: chmin3 (grid_valid_shape(1,1)-1: 
00146                                                  grid_valid_shape(2,1),   
00147                                                  grid_valid_shape(1,2)-1: 
00148                                                  grid_valid_shape(2,2),   
00149                                                  grid_valid_shape(1,3)-1: 
00150                                                  grid_valid_shape(2,3))
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175       Real, Intent (In)               :: chmax1 (grid_valid_shape(1,1)-1: 
00176                                                  grid_valid_shape(2,1),   
00177                                                  grid_valid_shape(1,2)-1: 
00178                                                  grid_valid_shape(2,2),   
00179                                                  grid_valid_shape(1,3)-1: 
00180                                                  grid_valid_shape(2,3))
00181       Real, Intent (In)               :: chmax2 (grid_valid_shape(1,1)-1: 
00182                                                  grid_valid_shape(2,1),   
00183                                                  grid_valid_shape(1,2)-1: 
00184                                                  grid_valid_shape(2,2),   
00185                                                  grid_valid_shape(1,3)-1: 
00186                                                  grid_valid_shape(2,3))
00187       Real, Intent (In)               :: chmax3 (grid_valid_shape(1,1)-1: 
00188                                                  grid_valid_shape(2,1),   
00189                                                  grid_valid_shape(1,2)-1: 
00190                                                  grid_valid_shape(2,2),   
00191                                                  grid_valid_shape(1,3)-1: 
00192                                                  grid_valid_shape(2,3))
00193 
00194 
00195 
00196 
00197       Real, Intent (In)               :: midp1  (grid_valid_shape(1,1)-1: 
00198                                                  grid_valid_shape(2,1),   
00199                                                  grid_valid_shape(1,2)-1: 
00200                                                  grid_valid_shape(2,2),   
00201                                                  grid_valid_shape(1,3)-1: 
00202                                                  grid_valid_shape(2,3))
00203       Real, Intent (In)               :: midp2  (grid_valid_shape(1,1)-1: 
00204                                                  grid_valid_shape(2,1),   
00205                                                  grid_valid_shape(1,2)-1: 
00206                                                  grid_valid_shape(2,2),   
00207                                                  grid_valid_shape(1,3)-1: 
00208                                                  grid_valid_shape(2,3))
00209       Real, Intent (In)               :: midp3  (grid_valid_shape(1,1)-1: 
00210                                                  grid_valid_shape(2,1),   
00211                                                  grid_valid_shape(1,2)-1: 
00212                                                  grid_valid_shape(2,2),   
00213                                                  grid_valid_shape(1,3)-1: 
00214                                                  grid_valid_shape(2,3))
00215 
00216 
00217 
00218       Real, Intent (In)               :: tol
00219 
00220 
00221 
00222 
00223 
00224 
00225       Integer,          Intent (Out)  :: ierror
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 #define USE6T
00244 #ifdef USE6T
00245       Integer, Parameter              :: ntet = 6
00246 #else
00247       Integer, Parameter              :: ntet = 4
00248 #endif
00249       Real, Parameter                 :: eps = 1.0d-9
00250       Real, Parameter                 :: rmxeps = 1.0d30
00251       Real, Parameter                 :: dzero = 0.0
00252 
00253       Integer, Parameter              :: nrefd = 3 * 3 * 3
00254 
00255       Integer, Parameter              :: val_direct  =  1
00256       Integer, Parameter              :: val_coupler = -1
00257 
00258 
00259 
00260       Integer, Parameter              :: lev = 1
00261 
00262 
00263 
00264 
00265 
00266       Real                            :: tol1, tol2
00267 
00268 
00269 
00270       Integer                         :: i, j, k
00271       Integer                         :: ibegl, iendl, jpart, n
00272       Integer                         :: ic (ndim_3d)
00273 
00274 
00275 
00276       Integer                         :: l, m
00277       Integer                         :: ijkctl (ndim_3d, nrefd)
00278       Integer                         :: ijkdst (ndim_3d, nrefd)
00279       Real                            :: dist (nrefd)
00280       Integer                         :: irange (2, ndim_3d)
00281 
00282       Integer                         :: ii, jj, kk, nref
00283       Integer                         :: nmin (1)
00284 
00285 
00286 
00287       Integer                         :: ijkref (ndim_3d, ntet)
00288       Integer                         :: ijkedg (ndim_3d, 3, ntet)
00289 
00290       Real                            :: real_huge
00291       Real                            :: xyzpnt (ndim_3d, ntet), 
00292                                          xyzref (ndim_3d, ntet)
00293       Real                            :: xyzedg (ndim_3d, 3, ntet)
00294       Real                            :: d1 (ntet), d2 (ntet), d3 (ntet)
00295       Real                            :: dnorm (ntet), det (ntet)
00296 
00297 #ifdef DEBUG
00298 
00299 
00300       Integer                         :: nfnd (0:2)
00301 #endif /* DEBUG */
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321    Character(len=len_cvs_string), save :: mycvs = 
00322        '$Id: psmile_mg_method_3d_real.F90 2325 2010-04-21 15:00:07Z valcke $'
00323 
00324 
00325 
00326 
00327 
00328 
00329       data ((ijkctl (i, n), i=1,ndim_3d), n = 1,nrefd) &
00330                             / -1,-1,-1,   0,-1,-1,   1,-1,-1, &
00331                               -1, 0,-1,   0, 0,-1,   1, 0,-1, &
00332                               -1, 1,-1,   0, 1,-1,   1, 1,-1, &
00333                               -1,-1, 0,   0,-1, 0,   1,-1, 0, &
00334                               -1, 0, 0,   0, 0, 0,   1, 0, 0, &
00335                               -1, 1, 0,   0, 1, 0,   1, 1, 0, &
00336                               -1,-1, 1,   0,-1, 1,   1,-1, 1, &
00337                               -1, 0, 1,   0, 0, 1,   1, 0, 1, &
00338                               -1, 1, 1,   0, 1, 1,   1, 1, 1/
00339 
00340 
00341 
00342 #ifdef USE6T
00343 
00344 
00345       data ((ijkref (i, n), i = 1, ndim_3d), n = 1, ntet) &
00346            / 0, 0, 1,   0, 0, 1,   1, 0, 1,   0, 1, 1,    &
00347              0, 1, 1,   1, 1, 1 /
00348 
00349       data (((ijkedg (i,j, n), i = 1, ndim_3d), j = 1, 3), n = 1, ntet) &
00350            / 0, 0, 0,   1, 0, 0,   0, 1, 0,                             &
00351              1, 0, 0,   0, 1, 0,   1, 1, 0,                             &
00352              1, 0, 0,   1, 1, 0,   0, 0, 1,                             &
00353              0, 1, 0,   1, 1, 0,   0, 0, 1,                             &
00354              1, 1, 0,   0, 0, 1,   1, 0, 1,                             &
00355              1, 1, 0,   1, 0, 1,   0, 1, 1 /
00356 #else
00357 
00358 
00359       data  ((ijkref (i,n), i = 1, ndim_3d), n = 1, ntet)               &
00360            / 0, 0, 0,   1, 1, 0,   0, 1, 1,   1, 0, 1/
00361 
00362       data (((ijkedg (i,j,n), i = 1, ndim_3d), j = 1, 3), n = 1, ntet)  &
00363            / 1, 0, 0,   0, 1, 0,   0, 0, 1,                             &
00364              0, 1, 0,   1, 0, 0,   1, 1, 1,                             &
00365              1, 1, 1,   0, 0, 1,   0, 1, 0,                             &
00366              0, 0, 1,   1, 1, 1,   1, 0, 0 /
00367 #endif /* USE6T */
00368 
00369 
00370 
00371 
00372 
00373       ierror = 0
00374 
00375 #ifdef VERBOSE
00376       print 9990, trim(ch_id), lev, control
00377 
00378       call psmile_flushstd
00379 #endif /* VERBOSE */
00380 
00381 #ifdef PRISM_ASSERTION
00382       if (tol < 0.0) then
00383          call psmile_assert (__FILE__, __LINE__, &
00384                              "tol must be >= 0.0")
00385       endif
00386 #endif
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396       tol1 = tol + 1.0
00397       tol2 = tol * tol
00398 
00399       real_huge = huge (dist(1))
00400 
00401 #ifdef DEBUG
00402       nfnd (:) = 0
00403 #endif /* DEBUG */
00404 
00405 
00406 
00407          do k = control(1,3), control(2,3)
00408             do j = control(1,2), control (2,2)
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417             ibegl = control (1, 1)
00418 
00419 
00420 
00421             do while (ibegl <= control(2,1))
00422 
00423 
00424                do i = ibegl, control(2,1)
00425                if (found(i, j, k) == lev) exit
00426                end do
00427             if (i > control(2,1)) exit
00428             ibegl = i
00429 
00430 
00431                do i = ibegl, control(2,1)
00432                if (found(i, j, k) /= lev) exit
00433                end do
00434 
00435             iendl = i - 1
00436 
00437 
00438 
00439 #ifdef PRISM_ASSERTION
00440                do i = ibegl, iendl
00441                if (loc(1, i,j,k) < coords_shape(1,1) .or. &
00442                    loc(1, i,j,k) > coords_shape(2,1) .or. &
00443                    loc(2, i,j,k) < coords_shape(1,2) .or. &
00444                    loc(2, i,j,k) > coords_shape(2,2) .or. &
00445                    loc(3, i,j,k) < coords_shape(1,3) .or. &
00446                    loc(3, i,j,k) > coords_shape(2,3)) exit
00447                end do
00448 
00449             if (i <= iendl) then
00450                print *, 'ic', loc (:, i,j,k)
00451                print *, 'coords_shape', coords_shape
00452                call psmile_assert (__FILE__, __LINE__, &
00453                                    'wrong index')
00454             endif
00455 #endif
00456 
00457             do jpart = 0, (iendl-ibegl)/5000
00458 
00459 loop_i:     do i = ibegl+jpart*5000, min (iendl, ibegl+(jpart+1)*5000-1)
00460 
00461             ic(:) = loc (:, i, j, k)
00462 
00463             irange (1, :) = max (ic(:)-1, grid_valid_shape (1, :))
00464             irange (2, :) = min (ic(:)+1, grid_valid_shape (2, :))
00465 
00466             nref = (irange (2,1) - irange (1,1) + 1) * &
00467                    (irange (2,2) - irange (1,2) + 1) * &
00468                    (irange (2,3) - irange (1,3) + 1)
00469 
00470 #ifdef PRISM_ASSERTION
00471             if (nref <= 0) then
00472                call psmile_assert (__FILE__, __LINE__, &
00473                                    'nref <= 0')
00474             endif
00475 #endif
00476 
00477             if (nref == nrefd) then
00478                   do n = 1, nrefd
00479                   ijkdst (:, n) = ic (:) + ijkctl (:, n)
00480                   end do
00481             else
00482                 n = 0
00483                 do kk = irange (1, 3), irange (2, 3)
00484                    do jj = irange (1, 2), irange (2, 2)
00485                       do ii = irange (1, 1), irange (2, 1)
00486                       n = n + 1
00487                       ijkdst (1, n) = ii
00488                       ijkdst (2, n) = jj
00489                       ijkdst (3, n) = kk
00490                       end do 
00491                    end do 
00492                 end do 
00493             endif
00494 
00495 
00496 
00497                do n = 1, nref
00498                dist (n) = (x_coords (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00499                              coords1(i,j,k)) ** 2 + &
00500                           (y_coords (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00501                              coords2(i,j,k)) ** 2 + &
00502                           (z_coords (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00503                              coords3(i,j,k)) ** 2
00504                end do
00505 
00506 
00507 
00508             nmin = MINLOC (dist(1:nref))
00509 #ifdef MINLOCFIX
00510             if (nmin(1).eq.0) nmin=1
00511 #endif /* MINLOCFIX */
00512 
00513             if (dist(nmin(1)) < tol2) then
00514 
00515 
00516 
00517 
00518                loc (:, i,j,k) = ijkdst (:, nmin(1))
00519 
00520 #ifdef DEBUG
00521                nfnd (1) = nfnd (1) + 1
00522 #endif /* DEBUG */
00523 
00524                cycle loop_i
00525             endif 
00526 
00527             found (i,j,k) = val_coupler
00528 
00529 
00530 
00531             if (ic(1) == grid_valid_shape(1,1) .or. &
00532                 ic(2) == grid_valid_shape(1,2) .or. &
00533                 ic(3) == grid_valid_shape(1,3)) then
00534                irange (1, :) = max (ic(:)-1, grid_valid_shape(1,:)-1)
00535                irange (2, :) = min (ic(:)+1, grid_valid_shape(2,:))
00536 
00537                nref = (irange (2,1) - irange (1,1) + 1) * &
00538                       (irange (2,2) - irange (1,2) + 1) * &
00539                       (irange (2,3) - irange (1,3) + 1)
00540 
00541 #ifdef PRISM_ASSERTION
00542                if (nref <= 0) then
00543                   call psmile_assert (__FILE__, __LINE__, &
00544                                       'nref <= 0')
00545                endif
00546 #endif
00547 
00548                if (nref == nrefd) then
00549                      do n = 1, nrefd
00550                      ijkdst (:, n) = ic (:) + ijkctl (:, n)
00551                      end do
00552                else
00553                    n = 0
00554                    do kk = irange (1, 3), irange (2, 3)
00555                       do jj = irange (1, 2), irange (2, 2)
00556                          do ii = irange (1, 1), irange (2, 1)
00557                          n = n + 1
00558                          ijkdst (1, n) = ii
00559                          ijkdst (2, n) = jj
00560                          ijkdst (3, n) = kk
00561                          end do 
00562                       end do 
00563                    end do 
00564                endif
00565             endif
00566 
00567 
00568 
00569 
00570               do n = 1, nref
00571               if (coords1(i,j,k) >= chmin1(ijkdst(1,n),         &
00572                                            ijkdst(2,n),         &
00573                                            ijkdst(3,n)) .and.   &
00574                   coords2(i,j,k) >= chmin2(ijkdst(1,n),         &
00575                                            ijkdst(2,n),         &
00576                                            ijkdst(3,n)) .and.   &
00577                   coords3(i,j,k) >= chmin3(ijkdst(1,n),         &
00578                                            ijkdst(2,n),         &
00579                                            ijkdst(3,n)) .and.   &
00580                   coords1(i,j,k) <= chmax1(ijkdst(1,n),         &
00581                                            ijkdst(2,n),         &
00582                                            ijkdst(3,n)) .and.   &
00583                   coords2(i,j,k) <= chmax2(ijkdst(1,n),         &
00584                                            ijkdst(2,n),         &
00585                                            ijkdst(3,n)) .and.   &
00586                   coords3(i,j,k) <= chmax3(ijkdst(1,n),         &
00587                                            ijkdst(2,n),         &
00588                                            ijkdst(3,n))) then
00589 
00590                   dist (n) = (midp1 (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00591                                 coords1(i,j,k)) ** 2 + &
00592                              (midp2 (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00593                                 coords2(i,j,k)) ** 2 + &
00594                              (midp3 (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00595                                 coords3(i,j,k)) ** 2
00596                else
00597                   dist (n) = real_huge
00598                endif
00599                end do
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610             nmin = MINLOC (dist(1:nref))
00611 #ifdef MINLOCFIX
00612             if (nmin(1).eq.0) nmin=1
00613 #endif /* MINLOCFIX */
00614 
00615                   do while (dist(nmin(1)) < real_huge) 
00616                   ic = ijkdst (:, nmin(1))
00617 
00618                   if (ic(1) >= grid_valid_shape(1,1) .and. &
00619                       ic(1) <  grid_valid_shape(2,1) .and. &
00620                       ic(2) >= grid_valid_shape(1,2) .and. &
00621                       ic(2) <  grid_valid_shape(2,2) .and. &
00622                       ic(3) >= grid_valid_shape(1,3) .and. &
00623                       ic(3) <  grid_valid_shape(2,3)) then
00624 
00625 
00626 
00627 
00628                      do n = 1, ntet
00629                      xyzref (1, n) = x_coords (ic(1)+ijkref(1, n), &
00630                                                ic(2)+ijkref(2, n), &
00631                                                ic(3)+ijkref(3, n))
00632                      xyzref (2, n) = y_coords (ic(1)+ijkref(1, n), &
00633                                                ic(2)+ijkref(2, n), &
00634                                                ic(3)+ijkref(3, n))
00635                      xyzref (3, n) = z_coords (ic(1)+ijkref(1, n), &
00636                                                ic(2)+ijkref(2, n), &
00637                                                ic(3)+ijkref(3, n))
00638                      end do
00639 
00640                   xyzpnt (1, :) = coords1 (i, j, k) - xyzref (1, :)
00641                   xyzpnt (2, :) = coords2 (i, j, k) - xyzref (2, :)
00642                   xyzpnt (3, :) = coords3 (i, j, k) - xyzref (3, :)
00643 
00644 
00645 
00646                      do n = 1, ntet
00647                         do m = 1, 3
00648                         xyzedg (1, m, n) = x_coords (ic(1)+ijkedg(1, m, n),   &
00649                                                      ic(2)+ijkedg(2, m, n),   &
00650                                                      ic(3)+ijkedg(3, m, n)) - &
00651                                            xyzref (1, n)
00652                         xyzedg (2, m, n) = y_coords (ic(1)+ijkedg(1, m, n),   &
00653                                                      ic(2)+ijkedg(2, m, n),   &
00654                                                      ic(3)+ijkedg(3, m, n)) - &
00655                                            xyzref (2, n)
00656                         xyzedg (3, m, n) = z_coords (ic(1)+ijkedg(1, m, n),   &
00657                                                      ic(2)+ijkedg(2, m, n),   &
00658                                                      ic(3)+ijkedg(3, m, n)) - &
00659                                            xyzref (3, n)
00660                         end do
00661                      end do
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675                   det(:) = xyzedg(1,1,:)*(xyzedg(2,2,:)*xyzedg(3,3,:) - &
00676                                           xyzedg(3,2,:)*xyzedg(2,3,:))  &
00677                          + xyzedg(1,2,:)*(xyzedg(2,3,:)*xyzedg(3,1,:) - &
00678                                           xyzedg(3,3,:)*xyzedg(2,1,:))  &
00679                          + xyzedg(1,3,:)*(xyzedg(2,1,:)*xyzedg(3,2,:) - &
00680                                           xyzedg(3,1,:)*xyzedg(2,2,:))
00681 
00682                      do n = 1, ntet
00683                      dnorm (n) = dzero
00684                         do m = 1, 3
00685 
00686                            do l = 1, ndim_3d
00687                            dnorm (n) = dnorm(n) + abs(xyzedg(l,m,n))
00688                            end do
00689                         end do
00690                      end do
00691 
00692 #define ALLOW_DEGRADED_CELL
00693 #ifdef ALLOW_DEGRADED_CELL
00694 
00695 
00696 
00697                      do n = 1, ntet
00698                      if (abs(det(n)) <= eps*dnorm(n)*dnorm(n)*dnorm(n) &
00699                          .or. dnorm(n) == dzero) then
00700                         det (n) = sign (rmxeps, det(n))
00701                      else
00702                         det (n) = 1.0 / det (n)
00703                      endif
00704                      end do
00705 #else 
00706 
00707                      do n = 1, ntet
00708                      if (abs(det(n)) <= eps*dnorm(n)*dnorm(n)*dnorm(n) &
00709                          .or. dnorm(n) == dzero) go to 170
00710                      end do
00711 
00712                   det (:) = 1.0/det (:)
00713 
00714 #endif /* ALLOW_DEGRADED_CELL */
00715 
00716                   d1(:) = (xyzpnt(1,  :)*(xyzedg(2,2,:)*xyzedg(3,3,:) -  &
00717                                           xyzedg(3,2,:)*xyzedg(2,3,:))   &
00718                          + xyzedg(1,2,:)*(xyzedg(2,3,:)*xyzpnt(3,  :) -  &
00719                                           xyzedg(3,3,:)*xyzpnt(2,  :))   &
00720                          + xyzedg(1,3,:)*(xyzpnt(2,  :)*xyzedg(3,2,:) -  &
00721                                           xyzpnt(3,  :)*xyzedg(2,2,:)))  &
00722                         * det (:)
00723 
00724                   d2(:) = (xyzedg(1,1,:)*(xyzpnt(2  ,:)*xyzedg(3,3,:) -  &
00725                                           xyzpnt(3,  :)*xyzedg(2,3,:))   &
00726                          + xyzpnt(1,  :)*(xyzedg(2,3,:)*xyzedg(3,1,:) -  &
00727                                           xyzedg(3,3,:)*xyzedg(2,1,:))   &
00728                          + xyzedg(1,3,:)*(xyzedg(2,1,:)*xyzpnt(3,  :) -  &
00729                                           xyzedg(3,1,:)*xyzpnt(2,  :)))  &
00730                         * det (:)
00731 
00732                   d3(:) = (xyzedg(1,1,:)*(xyzedg(2,2,:)*xyzpnt(3,  :) -  &
00733                                           xyzedg(3,2,:)*xyzpnt(2,  :))   &
00734                          + xyzedg(1,2,:)*(xyzpnt(2,  :)*xyzedg(3,1,:) -  &
00735                                           xyzpnt(3,  :)*xyzedg(2,1,:))   &
00736                          + xyzpnt(1,  :)*(xyzedg(2,1,:)*xyzedg(3,2,:) -  &
00737                                           xyzedg(3,1,:)*xyzedg(2,2,:)))  &
00738                         * det (:)
00739 
00740 #ifdef USE6T
00741 
00742                      do n = 1, ntet 
00743                      if (min(d1(n), d2(n), d3(n)) >= -tol .and. &
00744                          max(d1(n),dzero) +                     &
00745                          max(d2(n),dzero) +                     &
00746                          max(d3(n),dzero) <=  tol1) go to 160
00747                      end do
00748 
00749                   go to 190
00750 #else
00751                      do n = 1, ntet
00752                      if (min(d1(n), d2(n), d3(n)) < -tol .or. &
00753                          max(d1(n), d2(n), d3(n)) >  tol1) go to 190
00754                      end do
00755                   go to 160
00756 #endif
00757                   endif
00758 
00759 
00760 
00761 160               continue
00762 #ifdef DEBUG
00763                   nfnd (2) = nfnd (2) + 1
00764 #endif /* DEBUG */
00765 
00766                   loc (:, i, j, k) = ic
00767 
00768                   cycle loop_i
00769 
00770 
00771 
00772 #ifndef ALLOW_DEGRADED_CELL
00773 170               print 9960, trim(ch_id), method_id, ic, &
00774                      x_coords(ic(1),   ic(2),   ic(3)),  &
00775                      y_coords(ic(1),   ic(2),   ic(3)),  &
00776                      z_coords(ic(1),   ic(2),   ic(3)),  &
00777                      x_coords(ic(1)+1, ic(2),   ic(3)),  &
00778                      y_coords(ic(1)+1, ic(2),   ic(3)),  &
00779                      z_coords(ic(1)+1, ic(2),   ic(3)),  &
00780                      x_coords(ic(1),   ic(2)+1, ic(3)),  &
00781                      y_coords(ic(1),   ic(2)+1, ic(3)),  &
00782                      z_coords(ic(1),   ic(2)+1, ic(3)),  &
00783                      x_coords(ic(1)+1, ic(2)+1, ic(3)),  &
00784                      y_coords(ic(1)+1, ic(2)+1, ic(3)),  &
00785                      z_coords(ic(1)+1, ic(2)+1, ic(3)),  &
00786                      x_coords(ic(1),   ic(2),   ic(3)+1), &
00787                      y_coords(ic(1),   ic(2),   ic(3)+1), &
00788                      z_coords(ic(1),   ic(2),   ic(3)+1), &
00789                      x_coords(ic(1)+1, ic(2),   ic(3)+1), &
00790                      y_coords(ic(1)+1, ic(2),   ic(3)+1), &
00791                      z_coords(ic(1)+1, ic(2),   ic(3)+1), &
00792                      x_coords(ic(1),   ic(2)+1, ic(3)+1), &
00793                      y_coords(ic(1),   ic(2)+1, ic(3)+1), &
00794                      z_coords(ic(1),   ic(2)+1, ic(3)+1), &
00795                      x_coords(ic(1)+1, ic(2)+1, ic(3)+1), &
00796                      y_coords(ic(1)+1, ic(2)+1, ic(3)+1), &
00797                      z_coords(ic(1)+1, ic(2)+1, ic(3)+1)
00798 
00799                      do n = 1, ntet
00800                      if (abs(det(n)) < eps) then
00801                         print 9950, n, det (n), dnorm(n), &
00802                           xyzedg (1, 1, n),                   &
00803                           xyzedg (1, 2, n), xyzedg (1, 3, n), &
00804                           xyzedg (2, 1, n), xyzedg (2, 2, n), &
00805                           xyzedg (2, 3, n), xyzedg (3, 1, n), &
00806                           xyzedg (3, 2, n), xyzedg (3, 3, n)
00807                      endif
00808 
00809                      end do
00810 #endif /* ALLOW_DEGRADED_CELL */
00811 
00812 
00813 
00814 
00815 190               continue
00816 
00817                   dist(nmin(1)) = real_huge
00818                   nmin = MINLOC (dist(1:nref))
00819 #ifdef MINLOCFIX
00820                   if (nmin(1).eq.0) nmin=1
00821 #endif /* MINLOCFIX */
00822 
00823                end do 
00824 
00825 
00826 
00827 
00828 
00829 
00830               do n = 1, nref
00831               dist (n) = (midp1 (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00832                           coords1(i,j,k)) ** 2 + &
00833                          (midp2 (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00834                           coords2(i,j,k)) ** 2 + &
00835                          (midp3 (ijkdst(1,n), ijkdst (2,n), ijkdst (3,n))-&
00836                           coords3(i,j,k)) ** 2
00837               end do
00838 
00839               nmin = MINLOC (dist(1:nref))
00840 #ifdef MINLOCFIX
00841               if (nmin(1).eq.0) nmin=1
00842 #endif /* MINLOCFIX */
00843               loc (:, i,j,k) = ijkdst (:, nmin(1))
00844 
00845 #ifdef DEBUG
00846                nfnd (0) = nfnd (0) + 1
00847 
00848 #ifdef DEBUGX
00849                print *, trim(ch_id), ' Not found: -----'
00850                print *, 'i,j,k :', i, j, k
00851                print *, 'coords:', coords1(i,j,k), coords2(i,j,k), coords3(i,j,k)
00852                print *, 'irange:', irange
00853                print *, 'chmin low:', chmin1 (irange(1,1), irange(1,2), irange(1,3)), &
00854                                       chmin2 (irange(1,1), irange(1,2), irange(1,3)), &
00855                                       chmin3 (irange(1,1), irange(1,2), irange(1,3))
00856                print *, 'chmax low:', chmax1 (irange(1,1), irange(1,2), irange(1,3)), &
00857                                       chmax2 (irange(1,1), irange(1,2), irange(1,3)), &
00858                                       chmax3 (irange(1,1), irange(1,2), irange(1,3))
00859                print *, 'chmin hig:', chmin1 (irange(2,1), irange(2,2), irange(2,3)), &
00860                                       chmin2 (irange(2,1), irange(2,2), irange(2,3)), &
00861                                       chmin3 (irange(2,1), irange(2,2), irange(2,3))
00862                print *, 'chmax hig:', chmax1 (irange(2,1), irange(2,2), irange(2,3)), &
00863                                       chmax2 (irange(2,1), irange(2,2), irange(2,3)), &
00864                                       chmax3 (irange(2,1), irange(2,2), irange(2,3))
00865 #endif /* DEBUGX */
00866     
00867 #endif /* DEBUG */
00868 
00869             end do loop_i 
00870             end do 
00871 
00872 
00873 
00874             do l = 1, ndim_3d
00875             if (cyclic(l)) then
00876 
00877 
00878 
00879 
00880 
00881 
00882                   do i = ibegl, iendl
00883                   if (loc (l, i,j,k) < grid_valid_shape (1,l)) then
00884                       loc (l, i,j,k) = grid_valid_shape (2,l)
00885                   endif
00886                   enddo
00887 #ifdef REMOVED
00888             else
00889 
00890 
00891 
00892 
00893 
00894 
00895 
00896                   do i = ibegl, iendl
00897                   loc (l, i,j,k) = max (loc(l, i,j,k), grid_valid_shape (1,l))
00898                   enddo
00899 #endif
00900 
00901             endif
00902             end do 
00903 
00904 
00905 
00906             ibegl = iendl + 2
00907             end do 
00908 
00909             end do 
00910          end do 
00911 
00912 
00913 
00914 #ifdef DEBUG
00915       print 9970, trim(ch_id), lev, nfnd
00916 9970  format (1x, a, ': PSMILe_mg_method_3d_real: lev =', i3, &
00917               ': not :', i5, ', dir: ', i6, ', fnd :', i6, i5)
00918 #endif /* DEBUG */
00919 
00920 #ifdef VERBOSE
00921       print 9980, trim(ch_id), lev
00922 
00923       call psmile_flushstd
00924 #endif /* VERBOSE */
00925 
00926 
00927 
00928 
00929 9990 format (1x, a, ': psmile_mg_method_3d_real: level', i3, &
00930                     ', control', 6i6)
00931 9980 format (1x, a, ': psmile_mg_method_3d_real: eof, level', i3)
00932 9960 format (1x, a, ': psmile_mg_method_3d_real: method id =', i5, &
00933             /1x,  ' Grid cell (', i4, ',', i4, ',', i4,           &
00934                  ') is degraded! Cell coordinates are:', 1p,      &
00935             8 (/1x, '(', 2 (e17.9, ','), e17.9, ')'))
00936 9950 format (1x, i1, '-th spawn; det =', 1p, e17.9, ' (', e17.9, &
00937              ') of', 3 (/1x, 3e17.9, ','))
00938 
00939 
00940       end subroutine psmile_mg_method_3d_real