GRIDMAN
grid managment library
template.f
Go to the documentation of this file.
1 C> @file convert/template.f
2 C> Converters of GRIDMAN_GRID object to and from simple template (DG template)
3 C GRIDMAN, grid managment library. Author: Vladislav Kotov, v.kotov@fz-juelich.de
4 
5 ! Copyright (c) 2017 Forschungszentrum Juelich GmbH
6 ! Vladislav Kotov
7 !
8 ! This file is part of GRIDMAN.
9 !
10 ! GRIDMAN is free software: you can redistribute it and/or modify
11 ! it under the terms of the GNU General Public License as published by
12 ! the Free Software Foundation, either version 3 of the License, or
13 ! (at your option) any later version.
14 !
15 ! GRIDMAN is distributed in the hope that it will be useful,
16 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ! GNU General Public License for more details.
19 !
20 ! You should have received a copy of the GNU General Public License
21 ! along with GRIDMAN. If not, see <http://www.gnu.org/licenses/>.
22 
23 C**********************************************************************************************
24 C> Convert data read from a file in simple template format (DG template) into GRIDMAN_GRID object
25 C**********************************************************************************************
26 C>
27 C> WARNING: object GRID will be overwritten if already exists
28 C>
29 C> The code tries to figure out if the polygone is closed or not. For
30 C> closed polygones last point of the chain is moved to the first point.
31 C> WARNING: single points are not taken into the grid object
32 C>
33 C> Edge index EDGEINDEX(1) contains index of polygons for each edge
34  SUBROUTINE gridman_template2grid(GRID,M,N,L,X,Y,IERR)
36  u gridman_dbg,gridman_unit,gridman_check,
37  u gridman_tol
40  IMPLICIT NONE
41  INTRINSIC abs
42 C> Resulting grid object
43  TYPE(gridman_grid) :: GRID
44 C> Number of polygons
45  INTEGER(GRIDMAN_SP),INTENT(IN) :: M
46 C> Number of vertices in each polygon
47  INTEGER(GRIDMAN_SP),INTENT(IN) :: N(m)
48 C> Total number of points, must be L=SUM(N)
49  INTEGER(GRIDMAN_SP),INTENT(IN) :: L
50 C> X coordinates of the vertices
51  REAL(GRIDMAN_DP),INTENT(IN) :: X(l)
52 C> Y coordinates of the vertices
53  REAL(GRIDMAN_DP),INTENT(IN) :: Y(l)
54 C> Error code
55  INTEGER,INTENT(OUT) :: IERR
56 
57  INTEGER(GRIDMAN_SP) :: L1,IP,IV,IL,IPOINT,IPOINT0,
58  i iedge,nedges,npoints
59  INTEGER :: IERR0,RES
60  REAL(GRIDMAN_DP) :: X1,Y1,X2,Y2
61 
62  IF(gridman_dbg)
63  w WRITE(gridman_unit,*) "Starting GRIDMAN_TEMPLATE2GRID"
64 
65  ierr=0
66 
67 C CHECK INPUT
68  IF(m.LT.1) THEN
69  WRITE(gridman_unit,*) "ERROR in GRIDMAN_TEMPLATE2GRID: ",
70  w "incorrect number of polygons, M ",m
71  ierr=100
72  RETURN
73  END IF
74 
75  l1=sum(n)
76  IF(l1.NE.l) THEN
77  WRITE(gridman_unit,*) "ERROR in GRIDMAN_TEMPLATE2GRID: ",
78  w "incorrect number of points - L=/=sum(N)"
79  WRITE(gridman_unit,*) "L, SUM(N) ",l,l1
80  ierr=100
81  RETURN
82  END IF
83 
84 C FIND, WHICH POLYGONS ARE CLOSED AND
85 C CALCULATE NUMBER OF POINTS AND EDGES
86  il=0
87  npoints=0
88  nedges=0
89  DO ip=1,m
90  IF(n(ip).GT.1) THEN !SINGLE POINTS ARE SKIPPED
91  x1=x(il+1)
92  y1=y(il+1)
93  x2=x(il+n(ip))
94  y2=y(il+n(ip))
95  IF(abs(x1-x2).GT.gridman_tol*(abs(x1)+abs(x2)).OR.
96  f abs(y1-y2).GT.gridman_tol*(abs(y1)+abs(y2))) THEN
97 C OPEN POLYGON
98  nedges=nedges+n(ip)-1
99  npoints=npoints+n(ip)
100  ELSE
101 C CLOSED POLYGON
102  IF(n(ip).LT.4) THEN
103  WRITE(gridman_unit,*) "ERROR in GRIDMAN_TEMPLATE2GRID: ",
104  w "close polygon must have at least 4 points"
105  WRITE(gridman_unit,*) " IP, N ",ip,n(ip)
106  ierr=100
107  RETURN
108  END IF
109  nedges=nedges+n(ip)-1
110  npoints=npoints+n(ip)-1
111  END IF
112  END IF !IF(N(IP).GT.1)
113  il=il+n(ip)
114  END DO
115 
116 C ALLOCATE GRID OBJECT
117  CALL gridman_grid_allocate(grid,2,nedges,npoints,
118  c 0_gridman_sp,ierr,1)
119  IF(ierr.NE.0) THEN
120  WRITE(gridman_unit,*) "GRIDMAN_TEMPLATE2GRID terminated"
121  RETURN
122  END IF
123  CALL gridman_index_allocate(grid%EDGEINDEX(1),1,nedges,ierr)
124  IF(ierr.NE.0) THEN
125  WRITE(gridman_unit,*) "ERROR in GRIDMAN_TEMPLATE2GRID: ",
126  w "cannot allocate index"
127  CALL gridman_grid_deallocate(grid,ierr0)
128  RETURN
129  END IF
130 
131 C DEFINE GRID OBJECT
132  il=0
133  iedge=0
134  ipoint=0
135  DO ip=1,m
136  IF(n(ip).GT.1) THEN !SINGLE POINTS ARE SKIPPED
137  x1=x(il+1)
138  y1=y(il+1)
139  x2=x(il+n(ip))
140  y2=y(il+n(ip))
141  IF(abs(x1-x2).GT.gridman_tol*(abs(x1)+abs(x2)).OR.
142  f abs(y1-y2).GT.gridman_tol*(abs(y1)+abs(y2))) THEN
143 C OPEN POLYGON
144  DO iv=1,n(ip)-1
145  iedge=iedge+1
146  IF(iedge.GT.nedges) GOTO 200
147  ipoint=ipoint+1
148  IF(ipoint.GT.npoints) GOTO 300
149  grid%X(1,ipoint)=x(il+iv)
150  grid%X(2,ipoint)=y(il+iv)
151  grid%POINTS(1,iedge)=ipoint
152  grid%POINTS(2,iedge)=ipoint+1
153  grid%EDGEINDEX(1)%INDEXES(0,iedge)=iedge
154  grid%EDGEINDEX(1)%INDEXES(1,iedge)=ip
155  END DO
156  ipoint=ipoint+1
157  IF(ipoint.GT.npoints) GOTO 300
158  grid%X(1,ipoint)=x(il+n(ip))
159  grid%X(2,ipoint)=y(il+n(ip))
160  ELSE
161 C CLOSED POLYGON
162  ipoint0=ipoint+1
163  DO iv=1,n(ip)-1
164  iedge=iedge+1
165  IF(iedge.GT.nedges) GOTO 200
166  ipoint=ipoint+1
167  IF(ipoint.GT.npoints) GOTO 300
168  grid%X(1,ipoint)=x(il+iv)
169  grid%X(2,ipoint)=y(il+iv)
170  grid%POINTS(1,iedge)=ipoint
171  grid%POINTS(2,iedge)=ipoint+1
172  grid%EDGEINDEX(1)%INDEXES(0,iedge)=iedge
173  grid%EDGEINDEX(1)%INDEXES(1,iedge)=ip
174  END DO
175  grid%POINTS(2,iedge)=ipoint0
176  END IF
177  END IF !IF(N(IP).GT.1)
178  il=il+n(ip)
179  END DO
180  grid%CELLS=0
181 
182 C UNITS
183  grid%UNIT2SI=1e-3_gridman_dp
184  grid%UNITS='MILLIMETER'
185 C DEFAULT DESCRIPTION
186  grid%DESCRIPTION='Converted from DG template'
187  grid%EDGEINDEX(1)%DESCRIPTION='Index of polygon'
188  grid%EDGEINDEX(1)%COLUMNS(1)='DG_IPOL'
189 
190 C CHECK
191  IF(gridman_check) THEN
192  CALL gridman_grid2d_check(grid,res,ierr)
193  IF(res.NE.0.OR.ierr.GT.0) THEN
194  ierr=100
195  WRITE(gridman_unit,*) "ERROR in GRIDMAN_TEMPLATE2GRID: ",
196  w "the resulting grid is incorrect"
197  GOTO 100
198  END IF
199  END IF
200 
201  IF(gridman_dbg)
202  w WRITE(gridman_unit,*) "GRIDMAN_TEMPLATE2GRID finished"
203 
204  RETURN
205  100 WRITE(gridman_unit,*) "GRIDMAN_TEMPLATE2GRID terminated"
206  CALL gridman_grid_deallocate(grid,ierr0)
207  RETURN
208  200 WRITE(gridman_unit,*) "ERROR in GRIDMAN_TEMPLATE2GRID: ",
209  w "internal error"
210  WRITE(gridman_unit,*)
211  w " Edge index is out of range, IEDGE, NEDGES ",iedge,nedges
212  ierr=400
213  CALL gridman_grid_deallocate(grid,ierr0)
214  RETURN
215  300 WRITE(gridman_unit,*) "ERROR in GRIDMAN_TEMPLATE2GRID: ",
216  w "internal error"
217  WRITE(gridman_unit,*)
218  w " Point index is out of range, IPOINT, NPOINTS ",
219  w ipoint, npoints
220  ierr=400
221  CALL gridman_grid_deallocate(grid,ierr0)
222  RETURN
223 
224  END SUBROUTINE gridman_template2grid
225 
226 C**********************************************************************************************
227 C> Convert GRIDMAN_GRID object into arrays which can be stored in simple template format
228 C> (DG template)
229 C**********************************************************************************************
230 C>
231 C> WARNING: arrays N, X, Y must NOT be allcoated -
232 C> they are allocated inside the subroutine.
233 C> Arrays which already exist will be re-allocated
234 C>
235 C> Each edge is stored as a separate polygon. This subroutine
236 C> does not try to build chains of points
237 C
238  SUBROUTINE gridman_grid2template(GRID,M,N,L,X,Y,IERR)
240  u gridman_dbg,gridman_unit,gridman_check
242  IMPLICIT NONE
243 C> Grid object to be converted
244  TYPE(gridman_grid) :: GRID
245 C> Number of polygons
246  INTEGER(GRIDMAN_SP),INTENT(OUT) :: M
247 C> Number of vertices in each polygon, N(M)
248  INTEGER(GRIDMAN_SP),ALLOCATABLE :: N(:)
249 C> Total number of points, L=SUM(N)
250  INTEGER(GRIDMAN_SP),INTENT(OUT) :: L
251 C> X coordinates of the vertices, X(L)
252  REAL(GRIDMAN_DP),ALLOCATABLE :: X(:)
253 C> Y coordinates of the vertices, Y(L)
254  REAL(GRIDMAN_DP),ALLOCATABLE :: Y(:)
255 C> Error code
256  INTEGER,INTENT(OUT) :: IERR
257 
258  INTEGER(GRIDMAN_SP) :: IEDGE,IP1,IP2,IL
259  INTEGER :: RES,ST
260  REAL(GRIDMAN_DP) :: FC
261 
262  IF(gridman_dbg)
263  w WRITE(gridman_unit,*) "Starting GRIDMAN_GRID2TEMPLATE"
264 
265  ierr=0
266  m=0
267  l=0
268 
269 C CHECK INPUT
270  IF(grid%TYPE.NE.2.OR.grid%PDIM.NE.2.OR.grid%EDIM.NE.2) THEN
271  ierr=100
272  WRITE(gridman_unit,*) "ERROR in GRIDMAN_GRID2TEMPLATE: ",
273  w "grid is not of 2D type"
274  RETURN
275  END IF
276 
277  IF(gridman_check) THEN
278  CALL gridman_grid2d_check(grid,res,ierr)
279  IF(res.NE.0.OR.ierr.GT.0) THEN
280  ierr=100
281  WRITE(gridman_unit,*) "ERROR in GRIDMAN_GRID2TEMPLATE: ",
282  w "the input grid is incorrect"
283  RETURN
284  END IF
285  END IF
286 
287 C ALLOCATE ARRAYS
288  m=grid%NEDGES
289  l=2*grid%NEDGES
290  IF(ALLOCATED(n)) DEALLOCATE(n,stat=st)
291  IF(ALLOCATED(x)) DEALLOCATE(x,stat=st)
292  IF(ALLOCATED(y)) DEALLOCATE(y,stat=st)
293  ALLOCATE(n(m),x(l),y(l),stat=st)
294  IF(st.NE.0) THEN
295  ierr=200
296  WRITE(gridman_unit,*) "ERROR in GRIDMAN_GRID2TEMPLATE: ",
297  w "cannon perform allocation M, L ",m,l
298  m=0
299  l=0
300  RETURN
301  END IF
302 
303 C ASSIGN POINTS
304  fc=grid%UNIT2SI*1e3_gridman_dp !TO TRANSFER INTO MM
305  il=0
306  DO iedge=1,m
307  n(iedge)=2
308  ip1=grid%POINTS(1,iedge)
309  ip2=grid%POINTS(2,iedge)
310  il=il+1
311  x(il)=grid%X(1,ip1)*fc
312  y(il)=grid%X(2,ip1)*fc
313  il=il+1
314  x(il)=grid%X(1,ip2)*fc
315  y(il)=grid%X(2,ip2)*fc
316  END DO
317 
318  IF(gridman_dbg)
319  w WRITE(gridman_unit,*) "GRIDMAN_GRID2TEMPLATE finished"
320 
321  END SUBROUTINE gridman_grid2template
322 
323 C**********************************************************************************************
324 C> Read from a simple template file (DG template) into GRIDMAN_GRID object
325 C>
326 C> WARNING: the GRID object will be overwritten if elready exists
327 C>
328 C> This subroutine is a shell for GRIDMAN_TEMPLATE_READ_ARRAY
329 C>
330 C> GRIDMAN_TEMPLATE_READ_ARRAY AND GRIDMAN_TEMPLATE_READ_GRID
331 C> are combined in the interface GRIDMAN_TEMPLATE_READ
332 C>
333 C**********************************************************************************************
334  SUBROUTINE gridman_template_read_grid(GRID,FNAME,IERR)
336  u gridman_dbg,gridman_unit
339  IMPLICIT NONE
340 C> Resulting grid object
341  TYPE(gridman_grid) :: GRID
342 C> String containing the name of input file
343  CHARACTER(*),INTENT(IN) :: FNAME
344 
345 C> Error code
346  INTEGER,INTENT(OUT) :: IERR
347 
348  INTEGER(GRIDMAN_SP) :: M,L
349  INTEGER :: ST
350  INTEGER(GRIDMAN_SP),ALLOCATABLE :: N(:)
351  REAL(GRIDMAN_DP),ALLOCATABLE :: X(:),Y(:)
352 
353  IF(gridman_dbg)
354  w WRITE(gridman_unit,*) "Starting GRIDMAN_TEMPLATE_READ_GRID"
355 
356  ierr=0
357 
358  CALL gridman_template_read_array(fname,m,n,l,x,y,ierr)
359  IF(ierr.NE.0) GOTO 100
360 
361  CALL gridman_template2grid(grid,m,n,l,x,y,ierr)
362  IF(ierr.NE.0) GOTO 200
363 
364  DEALLOCATE(n,stat=st)
365  DEALLOCATE(x,stat=st)
366  DEALLOCATE(y,stat=st)
367 
368  IF(gridman_dbg)
369  w WRITE(gridman_unit,*) "GRIDMAN_TEMPLATE_READ_GRID finished"
370  RETURN
371 
372  200 IF(ALLOCATED(n)) DEALLOCATE(n,stat=st)
373  IF(ALLOCATED(x)) DEALLOCATE(x,stat=st)
374  IF(ALLOCATED(y)) DEALLOCATE(y,stat=st)
375  100 WRITE(gridman_unit,*) "GRIDMAN_TEMPLATE_READ_GRID terminated"
376 
377  END SUBROUTINE gridman_template_read_grid
378 
379 C**********************************************************************************************
380 C> Write GRIDMAN_GRID object in a simple template format (DG template)
381 C>
382 C> This subroutine is a shell for GRIDMAN_TEMPLATE_WRITE_ARRAY,
383 C> it uses GRIDMAN_GRID2TEMPLATE to convert grid into template
384 C>
385 C> GRIDMAN_TEMPLATE_WRITE_ARRAY and GRIDMAN_TEMPLATE_WRITE_GRID
386 C> are combined in the interface GRIDMAN_TEMPLATE_WRITE
387 C**********************************************************************************************
388  SUBROUTINE gridman_template_write_grid(GRID,FNAME,IERR)
390  u gridman_dbg,gridman_unit
393  IMPLICIT NONE
394 C> Grid object to be written
395  TYPE(gridman_grid) :: GRID
396 C> String containing the name of input file
397  CHARACTER(*),INTENT(IN) :: FNAME
398 C> Error code
399  INTEGER,INTENT(OUT) :: IERR
400 
401  INTEGER(GRIDMAN_SP) :: M,L
402  INTEGER :: ST
403  INTEGER(GRIDMAN_SP),ALLOCATABLE :: N(:)
404  REAL(GRIDMAN_DP),ALLOCATABLE :: X(:),Y(:)
405 
406  IF(gridman_dbg)
407  w WRITE(gridman_unit,*) "Starting GRIDMAN_TEMPLATE_WRITE_GRID"
408 
409  ierr=0
410 
411  CALL gridman_grid2template(grid,m,n,l,x,y,ierr)
412  IF(ierr.NE.0) GOTO 100
413 
414  CALL gridman_template_write_array(fname,m,n,l,x,y,ierr)
415  IF(ierr.NE.0) GOTO 200
416 
417  DEALLOCATE(n,stat=st)
418  DEALLOCATE(x,stat=st)
419  DEALLOCATE(y,stat=st)
420 
421  IF(gridman_dbg)
422  w WRITE(gridman_unit,*) "GRIDMAN_TEMPLATE_WRITE_GRID finished"
423  RETURN
424 
425  200 IF(ALLOCATED(n)) DEALLOCATE(n,stat=st)
426  IF(ALLOCATED(x)) DEALLOCATE(x,stat=st)
427  IF(ALLOCATED(y)) DEALLOCATE(y,stat=st)
428  100 WRITE(gridman_unit,*) "GRIDMAN_TEMPLATE_WRITE_GRID terminated"
429 
430  END SUBROUTINE gridman_template_write_grid
integer, parameter, public gridman_dp
Kind parameter for real numbers.
Definition: gridman.f:93
Explicit interfaces to GRIDMAN subroutines and functions.
Definition: gridman.f:251
subroutine gridman_template_write_grid(GRID, FNAME, IERR)
Write GRIDMAN_GRID object in a simple template format (DG template)
Definition: template.f:389
subroutine gridman_grid_allocate(GRID, TYPE, NEDGES, NPOINTS, NCELLS, IERR, NEDGEINDEX, NCELLINDEX)
Allocate GRIDMAN_GRID object.
Definition: grid1.f:30
subroutine gridman_grid2d_check(GRID, RES, IERR)
Check correctness of the 2D grid object.
Definition: grid2d.f:37
Data-type which describes a grid as a set of edges, methods in grid.f.
Definition: gridman.f:168
subroutine gridman_template_read_array(FNAME, M, N, L, X, Y, IERR)
Read planar coordinates from a simple template file (DG template)
Definition: template.f:54
subroutine gridman_grid_deallocate(GRID, IERR)
Deallocate grid object.
Definition: grid1.f:184
subroutine gridman_index_allocate(INDEX, NINDEX, NELEMENTS, IERR)
Allocate index object.
Definition: index.f:28
subroutine gridman_grid2template(GRID, M, N, L, X, Y, IERR)
Convert GRIDMAN_GRID object into arrays which can be stored in simple template format (DG template) ...
Definition: template.f:239
subroutine gridman_template_write_array(FNAME, M, N, L, X, Y, IERR)
Write coordinates into simple template file (DG template)
Definition: template.f:243
Definition of data types, global constants and variables.
Definition: gridman.f:83
subroutine gridman_template2grid(GRID, M, N, L, X, Y, IERR)
Convert data read from a file in simple template format (DG template) into GRIDMAN_GRID object...
Definition: template.f:35
integer, parameter, public gridman_sp
Kind parameter for integer numbers.
Definition: gridman.f:95
subroutine gridman_template_read_grid(GRID, FNAME, IERR)
Read from a simple template file (DG template) into GRIDMAN_GRID object.
Definition: template.f:335