- Timestamp:
- Aug 30, 2017, 2:54:25 PM (8 years ago)
- Location:
- trunk/tools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/module_definitions.f90
r1609 r1612 13 13 REAL(r_k) :: fillval64 = 1.e20 14 14 CHARACTER(len=50) :: fname 15 CHARACTER(len=256) :: msg 15 16 16 17 END MODULE module_definitions -
trunk/tools/module_generic.f90
r1608 r1612 5 5 ! ErrMsg: Subroutine to stop execution and provide an error message 6 6 ! ErrWarnMsg: Function to print error/warning message 7 ! index_list_coordsI: Function to provide the index of a given coordinate within a list of integer coordinates 7 8 ! Index1DArrayR: Function to provide the first index of a given value inside a 1D real array 8 9 ! Index1DArrayR_K: Function to provide the first index of a given value inside a 1D real(r_k) array … … 17 18 18 19 CONTAINS 20 21 INTEGER FUNCTION index_list_coordsI(Ncoords, coords, icoord) 22 ! Function to provide the index of a given coordinate within a list of integer coordinates 23 24 IMPLICIT NONE 25 26 INTEGER, INTENT(in) :: Ncoords 27 INTEGER, DIMENSION(Ncoords,2), INTENT(in) :: coords 28 INTEGER, DIMENSION(2), INTENT(in) :: icoord 29 30 ! Local 31 INTEGER, DIMENSION(Ncoords) :: dist 32 INTEGER :: i,mindist 33 INTEGER, DIMENSION(1) :: iloc 34 35 !!!!!!! Variables 36 ! Ncoords: number of coordinates in the list 37 ! coords: list of coordinates 38 ! icoord: coordinate to find 39 40 fname = 'index_list_coordsI' 41 42 dist = (coords(:,1)-icoord(1))**2+(coords(:,2)-icoord(2))**2 43 44 IF (ANY(dist == 0)) THEN 45 iloc = MINLOC(dist) 46 index_list_coordsI = iloc(1) 47 ELSE 48 index_list_coordsI = -1 49 END IF 50 51 END FUNCTION index_list_coordsI 19 52 20 53 CHARACTER(len=1000) FUNCTION vectorR_KS(d1, vector) -
trunk/tools/module_scientific.f90
r1609 r1612 3 3 4 4 !!!!!!! Functions & subroutines 5 ! borders_matrixL: Subroutine to provide the borders of a logical array (interested in .TRUE.) 5 6 ! FindMinimumR_K*: Function returns the location of the minimum in the section between Start and End. 7 ! gridpoints_InsidePolygon: Subroutine to determine if a series of grid points are inside a polygon 8 ! following ray casting algorithm 9 ! look_clockwise_borders: Subroutine to look clock-wise for a next point within a collection of borders 10 ! (limits of a region) 11 ! paths_border: Subroutine to search the paths of a border field. 12 ! path_properties: Subroutine to determine the properties of a path 13 ! polygons: Subroutine to search the polygons of a border field. FORTRAN based. 1st = 1! 14 ! polygons_t: Subroutine to search the polygons of a temporal series of boolean fields. FORTRAN based. 1st = 1! 6 15 ! PrintQuantilesR_K: Subroutine to print the quantiles of values REAL(r_k) 7 16 ! quantilesR_K: Subroutine to provide the quantiles of a given set of values of type real 'r_k' … … 17 26 18 27 CONTAINS 28 29 SUBROUTINE polygons_t(dbg, dx, dy, dt, boolmatt, polys, Npoly) 30 ! Subroutine to search the polygons of a temporal series of boolean fields. FORTRAN based. 1st = 1! 31 32 IMPLICIT NONE 33 34 INTEGER, INTENT(in) :: dx, dy, dt 35 LOGICAL, DIMENSION(dx,dy,dt), INTENT(in) :: boolmatt 36 LOGICAL, INTENT(in) :: dbg 37 INTEGER, DIMENSION(dt), INTENT(out) :: Npoly 38 INTEGER, DIMENSION(dx,dy,dt), INTENT(out) :: polys 39 40 ! Local 41 INTEGER :: i,it 42 43 !!!!!!! Variables 44 ! dx,dy: spatial dimensions of the space 45 ! boolmatt: boolean matrix tolook for the polygons (.TRUE. based) 46 ! polys: found polygons 47 ! Npoly: number of polygons found 48 49 fname = 'polygons' 50 51 IF (dbg) PRINT *,TRIM(fname) 52 53 polys = -1 54 55 DO it=1,dt 56 IF (dbg) THEN 57 PRINT *,' it:', it, ' bool _______' 58 DO i=1,dx 59 PRINT *,boolmatt(:,:,it) 60 END DO 61 END IF 62 CALL polygons(dbg, dx, dy, boolmatt(:,:,it), polys(:,:,it), Npoly(it)) 63 END DO 64 65 END SUBROUTINE polygons_t 66 67 SUBROUTINE polygons(dbg, dx, dy, boolmat, polys, Npoly) 68 ! Subroutine to search the polygons of a boolean field. FORTRAN based. 1st = 1! 69 70 IMPLICIT NONE 71 72 INTEGER, INTENT(in) :: dx, dy 73 LOGICAL, DIMENSION(dx,dy), INTENT(in) :: boolmat 74 LOGICAL, INTENT(in) :: dbg 75 INTEGER, INTENT(out) :: Npoly 76 INTEGER, DIMENSION(dx,dy), INTENT(out) :: polys 77 78 ! Local 79 INTEGER :: i, j, ip, ipp, Nppt 80 INTEGER :: ierr 81 INTEGER, DIMENSION(:,:), ALLOCATABLE :: borders 82 LOGICAL, DIMENSION(dx,dy) :: isborder 83 INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: paths 84 INTEGER :: Npath 85 INTEGER, DIMENSION(:), ALLOCATABLE :: Nptpaths 86 INTEGER, DIMENSION(2) :: xtrx, xtry, meanpth 87 INTEGER :: Nvertx 88 INTEGER, DIMENSION(:,:), ALLOCATABLE :: vertxs, points 89 LOGICAL, DIMENSION(:), ALLOCATABLE :: isin 90 91 !!!!!!! Variables 92 ! dx,dy: spatial dimensions of the space 93 ! boolmat: boolean matrix tolook for the polygons (.TRUE. based) 94 ! polys: found polygons 95 ! Npoly: number of polygons found 96 97 fname = 'polygons' 98 99 polys = -1 100 101 Nppt = dx*dy 102 IF (ALLOCATED(borders)) DEALLOCATE(borders) 103 ALLOCATE(borders(Nppt,2), STAT=ierr) 104 msg = "Problems allocating matrix 'borders'" 105 CALL ErrMsg(msg, fname, ierr) 106 107 IF (ALLOCATED(paths)) DEALLOCATE(paths) 108 ALLOCATE(paths(Nppt,Nppt,2), STAT=ierr) 109 msg = "Problems allocating matrix 'paths'" 110 CALL ErrMsg(msg, fname, ierr) 111 112 IF (ALLOCATED(Nptpaths)) DEALLOCATE(Nptpaths) 113 ALLOCATE(Nptpaths(Nppt), STAT=ierr) 114 msg = "Problems allocating matrix 'Nptpaths'" 115 CALL ErrMsg(msg, fname, ierr) 116 117 ! Filling with the points of all the space 118 IF (ALLOCATED(points)) DEALLOCATE(points) 119 ALLOCATE(points(Nppt,2), STAT=ierr) 120 msg = "Problems allocating matrix 'points'" 121 CALL ErrMsg(msg, fname, ierr) 122 123 ip = 1 124 DO i=1, dx 125 DO j=1, dy 126 points(ip,1) = i 127 points(ip,2) = j 128 ip = ip + 1 129 END DO 130 END DO 131 132 CALL borders_matrixL(dx, dy, Nppt, boolmat, borders, isborder) 133 CALL paths_border(dbg, dx, dy, isborder, Nppt, borders, paths, Npath, Nptpaths) 134 135 Npoly = Npath 136 137 DO ip=1, Npath 138 IF (ALLOCATED(vertxs)) DEALLOCATE(vertxs) 139 ALLOCATE(vertxs(Nptpaths(ip),2)) 140 msg = "Problems allocating matrix 'vertxs'" 141 CALL ErrMsg(msg, fname, ierr) 142 143 IF (ALLOCATED(isin)) DEALLOCATE(isin) 144 ALLOCATE(isin(Nppt), STAT=ierr) 145 msg = "Problems allocating matrix 'isin'" 146 CALL ErrMsg(msg, fname, ierr) 147 148 isin = .FALSE. 149 150 IF (dbg) PRINT *, ' path:', ip, ' N pts:', Nptpaths(ip) 151 152 CALL path_properties(dx, dy, boolmat, Nptpaths(ip), paths(ip,1:Nptpaths(ip),:), xtrx, xtry, & 153 meanpth, 'y', Nvertx, vertxs) 154 155 IF (dbg) THEN 156 PRINT *, ' properties _______' 157 PRINT *, ' x-extremes:', xtrx 158 PRINT *, ' y-extremes:', xtry 159 PRINT *, ' center mean:', meanpth 160 PRINT *, ' y-vertexs:', Nvertx,' ________' 161 DO i=1, Nvertx 162 PRINT *,' ',i,':',vertxs(i,:) 163 END DO 164 END IF 165 166 CALL gridpoints_InsidePolygon(dx, dy, boolmat, Nptpaths(ip), paths(ip,1:Nptpaths(ip),:), Nvertx, & 167 xtrx, xtry, vertxs, Nppt, points, isin) 168 169 ! Filling polygons 170 ipp = 1 171 DO i=1, dx 172 DO j=1, dy 173 IF (isin(ipp)) polys(i,j) = ip 174 ipp = ipp + 1 175 END DO 176 END DO 177 178 END DO 179 180 DEALLOCATE (borders) 181 DEALLOCATE (Nptpaths) 182 DEALLOCATE (paths) 183 DEALLOCATE (vertxs) 184 DEALLOCATE (points) 185 DEALLOCATE (isin) 186 187 RETURN 188 189 END SUBROUTINE polygons 190 191 SUBROUTINE path_properties(dx, dy, Lmat, Nptspth, pth, xxtrm, yxtrm, meanctr, axs, Nvrtx, vrtxs) 192 ! Subroutine to determine the properties of a path: 193 ! extremes: minimum and maximum of the path along x,y axes 194 ! meancenter: center from the mean of the coordinates of the paths locations 195 ! vertexs: path point, without neighbours along a given axis 196 197 IMPLICIT NONE 198 199 INTEGER, INTENT(in) :: dx, dy, Nptspth 200 LOGICAL, DIMENSION(dx,dy), INTENT(in) :: Lmat 201 INTEGER, DIMENSION(Nptspth,2), INTENT(in) :: pth 202 CHARACTER, INTENT(in) :: axs 203 INTEGER, DIMENSION(2), INTENT(out) :: meanctr, xxtrm, yxtrm 204 INTEGER, INTENT(out) :: Nvrtx 205 INTEGER, DIMENSION(Nptspth,2), INTENT(out) :: vrtxs 206 207 ! Local 208 INTEGER :: i, ip, jp 209 INTEGER :: neig1, neig2 210 211 !!!!!!! Variables 212 ! dx,dy: size of the space 213 ! Lmat: original matrix of logical values for the path 214 ! Nptspth: number of points of the path 215 ! pth: path coordinates (clockwise) 216 ! axs: axis of finding the vertex 217 ! [x/y]xtrm: minimum and maximum coordinates of the path 218 ! meanctr: center from the mean of the coordinates of the path 219 ! Nvrtx: Number of vertexs of the path 220 ! vrtxs: coordinates of the vertexs 221 222 fname = 'path_properties' 223 224 vrtxs = -1 225 Nvrtx = 0 226 227 xxtrm = (/ MINVAL(pth(:,1)), MAXVAL(pth(:,1)) /) 228 yxtrm = (/ MINVAL(pth(:,2)), MAXVAL(pth(:,2)) /) 229 meanctr = (/ SUM(pth(:,1))/Nptspth, SUM(pth(:,2))/Nptspth /) 230 231 IF (axs == 'x' .OR. axs == 'X') THEN 232 ! Looking vertexs along x-axis 233 DO i=1, Nptspth 234 ip = pth(i,1) 235 jp = pth(i,2) 236 neig1 = 0 237 neig2 = 0 238 ! W-point 239 IF (ip == 1) THEN 240 neig1 = -1 241 ELSE 242 IF (.NOT.Lmat(ip-1,jp)) neig1 = -1 243 END IF 244 ! E-point 245 IF (ip == dx) THEN 246 neig2 = -1 247 ELSE 248 IF (.NOT.Lmat(ip+1,jp)) neig2 = -1 249 END IF 250 251 IF (neig1 == -1 .AND. neig2 == -1) THEN 252 Nvrtx = Nvrtx + 1 253 vrtxs(Nvrtx,:) = (/ip,jp/) 254 END IF 255 END DO 256 ELSE IF (axs == 'y' .OR. axs == 'Y') THEN 257 ! Looking vertexs along x-axis 258 DO i=1, Nptspth 259 ip = pth(i,1) 260 jp = pth(i,2) 261 262 neig1 = 0 263 neig2 = 0 264 ! S-point 265 IF (jp == 1) THEN 266 neig1 = -1 267 ELSE 268 IF (.NOT.Lmat(ip,jp-1)) neig1 = -1 269 END IF 270 ! N-point 271 IF (jp == dy) THEN 272 neig2 = -1 273 ELSE 274 IF (.NOT.Lmat(ip,jp+1)) neig2 = -1 275 END IF 276 277 IF (neig1 == -1 .AND. neig2 == -1) THEN 278 Nvrtx = Nvrtx + 1 279 vrtxs(Nvrtx,:) = (/ ip, jp /) 280 END IF 281 END DO 282 ELSE 283 msg = "Axis '" // axs // "' not available" // CHAR(10) // " Available ones: 'x', 'X', 'y, 'Y'" 284 CALL ErrMsg(msg, fname, -1) 285 END IF 286 287 RETURN 288 289 END SUBROUTINE path_properties 290 291 SUBROUTINE gridpoints_InsidePolygon(dx, dy, isbrdr, Npath, path, Nvrtx, xpathxtrm, ypathxtrm, & 292 vrtxs, Npts, pts, inside) 293 ! Subroutine to determine if a series of grid points are inside a polygon following ray casting algorithm 294 ! FROM: https://en.wikipedia.org/wiki/Point_in_polygon 295 296 IMPLICIT NONE 297 298 INTEGER, INTENT(in) :: dx,dy,Npath,Nvrtx,Npts 299 LOGICAL, DIMENSION(dx,dy), INTENT(in) :: isbrdr 300 INTEGER, DIMENSION(Npath,2), INTENT(in) :: path 301 INTEGER, DIMENSION(2), INTENT(in) :: xpathxtrm, ypathxtrm 302 INTEGER, DIMENSION(Npath,2) :: vrtxs 303 INTEGER, DIMENSION(Npts,2), INTENT(in) :: pts 304 LOGICAL, DIMENSION(Npts), INTENT(out) :: inside 305 306 ! Local 307 INTEGER :: i,j,ip,ix,iy 308 INTEGER :: Nintersecs, isvertex 309 INTEGER :: ierr 310 LOGICAL, DIMENSION(:,:), ALLOCATABLE :: halo_brdr 311 312 !!!!!!! Variables 313 ! dx,dy: space size 314 ! Npath: number of points of the path of the polygon 315 ! path: path of the polygon 316 ! isbrdr: boolean matrix of the space wqith .T. on polygon border 317 ! Nvrtx: number of vertexs of the path 318 ! vrtxs: vertexs of the path along y-axis 319 ! Npts: number of points 320 ! pts: points to look for 321 ! inside: vector wether point is inside or not (coincident to a border is inside) 322 323 fname = 'gridpoints_InsidePolygon' 324 325 ! Creation of a 1-grid point larger matrix to deal with points reaching the limits 326 IF (ALLOCATED(halo_brdr)) DEALLOCATE(halo_brdr) 327 ALLOCATE(halo_brdr(dx+2,dy+2), STAT=ierr) 328 msg = "Problems allocating matrix 'halo_brdr'" 329 CALL ErrMsg(msg, fname, ierr) 330 halo_brdr = .FALSE. 331 332 DO i=1,dx 333 halo_brdr(i+1,2:dy+1) = isbrdr(i,:) 334 END DO 335 336 inside = .FALSE. 337 338 DO ip=1,Npts 339 Nintersecs = 0 340 ix = pts(ip,1) 341 iy = pts(ip,2) 342 ! Point might be outside path range... 343 IF (ix >= xpathxtrm(1) .AND. ix <= xpathxtrm(2) .AND. iy >= ypathxtrm(1) .AND. & 344 iy <= ypathxtrm(2)) THEN 345 346 ! It is a border point? 347 IF (isbrdr(ix,iy)) THEN 348 inside(ip) = .TRUE. 349 CYCLE 350 END IF 351 352 ! Looking along y-axis 353 DO j=1,iy 354 ! Only counting that borders that are not vertexs 355 isvertex = index_list_coordsI(Npath, vrtxs, (/ix,j/)) 356 IF (halo_brdr(ix+1,j+1) .AND. ( isvertex == -1)) Nintersecs = Nintersecs + 1 357 END DO 358 IF (MOD(Nintersecs,2) /= 0) inside(ip) = .TRUE. 359 END IF 360 361 END DO 362 363 RETURN 364 365 END SUBROUTINE gridpoints_InsidePolygon 366 367 SUBROUTINE look_clockwise_borders(dx,dy,Nbrdrs,brdrs,gbrdr,isbrdr,ix,iy,dbg,xf,yf,iff) 368 ! Subroutine to look clock-wise for a next point within a collection of borders (limits of a region) 369 370 IMPLICIT NONE 371 372 INTEGER, INTENT(in) :: dx, dy, Nbrdrs, ix, iy 373 INTEGER, DIMENSION(Nbrdrs,2), INTENT(in) :: brdrs 374 LOGICAL, DIMENSION(Nbrdrs), INTENT(in) :: gbrdr 375 LOGICAL, DIMENSION(dx,dy), INTENT(in) :: isbrdr 376 LOGICAL, INTENT(in) :: dbg 377 INTEGER, INTENT(out) :: xf, yf, iff 378 379 ! Local 380 INTEGER :: isch 381 CHARACTER(len=2), DIMENSION(8) :: Lclock 382 INTEGER, DIMENSION(8,2) :: spt 383 INTEGER :: iif, jjf 384 385 !!!!!!! Variables 386 ! dx, dy: 2D shape ot the space 387 ! Nbrdrs: number of brdrs found in this 2D space 388 ! brdrs: list of coordinates of the borders 389 ! gbrdr: accounts for the use if the given border point 390 ! isbrdr: accounts for the matrix of the point is a border or not 391 ! ix,iy: coordinates of the point to start to find for 392 ! xf,yf: coordinates of the found point 393 ! iff: position of the border found within the list of borders 394 395 fname = 'look_clockwise_borders' 396 397 ! Looking clock-wise assuming that one starts from the westernmost point 398 399 ! Label of the search 400 lclock = (/ 'N ', 'NE', 'E ', 'SE', 'S ', 'SW', 'W ', 'NW' /) 401 ! Transformation to apply 402 !spt = (/ (/0,1/), (/1,1/), (/1,0/), (/1,-1/), (/0,-1/), (/-1,-1/), (/-1,0/), (/-1,1/) /) 403 spt(:,1) = (/ 0, 1, 1, 1, 0, -1, -1, -1 /) 404 spt(:,2) = (/ 1, 1, 0, -1, -1, -1, 0, 1 /) 405 406 xf = -1 407 yf = -1 408 DO isch=1, 8 409 ! clock-wise search 410 IF (spt(isch,1) >= 0) THEN 411 iif = MIN(dx,ix+spt(isch,1)) 412 ELSE 413 iif = MAX(1,ix+spt(isch,1)) 414 END IF 415 IF (spt(isch,2) >= 0) THEN 416 jjf = MIN(dy,iy+spt(isch,2)) 417 ELSE 418 jjf = MAX(1,iy+spt(isch,2)) 419 END IF 420 iff = index_list_coordsI(Nbrdrs, brdrs,(/iif,jjf/)) 421 IF (iff > 0) THEN 422 IF (dbg) PRINT *,' ' // lclock(isch) // '-point:', iif,jjf, ':', iff, 'is',isbrdr(iif,jjf), & 423 'got',gbrdr(iff) 424 IF (isbrdr(iif,jjf) .AND. .NOT.gbrdr(iff)) THEN 425 xf = iif 426 yf = jjf 427 EXIT 428 END IF 429 END IF 430 END DO 431 432 RETURN 433 434 END SUBROUTINE look_clockwise_borders 435 436 SUBROUTINE borders_matrixL(dx,dy,dxy,Lmat,brdrs,isbrdr) 437 ! Subroutine to provide the borders of a logical array (interested in .TRUE.) 438 439 IMPLICIT NONE 440 441 INTEGER, INTENT(in) :: dx,dy,dxy 442 LOGICAL, DIMENSION(dx,dy), INTENT(in) :: Lmat 443 INTEGER, DIMENSION(dxy,2), INTENT(out) :: brdrs 444 LOGICAL, DIMENSION(dx,dy), INTENT(out) :: isbrdr 445 446 ! Local 447 INTEGER :: i,j,ib 448 449 !!!!!!! Variables 450 ! dx,dy: size of the space 451 ! dxy: maximum number of border points 452 ! Lmat: Matrix to look for the borders 453 ! brdrs: list of coordinates of the borders 454 ! isbrdr: matrix with .T./.F. wether the given matrix point is a border or not 455 456 fname = 'borders_matrixL' 457 458 isbrdr = .FALSE. 459 brdrs = -1 460 ib = 1 461 462 ! Starting with the borders. If a given point is TRUE it is a path-vertex 463 ! Along y-axis 464 DO i=1, dx 465 IF (Lmat(i,1) .AND. .NOT.isbrdr(i,1)) THEN 466 brdrs(ib,1) = i 467 brdrs(ib,2) = 1 468 isbrdr(i,1) = .TRUE. 469 ib=ib+1 470 END IF 471 IF (Lmat(i,dy) .AND. .NOT.isbrdr(i,dy)) THEN 472 brdrs(ib,1) = i 473 brdrs(ib,2) = dy 474 isbrdr(i,dy) = .TRUE. 475 ib=ib+1 476 END IF 477 END DO 478 ! Along x-axis 479 DO j=1, dy 480 IF (Lmat(1,j) .AND. .NOT.isbrdr(1,j)) THEN 481 brdrs(ib,1) = 1 482 brdrs(ib,2) = j 483 isbrdr(1,j) = .TRUE. 484 ib=ib+1 485 END IF 486 IF (Lmat(dx,j) .AND. .NOT.isbrdr(dx,j)) THEN 487 brdrs(ib,1) = dx 488 brdrs(ib,2) = j 489 isbrdr(dx,j) = .TRUE. 490 ib=ib+1 491 END IF 492 END DO 493 494 ! Border as that when looking on x-axis points with Lmat(i) /= Lmat(i+1) 495 DO i=1, dx-1 496 DO j=1, dy-1 497 IF ( Lmat(i,j) .NEQV. Lmat(i+1,j) ) THEN 498 IF (Lmat(i,j) .AND. .NOT.isbrdr(i,j)) THEN 499 brdrs(ib,1) = i 500 brdrs(ib,2) = j 501 isbrdr(i,j) = .TRUE. 502 ib=ib+1 503 ELSE IF (Lmat(i+1,j) .AND. .NOT.isbrdr(i+1,j)) THEN 504 brdrs(ib,1) = i+1 505 brdrs(ib,2) = j 506 isbrdr(i+1,j) = .TRUE. 507 ib=ib+1 508 END IF 509 END IF 510 ! y-axis 511 IF ( Lmat(i,j) .NEQV. Lmat(i,j+1) ) THEN 512 IF (Lmat(i,j) .AND. .NOT.isbrdr(i,j)) THEN 513 brdrs(ib,1) = i 514 brdrs(ib,2) = j 515 isbrdr(i,j) = .TRUE. 516 ib=ib+1 517 ELSE IF (Lmat(i,j+1) .AND. .NOT.isbrdr(i,j+1)) THEN 518 brdrs(ib,1) = i 519 brdrs(ib,2) = j+1 520 isbrdr(i,j+1) = .TRUE. 521 ib=ib+1 522 END IF 523 END IF 524 END DO 525 END DO 526 527 RETURN 528 529 END SUBROUTINE borders_matrixL 530 531 SUBROUTINE paths_border(dbg, dx, dy, isborder, Nppt, borders, paths, Npath, Nptpaths) 532 ! Subroutine to search the paths of a border field. 533 534 IMPLICIT NONE 535 536 INTEGER, INTENT(in) :: dx, dy, Nppt 537 LOGICAL, INTENT(in) :: dbg 538 LOGICAL, DIMENSION(dx,dy), INTENT(in) :: isborder 539 INTEGER, DIMENSION(Nppt,2), INTENT(in) :: borders 540 INTEGER, DIMENSION(Nppt,Nppt,2), INTENT(out) :: paths 541 INTEGER, INTENT(out) :: Npath 542 INTEGER, DIMENSION(Nppt), INTENT(out) :: Nptpaths 543 544 ! Local 545 INTEGER :: i,j,k,ib 546 INTEGER :: ierr 547 INTEGER :: Nbrdr 548 LOGICAL, DIMENSION(:), ALLOCATABLE :: gotbrdr, emptygotbrdr 549 INTEGER :: iipth, ipath, ip, Nptspath 550 INTEGER :: iib, jjb, iip, ijp, iif, jjf, iff 551 LOGICAL :: found, finishedstep 552 553 !!!!!!! Variables 554 ! dx,dy: spatial dimensions of the space 555 ! Nppt: possible number of paths and points that the paths can have 556 ! isborder: boolean matrix which provide the borders of the polygon 557 ! borders: coordinates of the borders of the polygon 558 ! paths: coordinates of each found path 559 ! Npath: number of paths found 560 ! Nptpaths: number of points per path 561 562 fname = 'paths_border' 563 564 ! Sarting matrix 565 paths = -1 566 Npath = 0 567 Nptspath = 0 568 Nptpaths = -1 569 570 ib=1 571 finishedstep = .FALSE. 572 573 ! Number of border points 574 DO ib=1, Nppt 575 IF (borders(ib,1) == -1 ) EXIT 576 END DO 577 Nbrdr = ib-1 578 579 IF (dbg) THEN 580 PRINT *,' isborder ______' 581 DO i=1,dx 582 PRINT *,isborder(i,:) 583 END DO 584 585 PRINT *,' borders _______' 586 DO i=1,Nbrdr 587 PRINT *,' ',i,':',borders(i,:) 588 END DO 589 END IF 590 591 ! Matrix which keeps track if a border point has been located 592 IF (ALLOCATED(gotbrdr)) DEALLOCATE(gotbrdr) 593 ALLOCATE(gotbrdr(Nbrdr), STAT=ierr) 594 msg = "Problems allocating matrix 'gotbrdr'" 595 CALL ErrMsg(msg, fname, ierr) 596 IF (ALLOCATED(emptygotbrdr)) DEALLOCATE(emptygotbrdr) 597 ALLOCATE(emptygotbrdr(Nbrdr), STAT=ierr) 598 msg = "Problems allocating matrix 'emptygotbrdr'" 599 CALL ErrMsg(msg, fname, ierr) 600 601 gotbrdr = .FALSE. 602 emptygotbrdr = .FALSE. 603 604 ! Starting the fun... 605 606 ! Looking along the lines and when a border is found, starting from there in a clock-wise way 607 iipth = 1 608 ipath = 1 609 DO ib=1,Nbrdr 610 iib = borders(iipth,1) 611 jjb = borders(iipth,2) 612 ! Starting new path 613 newpath: IF (.NOT.gotbrdr(iipth)) THEN 614 ip = 1 615 Nptspath = 1 616 paths(ipath,ip,:) = borders(iipth,:) 617 gotbrdr(iipth) = .TRUE. 618 ! Looking for following clock-wise search 619 ! Not looking for W, because search starts from the W 620 iip = iib 621 ijp = jjb 622 DO k=1,Nbrdr 623 IF (dbg) PRINT *,ipath,'iip jip:', iip, ijp 624 found = .FALSE. 625 CALL look_clockwise_borders(dx,dy,Nppt,borders,gotbrdr,isborder,iip,ijp,.FALSE.,iif,jjf,iff) 626 IF (iif /= -1) THEN 627 ip=ip+1 628 paths(ipath,ip,:) = (/ iif,jjf /) 629 found = .TRUE. 630 gotbrdr(iff) = .TRUE. 631 iip = iif 632 ijp = jjf 633 Nptspath = Nptspath + 1 634 END IF 635 636 IF (dbg) THEN 637 PRINT *,iib,jjb,' end of this round path:', ipath, '_____', gotbrdr 638 DO i=1, Nptspath 639 PRINT *,' ',i,':',paths(ipath,i,:) 640 END DO 641 END IF 642 ! If it is not found a next point, might be because it is a non-polygon related value 643 IF (.NOT.found) THEN 644 IF (dbg) PRINT *,'NOT FOUND !!!', gotbrdr 645 ! Are still there available borders? 646 IF (ALL(gotbrdr) .EQV. .TRUE.) THEN 647 finishedstep = .TRUE. 648 Npath = ipath 649 Nptpaths(ipath) = Nptspath 650 EXIT 651 ELSE 652 Nptpaths(ipath) = Nptspath 653 ! Let's have a look if the next point would be someone already in the path 654 CALL look_clockwise_borders(dx,dy,Nppt,borders,gotbrdr,isborder,iip,ijp,.FALSE.,iif,jjf, & 655 iff) 656 iff = index_list_coordsI(Nptspath, paths(ipath,:,:),(/iif,jjf/)) 657 IF (iff /= -1) THEN 658 IF (dbg) THEN 659 PRINT *,' point already in Path!' 660 PRINT *,' path:', ipath, '_____' 661 DO i=1, Nptspath 662 PRINT *,' ',i,':',paths(ipath,i,:) 663 END DO 664 END IF 665 ! Continung unfinished path 666 iip = paths(ipath,Nptspath,1) 667 ijp = paths(ipath,Nptspath,2) 668 iipth = index_list_coordsI(Nppt, borders, (/iip,ijp/)) 669 ELSE 670 ! Looking for the next available border point for the new path 671 DO i=1,Nbrdr 672 IF (.NOT.gotbrdr(i)) THEN 673 iipth = i 674 EXIT 675 END IF 676 END DO 677 IF (dbg) PRINT *,' Looking for next path starting at:', iipth, ' point:', & 678 borders(iipth,:) 679 ipath=ipath+1 680 EXIT 681 END IF 682 END IF 683 ELSE 684 IF (dbg) PRINT *,' looking for next point...' 685 END IF 686 IF (finishedstep) EXIT 687 END DO 688 END IF newpath 689 END DO 690 Npath = ipath 691 Nptpaths(ipath) = Nptspath 692 693 DEALLOCATE (gotbrdr) 694 DEALLOCATE (emptygotbrdr) 695 696 RETURN 697 698 END SUBROUTINE paths_border 19 699 20 700 SUBROUTINE rand_sample(Nvals, Nsample, sample)
Note: See TracChangeset
for help on using the changeset viewer.