43 INTRINSIC tiny,count,abs,maxval,minval
49 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NP
53 REAL(GRIDMAN_DP),
INTENT(IN) :: XP(np)
57 REAL(GRIDMAN_DP),
INTENT(IN) :: YP(np)
62 LOGICAL,
INTENT(IN) :: LEX
64 INTEGER,
INTENT(OUT) :: IERR
68 s icell_pol,iedge_pol,x_pol,y_pol,indvert,indseg,
72 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: NPOL,NPEDGE(grid%nedges)
73 INTEGER(GRIDMAN_SP),
ALLOCATABLE :: ICELL_POL(:),
74 i iedge_pol(:),indseg(:)
75 REAL(GRIDMAN_DP),
ALLOCATABLE :: X_POL(:),Y_POL(:)
76 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NP
77 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: INDVERT(np)
78 REAL(GRIDMAN_DP) :: XP(np),YP(np)
79 INTEGER,
INTENT(OUT) :: IERR
84 LOGICAL :: LFIRST_POINT_INSIDE_POLYGON
85 LOGICAL :: LPOINT(grid%npoints),LCELL(grid%ncells)
86 INTEGER(GRIDMAN_SP) :: NPOL,NPMAX,NEMAX,NWORK,IEP,
87 i npoints,nedges,ncells,ncells0,nseg,
88 i ip,icell,icell1,iedge,iedge1,iedge0,
89 i ipoint,ipoint1,ipoint2,
90 i ie,ic,ne,n,ncount,st
91 INTEGER :: RES,IERR0,IWARN
92 INTEGER (GRIDMAN_SP) :: NPEDGE(grid%nedges),
93 i npcell(grid%NCELLS),
94 i inewcell(grid%NCELLS),
95 i inewedge(grid%NEDGES),
96 i indpoint(grid%NPOINTS),
100 REAL(GRIDMAN_DP) :: X0,Y0
102 REAL(GRIDMAN_DP),
ALLOCATABLE :: X1(:),X2(:)
103 INTEGER(GRIDMAN_SP),
ALLOCATABLE :: IOLDEDGE(:),
105 i icell_pol(:),iedge_pol(:),indseg_pol(:),
106 i cells(:,:),points(:,:)
107 INTEGER(GRIDMAN_SP),
ALLOCATABLE :: INDSEG(:,:)
109 INTEGER(GRIDMAN_SP),
ALLOCATABLE :: IPWORK(:),TPWORK(:),ICOUNT(:)
110 REAL(GRIDMAN_DP),
ALLOCATABLE :: X_POL(:),Y_POL(:),DWORK(:)
111 LOGICAL,
ALLOCATABLE :: LWORK(:)
121 IF(grid%TYPE.NE.2.OR.grid%PDIM.NE.2.OR.grid%EDIM.NE.2)
THEN
124 w
"grid object is not of 2D type"
126 w grid%TYPE,grid%PDIM,grid%EDIM
130 IF(gridman_check)
THEN
133 IF(res.NE.0.OR.ierr.GT.0)
THEN
136 w
"incorrect input grid"
143 IF(ierr.GT.0)
GOTO 100
148 s icell_pol,iedge_pol,
150 s indvert,indseg_pol,
151 s xp,yp,np,grid,ierr)
152 IF(ierr.NE.0)
GOTO 100
155 lfirst_point_inside_polygon=.true.
156 DO ipoint=1,grid%NPOINTS
157 x0=grid%X(1,ipoint)*grid%UNIT2SI
158 y0=grid%X(2,ipoint)*grid%UNIT2SI
159 lpoint(ipoint)=point_inside_polygon(xp,yp,np,x0,y0,lex)
162 npoints=count(lpoint(1:grid%NPOINTS))
166 f
WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_CUT: NPOINTS ",npoints
170 CALL allocate_temporary(npoints,npol,npmax,ierr)
171 IF(ierr.GT.0)
GOTO 100
180 DO ipoint=1,grid%NPOINTS
181 IF(lpoint(ipoint))
THEN
183 indpoint(ipoint)=npoints
184 x1(npoints)=grid%X(1,ipoint)
185 x2(npoints)=grid%X(2,ipoint)
195 DO iedge=1,grid%NEDGES
199 CALL edge_points(ipwork,tpwork,nwork,iedge,ierr)
200 IF(ierr.GT.0)
GOTO 100
202 IF( (tpwork(iep).GT.0.AND.tpwork(iep+1).GE.0).OR.
203 f (tpwork(iep+1).GT.0.AND.tpwork(iep).GE.0))
THEN
207 cells(:,nedges)=grid%CELLS(:,iedge)
208 points(1,nedges)=ipwork(iep)
209 points(2,nedges)=ipwork(iep+1)
210 ioldedge(nedges)=iedge
211 inewedge(iedge)=nedges
212 ELSE IF( (tpwork(iep).EQ.0.AND.tpwork(iep+1).EQ.0) )
THEN
216 ipoint2=ipwork(iep+1)
217 x0=0.5*(x1(ipoint1)+x1(ipoint2))*grid%UNIT2SI
218 y0=0.5*(x2(ipoint1)+x2(ipoint2))*grid%UNIT2SI
219 IF(point_inside_polygon(xp,yp,np,x0,y0,lex))
THEN
221 cells(:,nedges)=grid%CELLS(:,iedge)
222 points(1,nedges)=ipoint1
223 points(2,nedges)=ipoint2
224 ioldedge(nedges)=iedge
225 inewedge(iedge)=nedges
232 f
WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_CUT: NEDGES (*) ",nedges
237 ALLOCATE(indseg(2,npol),stat=st)
245 cells(1,nedges)=icell
249 points(2,nedges)=ip+1
254 indseg(1,nseg)=nedges
255 indseg(2,nseg)=indseg_pol(ip)
261 f
WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_CUT: NEDGES ",nedges
263 IF(nedges.EQ.0)
GOTO 200
269 IF(icell.GT.0) lcell(icell)=.true.
271 IF(icell.GT.0) lcell(icell)=.true.
276 DO icell=1,grid%NCELLS
277 IF(lcell(icell))
THEN
279 inewcell(icell)=ncells
280 ioldcell(ncells)=icell
288 icell=cells(ic,iedge)
290 icell1=inewcell(icell)
291 IF(icell1.LT.1)
GOTO 300
292 cells(ic,iedge)=icell1
293 iedge0=ioldedge(iedge)
295 f npcell(icell1)=npcell(icell1)+npedge(iedge0)
296 ELSEIF(icell.LT.0)
THEN
298 iedge1=inewedge(-icell)
299 cells(ic,iedge)=-iedge1
305 f
WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_CUT: NCELLS (*) ",ncells
309 IF(maxval(npcell).GT.2)
THEN
310 CALL list_of_edges(celledges,ierr)
311 IF(ierr.GT.0)
GOTO 100
316 IF(npcell(icell).LE.2) cycle
318 ne=celledges%ILAST(icell)-celledges%IFIRST(icell)+1
325 CALL find_contour(icount,ncount,lwork,icell,ierr)
330 ioldcell(ncells)=ioldcell(icell)
334 IF(cells(1,iedge).EQ.icell)
THEN
335 cells(1,iedge)=ncells
337 cells(2,iedge)=ncells
351 f
WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_CUT: NCELLS ",ncells
353 CALL create_cutgrid(ierr)
354 IF(ierr.GT.0)
GOTO 100
356 CALL deallocate_temporary(ierr)
359 IF(ierr.EQ.0) ierr=iwarn
366 100
WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_CUT terminated"
367 CALL deallocate_all(ierr0)
371 w
"resulting grid is empty"
372 CALL deallocate_all(ierr0)
378 w
"Cell is taken into new grid but the index is <1"
380 CALL deallocate_all(ierr0)
381 400
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_CUT: ",
382 w
"cannot allocate temporary array INDSEG"
384 CALL deallocate_all(ierr0)
395 SUBROUTINE find_contour(ICOUNT,NCOUNT,LWORK,ICELL,IERR)
396 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: ICOUNT(nemax),
398 INTEGER(GRIDMAN_SP),
INTENT(IN) :: ICELL
399 LOGICAL,
INTENT(INOUT) :: LWORK(nemax)
400 INTEGER,
INTENT(OUT) :: IERR
402 INTEGER(GRIDMAN_SP) :: IE,I,IEDGE,IPOINT,IPOINT0,IPOINT00,NMAX
407 DO ie=celledges%IFIRST(icell),celledges%ILAST(icell)
408 iedge=celledges%IND(ie)
409 i=ie-celledges%IFIRST(icell)+1
413 ipoint0=points(1,iedge)
416 nmax=celledges%ILAST(icell)-celledges%IFIRST(icell)+1
422 DO ie=celledges%IFIRST(icell),celledges%ILAST(icell)
423 i=ie-celledges%IFIRST(icell)+1
425 iedge=celledges%IND(ie)
431 WRITE(
gridman_unit,*)
" ICELL, IE, IEDGE ",icell,ie,iedge
434 ipoint=points(1,iedge)
435 IF(ipoint.EQ.ipoint0)
THEN
438 IF(ncount.GT.nmax)
GOTO 100
440 ipoint0=points(2,iedge)
444 ipoint=points(2,iedge)
445 IF(ipoint.EQ.ipoint0)
THEN
448 IF(ncount.GT.nmax)
GOTO 100
450 ipoint0=points(1,iedge)
465 20
IF(ipoint0.EQ.ipoint00)
EXIT
473 WRITE(
gridman_unit,*)
"Index out of range in FIND_CONTOUR"
477 END SUBROUTINE find_contour
483 SUBROUTINE list_of_edges(CELLEDGES,IERR)
485 INTEGER,
INTENT(OUT) :: IERR
486 INTEGER(GRIDMAN_SP) :: IEDGE,IC,ICELL,L,ST,IE,NLAST
493 ALLOCATE(celledges%IFIRST(ncells),
494 a celledges%ILAST(ncells),stat=st)
497 w
"cannot allocate temporary data structure CELLEDGES"
506 icell=cells(ic,iedge)
508 celledges%ILAST(icell)=celledges%ILAST(icell)+1
514 nemax=maxval(celledges%ILAST)
517 ALLOCATE(celledges%IND(l),stat=st)
520 w
"cannot allocate temporary data structure CELLEDGES"
525 celledges%IFIRST(1)=1
526 nlast=celledges%ILAST(1)
528 DO icell=2,celledges%N
529 celledges%IFIRST(icell)=nlast+1
530 nlast=nlast+celledges%ILAST(icell)
531 celledges%ILAST(icell)=celledges%IFIRST(icell)-1
535 icell=cells(ic,iedge)
537 celledges%ILAST(icell)=celledges%ILAST(icell)+1
538 ie=celledges%ILAST(icell)
539 celledges%IND(ie)=iedge
543 ALLOCATE(lwork(nemax),icount(nemax),stat=st)
546 w
"cannot allocate temporary arrays"
552 END SUBROUTINE list_of_edges
557 SUBROUTINE edge_points(IPEDGE,TPEDGE,NP,IEDGE,IERR)
558 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: IPEDGE(npmax+2),
566 INTEGER(GRIDMAN_SP),
INTENT(IN) :: IEDGE
567 INTEGER,
INTENT(OUT) :: IERR
569 INTEGER(GRIDMAN_SP) :: IPOINT,IP,IPOINT1,ITMP
570 REAL(GRIDMAN_DP) :: Xa,Ya,Xs,Ys,DTMP
573 IF(npedge(iedge).LT.1)
THEN
577 ipoint=grid%POINTS(ip,iedge)
578 IF(lpoint(ipoint))
THEN
583 ipedge(ip)=indpoint(ipoint)
585 IF(tpedge(1).NE.tpedge(2))
THEN
590 w
"If edge is not intersected by the polygon"
592 w
"then both its ends must be either inside ",
593 w
"or outside the grid"
594 WRITE(
gridman_unit,*)
" IEDGE, TPEDGE ",iedge,tpedge(1:2)
602 ipoint=grid%POINTS(1,iedge)
603 ipoint1=indpoint(ipoint)
607 IF(lpoint(ipoint))
THEN
613 IF(iedge_pol(ip).EQ.iedge)
THEN
623 dwork(np)=(xa-xs)**2+(ya-ys)**2
628 ipoint=grid%POINTS(2,iedge)
629 ipoint1=indpoint(ipoint)
631 IF(lpoint(ipoint))
THEN
641 IF(dwork(ip).GT.dwork(ip+1))
THEN
643 dwork(ip)=dwork(ip+1)
646 ipedge(ip)=ipedge(ip+1)
649 tpedge(ip)=tpedge(ip+1)
658 END SUBROUTINE edge_points
665 FUNCTION point_inside_polygon(XP,YP,NP,X0,Y0,LEX)
667 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NP
668 REAL(GRIDMAN_DP),
INTENT(IN) :: XP(np),YP(np),X0,Y0
669 LOGICAL,
INTENT(IN) :: LEX
670 LOGICAL :: POINT_INSIDE_POLYGON
672 REAL(GRIDMAN_DP),
SAVE :: XMIN,XMAX,YMIN,YMAX
674 IF(lfirst_point_inside_polygon)
THEN
680 lfirst_point_inside_polygon=.false.
683 IF(x0.GT.xmax.OR.x0.LT.xmin.OR.
684 f y0.GT.ymax.OR.y0.LT.ymin)
THEN
686 point_inside_polygon=.true.
688 point_inside_polygon=.false.
694 IF(lex) point_inside_polygon=.NOT.point_inside_polygon
696 END FUNCTION point_inside_polygon
701 SUBROUTINE create_cutgrid(IERR)
704 INTEGER,
INTENT(OUT) :: IERR
705 INTEGER(GRIDMAN_SP) :: ICELL,ICELL0,IEDGE,IEDGE0
707 INTEGER (GRIDMAN_SP) :: M,IEMAP(2,nedges),ICMAP(2,ncells)
710 nei=grid%NEDGEINDEX+1
715 s ncells,ierr,nei,grid%NCELLINDEX)
720 cutgrid%CELLS=cells(1:2,1:nedges)
721 cutgrid%POINTS(1:2,:)=points(1:2,1:nedges)
722 cutgrid%X(1,:)=x1(1:npoints)
723 cutgrid%X(2,:)=x2(1:npoints)
724 cutgrid%UNIT2SI=grid%UNIT2SI
725 cutgrid%UNITS=grid%UNITS
726 cutgrid%DESCRIPTION=trim(grid%DESCRIPTION)//
727 /
" << processed by GRIDMAN_GRID2D_CUT"
730 DO ii=1,grid%NEDGEINDEX
733 iedge0=ioldedge(iedge)
741 c grid%EDGEINDEX(ii),iemap,m,ierr)
744 w
"cannot create edge index II ",ii
753 w
"cannot create the polygon segment index, NSEG ",nseg
756 cutgrid%EDGEINDEX(nei)%INDEXES(0:1,1:nseg)=indseg(1:2,1:nseg)
757 cutgrid%EDGEINDEX(nei)%DESCRIPTION=
758 w
'Indices of the polygon segments'
759 cutgrid%EDGEINDEX(nei)%COLUMNS(1)=
'CUT_ISEG'
763 DO ii=1,grid%NCELLINDEX
766 icell0=ioldcell(icell)
774 c grid%CELLINDEX(ii),icmap,m,ierr)
777 w
"cannot create edge index II ",ii
783 IF(res.NE.0.OR.ierr.GT.0)
THEN
786 w
"wrong resulting GRID object"
790 END SUBROUTINE create_cutgrid
797 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NP
798 REAL(GRIDMAN_DP),
INTENT(IN) :: XP(np),YP(np)
799 INTEGER,
INTENT(OUT) :: IERR
800 INTEGER(GRIDMAN_SP) :: IP,IP1,NP1,IPOINT
801 REAL(GRIDMAN_DP) :: DX,EX,DY,EY,EPS,X1,Y1,X2,Y2,X0,Y0,
802 r x11,y11,x12,y12,x21,y21,x22,y22,xi,yi
808 w
"polygon must have at least 3 vertices"
814 dx=abs(xp(ip+1)-xp(ip))
815 dy=abs(yp(ip+1)-yp(ip))
817 IF(dx.LT.ex.AND.dy.LT.ex)
THEN
820 w
"duplicate points in the polygon"
823 w ip+1,xp(ip+1),yp(ip+1)
828 ex=gridman_tol*(abs(xp(1))+abs(xp(np)))+tiny(dx)*10
830 ey=gridman_tol*(abs(yp(1))+abs(yp(np)))+tiny(dy)*10
832 IF(dx.GT.ex.OR.dy.GT.ey)
THEN
835 w
"no closed polygon"
838 IF(gridman_check)
THEN
854 f x21,y21,x22,y22,xi,yi))
THEN
857 w
"polygon have self intersection"
872 DO ipoint=1,grid%NPOINTS
873 x0=grid%X(1,ipoint)*grid%UNIT2SI
874 y0=grid%X(2,ipoint)*grid%UNIT2SI
876 f x2,y2,x0,y0,gridman_tol))
THEN
878 WRITE(
gridman_unit,*)
"WARNING from GRIDMAN_GRID2D_CUT: ",
879 w
"polygone segment comes too close to a grid node"
887 DO iedge=1,grid%NEDGES
888 ipoint=grid%POINTS(1,iedge)
889 x1=grid%X(1,ipoint)*grid%UNIT2SI
890 y1=grid%X(2,ipoint)*grid%UNIT2SI
891 ipoint=grid%POINTS(2,iedge)
892 x2=grid%X(1,ipoint)*grid%UNIT2SI
893 y2=grid%X(2,ipoint)*grid%UNIT2SI
896 w xp(ip),yp(ip),gridman_tol))
THEN
898 WRITE(
gridman_unit,*)
"WARNING from GRIDMAN_GRID2D_CUT: ",
899 w
"grid edge comes too close to a polygone vertex"
901 w iedge, x1, y1, x2, y2
914 SUBROUTINE allocate_temporary(NPOINTS,NPOL,NPMAX,IERR)
915 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NPOINTS,NPOL,NPMAX
916 INTEGER,
INTENT(OUT) :: IERR
917 INTEGER(GRIDMAN_SP) :: NE,NC,ST
921 ne=grid%NEDGES+2*npol
926 w
"GRIDMAN_GRID2D_CUT: NPOL, NPOINTS, NPMAX ",
927 w npol, npoints, npmax
929 ALLOCATE(x1(npoints),x2(npoints),
930 a ioldedge(ne),ioldcell(nc),
931 a cells(2,ne),points(2,ne),
932 a ipwork(npmax+2),tpwork(npmax+2),dwork(npmax+2),stat=st)
935 w
"cannot allocate temporary arrays"
937 w npoints, npmax, npol
938 WRITE(
gridman_unit,*)
" NCELLS, NEDGES ",grid%NCELLS,grid%NEDGES
943 END SUBROUTINE allocate_temporary
948 SUBROUTINE deallocate_temporary(IERR)
949 INTEGER,
INTENT(OUT) :: IERR
954 IF(
ALLOCATED(x1))
DEALLOCATE(x1,stat=st(1))
955 IF(
ALLOCATED(x2))
DEALLOCATE(x2,stat=st(2))
956 IF(
ALLOCATED(ioldedge))
DEALLOCATE(ioldedge,stat=st(3))
957 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell,stat=st(4))
958 IF(
ALLOCATED(cells))
DEALLOCATE(cells,stat=st(5))
959 IF(
ALLOCATED(points))
DEALLOCATE(points,stat=st(6))
960 IF(
ALLOCATED(icell_pol))
DEALLOCATE(icell_pol,stat=st(7))
961 IF(
ALLOCATED(iedge_pol))
DEALLOCATE(iedge_pol,stat=st(8))
962 IF(
ALLOCATED(ipwork))
DEALLOCATE(ipwork,stat=st(9))
963 IF(
ALLOCATED(tpwork))
DEALLOCATE(tpwork,stat=st(10))
964 IF(
ALLOCATED(icount))
DEALLOCATE(icount,stat=st(11))
965 IF(
ALLOCATED(x_pol))
DEALLOCATE(x_pol,stat=st(12))
966 IF(
ALLOCATED(y_pol))
DEALLOCATE(y_pol,stat=st(13))
967 IF(
ALLOCATED(dwork))
DEALLOCATE(dwork,stat=st(14))
968 IF(
ALLOCATED(lwork))
DEALLOCATE(lwork,stat=st(15))
969 IF(
ALLOCATED(indseg))
DEALLOCATE(indseg,stat=st(16))
973 IF(any(st.NE.0))
THEN
976 w
"problems with deallocation of temporary arrays"
980 END SUBROUTINE deallocate_temporary
983 SUBROUTINE deallocate_all(IERR)
984 INTEGER,
INTENT(OUT) :: IERR
985 CALL deallocate_temporary(ierr)
987 END SUBROUTINE deallocate_all
997 s icell_pol,iedge_pol,
1007 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NP
1008 REAL(GRIDMAN_DP) :: XP(np),YP(np)
1011 INTEGER(GRIDMAN_SP),
INTENT(OUT) ::
1013 i npedge(grid%NEDGES)
1014 INTEGER(GRIDMAN_SP),
ALLOCATABLE ::
1021 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: INDVERT(np)
1024 REAL(GRIDMAN_DP),
ALLOCATABLE :: X_POL(:),Y_POL(:)
1025 INTEGER,
INTENT(OUT) :: IERR
1027 INTEGER(GRIDMAN_SP) :: NWORK,IEDGE0,IEDGE1,ICELL0,ICELL1,IP,
1028 i icell_first,iedge_first,ip_first,ipol
1029 REAL(GRIDMAN_DP) :: X0,Y0,X1,Y1,X_FIRST,Y_FIRST
1032 REAL(GRIDMAN_DP),
ALLOCATABLE :: XWORK(:),YWORK(:)
1037 w
"Starting GRIDMAN_GRID2D_POLYGON_TRAJECTORY"
1043 IF(ierr.GT.0)
RETURN
1047 IF(ierr.GT.0)
RETURN
1050 CALL allocate_work(chains,ierr)
1051 IF(ierr.GT.0)
RETURN
1054 CALL first_point(x_first,y_first,
1055 s icell_first,iedge_first,ip_first)
1056 IF(ierr.GT.0)
RETURN
1058 IF(gridman_dbg)
THEN
1059 WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_POLYGON_TRAJECTORY:"
1060 WRITE(
gridman_unit,*)
" ICELL_FIRST, IEDGE_FIRST, IP_FIRST ",
1061 w icell_first, iedge_first, ip_first
1062 WRITE(
gridman_unit,*)
" X_FIRST, Y_FIRST ", x_first,y_first
1067 IF(iedge_first.LT.0.AND.icell_first.LT.0)
THEN
1086 IF(iedge0.GT.0) npedge(iedge0)=npedge(iedge0)+1
1089 CALL find_next_point(iedge1,icell1,x1,y1,iedge0,icell0,
1090 c x0,y0,xp(ip),yp(ip))
1091 IF(iedge1.LT.1.AND.icell1.LT.1)
GOTO 300
1096 IF(iedge0.GT.0) npedge(iedge0)=npedge(iedge0)+1
1097 IF(iedge0.LT.1)
THEN
1105 IF(icell1.LT.1)
THEN
1110 c x0,y0,xp(ip),yp(ip))
1111 IF(iedge1.GT.0)
THEN
1116 npedge(iedge0)=npedge(iedge0)+1
1117 icell0=grid%CELLS(1,iedge0)
1118 IF(icell0.LT.1) icell0=grid%CELLS(2,iedge0)
1135 w
"GRIDMAN_GRID2D_POLYGON_TRAJECTORY: NPOL ",npol
1138 CALL allocate_arrays(npol,ierr)
1139 IF(ierr.GT.0)
RETURN
1151 icell_pol(ipol)=icell0
1152 iedge_pol(ipol)=iedge0
1153 IF(iedge0.LT.0)
THEN
1154 IF(ip.LT.2)
GOTO 100
1159 CALL find_next_point(iedge1,icell1,x1,y1,iedge0,icell0,
1160 c x0,y0,xp(ip),yp(ip))
1161 IF(iedge1.LT.1.AND.icell1.LT.1)
GOTO 300
1166 IF(iedge0.LT.1)
THEN
1177 icell_pol(ipol)=icell0
1178 iedge_pol(ipol)=iedge0
1180 IF(icell1.LT.1)
THEN
1182 c x0,y0,xp(ip),yp(ip))
1185 IF(iedge1.GT.0)
THEN
1189 icell0=grid%CELLS(1,iedge0)
1190 IF(icell0.LT.1) icell0=grid%CELLS(2,iedge0)
1194 icell_pol(ipol)=icell0
1195 iedge_pol(ipol)=iedge0
1210 IF(ipol.NE.npol)
GOTO 200
1212 indvert(np)=indvert(1)
1215 x_pol(1:npol)=x_pol(1:npol)/grid%UNIT2SI
1216 y_pol(1:npol)=y_pol(1:npol)/grid%UNIT2SI
1218 CALL deallocate_local(ierr)
1222 w
"GRIDMAN_GRID2D_POLYGON_TRAJECTORY finished"
1227 w
"ERROR in GRIDMAN_GRID2D_POLYGON_TRAJECTORY: ",
1228 w
"internal error (1)"
1230 CALL deallocate_local(ierr)
1233 w
"ERROR in GRIDMAN_GRID2D_POLYGON_TRAJECTORY: ",
1234 w
"internal error (2)"
1236 CALL deallocate_local(ierr)
1239 w
"ERROR in GRIDMAN_GRID2D_POLYGON_TRAJECTORY: ",
1240 w
"internal error (3)"
1248 CALL deallocate_local(ierr)
1256 SUBROUTINE first_point(X_FIRST,Y_FIRST,
1257 s icell_first,iedge_first,ip_first)
1258 REAL(GRIDMAN_DP),
INTENT(OUT) :: X_FIRST,
1260 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: ICELL_FIRST,
1264 INTEGER(GRIDMAN_SP) :: IP,ICELL1,ICELL2,ICELL0,IEDGE,IEDGE0
1265 REAL(GRIDMAN_DP) :: X0,Y0,X1,Y1
1270 c xp(ip+1),yp(ip+1))
1288 icell1=grid%CELLS(1,iedge)
1289 IF(icell1.GT.0)
THEN
1290 IF(point_in_cell(x0,y0,icell1))
THEN
1297 icell2=grid%CELLS(2,iedge)
1298 IF(icell2.GT.0)
THEN
1315 icell2=grid%CELLS(2,iedge)
1316 IF(icell2.GT.0)
THEN
1318 IF(point_in_cell(x0,y0,icell2))
THEN
1344 END SUBROUTINE first_point
1352 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: IEDGE_OUT
1354 REAL(GRIDMAN_DP),
INTENT(OUT) :: X_OUT,Y_OUT
1355 REAL(GRIDMAN_DP),
INTENT(IN) :: X1,Y1,X2,Y2
1357 REAL(GRIDMAN_DP) :: XE1,YE1,XE2,YE2,XI,YI,D,DMIN
1358 INTEGER(GRIDMAN_SP) :: IEDGE,IPOINT
1362 dmin=(x1-x2)**2+(y1-y2)**2
1366 DO iedge=1,grid%NEDGES
1367 ipoint=grid%POINTS(1,iedge)
1368 xe1=grid%X(1,ipoint)*grid%UNIT2SI
1369 ye1=grid%X(2,ipoint)*grid%UNIT2SI
1370 ipoint=grid%POINTS(2,iedge)
1371 xe2=grid%X(1,ipoint)*grid%UNIT2SI
1372 ye2=grid%X(2,ipoint)*grid%UNIT2SI
1374 d=(x1-xi)**2+(y1-yi)**2
1392 s iedge0,x1,y1,x2,y2)
1394 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: IEDGE_OUT
1396 REAL(GRIDMAN_DP),
INTENT(OUT) :: X_OUT,Y_OUT
1397 INTEGER(GRIDMAN_SP),
INTENT(IN) :: IEDGE0
1398 REAL(GRIDMAN_DP),
INTENT(IN) :: X1,Y1
1399 REAL(GRIDMAN_DP),
INTENT(IN) :: X2,Y2
1401 REAL(GRIDMAN_DP) :: XE1,YE1,XE2,YE2,XI,YI,D,DMIN,VX,VY
1402 INTEGER(GRIDMAN_SP) :: IEDGE,IPOINT,ICELL1,ICELL2
1408 dmin=(x1-x2)**2+(y1-y2)**2
1412 DO iedge=1,grid%NEDGES
1413 IF(iedge.EQ.iedge0) cycle
1414 icell1=grid%CELLS(1,iedge)
1415 icell2=grid%CELLS(2,iedge)
1417 IF(icell1.GT.0.AND.icell2.GT.0) cycle
1418 ipoint=grid%POINTS(1,iedge)
1419 xe1=grid%X(1,ipoint)*grid%UNIT2SI
1420 ye1=grid%X(2,ipoint)*grid%UNIT2SI
1421 ipoint=grid%POINTS(2,iedge)
1422 xe2=grid%X(1,ipoint)*grid%UNIT2SI
1423 ye2=grid%X(2,ipoint)*grid%UNIT2SI
1425 d=(x1-xi)**2+(y1-yi)**2
1441 FUNCTION point_in_cell(X0,Y0,ICELL)
1443 REAL(GRIDMAN_DP),
INTENT(IN) :: X0,Y0
1444 INTEGER(GRIDMAN_SP),
INTENT(IN) :: ICELL
1445 INTEGER(GRIDMAN_SP) :: IP,IPOINT,N
1446 LOGICAL :: POINT_IN_CELL
1449 DO ip=chains%IFIRST(icell),chains%ILAST(icell)
1450 ipoint=chains%IND(ip)
1452 xwork(n)=grid%X(1,ipoint)*grid%UNIT2SI
1453 ywork(n)=grid%X(2,ipoint)*grid%UNIT2SI
1456 point_in_cell=.true.
1458 point_in_cell=.false.
1461 END FUNCTION point_in_cell
1466 SUBROUTINE find_next_point(IEDGE1,ICELL1,X1,Y1,
1467 f iedge0,icell0,x0,y0,xn,yn)
1470 INTEGER(GRIDMAN_SP),
INTENT(OUT) :: IEDGE1,ICELL1
1472 REAL(GRIDMAN_DP),
INTENT(OUT) :: X1,Y1
1474 INTEGER(GRIDMAN_SP),
INTENT(IN) :: IEDGE0,ICELL0
1476 REAL(GRIDMAN_DP),
INTENT(IN) :: X0,Y0
1478 REAL(GRIDMAN_DP),
INTENT(IN) :: XN,YN
1479 INTEGER(GRIDMAN_SP) :: IE,IEDGE,IPOINT,IMIN
1480 REAL(GRIDMAN_DP) :: VX,VY,D,DMIN,XE1,YE1,XE2,YE2,XI,YI,
1488 dmin=(xn-x0)**2+(yn-y0)**2
1491 DO ie=cells%IFIRST(icell0),cells%ILAST(icell0)
1493 IF(iedge.EQ.iedge0) cycle
1494 ipoint=grid%POINTS(1,iedge)
1495 xe1=grid%X(1,ipoint)*grid%UNIT2SI
1496 ye1=grid%X(2,ipoint)*grid%UNIT2SI
1497 ipoint=grid%POINTS(2,iedge)
1498 xe2=grid%X(1,ipoint)*grid%UNIT2SI
1499 ye2=grid%X(2,ipoint)*grid%UNIT2SI
1501 d=(x0-xi)**2+(y0-yi)**2
1522 icell1=grid%CELLS(1,iedge1)
1523 IF(icell1.EQ.icell0) icell1=grid%CELLS(2,iedge1)
1534 END SUBROUTINE find_next_point
1539 SUBROUTINE allocate_arrays(NPOL,IERR)
1540 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NPOL
1541 INTEGER,
INTENT(OUT) :: IERR
1546 ALLOCATE(icell_pol(npol),iedge_pol(npol),indseg(npol),
1547 w x_pol(npol),y_pol(npol),stat=st)
1550 w
"ERROR in GRIDMAN_GRID2D_POLYGON_TRAJECTORY: ",
1551 w
"cannot allocate temporary arrays"
1557 END SUBROUTINE allocate_arrays
1562 SUBROUTINE allocate_work(CHAINS,IERR)
1564 INTEGER,
INTENT(OUT) :: IERR
1565 INTEGER(GRIDMAN_SP) :: N,IC,ST
1569 n=chains%ILAST(ic)-chains%IFIRST(ic)+1
1570 IF(n.GT.nwork) nwork=n
1572 ALLOCATE(xwork(nwork),ywork(nwork),stat=st)
1575 w
"ERROR in GRIDMAN_GRID2D_POLYGON_TRAJECTORY: ",
1576 w
"cannot allocate XWORK, YWORK"
1581 END SUBROUTINE allocate_work
1586 SUBROUTINE deallocate_local(IERR)
1587 INTEGER,
INTENT(OUT) :: IERR
1588 INTEGER :: ST(4),IERR0
1591 IF(
ALLOCATED(xwork))
DEALLOCATE(xwork,stat=st(1))
1592 IF(
ALLOCATED(xwork))
DEALLOCATE(ywork,stat=st(2))
1594 IF(ierr0.NE.0) st(3)=1
1596 IF(ierr0.NE.0) st(4)=1
1597 IF(any(st.NE.0))
THEN
1600 w
"ERROR in GRIDMAN_GRID2D_POLYGON_TRAJECTORY: ",
1601 w
"problems with deallocation of temporary arrays"
1603 END SUBROUTINE deallocate_local
subroutine find_closest_edge(IEDGE_OUT, X_OUT, Y_OUT, X1, Y1, X2, Y2)
logical function gridman_intersect2d(X11, Y11, X12, Y12, X21, Y21, X22, Y22, XI, YI)
Intersection of two intervals on a plane.
logical function gridman_cross2d(X0, Y0, V, U, X1, Y1, X2, Y2, XI, YI)
Intersection of "particle trajectory" with an interval (2D)
integer, save, public gridman_unit
Index of the standard output unit.
integer, parameter, public gridman_dp
Kind parameter for real numbers.
Explicit interfaces to GRIDMAN subroutines and functions.
subroutine gridman_grid2d_polygon_trajectory(NPOL, NPEDGE, ICELL_POL, IEDGE_POL, X_POL, Y_POL, INDVERT, INDSEG, XP, YP, NP, GRID, IERR)
subroutine check_polygon(XP, YP, NP, IERR)
subroutine gridman_grid_allocate(GRID, TYPE, NEDGES, NPOINTS, NCELLS, IERR, NEDGEINDEX, NCELLINDEX)
Allocate GRIDMAN_GRID object.
subroutine gridman_grid2d_chains(GRID, CHAINS, IERR)
Find closed chain of points which form each cell.
subroutine gridman_grid2d_cut(CUTGRID, GRID, XP, YP, NP, LEX, IERR)
Select part of a 2D grid cut by polygon.
logical function gridman_close2interval2d(X1, Y1, X2, Y2, X, Y, TOL)
Find if point is close to the interval within prescribed tolerance.
subroutine gridman_grid_cells(EDGES, GRID, IERR)
Create a list of edges which belong to each cell.
subroutine gridman_grid2d_check(GRID, RES, IERR)
Check correctness of the 2D grid object.
subroutine gridman_index_transform(INDEX2, INDEX1, IMAP12, N12, IERR)
Transform indices of elements - IND(0,:)
subroutine gridman_indlist_deallocate(INDLIST, IERR)
Deallocate list of indices.
Data-type which describes a grid as a set of edges, methods in grid.f.
subroutine gridman_grid_deallocate(GRID, IERR)
Deallocate grid object.
subroutine gridman_index_allocate(INDEX, NINDEX, NELEMENTS, IERR)
Allocate index object.
logical function gridman_point_in_polygon(XP, YP, NP, X0, Y0)
Find if point lies inside a closed polygon.
subroutine find_closest_boundary(IEDGE_OUT, X_OUT, Y_OUT, IEDGE0, X1, Y1, X2, Y2)
Data-type which describes lists of elements with variable number of indices for each element...
Definition of data types, global constants and variables.
integer, parameter, public gridman_sp
Kind parameter for integer numbers.