69 INTEGER,
INTENT(OUT) :: IERR
71 INTEGER :: RES,IERR0,II,ST
72 INTEGER(GRIDMAN_SP) :: ICELL,NP,NCELLS0,NEDGES0,ICELL0,
73 i dnc,dne,ncells,nedges,n,ie,i,nelements
74 INTEGER(GRIDMAN_SP),
ALLOCATABLE :: IOLDCELL(:)
82 IF(grid%TYPE.NE.2.OR.grid%PDIM.NE.2.OR.grid%EDIM.NE.2)
THEN
85 w
"the grid is not of 2D type"
87 w grid%TYPE,grid%PDIM,grid%EDIM
91 IF(grid%NCELLS.LT.1)
GOTO 100
93 IF(gridman_check)
THEN
95 IF(res.NE.0.OR.ierr.GT.0)
THEN
97 WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
98 w
"incorrect input grid"
105 IF(ierr.GT.0)
GOTO 150
109 np=chains%ILAST(icell)-chains%IFIRST(icell)
116 s ncells,ierr,grid%NEDGEINDEX)
117 IF(ierr.GT.0)
GOTO 1000
120 IF(ierr.GT.0)
GOTO 1000
122 DO ii=1,grid%NEDGEINDEX
124 c grid%EDGEINDEX(ii),ierr)
125 IF(ierr.NE.0)
GOTO 600
130 tria%NCELLS=grid%NCELLS
131 tria%NEDGES=grid%NEDGES
132 IF(grid%NCELLINDEX.GT.0)
THEN
134 ALLOCATE(ioldcell(ncells),stat=st)
137 ioldcell(icell)=icell
144 IF(
ALLOCATED(ioldcell))
THEN
145 CALL gridman_grid2d_triang_step(tria,ncells,nedges,chains,ierr,
148 CALL gridman_grid2d_triang_step(tria,ncells,nedges,chains,ierr)
150 IF(ierr.GT.0)
GOTO 1000
152 dnc=tria%NCELLS-ncells0
153 dne=tria%NEDGES-nedges0
154 IF(dnc.LT.0.OR.dne.LT.0.OR.dnc.NE.dne)
GOTO 400
160 IF(ierr.GT.0)
GOTO 1000
167 IF(tria%NCELLS.NE.ncells.OR.tria%NEDGES.NE.nedges)
GOTO 500
170 IF(
ALLOCATED(ioldcell))
THEN
172 IF(ierr.NE.0)
GOTO 700
175 inewcell%IFIRST(icell0)=n+1
177 IF(icell0.EQ.ioldcell(icell))
THEN
179 IF(n.GT.ncells)
GOTO 710
180 inewcell%IND(n)=icell
183 inewcell%ILAST(icell0)=n
185 IF(n.NE.ncells)
GOTO 720
187 ALLOCATE(tria%CELLINDEX(grid%NCELLINDEX),stat=st)
189 tria%NCELLINDEX=grid%NCELLINDEX
190 DO ii=1,grid%NCELLINDEX
192 DO ie=1,grid%CELLINDEX(ii)%NELEMENTS
193 icell0=grid%CELLINDEX(ii)%INDEXES(0,ie)
194 nelements=nelements+inewcell%ILAST(icell0)
195 - -inewcell%IFIRST(icell0)+1
198 c grid%CELLINDEX(ii)%NINDEX,
200 IF(ierr.GT.0)
GOTO 1000
202 DO ie=1,grid%CELLINDEX(ii)%NELEMENTS
203 icell0=grid%CELLINDEX(ii)%INDEXES(0,ie)
204 DO i=inewcell%IFIRST(icell0),inewcell%ILAST(icell0)
205 icell=inewcell%IND(i)
207 IF(n.GT.tria%CELLINDEX(ii)%NELEMENTS)
GOTO 730
208 tria%CELLINDEX(ii)%INDEXES(0,n)=icell
209 tria%CELLINDEX(ii)%INDEXES(1:,n)=
210 = grid%CELLINDEX(ii)%INDEXES(1:,ie)
213 IF(n.NE.tria%CELLINDEX(ii)%NELEMENTS)
GOTO 730
214 tria%CELLINDEX(ii)%DESCRIPTION=grid%CELLINDEX(ii)%DESCRIPTION
215 tria%CELLINDEX(ii)%COLUMNS=grid%CELLINDEX(ii)%COLUMNS
221 tria%DESCRIPTION=trim(grid%DESCRIPTION)//
222 /
" >> triangulated by GRIDMAN_GRID2D_TRIANG"
225 IF(gridman_check)
THEN
227 IF(res.NE.0.OR.ierr.GT.0)
THEN
229 WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
230 w
"wrong resulting grid"
235 f
WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_TRIANG finished"
239 100
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
240 w
"grid has no cells"
244 150
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
245 w
"cannon create temporar index list CHAINS"
248 200
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
251 w
" Cell has less than 3 points, ICELL ",icell
256 300
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
257 w
"cannot allocate temporary array"
262 WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
265 w
" Wrong increment of the number of edges or cells"
266 WRITE(
gridman_unit,*)
" NCELLS, NCELLS0 ",tria%NCELLS,ncells0
267 WRITE(
gridman_unit,*)
" NEDGES, NEDGES0 ",tria%NEDGES,nedges0
269 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell)
273 WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
274 w
"mismatch between expected and actual grid size"
275 WRITE(
gridman_unit,*)
"Expected: NCELLS, NEDGES ",ncells,nedges
277 w tria%NCELLS,tria%NEDGES
278 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell)
280 600
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
281 w
"cannon create edge index II ",ii
282 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell)
286 700
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
287 w
"cannon create temporar index list INEWCELL"
290 710
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
291 w
"internal error - wrong IOLDCELL"
293 w icell0,icell,n,ncells
296 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell)
298 720
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
299 w
"internal error - wrong IOLDCELL"
300 WRITE(
gridman_unit,*)
" It must be N==NCELLS, N, NCELLS ",n,ncells
303 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell)
305 725
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
306 w
"cannot allocate TRIA%CELLINDEX"
310 730
WRITE(
gridman_unit,*)
"ERROR in GRIDMAN_GRID2D_TRIANG: ",
311 w
"internal error - unexpected cell index"
312 WRITE(
gridman_unit,*)
" II, N, NELEMENTS ",ii,n,nelements
315 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell)
319 IF(
ALLOCATED(ioldcell))
DEALLOCATE(ioldcell)
320 WRITE(
gridman_unit,*)
"GRIDMAN_GRID2D_TRIANG is terminated"
328 SUBROUTINE gridman_grid2d_triang_step(GRID,NCELLS_MAX,NEDGES_MAX,
329 c chains,ierr,ioldcell)
334 INTEGER(GRIDMAN_SP),
INTENT(IN) :: NCELLS_MAX,NEDGES_MAX
336 INTEGER,
INTENT(OUT) :: IERR
337 INTEGER(GRIDMAN_SP),
OPTIONAL :: IOLDCELL(ncells_max)
339 INTEGER(GRIDMAN_SP) :: ICELL,IPOINT(3),IP1,IP,IP2,I,N,ID,IE,IEDGE,
340 i ncells0,ncells,nedges,npmax,np,st
342 REAL(GRIDMAN_DP) :: VTVS,VTVT,STOT,MMCOS
343 REAL(GRIDMAN_DP) :: X(3),Y(3)
346 INTEGER(GRIDMAN_DP),
ALLOCATABLE :: IEP(:,:)
347 REAL(GRIDMAN_DP),
ALLOCATABLE :: VTV(:),S(:),MAXCOS(:)
350 f
WRITE(gridman_unit,*)
"Starting GRIDMAN_GRID2D_TRIANG_STEP"
357 np=chains%ILAST(icell)-chains%IFIRST(icell)
358 IF(np.GT.npmax) npmax=np
362 ALLOCATE(iep(3,npmax),vtv(npmax),s(npmax),maxcos(npmax),stat=st)
365 WRITE(gridman_unit,*)
"Erroor in GRIDMAN_GRID2D_TRIANG_STEP: ",
366 w
"can not allocate temporary arrays"
372 IF(ierr.GT.0)
GOTO 500
378 n=chains%ILAST(icell)-chains%IFIRST(icell)
383 ip1=chains%ILAST(icell)-1
384 DO ip=chains%IFIRST(icell),chains%ILAST(icell)-1
387 ipoint(1)=chains%IND(ip1)
388 ipoint(2)=chains%IND(ip)
389 ipoint(3)=chains%IND(ip+1)
390 x(1:3)=grid%X(1,ipoint(1:3))
391 y(1:3)=grid%X(2,ipoint(1:3))
392 vtvt=(x(2)-x(1))*(y(3)-y(2))-(x(3)-x(2))*(y(2)-y(1))
394 stot=stot+(x(3)+x(2))*(y(3)-y(2))
395 IF(self_intersections(ipoint(1),ipoint(3),icell))
THEN
401 iep(1:3,n)=ipoint(1:3)
405 s(n)=(x(3)+x(2))*(y(3)-y(2))+
406 + (x(2)+x(1))*(y(2)-y(1))+(x(1)+x(3))*(y(1)-y(3))
408 maxcos(n)=maximum_cosine(x,y)
409 IF(maxcos(n).LT.-1.0)
THEN
428 IF(( vtvs.LT.0.AND.vtv(i).GT.-tiny(vtvs)).OR.
429 f ( vtvs.GT.0.AND.vtv(i).LT.tiny(vtvs)).OR.
430 f abs(s(i)).GT.stot) cycle
431 IF(maxcos(i).LT.mmcos)
THEN
432 ipoint(1:3)=iep(1:3,i)
439 WRITE(gridman_unit,*)
"ERROR in GRIDMAN_GRID2_TRIANG_STEP: ",
440 w
"internal error - no new edges found"
441 WRITE(gridman_unit,*)
" ICELL, N ",icell,n
442 WRITE(gridman_unit,*)
" MAXCOS ",maxcos(1:n)
443 WRITE(gridman_unit,*)
" STOT, S ",stot,abs(s(1:n))
449 IF(ncells.GT.ncells_max.OR.nedges.GT.nedges_max)
THEN
451 WRITE(gridman_unit,*)
"ERROR in GRIDMAN_GRID2_TRIANG_STEP: ",
452 w
"internal error - index exceeds the maximum"
453 WRITE(gridman_unit,*)
" ICELL ",icell
454 WRITE(gridman_unit,*)
" NCELLS, NCELLS_MAX ",ncells,ncells_max
455 WRITE(gridman_unit,*)
" NEDGES, NEDGES_MAX ",nedges,nedges_max
458 grid%CELLS(1,nedges)=icell
459 grid%CELLS(2,nedges)=ncells
460 grid%POINTS(1,nedges)=ipoint(1)
461 grid%POINTS(2,nedges)=ipoint(3)
463 DO ie=cells%IFIRST(icell),cells%ILAST(icell)
465 IF(iedge.LT.1.OR.iedge.GT.nedges_max)
THEN
467 WRITE(gridman_unit,*)
"ERROR in GRIDMAN_GRID2_TRIANG_STEP: ",
468 w
"internal erorr - edge index out of range"
469 WRITE(gridman_unit,*)
" ICELL, IEDGE, NEDGES_MAX ",
470 w icell, iedge, nedges_max
472 ip1=grid%POINTS(1,iedge)
473 ip2=grid%POINTS(2,iedge)
475 IF((ip1.EQ.ipoint(i).AND.ip2.EQ.ipoint(i+1)).OR.
476 f (ip2.EQ.ipoint(i).AND.ip1.EQ.ipoint(i+1)))
THEN
477 IF(grid%CELLS(1,iedge).EQ.icell )
THEN
478 grid%CELLS(1,iedge)=ncells
480 ELSE IF(grid%CELLS(2,iedge).EQ.icell )
THEN
481 grid%CELLS(2,iedge)=ncells
485 WRITE(gridman_unit,*)
486 w
"ERROR in GRIDMAN_GRID2_TRIANG_STEP: ",
487 w
"internal erorr - cell index mismatch"
488 WRITE(gridman_unit,*)
" ICELL, IEDGE ",icell,iedge
489 WRITE(gridman_unit,*)
" IPOINT1, IPOINT2 ",
490 w ipoint(i),ipoint(i+1)
491 WRITE(gridman_unit,*)
" IP1, IP2 ",ip2,ip2
492 WRITE(gridman_unit,*)
" CELLS ",grid%CELLS(:,iedge)
500 IF(
PRESENT(ioldcell)) ioldcell(ncells)=ioldcell(icell)
503 DEALLOCATE(iep,vtv,s,maxcos,stat=st)
506 WRITE(gridman_unit,*)
507 w
"Warning from GRIDMAN_GRID2D_TRIANG_STEP ",
508 w
"could not deallocate temporary arrays"
513 f
WRITE(gridman_unit,*)
"GRIDMAN_GRID2_TRIANG_STEP finished"
517 500
DEALLOCATE(iep,vtv,s,maxcos,stat=st)
519 WRITE(gridman_unit,*)
"GRIDMAN_GRID2_TRIANG_STEP terminated"
522 END SUBROUTINE gridman_grid2d_triang_step
528 FUNCTION maximum_cosine(X,Y)
530 REAL(GRIDMAN_DP),
INTENT(IN) :: X(3),Y(3)
531 REAL(GRIDMAN_DP) :: MAXIMUM_COSINE
532 REAL(GRIDMAN_DP) :: VX(3),VY(3),V(3),CS
543 v(i)=sqrt(vx(i)**2+vy(i)**2)
544 IF(.NOT.v(i).GT.tiny(cs))
THEN
545 WRITE(gridman_unit,*)
"ERROR in GRIDMAN_GRID2_TRIANG: ",
546 w
"edge has zero length"
547 WRITE(gridman_unit,*)
" X ",x
549 WRITE(gridman_unit,*)
" Y ",y
557 cs=vx(i)*vx(i1)+vy(i)*vy(i1)
559 IF(cs.GT.maximum_cosine) maximum_cosine=cs
562 END FUNCTION maximum_cosine
565 FUNCTION self_intersections(IPOINT10,IPOINT20,ICELL)
568 INTEGER(GRIDMAN_SP),
INTENT(IN) :: IPOINT10,IPOINT20,ICELL
569 LOGICAL :: SELF_INTERSECTIONS
570 REAL(GRIDMAN_DP) :: X01,X02,Y01,Y02,X1,X2,Y1,Y2,XI,YI
571 INTEGER(GRIDMAN_SP) :: IP,IPOINT1,IPOINT2
573 x01=grid%X(1,ipoint10)
574 y01=grid%X(2,ipoint10)
575 x02=grid%X(1,ipoint20)
576 y02=grid%X(2,ipoint20)
577 DO ip=chains%IFIRST(icell),chains%ILAST(icell)-1
578 ipoint1=chains%IND(ip)
579 ipoint2=chains%IND(ip+1)
580 IF(ipoint1.EQ.ipoint10.OR.ipoint1.EQ.ipoint20.OR.
581 f ipoint2.EQ.ipoint10.OR.ipoint2.EQ.ipoint20) cycle
587 f x1,y1,x2,y2,xi,yi))
THEN
588 self_intersections=.true.
592 self_intersections=.false.
594 END FUNCTION self_intersections
subroutine gridman_grid_check(GRID, RES, IERR)
Check consistency of the grid data.
logical function gridman_intersect2d(X11, Y11, X12, Y12, X21, Y21, X22, Y22, XI, YI)
Intersection of two intervals on a plane.
subroutine gridman_indlist_allocate(INDLIST, N, L, IERR)
Allocate list of elements.
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_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_index_copy(INDEX2, INDEX1, IERR)
Create a copy of the index object.
subroutine gridman_grid_cells(EDGES, GRID, IERR)
Create a list of edges which belong to each cell.
subroutine gridman_grid_take(GRID2, GRID1, IERR)
Take data from one grid object to another.
subroutine gridman_grid2d_check(GRID, RES, IERR)
Check correctness of the 2D grid object.
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_grid2d_triang(TRIA, GRID, IERR)
Triangulation of 2D grid.
subroutine gridman_index_allocate(INDEX, NINDEX, NELEMENTS, IERR)
Allocate index object.
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.