GRIDMAN
grid managment library
cutgrid.f
Go to the documentation of this file.
1 C> @file apps/cutgrid.f
2 C> Cut part of the grid inside or outside a contour
3 C>
4 C> Based on GRIDMAN library
5 C Author: Vladislav Kotov, v.kotov@fz-juelich.de
6 
7 ! Copyright (c) 2017 Forschungszentrum Juelich GmbH
8 ! Vladislav Kotov
9 !
10 ! This file is part of GRIDMAN.
11 !
12 ! GRIDMAN is free software: you can redistribute it and/or modify
13 ! it under the terms of the GNU General Public License as published by
14 ! the Free Software Foundation, either version 3 of the License, or
15 ! (at your option) any later version.
16 !
17 ! GRIDMAN is distributed in the hope that it will be useful,
18 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ! GNU General Public License for more details.
21 !
22 ! You should have received a copy of the GNU General Public License
23 ! along with GRIDMAN. If not, see <http://www.gnu.org/licenses/>.
24 
25  PROGRAM cutgrid
26 
28  u gridman_unit,gridman_tol
29  USE gridman_lib,ONLY:gridman_grid_read,gridman_grid_write,
31  IMPLICIT NONE
32  INTRINSIC len_trim,get_command_argument,adjustl,trim
33 
34  INTERFACE
35 C
36  SUBROUTINE cutgrid_read_contour(CONTOUR_IN,UNIT2METER,XP,YP,NP)
38  CHARACTER(LEN=256),INTENT(IN) :: contour_in
39  REAL(GRIDMAN_DP),INTENT(IN) :: unit2meter
40  INTEGER(GRIDMAN_SP),INTENT(OUT) :: np
41  REAL(GRIDMAN_DP),ALLOCATABLE :: xp(:),yp(:)
42  END SUBROUTINE cutgrid_read_contour
43 C
44  SUBROUTINE cutrgrid_mergeindex(GRID,IEIND)
45  USE gridman,ONLY:gridman_grid
46  TYPE(gridman_grid) :: grid
47  INTEGER,INTENT(IN) :: ieind
48  END SUBROUTINE cutrgrid_mergeindex
49 
50  END INTERFACE
51 
52 C INPUT PARAMETERS
53  CHARACTER(LEN=256) :: description,
54  c grid_in,contour_in,grid_out
55  LOGICAL :: lexclude,dbgmod,lcheck
56  REAL(GRIDMAN_DP) :: unit2meter,tol
57 C LOCAL
58  TYPE(gridman_grid) :: grid0,grid1
59  INTEGER(GRIDMAN_SP) :: np
60  INTEGER ::ieind
61  INTEGER :: lt,ierr
62  REAL(GRIDMAN_DP),ALLOCATABLE :: xp(:),yp(:)
63  CHARACTER(LEN=8) :: ftmp
64 
65  CALL get_command_argument(1,ftmp)
66  IF(len_trim(ftmp).GT.0) THEN
67  IF(adjustl(trim(ftmp)).EQ.'help') THEN
68  CALL print_description
69  stop
70  END IF
71  ELSE
72 C 1. READ INPUT FROM NAMELIST
73  CALL read_input
74  END IF
75 
76 C 2. READ INPUT GRID
77  lt=len_trim(grid_in)
78  IF(lt.GT.0) THEN
79  WRITE(gridman_unit,*) "CUTGRID: reading file ",grid_in(1:lt)
80  CALL gridman_grid_read(grid0,grid_in,ierr)
81  IF(ierr.GT.0) CALL cutgrid_error("")
82  ELSE
83  CALL cutgrid_error("GRID_IN is not defined")
84  END IF
85 
86 C 3. READ CONTOUR
87  CALL cutgrid_read_contour(contour_in,unit2meter,xp,yp,np)
88 
89 C 4. PERFORM CUT
90  WRITE(gridman_unit,*) "CUTGRID: cut the grid"
91  CALL gridman_grid2d_cut(grid1,grid0,xp,yp,np,lexclude,ierr)
92  IF(ierr.GT.0) CALL cutgrid_error("")
93  lt=len_trim(description)
94  IF(lt.GT.0) grid1%DESCRIPTION=description
95 
96 C 5. MERGE INDEXES
97  IF(ieind.GT.0.AND.
98  f grid1%NEDGEINDEX.GT.grid0%NEDGEINDEX) THEN
99  WRITE(gridman_unit,*) "CUTGRID: merging edge indexes"
100  CALL cutrgrid_mergeindex(grid1,ieind)
101  END IF
102 
103 C 6. WRITE GRID
104  lt=len_trim(grid_out)
105  IF(lt.GT.0) THEN
106  WRITE(gridman_unit,*) "CUTGRID: writing file ",grid_out(1:lt)
107  CALL gridman_grid_write(grid1,grid_out,ierr)
108  IF(ierr.NE.0) CALL cutgrid_error("")
109  END IF
110 
111  CALL gridman_grid_deallocate(grid0,ierr)
112  CALL gridman_grid_deallocate(grid1,ierr)
113 
114  WRITE(gridman_unit,*) "CUTGRID COMPLETED"
115 
116  CONTAINS
117 
118 C********************************************************************
119 C Read namelist from standard input
120 C********************************************************************
121  SUBROUTINE read_input
122  namelist /cutgrid/ description,grid_in,grid_out,contour_in,
123  n lexclude,ieind,dbgmod,lcheck,tol,unit2meter
124  INTEGER :: io
125 
126  description=''
127  grid_in=''
128  contour_in=''
129  grid_out=''
130  lexclude=.false.
131  ieind=-1
132  dbgmod=.false.
133  lcheck=.false.
134  tol=-1.
135  unit2meter=-1.
136 
137  rewind(5)
138  READ(5,nml=cutgrid,iostat=io)
139  IF(io.NE.0) CALL cutgrid_error("can not read namelist CUTGRID")
140 
141  IF(tol.GT.0) gridman_tol=tol
142 
143  END SUBROUTINE read_input
144 
145 C
146  SUBROUTINE print_description
147  USE gridman,ONLY:gridman_dbg
148  INTRINSIC index,len,trim
149  INTEGER,PARAMETER :: file_length=1024
150  CHARACTER(LEN=FILE_LENGTH) :: path
151  CHARACTER(LEN=128) :: str
152  INTEGER :: i,io
153  CALL get_command_argument(0,path)
154  i=index(path,'/',.true.)
155  IF(i.GT.len(path)) THEN
156  path=''
157  ELSE
158  path=path(1:i)
159  END IF
160 
161  IF(gridman_dbg) WRITE(gridman_unit,*) " PATH:",trim(path)
162 
163  OPEN(unit=3,file=trim(path)//'cutgrid.parameters.description',
164  o status='OLD',iostat=io)
165  IF(io.NE.0) GOTO 100
166 
167  DO
168  READ(3,'(A)',iostat=io,end=200) str
169  IF(io.NE.0) GOTO 200
170  WRITE(*,*) trim(str)
171  END DO
172  200 RETURN
173 
174  100 WRITE(gridman_unit,*)
175  w "Could not find cutgrid.parameters.description",
176  w trim(path)
177  WRITE(gridman_unit,*)
178  w "Use 'which cutgrid' to invoke via the full path"
179 
180  END SUBROUTINE print_description
181 
182  END PROGRAM cutgrid
183 
184 C***************************************************************************************
185 C Read contour
186 C***************************************************************************************
187  SUBROUTINE cutgrid_read_contour(CONTOUR_IN,UNIT2METER,XP,YP,NP)
189  USE gridman_lib,ONLY:gridman_template_read
190  IMPLICIT NONE
191  INTRINSIC len_trim,abs,tiny
192 
193  CHARACTER(LEN=256),INTENT(IN) :: contour_in
194  REAL(GRIDMAN_DP),INTENT(IN) :: unit2meter
195  INTEGER(GRIDMAN_SP),INTENT(OUT) :: np
196  REAL(GRIDMAN_DP),ALLOCATABLE :: xp(:),yp(:)
197 
198  INTEGER(GRIDMAN_SP),ALLOCATABLE :: n(:)
199  REAL(GRIDMAN_DP),ALLOCATABLE :: x0(:),y0(:)
200  REAL(GRIDMAN_DP) :: dx,dy
201  INTEGER(GRIDMAN_SP) :: m,l,n0
202  INTEGER :: lt,st,ierr
203 
204  lt=len_trim(contour_in)
205  IF(lt.GT.0) THEN
206  WRITE(gridman_unit,*) "CUTGRID: reading file ",contour_in(1:lt)
207  CALL gridman_template_read(contour_in,m,n,l,x0,y0,ierr)
208  IF(ierr.GT.0) CALL cutgrid_error("")
209  IF(m.GT.1) THEN
210  WRITE(gridman_unit,*) "WARNING from CUTGRID:"
211  WRITE(gridman_unit,*)
212  w " more then one contour is defined in the file ",
213  w contour_in(1:lt)
214  WRITE(gridman_unit,*) " First contour will be taken"
215  END IF
216  n0=n(1)
217  dx=gridman_tol*(abs(x0(1))+abs(x0(n0)))+10.*tiny(dx)
218  dy=gridman_tol*(abs(y0(1))+abs(y0(n0)))+10.*tiny(dy)
219  IF( abs(x0(1)-x0(n0)).GT.dx.OR.
220  f abs(y0(1)-y0(n0)).GT.dy) THEN
221 C THE CONTOUR IS NOT CLOSED, ONE MORE POINT WILL BE ADDED
222  np=n0+1
223  ELSE
224  np=n0
225  END IF
226  ALLOCATE(xp(np),yp(np),stat=st)
227  IF(st.NE.0) THEN
228  WRITE(gridman_unit,*) " NP ",np
229  CALL cutgrid_error("Cannot allocate temporary arrays")
230  END IF
231  IF(unit2meter.GT.0.) THEN
232  xp(1:n0)=x0(1:n0)*unit2meter
233  yp(1:n0)=y0(1:n0)*unit2meter
234  ELSE
235  WRITE(gridman_unit,*) "WARNING from CUTGRID: ",
236  w " UNIT2METER is not defined"
237  WRITE(gridman_unit,*)
238  w " I assume that the coordinates in file ",contour_in(1:lt)
239  WRITE(gridman_unit,*) " are defined in Millimeter"
240  xp(1:n0)=x0(1:n0)*1e-3
241  yp(1:n0)=y0(1:n0)*1e-3
242  END IF
243  IF(np.GT.n0) THEN
244 C CLOSE THE CONTOUR
245  xp(np)=xp(1)
246  yp(np)=yp(1)
247  WRITE(gridman_unit,*)
248  w "CUTGRID: point added to close the contour"
249  END IF
250  DEALLOCATE(n,x0,y0)
251  ELSE
252  CALL cutgrid_error("CONTOUR_IN is not defined")
253  END IF !IF(LT.GT.0) THEN
254 
255  END SUBROUTINE cutgrid_read_contour
256 
257 
258 C***************************************************************************************
259 C Merge selected edge index into indexes of the polygon segments
260 C***************************************************************************************
261  SUBROUTINE cutrgrid_mergeindex(GRID,IEIND)
264  IMPLICIT NONE
265  INTRINSIC trim
266  TYPE(gridman_grid) :: grid
267  INTEGER,INTENT(IN) :: ieind
268 
269  TYPE(gridman_index) :: ind1,indseg,ind0,
270  t indtmp(grid%NEDGEINDEX)
271  INTEGER :: ierr
272 
273 C After call of cutgrid the last index is the
274 C index of the polygon segments, otherwise
275 C this subroutine is not called at all
276  indseg=grid%EDGEINDEX(grid%NEDGEINDEX)
277  IF(ieind.LT.1.OR.ieind.GT.grid%NEDGEINDEX) THEN
278  WRITE(gridman_unit,*) " IEIND, NEDGEINDEX ",
279  w ieind, grid%NEDGEINDEX
280  CALL cutgrid_error("IEIND is out of range")
281  END IF
282  ind0=grid%EDGEINDEX(ieind)
283  IF(ind0%NINDEX.NE.1) THEN
284  WRITE(gridman_unit,*) " NINDEX ",ind0%NINDEX
285  CALL cutgrid_error("NINDEX of IEIND must be 1")
286  END IF
287 
288  CALL gridman_index_merge(ind1,indseg,ind0,ierr)
289  IF(ierr.NE.0) CALL cutgrid_error("")
290 
291 C Move indices
292  indtmp=grid%EDGEINDEX
293  DEALLOCATE(grid%EDGEINDEX)
294  ALLOCATE(grid%EDGEINDEX(grid%NEDGEINDEX+1))
295  grid%EDGEINDEX(1)=ind1
296  grid%EDGEINDEX(2:grid%NEDGEINDEX+1)=indtmp
297  grid%NEDGEINDEX=grid%NEDGEINDEX+1
298 
299  END SUBROUTINE cutrgrid_mergeindex
300 
301 C***************************************************************************************
302 C Print error message and exit
303 C***************************************************************************************
304  SUBROUTINE cutgrid_error(STR)
305  USE gridman,ONLY:gridman_unit
306  IMPLICIT NONE
307  CHARACTER(*),INTENT(IN) :: str
308  INTEGER :: lt
309  INTRINSIC len_trim
310  lt=len_trim(str)
311  IF(lt.GT.0)
312  w WRITE(gridman_unit,*) "ERROR in CUTGRID: "//str(1:lt)
313  stop "ERROR in CUTGRID - see log output"
314  END SUBROUTINE cutgrid_error
integer, save, public gridman_unit
Index of the standard output unit.
Definition: gridman.f:116
real(gridman_dp), save, public gridman_tol
Tolerance parameter which is used to compare two real numbers.
Definition: gridman.f:127
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_grid2d_cut(CUTGRID, GRID, XP, YP, NP, LEX, IERR)
Select part of a 2D grid cut by polygon.
Definition: cut.f:38
Data-type which describes a grid as a set of edges, methods in grid.f.
Definition: gridman.f:168
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
logical, save, public gridman_dbg
Switch for debugging mode.
Definition: gridman.f:122
Data-type which stores indices defined on the grid cells or edges.
Definition: gridman.f:144
subroutine print_description
Print manual.
Definition: convgrid.f:690
subroutine gridman_index_merge(INDEX, INDEX1, INDEX2, IERR)
Merge INDEX2 into INDEX1.
Definition: index.f:880
Definition of data types, global constants and variables.
Definition: gridman.f:83
integer, parameter, public gridman_sp
Kind parameter for integer numbers.
Definition: gridman.f:95