Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/GlaDSchannelSolver.F90
3204 views
1
! !/*****************************************************************************/
2
!
3
! * Elmer/Ice, a glaciological add-on to Elmer
4
! * http://elmerice.elmerfem.org
5
! *
6
! *
7
! * This program is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU General Public License
9
! * as published by the Free Software Foundation; either version 2
10
! * of the License, or (at your option) any later version.
11
! *
12
! * This program is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
! * GNU General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU General Public License
18
! * along with this program (in file fem/GPL-2); if not, write to the
19
! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
! * Boston, MA 02110-1301, USA.
21
! *
22
! *****************************************************************************/
23
! ******************************************************************************
24
! *
25
! * Authors: Olivier Gagliardini, Mauro Werder, Mondher Chekki
26
! * Email: [email protected], [email protected]
27
! * Web: http://www.csc.fi/elmer
28
! * Address: CSC - Scientific Computing Ltd.
29
! * Keilaranta 14
30
! * 02101 Espoo, Finland
31
! *
32
! * Original Date: 15 February 2013
33
! *
34
! *****************************************************************************/
35
36
37
! *****************************************************************************/
38
!> Save output files for the Channels
39
!> To be used with the GlaDSCoupledSolver
40
!> Solver section also used to declare the Channel Area variable
41
!> Need to be executed with the "Exec Solver = After Saving" option
42
RECURSIVE SUBROUTINE GlaDSchannelOut( Model,Solver,Timestep,TransientSimulation )
43
!******************************************************************************
44
!
45
! ARGUMENTS:
46
!
47
! TYPE(Model_t) :: Model,
48
! INPUT: All model information (mesh,materials,BCs,etc...)
49
!
50
! TYPE(Solver_t) :: Solver
51
! INPUT: Linear equation solver options
52
!
53
! REAL(KIND=dp) :: Timestep
54
! INPUT: Timestep size for time dependent simulations
55
!
56
!******************************************************************************
57
USE Differentials
58
USE MaterialModels
59
USE DefUtils
60
61
!------------------------------------------------------------------------------
62
IMPLICIT NONE
63
!------------------------------------------------------------------------------
64
!------------------------------------------------------------------------------
65
! External variables
66
!------------------------------------------------------------------------------
67
TYPE(Model_t) :: Model
68
TYPE(Solver_t), TARGET :: Solver
69
LOGICAL :: TransientSimulation
70
REAL(KIND=dp) :: Timestep
71
!------------------------------------------------------------------------------
72
! Local variables
73
!------------------------------------------------------------------------------
74
TYPE(Nodes_t) :: ElementNodes, EdgeNodes
75
TYPE(Element_t), POINTER :: Element, Edge
76
77
TYPE(Variable_t), POINTER :: TimeVar
78
TYPE(Variable_t), POINTER :: HydPotSol, AreaSol, QcSol, QmSol
79
INTEGER, POINTER :: NodeIndexes(:), HydPotPerm(:), &
80
AreaPerm(:), QcPerm(:), QmPerm(:)
81
REAL(KIND=dp), POINTER :: HydPot(:), AreaSolution(:), QcSolution(:), QmSolution(:)
82
83
TYPE(ValueList_t), POINTER :: BC, Constants
84
85
INTEGER :: i, j, k, l, m, n, t, iter, body_id, eq_id, material_id, &
86
istat, LocalNodes, bc_id, DIM, NodeSheet, EdgeSheet, NbMoulin, NbMoulinAll, &
87
GhostNodes, it, itOut, ierr, ChannelSolver
88
INTEGER, ALLOCATABLE :: TableNodeSheet(:), TableMoulin(:)
89
90
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName, HydPotName, &
91
OutPutFileName, nit
92
93
LOGICAL :: Found, AllocationsDone = .FALSE., SubroutineVisited = .FALSE., &
94
FirstTime = .TRUE., FirstVisit = .TRUE.
95
96
INTEGER, PARAMETER :: PVtuUnit=1300
97
INTEGER :: VtuUnit, offset, Cpt, kk
98
INTEGER, ALLOCATABLE :: EdgePointArray(:), EdgeOffsetArray(:), EdgeTypeArray(:)
99
100
LOGICAL :: SaveVTU=.False. , VtuBinary=.False., FileVTU = .FALSE., OutPutQm = .FALSE., Calving = .FALSE.
101
102
CHARACTER :: lf
103
CHARACTER(LEN=1024) :: OutStr
104
CHARACTER(MAX_NAME_LEN) :: proc_number, number_procs, VtuFile, PVtuFile, VtuFormat, VtuFileFormat, OutPutDirectoryName
105
CHARACTER(MAX_NAME_LEN) :: ChFluxVarName, ChAreaVarName, QmVarName
106
107
REAL(KIND=dp) , ALLOCATABLE :: tmparray(:,:), Flux(:)
108
REAL(KIND=dp) , ALLOCATABLE :: NodePointArray(:), ChannelAreaArray(:), ChannelFluxArray(:), MoulinInputArray(:)
109
110
LOGICAL, ALLOCATABLE :: IsGhostNode(:)
111
112
REAL(KIND=dp) :: x, y, z
113
114
SAVE &
115
ElementNodes, EdgeNodes, &
116
IsGhostNode, OutPutFileName, OutPutDirectoryName, FileVTU, VtuBinary, it, itOut, &
117
AllocationsDone, FirstTime, FirstVisit, SolverName, HydPotName, M, &
118
NodeSheet, TableNodeSheet, EdgeSheet, NbMoulin, TableMoulin, OutPutQm, Flux, &
119
ChFluxVarName, ChAreaVarName, QmVarName, ChannelSolver
120
121
!------------------------------------------------------------------------------
122
! Get variables needed for solution
123
!------------------------------------------------------------------------------
124
SolverName = 'GlaDSchannelOut ('// TRIM(Solver % Variable % Name) // ')'
125
!CHANGE - to get Channel variables added to this solver mesh if
126
!doing calving and hydrology and consequently having many meshes
127
Calving = ListGetLogical(Model % Simulation, 'Calving', Found)
128
IF(.NOT. Found) Calving = .FALSE.
129
IF(Calving) THEN
130
IF(FirstVisit) THEN
131
DO i=1,Model % NumberOfSolvers
132
IF(Model % Solvers(i) % Variable % Name == 'hydraulic potential') THEN
133
ChannelSolver = i
134
EXIT
135
END IF
136
END DO
137
AreaSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&
138
% Variables, 'Channel Area', ThisOnly=.TRUE.)
139
IF (ASSOCIATED(AreaSol)) THEN
140
AreaPerm => AreaSol % Perm
141
AreaSolution => AreaSol % Values
142
END IF
143
LocalNodes = COUNT( AreaPerm > 0 )
144
IF ( LocalNodes <= 0 ) RETURN
145
ELSE
146
AreaSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&
147
% Variables, 'Channel Area', ThisOnly=.TRUE.)
148
IF (ASSOCIATED(AreaSol)) THEN
149
AreaPerm => AreaSol % Perm
150
AreaSolution => AreaSol % Values
151
END IF
152
LocalNodes = COUNT( AreaPerm > 0 )
153
IF ( LocalNodes <= 0 ) RETURN
154
END IF
155
ELSE
156
AreaSol => Solver % Variable
157
AreaPerm => AreaSol % Perm
158
AreaSolution => AreaSol % Values
159
160
LocalNodes = COUNT( AreaPerm > 0 )
161
IF ( LocalNodes <= 0 ) RETURN
162
END IF
163
164
DIM = CoordinateSystemDimension()
165
166
!------------------------------------------------------------------------------
167
! Allocate some permanent storage, this is done first time only
168
!------------------------------------------------------------------------------
169
IF ( .NOT. AllocationsDone .OR. Solver % Mesh % Changed ) THEN
170
N = Solver % Mesh % MaxElementNodes
171
M = Solver % Mesh % NumberOfNodes
172
173
IF ( AllocationsDone ) THEN
174
DEALLOCATE( &
175
ElementNodes % x, &
176
ElementNodes % y, &
177
ElementNodes % z, &
178
EdgeNodes % x, &
179
EdgeNodes % y, &
180
EdgeNodes % z, &
181
IsGhostNode, &
182
TableNodeSheet, TableMoulin, Flux )
183
END IF
184
185
ALLOCATE( &
186
ElementNodes % x( N ), &
187
ElementNodes % y( N ), &
188
ElementNodes % z( N ), &
189
EdgeNodes % x( N ), &
190
EdgeNodes % y( N ), &
191
EdgeNodes % z( N ), &
192
IsGhostNode( M ), &
193
TableNodeSheet(M), TableMoulin(M), Flux(M), &
194
STAT=istat )
195
196
IF ( istat /= 0 ) THEN
197
CALL FATAL( SolverName, 'Memory allocation error' )
198
ELSE
199
CALL INFO(SolverName, 'Memory allocation done', level=1 )
200
END IF
201
202
IF ( ParEnv % PEs > 1 ) THEN !only if we have a parallel run
203
IsGhostNode( 1:M ) = .FALSE.
204
GhostNodes = 0
205
DO t=1,Solver % NumberOfActiveElements
206
Element => GetActiveElement(t)
207
IF (ParEnv % myPe .EQ. Element % partIndex) CYCLE
208
DO i=1,GetElementNOFNodes(Element)
209
IsGhostNode(Element % NodeIndexes(i)) = .TRUE.
210
GhostNodes = GhostNodes + 1
211
END DO
212
END DO
213
PRINT *, ParEnv % myPe, ':', GhostNodes, ' ghost nodes'
214
END IF
215
216
AllocationsDone = .TRUE.
217
END IF
218
219
IF (FirstVisit) THEN
220
FirstVisit = .FALSE.
221
Constants => GetConstants()
222
HydPotName = GetString( Constants, &
223
'Hydraulic Potential Variable Name', Found )
224
IF(.NOT.Found) THEN
225
CALL WARN(SolverName,'Keyword >Hydraulic Potential Variable Name< not found in section Constants')
226
CALL WARN(SolverName,'Taking default value >Hydraulic Potential<')
227
WRITE(HydPotName,'(A)') 'Hydraulic Potential'
228
END IF
229
ChAreaVarName = GetString( Constants, &
230
'Channel Area Variable Name', Found )
231
IF(.NOT.Found) THEN
232
CALL WARN(SolverName,'Keyword >Channel Area Variable Name< not found in section Constants')
233
CALL WARN(SolverName,'Taking default value >Channel Area<')
234
WRITE(ChAreaVarName,'(A)') 'Channel Area'
235
END IF
236
WRITE(QmVarName,'(A)') 'Flux from Moulins'
237
WRITE(ChFluxVarName,'(A)') 'Channel Flux'
238
END IF
239
240
! Point on the needed variables
241
!CHANGE - to avoid interpolation of variables between solvers when calving
242
IF(Calving) THEN
243
HydPotSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&
244
% Variables, HydPotName, ThisOnly=.TRUE.)
245
HydPotPerm => HydPotSol % Perm
246
HydPot => HydPotSol % Values
247
QcSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&
248
% Variables, ChFluxVarName)
249
IF (ASSOCIATED(QcSol)) THEN
250
QcPerm => QcSol % Perm
251
QcSolution => QcSol % Values
252
END IF
253
QmSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&
254
% Variables, QmVarName)
255
IF (ASSOCIATED(QmSol)) THEN
256
QmPerm => QmSol % Perm
257
QmSolution => QmSol % Values
258
END IF
259
ELSE
260
QcSol => VariableGet( Solver % Mesh % Variables, ChFluxVarName )
261
IF (ASSOCIATED(QcSol)) THEN
262
QcPerm => QcSol % Perm
263
QcSolution => QcSol % Values
264
END IF
265
266
QmSol => VariableGet( Solver % Mesh % Variables, QmVarName )
267
IF (ASSOCIATED(QmSol)) THEN
268
QmPerm => QmSol % Perm
269
QmSolution => QmSol % Values
270
END IF
271
272
HydPotSol => VariableGet(Solver % Mesh % Variables, HydPotName,&
273
UnfoundFatal=.TRUE.)
274
HydPotPerm => HydPotSol % Perm
275
HydPot => HydPotSol % Values
276
END IF
277
278
TimeVar => VariableGet( Solver % Mesh % Variables, 'Time' )
279
IF (FirstTime) THEN
280
FirstTime = .FALSE.
281
itOut = 0
282
it = 0
283
FileVTU = GetLogical( Solver % Values, 'VTU OutPutFile' )
284
VtuBinary = GetLogical( Solver % Values, 'VTU BinaryFile')
285
286
IF (FileVTU) THEN
287
OutPutDirectoryName = GetString( Solver % Values, 'Channels OutPut Directory Name', Found )
288
IF (.NOT.Found) THEN
289
WRITE(Message,'(a)') 'Keyword > Channels OutPut Directory Name < not found'
290
WRITE(Message,'(a)') 'Output Files will be created in the .sif Directory'
291
END IF
292
OutPutFileName = GetString( Solver % Values, 'Channels OutPut File Name', Found )
293
IF (.NOT.Found) THEN
294
WRITE(Message,'(a)') 'Keyword > Channels OutPut File Name < not found'
295
CALL FATAL(SolverName, Message)
296
END IF
297
END IF
298
299
! Save some information regarding the mesh for VTU output
300
! Number of nodes in the sheet layer: NodeSheet
301
! Number of channels (edges) in the sheet layer: EdgeSheet
302
! Permutation table for the NodeSheet nodes and global nodes
303
IF (FileVTU) THEN
304
NodeSheet = 0
305
TableNodeSheet = 0
306
DO i = 1, Model % NumberOfNodes
307
IF (HydPotPerm(i)>0) THEN
308
NodeSheet = NodeSheet + 1
309
TableNodeSheet(i) = NodeSheet
310
END IF
311
END DO
312
313
EdgeSheet = 0
314
DO t=1, Solver % Mesh % NumberOfEdges
315
Edge => Solver % Mesh % Edges(t)
316
n = Edge % TYPE % NumberOfNodes
317
IF (.NOT.ASSOCIATED(Edge)) CYCLE
318
IF (ParEnv % PEs > 1) THEN
319
IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE
320
END IF
321
IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE
322
EdgeSheet = EdgeSheet + 1
323
END DO
324
WRITE(Message,'(a,i0)')'Number of Channels (edges): ', EdgeSheet
325
CALL INFO(SolverName, Message, level=3 )
326
WRITE(Message,'(a,i0)')'Number of nodes in the sheet layer: ', NodeSheet
327
CALL INFO(SolverName, Message, level=3 )
328
329
NbMoulin = 0
330
TableMoulin = 0
331
! Moulins are located on 101 Boundary elements
332
DO t=1, Solver % Mesh % NumberOfBoundaryElements
333
Element => GetBoundaryElement(t)
334
! IF ( .NOT.ActiveBoundaryElement() ) CYCLE
335
IF (ParEnv % PEs > 1) THEN
336
IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE
337
END IF
338
n = GetElementNOFNodes()
339
340
IF ( GetElementFamily() > 1 ) CYCLE
341
NbMoulin = NbMoulin + 1
342
j = Element % NodeIndexes(1)
343
TableMoulin(j) = NbMoulin
344
END DO
345
OutPutQm = .FALSE.
346
IF ((NbMoulin>0).AND.(.Not.ASSOCIATED(QmSol))) THEN
347
WRITE(Message,'(i0,a,i0)') &
348
NbMoulin, 'moulins found, but not variable >Flux from Moulins< associated, part ',ParEnv%myPe
349
CALL INFO(SolverName, Message, level=1 )
350
ELSE IF (NbMoulin==0) THEN
351
WRITE(Message,'(a,i0)')'No moulin found, part ',ParEnv%myPe
352
CALL INFO(SolverName, Message, level=3 )
353
ELSE
354
WRITE(Message,'(a,i0,a,i0)')'Qm will be saved for ',NbMoulin,' moulins in part ',ParEnv%myPe
355
CALL INFO(SolverName, Message, level=3 )
356
OutPutQm = .TRUE.
357
END IF
358
END IF
359
END IF ! FirstTime
360
361
! Check the number of moulins on all partitions
362
CALL MPI_ALLREDUCE( NbMoulin, NbMoulinAll, 1, MPI_INTEGER, &
363
MPI_SUM, ELMER_COMM_WORLD, ierr )
364
WRITE(Message,'(a,i0,a)')'Qm will be saved for ',NbMoulinAll,' moulins in total'
365
CALL INFO(SolverName, Message, level=3 )
366
367
! If we are here, it means we have to save
368
! assuming Exec Solver = After Saving is set in the solver section
369
! number of file is incremented by one
370
itOut = itOut + 1
371
372
SaveVTU = FileVTU
373
374
CALL Info( SolverName, ' Channels Output will be saved ', Level=4 )
375
376
WRITE(Message,'(A,D15.7)')' Maximum Channel Area: ', &
377
MAXVAL(AreaSolution(AreaPerm(M+1:M+Solver%Mesh%NumberOfEdges)))
378
CALL INFO(SolverName, Message, level=4 )
379
380
! Save results in VTU Format
381
IF (SaveVTU) THEN
382
lf = CHAR(10)
383
WRITE(nit,'(i4.4)')itOut
384
nit = ADJUSTL(nit)
385
386
IF ( ParEnv%PEs >1 ) THEN
387
WRITE(proc_number,'(i4.4)') ParEnv%myPe+1
388
WRITE(number_procs,'(i4.4)') ParEnv%PEs
389
proc_number = ADJUSTL(proc_number)
390
! Add the number of procs as a suffix in case of multiple runs with different partitions
391
PVtuFile=TRIM(OutPutDirectoryName)//'/'//TRIM(OutPutFileName)//'_'//TRIM(number_procs)//'procs_'//TRIM(nit)//'.pvtu'
392
VtuFile=TRIM(OutPutDirectoryName)//'/'//TRIM(OutPutFileName)//'_'&
393
//TRIM(number_procs)//'procs_'//TRIM(proc_number)//'par'//TRIM(nit)//'.vtu'
394
VtuUnit = 1500 +ParEnv%myPe
395
ELSE
396
VtuUnit = 1500
397
VtuFile=TRIM(OutPutDirectoryName)//'/'//TRIM(OutPutFileName)//'_'//TRIM(nit)//'.vtu'
398
END IF
399
400
IF (VtuBinary) THEN
401
VtuFileFormat="appended"
402
ELSE
403
VtuFileFormat="ascii"
404
ENDIF
405
406
IF (ParEnv%myPe == 0 .AND. ParEnv%PEs >1 ) THEN
407
OPEN( UNIT=PVtuUnit, FILE=PVtuFile, FORM = 'formatted', STATUS='unknown' )
408
WRITE( PVtuUnit,'(A)') '<VTKFile type="PUnstructuredGrid" version="0.1" byte_order="LittleEndian">'
409
WRITE( PVtuUnit,'(A)') ' <PUnstructuredGrid>'
410
WRITE( PVtuUnit,'(A)') ' <PPoints>'
411
WRITE( PVtuUnit,'(A)') &
412
' <PDataArray type="Float64" NumberOfComponents="3" format="'//TRIM(VtuFileFormat)//'"/>'
413
WRITE( PVtuUnit,'(A)') ' </PPoints>'
414
WRITE( PVtuUnit,'(A)') ' <PCells>'
415
WRITE( PVtuUnit,'(A)') &
416
' <PDataArray type="Int32" Name="connectivity" NumberOfComponents="1" format="'//TRIM(VtuFileFormat)//'"/>'
417
WRITE( PVtuUnit,'(A)') &
418
' <PDataArray type="Int32" Name="offsets" NumberOfComponents="1" format="'//TRIM(VtuFileFormat)//'"/>'
419
WRITE( PVtuUnit,'(A)') &
420
' <PDataArray type="Int32" Name="types" NumberOfComponents="1" format="'//TRIM(VtuFileFormat)//'"/>'
421
WRITE( PVtuUnit,'(A)') ' </PCells>'
422
WRITE( PVtuUnit,'(A)') ' <PCellData >'
423
WRITE( PVtuUnit,'(A)') &
424
' <PDataArray type="Float64" Name="'//TRIM(ChAreaVarName)//'" format="'//TRIM(VtuFileFormat)//'"/>'
425
WRITE( PVtuUnit,'(A)') &
426
' <PDataArray type="Float64" Name="'//TRIM(ChFluxVarName)//'" format="'//TRIM(VtuFileFormat)//'"/>'
427
WRITE( PVtuUnit,'(A)') ' </PCellData>'
428
IF (ASSOCIATED(QmSol) .AND. NbMoulinAll >0 ) THEN
429
WRITE( PVtuUnit,'(A)') ' <PPointData>'
430
WRITE( PVtuUnit,'(A)') &
431
' <PDataArray type="Float64" Name="'//TRIM(QmVarName)//'" format="'//TRIM(VtuFileFormat)//'"/>'
432
WRITE( PVtuUnit,'(A)') ' </PPointData>'
433
END IF
434
DO i=1, ParEnv%PEs
435
WRITE(proc_number,'(i4.4)') i
436
proc_number = ADJUSTL(proc_number)
437
WRITE( PVtuUnit,'(A)') &
438
' <Piece Source="'//TRIM(OutPutFileName)//'_'&
439
//TRIM(number_procs)//'procs_'//TRIM(proc_number)//'par'//TRIM(nit)//'.vtu" />'
440
ENDDO
441
WRITE( PVtuUnit,'(A)') ' </PUnstructuredGrid>'
442
WRITE( PVtuUnit,'(A)') '</VTKFile>'
443
CLOSE(PVtuUnit)
444
END IF
445
446
ALLOCATE(tmparray(3,NodeSheet))
447
tmparray(:,:)=0
448
449
ALLOCATE(NodePointArray(3*NodeSheet))
450
NodePointArray(:)=0.0
451
452
Cpt=0
453
DO i = 1, Model % NumberOfNodes
454
IF (TableNodeSheet(i)>0) THEN
455
x = Solver % Mesh % Nodes % x(i)
456
y = Solver % Mesh % Nodes % y(i)
457
z = Solver % Mesh % Nodes % z(i)
458
Cpt = Cpt +1
459
tmparray(1,Cpt)=x
460
tmparray(2,Cpt)=y
461
tmparray(3,Cpt)=z
462
END IF
463
END DO
464
465
DO i=1,NodeSheet
466
DO j=1,3
467
kk=j+ (i-1)*3
468
NodePointArray(kk)=tmparray(j,i)
469
END DO
470
END DO
471
DEALLOCATE(tmparray)
472
473
ALLOCATE(tmparray(2,EdgeSheet))
474
ALLOCATE(EdgePointArray(2*EdgeSheet))
475
ALLOCATE(EdgeOffsetArray(EdgeSheet))
476
ALLOCATE(EdgeTypeArray(EdgeSheet))
477
478
tmparray(:,:)=0
479
EdgePointArray(:)=0
480
EdgeOffsetArray(:)=0
481
EdgeTypeArray(:)=0
482
483
Cpt=0
484
DO t=1, Solver % Mesh % NumberOfEdges
485
Edge => Solver % Mesh % Edges(t)
486
IF (.NOT.ASSOCIATED(Edge)) CYCLE
487
IF (ParEnv % PEs > 1) THEN
488
IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE
489
END IF
490
n = Edge % TYPE % NumberOfNodes
491
IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE
492
493
Cpt = Cpt+1
494
tmparray(1,Cpt) = TableNodeSheet(Edge % NodeIndexes(1))-1
495
tmparray(2,Cpt) = TableNodeSheet(Edge % NodeIndexes(2))-1
496
END DO
497
498
DO i=1,EdgeSheet
499
DO j=1,2
500
kk=j+ (i-1)*2
501
EdgePointArray(kk)=tmparray(j,i)
502
END DO
503
END DO
504
505
DO j=1,EdgeSheet
506
EdgeOffsetArray(j)= 2 * j
507
EdgeTypeArray(j) = 3
508
END DO
509
510
DEALLOCATE(tmparray)
511
512
ALLOCATE(ChannelAreaArray(EdgeSheet))
513
514
! Loops to get the Channels Area variable
515
Cpt=0
516
DO t=1, Solver % Mesh % NumberOfEdges
517
Edge => Solver % Mesh % Edges(t)
518
IF (.NOT.ASSOCIATED(Edge)) CYCLE
519
IF (ParEnv % PEs > 1) THEN
520
IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE
521
END IF
522
n = Edge % TYPE % NumberOfNodes
523
IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE
524
525
M = Solver % Mesh % NumberOfNodes
526
Cpt = Cpt+1
527
ChannelAreaArray(Cpt) = AreaSolution(AreaPerm(M+t))
528
END DO
529
530
531
! Loops to get the Channels Flux variable
532
IF (ASSOCIATED(QcSol)) THEN
533
ALLOCATE(ChannelFluxArray(EdgeSheet))
534
535
Cpt=0
536
DO t=1, Solver % Mesh % NumberOfEdges
537
Edge => Solver % Mesh % Edges(t)
538
IF (.NOT.ASSOCIATED(Edge)) CYCLE
539
IF (ParEnv % PEs > 1) THEN
540
IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE
541
END IF
542
n = Edge % TYPE % NumberOfNodes
543
IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE
544
545
M = Solver % Mesh % NumberOfNodes
546
Cpt = Cpt+1
547
ChannelFluxArray(Cpt) = QcSolution(QcPerm(M+t))
548
END DO
549
END IF
550
551
! Loops to get the Flux from Moulins variable
552
IF (OutPutQm) THEN
553
ALLOCATE(MoulinInputArray(NodeSheet))
554
Flux = 0.0_dp
555
DO t=1, Solver % Mesh % NumberOfBoundaryElements
556
Element => GetBoundaryElement(t)
557
n = GetElementNOFNodes()
558
559
IF ( GetElementFamily() > 1 ) CYCLE
560
561
BC => GetBC()
562
bc_id = GetBCId( Element )
563
CALL GetElementNodes( ElementNodes )
564
IF ( ASSOCIATED( BC ) ) THEN
565
j = Element % NodeIndexes(1)
566
IF (QmPerm(j) <= 0 ) CYCLE
567
Flux(j) = QmSolution(QmPerm(j))
568
END IF
569
END DO
570
571
Cpt=0
572
DO i = 1, Model % NumberOfNodes
573
IF (TableNodeSheet(i)>0) THEN
574
Cpt = Cpt+1
575
MoulinInputArray(Cpt) = Flux(i)
576
END IF
577
END DO
578
END IF
579
580
IF( VtuBinary) THEN
581
OPEN( UNIT=VtuUnit, FILE=VtuFile, FORM = 'unformatted', ACCESS = 'stream', STATUS='unknown')
582
WRITE( OutStr,'(A)' ) '<?xml version="1.0"?> '//lf
583
CALL VtuStrWrite( OutStr , VtuUnit )
584
WRITE( OutStr,'(A)' ) '<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'//lf
585
CALL VtuStrWrite( OutStr , VtuUnit )
586
WRITE( OutStr,'(A)' ) ' <UnstructuredGrid>'//lf
587
CALL VtuStrWrite( OutStr , VtuUnit )
588
WRITE( OutStr,'(A,I0,A,I0,A)') ' <Piece NumberOfPoints="',NodeSheet,'" NumberOfCells="',EdgeSheet,'" >'//lf
589
CALL VtuStrWrite( OutStr , VtuUnit )
590
WRITE( OutStr,'(A)' ) ' <Points>'//lf
591
CALL VtuStrWrite( OutStr , VtuUnit )
592
593
offset=0
594
WRITE( OutStr,'(A,I0,A)') &
595
' <DataArray type="Float64" NumberOfComponents="3" format="appended" offset="',offset,'" />'//lf
596
CALL VtuStrWrite( OutStr , VtuUnit )
597
WRITE( OutStr,'(A)' ) ' </Points>'//lf
598
CALL VtuStrWrite( OutStr , VtuUnit )
599
WRITE( OutStr,'(A)' ) ' <Cells>'//lf
600
CALL VtuStrWrite( OutStr , VtuUnit )
601
602
offset = offset + 8*NodeSheet*3 + 4
603
WRITE( OutStr,'(A,I0,A)') &
604
' <DataArray type="Int32" Name="connectivity" NumberOfComponents="1" &
605
& format="appended" offset="',offset,'" />'//lf
606
CALL VtuStrWrite( OutStr , VtuUnit )
607
608
offset = offset + 4*EdgeSheet*2+4
609
WRITE( OutStr,'(A,I0,A)') &
610
' <DataArray type="Int32" Name="offsets" NumberOfComponents="1" &
611
& format="appended" offset="',offset,'" />'//lf
612
CALL VtuStrWrite( OutStr , VtuUnit )
613
614
offset = offset + 4*EdgeSheet+4
615
WRITE( OutStr,'(A,I0,A)') &
616
' <DataArray type="Int32" Name="types" NumberOfComponents="1" &
617
& format="appended" offset="',offset,'" />'//lf
618
CALL VtuStrWrite( OutStr , VtuUnit )
619
620
WRITE( OutStr,'(A)' ) ' </Cells>'//lf
621
CALL VtuStrWrite( OutStr , VtuUnit )
622
WRITE( OutStr,'(A)' ) ' <CellData>'//lf
623
CALL VtuStrWrite( OutStr , VtuUnit )
624
625
offset = offset + 4*EdgeSheet+4
626
WRITE( OutStr,'(A,I0,A)') &
627
' <DataArray type="Float64" Name="'//TRIM(ChAreaVarName)//'" NumberOfComponents="1" &
628
& format="appended" offset="',offset,'" />'//lf
629
CALL VtuStrWrite( OutStr , VtuUnit )
630
631
offset = offset + 8*EdgeSheet +4
632
WRITE( OutStr,'(A,I0,A)') &
633
' <DataArray type="Float64" Name="'//TRIM(ChFluxVarName)//'" NumberOfComponents="1" &
634
& format="appended" offset="',offset,'" />'//lf
635
CALL VtuStrWrite( OutStr , VtuUnit )
636
WRITE( OutStr,'(A)' ) ' </CellData>'//lf
637
CALL VtuStrWrite( OutStr , VtuUnit )
638
639
IF (OutPutQm) THEN
640
WRITE( OutStr,'(A)' ) ' <PointData>'//lf
641
CALL VtuStrWrite( OutStr , VtuUnit )
642
offset = offset + 8*EdgeSheet + 4
643
WRITE( OutStr,'(A,I0,A)') &
644
' <DataArray type="Float64" Name="'//TRIM(QmVarName)//'" NumberOfComponents="1" &
645
& format="appended" offset="',offset,'" />'//lf
646
CALL VtuStrWrite( OutStr , VtuUnit )
647
WRITE( OutStr,'(A)' ) ' </PointData>'//lf
648
CALL VtuStrWrite( OutStr , VtuUnit )
649
END IF
650
651
WRITE( OutStr,'(A)' ) ' </Piece>'//lf
652
CALL VtuStrWrite( OutStr , VtuUnit )
653
WRITE( OutStr,'(A)' ) ' </UnstructuredGrid>'//lf
654
CALL VtuStrWrite( OutStr , VtuUnit )
655
WRITE( OutStr,'(A)' ) '<AppendedData encoding="raw">'//lf
656
CALL VtuStrWrite( OutStr , VtuUnit )
657
IF (OutPutQm) THEN
658
WRITE(VtuUnit) '_', KIND(NodePointArray) *size(NodePointArray) , NodePointArray(:) ,&
659
KIND(EdgePointArray) *size(EdgePointArray) , EdgePointArray(:) ,&
660
KIND(EdgeOffsetArray) *size(EdgeOffsetArray) , EdgeOffsetArray(:) ,&
661
KIND(EdgeTypeArray) *size(EdgeTypeArray) , EdgeTypeArray(:) ,&
662
KIND(ChannelAreaArray)*size(ChannelAreaArray), ChannelAreaArray(:) ,&
663
KIND(ChannelFluxArray)*size(ChannelFluxArray), ChannelFluxArray(:) ,&
664
KIND(MoulinInputArray)*size(MoulinInputArray), MoulinInputArray(:)
665
ELSE
666
WRITE(VtuUnit) '_', KIND(NodePointArray) *size(NodePointArray) , NodePointArray(:) ,&
667
KIND(EdgePointArray) *size(EdgePointArray) , EdgePointArray(:) ,&
668
KIND(EdgeOffsetArray) *size(EdgeOffsetArray) , EdgeOffsetArray(:) ,&
669
KIND(EdgeTypeArray) *size(EdgeTypeArray) , EdgeTypeArray(:) ,&
670
KIND(ChannelAreaArray)*size(ChannelAreaArray), ChannelAreaArray(:) ,&
671
KIND(ChannelFluxArray)*size(ChannelFluxArray), ChannelFluxArray(:)
672
END IF
673
WRITE( OutStr,'(A)' ) lf//'</AppendedData>'//lf
674
CALL VtuStrWrite( OutStr , VtuUnit )
675
ELSE
676
OPEN( UNIT=VtuUnit, FILE=VtuFile, FORM = 'formatted', ACCESS = 'sequential', STATUS='unknown')
677
WRITE( OutStr,'(A)' ) '<?xml version="1.0"?> '//lf
678
CALL VtuStrWrite( OutStr , VtuUnit )
679
WRITE( OutStr,'(A)' ) '<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'//lf
680
CALL VtuStrWrite( OutStr , VtuUnit )
681
WRITE( OutStr,'(A)' ) ' <UnstructuredGrid>'//lf
682
CALL VtuStrWrite( OutStr , VtuUnit )
683
684
WRITE( OutStr,'(A,I0,A,I0,A)') ' <Piece NumberOfPoints="',NodeSheet,'" NumberOfCells="',EdgeSheet,'" >'//lf
685
CALL VtuStrWrite( OutStr , VtuUnit )
686
687
WRITE( OutStr,'(A)' ) ' <Points>'//lf
688
CALL VtuStrWrite( OutStr , VtuUnit )
689
690
WRITE( OutStr,'(A)') ' <DataArray type="Float64" NumberOfComponents="3" format="ascii" >'//lf
691
CALL VtuStrWrite( OutStr , VtuUnit )
692
WRITE(VtuFormat,'(A,I0,A,A)') &
693
"(",size(NodePointArray), "ES16.7E3",")"
694
WRITE(VtuUnit,VtuFormat) NodePointArray(:)
695
WRITE( OutStr,'(A)') ' </DataArray>'//lf
696
CALL VtuStrWrite( OutStr , VtuUnit )
697
698
WRITE( OutStr,'(A)' ) ' </Points>'//lf
699
CALL VtuStrWrite( OutStr , VtuUnit )
700
WRITE( OutStr,'(A)' ) ' <Cells>'//lf
701
CALL VtuStrWrite( OutStr , VtuUnit )
702
703
WRITE( OutStr,'(A)') &
704
' <DataArray type="Int32" Name="connectivity" NumberOfComponents="1" format="ascii" >'//lf
705
CALL VtuStrWrite( OutStr , VtuUnit )
706
WRITE(VtuFormat,'(A,I0,A,A)') &
707
"(",size(EdgePointArray), '(" ",I0)',")"
708
WRITE(VtuUnit,VtuFormat) EdgePointArray(:)
709
WRITE( OutStr,'(A)') ' </DataArray>'//lf
710
CALL VtuStrWrite( OutStr , VtuUnit )
711
712
WRITE( OutStr,'(A)') &
713
' <DataArray type="Int32" Name="offsets" NumberOfComponents="1" format="ascii" >'//lf
714
CALL VtuStrWrite( OutStr , VtuUnit )
715
WRITE(VtuFormat,'(A,I0,A,A)') &
716
"(",size(EdgeOffsetArray), '(" ",I0)',")"
717
WRITE(VtuUnit,VtuFormat) EdgeOffsetArray(:)
718
WRITE( OutStr,'(A)') ' </DataArray>'//lf
719
CALL VtuStrWrite( OutStr , VtuUnit )
720
721
WRITE( OutStr,'(A)') &
722
' <DataArray type="Int32" Name="types" NumberOfComponents="1" format="ascii" >'//lf
723
CALL VtuStrWrite( OutStr , VtuUnit )
724
WRITE(VtuFormat,'(A,I0,A,A)') &
725
"(",size(EdgeTypeArray), '(" ",I0)',")"
726
WRITE(VtuUnit,VtuFormat) EdgeTypeArray(:)
727
WRITE( OutStr,'(A)') ' </DataArray>'//lf
728
CALL VtuStrWrite( OutStr , VtuUnit )
729
730
WRITE( OutStr,'(A)' ) ' </Cells>'//lf
731
CALL VtuStrWrite( OutStr , VtuUnit )
732
WRITE( OutStr,'(A)' ) ' <CellData>'//lf
733
CALL VtuStrWrite( OutStr , VtuUnit )
734
735
WRITE( OutStr,'(A)') &
736
' <DataArray type="Float64" Name="'//TRIM(ChAreaVarName)//'" NumberOfComponents="1" format="ascii" >'//lf
737
CALL VtuStrWrite( OutStr , VtuUnit )
738
WRITE(VtuFormat,'(A,I0,A,A)') &
739
"(",size(ChannelAreaArray), "E16.7",")"
740
WRITE(VtuUnit,VtuFormat) ChannelAreaArray(:)
741
WRITE( OutStr,'(A)') ' </DataArray>'//lf
742
CALL VtuStrWrite( OutStr , VtuUnit )
743
744
WRITE( OutStr,'(A)') &
745
' <DataArray type="Float64" Name="'//TRIM(ChFluxVarName)//'" NumberOfComponents="1" format="ascii" >'//lf
746
CALL VtuStrWrite( OutStr , VtuUnit )
747
WRITE(VtuFormat,'(A,I0,A,A)') &
748
"(",size(ChannelFluxArray), "E16.7",")"
749
WRITE(VtuUnit,VtuFormat) ChannelFluxArray(:)
750
WRITE( OutStr,'(A)') ' </DataArray>'//lf
751
CALL VtuStrWrite( OutStr , VtuUnit )
752
753
WRITE( OutStr,'(A)' ) ' </CellData>'//lf
754
CALL VtuStrWrite( OutStr , VtuUnit )
755
756
IF (OutPutQm) THEN
757
WRITE( OutStr,'(A)' ) ' <PointData>'//lf
758
CALL VtuStrWrite( OutStr , VtuUnit )
759
WRITE( OutStr,'(A)') &
760
' <DataArray type="Float64" Name="'//TRIM(QmVarName)//'" NumberOfComponents="1" format="ascii" >'//lf
761
CALL VtuStrWrite( OutStr , VtuUnit )
762
WRITE(VtuFormat,'(A,I0,A,A)') &
763
"(",size(MoulinInputArray), "E16.7",")"
764
WRITE(VtuUnit,VtuFormat) MoulinInputArray(:)
765
WRITE( OutStr,'(A)') ' </DataArray>'//lf
766
CALL VtuStrWrite( OutStr , VtuUnit )
767
WRITE( OutStr,'(A)' ) ' </PointData>'//lf
768
CALL VtuStrWrite( OutStr , VtuUnit )
769
END IF
770
771
WRITE( OutStr,'(A)' ) ' </Piece>'//lf
772
CALL VtuStrWrite( OutStr , VtuUnit )
773
WRITE( OutStr,'(A)' ) ' </UnstructuredGrid>'//lf
774
CALL VtuStrWrite( OutStr , VtuUnit )
775
ENDIF
776
WRITE( OutStr,'(A)' ) '</VTKFile>'//lf
777
CALL VtuStrWrite( OutStr , VtuUnit )
778
CLOSE(VtuUnit)
779
780
DEALLOCATE(NodePointArray)
781
DEALLOCATE(EdgePointArray)
782
DEALLOCATE(EdgeOffsetArray)
783
DEALLOCATE(EdgeTypeArray)
784
DEALLOCATE(ChannelAreaArray)
785
DEALLOCATE(ChannelFluxArray)
786
IF (OutPutQm) DEALLOCATE(MoulinInputArray)
787
END IF ! Output VTU
788
789
SubroutineVisited = .TRUE.
790
791
CONTAINS
792
793
SUBROUTINE VtuStrWrite( Str , VtuUnit )
794
795
CHARACTER(LEN=1024) :: Str
796
INTEGER :: VtuUnit
797
798
IF ( VtuBinary ) THEN
799
WRITE( VtuUnit ) TRIM(Str)
800
ELSE
801
WRITE( VtuUnit, '(A)' ) TRIM(Str)
802
END IF
803
804
END SUBROUTINE VtuStrWrite
805
806
!------------------------------------------------------------------------------
807
END SUBROUTINE GlaDSchannelOut
808
!------------------------------------------------------------------------------
809
810