Path: blob/devel/elmerice/Solvers/GlaDSchannelSolver.F90
3204 views
! !/*****************************************************************************/1!2! * Elmer/Ice, a glaciological add-on to Elmer3! * http://elmerice.elmerfem.org4! *5! *6! * This program is free software; you can redistribute it and/or7! * modify it under the terms of the GNU General Public License8! * as published by the Free Software Foundation; either version 29! * of the License, or (at your option) any later version.10! *11! * This program is distributed in the hope that it will be useful,12! * but WITHOUT ANY WARRANTY; without even the implied warranty of13! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14! * GNU General Public License for more details.15! *16! * You should have received a copy of the GNU General Public License17! * along with this program (in file fem/GPL-2); if not, write to the18! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,19! * Boston, MA 02110-1301, USA.20! *21! *****************************************************************************/22! ******************************************************************************23! *24! * Authors: Olivier Gagliardini, Mauro Werder, Mondher Chekki25! * Email: [email protected], [email protected]26! * Web: http://www.csc.fi/elmer27! * Address: CSC - Scientific Computing Ltd.28! * Keilaranta 1429! * 02101 Espoo, Finland30! *31! * Original Date: 15 February 201332! *33! *****************************************************************************/343536! *****************************************************************************/37!> Save output files for the Channels38!> To be used with the GlaDSCoupledSolver39!> Solver section also used to declare the Channel Area variable40!> Need to be executed with the "Exec Solver = After Saving" option41RECURSIVE SUBROUTINE GlaDSchannelOut( Model,Solver,Timestep,TransientSimulation )42!******************************************************************************43!44! ARGUMENTS:45!46! TYPE(Model_t) :: Model,47! INPUT: All model information (mesh,materials,BCs,etc...)48!49! TYPE(Solver_t) :: Solver50! INPUT: Linear equation solver options51!52! REAL(KIND=dp) :: Timestep53! INPUT: Timestep size for time dependent simulations54!55!******************************************************************************56USE Differentials57USE MaterialModels58USE DefUtils5960!------------------------------------------------------------------------------61IMPLICIT NONE62!------------------------------------------------------------------------------63!------------------------------------------------------------------------------64! External variables65!------------------------------------------------------------------------------66TYPE(Model_t) :: Model67TYPE(Solver_t), TARGET :: Solver68LOGICAL :: TransientSimulation69REAL(KIND=dp) :: Timestep70!------------------------------------------------------------------------------71! Local variables72!------------------------------------------------------------------------------73TYPE(Nodes_t) :: ElementNodes, EdgeNodes74TYPE(Element_t), POINTER :: Element, Edge7576TYPE(Variable_t), POINTER :: TimeVar77TYPE(Variable_t), POINTER :: HydPotSol, AreaSol, QcSol, QmSol78INTEGER, POINTER :: NodeIndexes(:), HydPotPerm(:), &79AreaPerm(:), QcPerm(:), QmPerm(:)80REAL(KIND=dp), POINTER :: HydPot(:), AreaSolution(:), QcSolution(:), QmSolution(:)8182TYPE(ValueList_t), POINTER :: BC, Constants8384INTEGER :: i, j, k, l, m, n, t, iter, body_id, eq_id, material_id, &85istat, LocalNodes, bc_id, DIM, NodeSheet, EdgeSheet, NbMoulin, NbMoulinAll, &86GhostNodes, it, itOut, ierr, ChannelSolver87INTEGER, ALLOCATABLE :: TableNodeSheet(:), TableMoulin(:)8889CHARACTER(LEN=MAX_NAME_LEN) :: SolverName, HydPotName, &90OutPutFileName, nit9192LOGICAL :: Found, AllocationsDone = .FALSE., SubroutineVisited = .FALSE., &93FirstTime = .TRUE., FirstVisit = .TRUE.9495INTEGER, PARAMETER :: PVtuUnit=130096INTEGER :: VtuUnit, offset, Cpt, kk97INTEGER, ALLOCATABLE :: EdgePointArray(:), EdgeOffsetArray(:), EdgeTypeArray(:)9899LOGICAL :: SaveVTU=.False. , VtuBinary=.False., FileVTU = .FALSE., OutPutQm = .FALSE., Calving = .FALSE.100101CHARACTER :: lf102CHARACTER(LEN=1024) :: OutStr103CHARACTER(MAX_NAME_LEN) :: proc_number, number_procs, VtuFile, PVtuFile, VtuFormat, VtuFileFormat, OutPutDirectoryName104CHARACTER(MAX_NAME_LEN) :: ChFluxVarName, ChAreaVarName, QmVarName105106REAL(KIND=dp) , ALLOCATABLE :: tmparray(:,:), Flux(:)107REAL(KIND=dp) , ALLOCATABLE :: NodePointArray(:), ChannelAreaArray(:), ChannelFluxArray(:), MoulinInputArray(:)108109LOGICAL, ALLOCATABLE :: IsGhostNode(:)110111REAL(KIND=dp) :: x, y, z112113SAVE &114ElementNodes, EdgeNodes, &115IsGhostNode, OutPutFileName, OutPutDirectoryName, FileVTU, VtuBinary, it, itOut, &116AllocationsDone, FirstTime, FirstVisit, SolverName, HydPotName, M, &117NodeSheet, TableNodeSheet, EdgeSheet, NbMoulin, TableMoulin, OutPutQm, Flux, &118ChFluxVarName, ChAreaVarName, QmVarName, ChannelSolver119120!------------------------------------------------------------------------------121! Get variables needed for solution122!------------------------------------------------------------------------------123SolverName = 'GlaDSchannelOut ('// TRIM(Solver % Variable % Name) // ')'124!CHANGE - to get Channel variables added to this solver mesh if125!doing calving and hydrology and consequently having many meshes126Calving = ListGetLogical(Model % Simulation, 'Calving', Found)127IF(.NOT. Found) Calving = .FALSE.128IF(Calving) THEN129IF(FirstVisit) THEN130DO i=1,Model % NumberOfSolvers131IF(Model % Solvers(i) % Variable % Name == 'hydraulic potential') THEN132ChannelSolver = i133EXIT134END IF135END DO136AreaSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&137% Variables, 'Channel Area', ThisOnly=.TRUE.)138IF (ASSOCIATED(AreaSol)) THEN139AreaPerm => AreaSol % Perm140AreaSolution => AreaSol % Values141END IF142LocalNodes = COUNT( AreaPerm > 0 )143IF ( LocalNodes <= 0 ) RETURN144ELSE145AreaSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&146% Variables, 'Channel Area', ThisOnly=.TRUE.)147IF (ASSOCIATED(AreaSol)) THEN148AreaPerm => AreaSol % Perm149AreaSolution => AreaSol % Values150END IF151LocalNodes = COUNT( AreaPerm > 0 )152IF ( LocalNodes <= 0 ) RETURN153END IF154ELSE155AreaSol => Solver % Variable156AreaPerm => AreaSol % Perm157AreaSolution => AreaSol % Values158159LocalNodes = COUNT( AreaPerm > 0 )160IF ( LocalNodes <= 0 ) RETURN161END IF162163DIM = CoordinateSystemDimension()164165!------------------------------------------------------------------------------166! Allocate some permanent storage, this is done first time only167!------------------------------------------------------------------------------168IF ( .NOT. AllocationsDone .OR. Solver % Mesh % Changed ) THEN169N = Solver % Mesh % MaxElementNodes170M = Solver % Mesh % NumberOfNodes171172IF ( AllocationsDone ) THEN173DEALLOCATE( &174ElementNodes % x, &175ElementNodes % y, &176ElementNodes % z, &177EdgeNodes % x, &178EdgeNodes % y, &179EdgeNodes % z, &180IsGhostNode, &181TableNodeSheet, TableMoulin, Flux )182END IF183184ALLOCATE( &185ElementNodes % x( N ), &186ElementNodes % y( N ), &187ElementNodes % z( N ), &188EdgeNodes % x( N ), &189EdgeNodes % y( N ), &190EdgeNodes % z( N ), &191IsGhostNode( M ), &192TableNodeSheet(M), TableMoulin(M), Flux(M), &193STAT=istat )194195IF ( istat /= 0 ) THEN196CALL FATAL( SolverName, 'Memory allocation error' )197ELSE198CALL INFO(SolverName, 'Memory allocation done', level=1 )199END IF200201IF ( ParEnv % PEs > 1 ) THEN !only if we have a parallel run202IsGhostNode( 1:M ) = .FALSE.203GhostNodes = 0204DO t=1,Solver % NumberOfActiveElements205Element => GetActiveElement(t)206IF (ParEnv % myPe .EQ. Element % partIndex) CYCLE207DO i=1,GetElementNOFNodes(Element)208IsGhostNode(Element % NodeIndexes(i)) = .TRUE.209GhostNodes = GhostNodes + 1210END DO211END DO212PRINT *, ParEnv % myPe, ':', GhostNodes, ' ghost nodes'213END IF214215AllocationsDone = .TRUE.216END IF217218IF (FirstVisit) THEN219FirstVisit = .FALSE.220Constants => GetConstants()221HydPotName = GetString( Constants, &222'Hydraulic Potential Variable Name', Found )223IF(.NOT.Found) THEN224CALL WARN(SolverName,'Keyword >Hydraulic Potential Variable Name< not found in section Constants')225CALL WARN(SolverName,'Taking default value >Hydraulic Potential<')226WRITE(HydPotName,'(A)') 'Hydraulic Potential'227END IF228ChAreaVarName = GetString( Constants, &229'Channel Area Variable Name', Found )230IF(.NOT.Found) THEN231CALL WARN(SolverName,'Keyword >Channel Area Variable Name< not found in section Constants')232CALL WARN(SolverName,'Taking default value >Channel Area<')233WRITE(ChAreaVarName,'(A)') 'Channel Area'234END IF235WRITE(QmVarName,'(A)') 'Flux from Moulins'236WRITE(ChFluxVarName,'(A)') 'Channel Flux'237END IF238239! Point on the needed variables240!CHANGE - to avoid interpolation of variables between solvers when calving241IF(Calving) THEN242HydPotSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&243% Variables, HydPotName, ThisOnly=.TRUE.)244HydPotPerm => HydPotSol % Perm245HydPot => HydPotSol % Values246QcSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&247% Variables, ChFluxVarName)248IF (ASSOCIATED(QcSol)) THEN249QcPerm => QcSol % Perm250QcSolution => QcSol % Values251END IF252QmSol => VariableGet(Model % Solvers(ChannelSolver) % Mesh&253% Variables, QmVarName)254IF (ASSOCIATED(QmSol)) THEN255QmPerm => QmSol % Perm256QmSolution => QmSol % Values257END IF258ELSE259QcSol => VariableGet( Solver % Mesh % Variables, ChFluxVarName )260IF (ASSOCIATED(QcSol)) THEN261QcPerm => QcSol % Perm262QcSolution => QcSol % Values263END IF264265QmSol => VariableGet( Solver % Mesh % Variables, QmVarName )266IF (ASSOCIATED(QmSol)) THEN267QmPerm => QmSol % Perm268QmSolution => QmSol % Values269END IF270271HydPotSol => VariableGet(Solver % Mesh % Variables, HydPotName,&272UnfoundFatal=.TRUE.)273HydPotPerm => HydPotSol % Perm274HydPot => HydPotSol % Values275END IF276277TimeVar => VariableGet( Solver % Mesh % Variables, 'Time' )278IF (FirstTime) THEN279FirstTime = .FALSE.280itOut = 0281it = 0282FileVTU = GetLogical( Solver % Values, 'VTU OutPutFile' )283VtuBinary = GetLogical( Solver % Values, 'VTU BinaryFile')284285IF (FileVTU) THEN286OutPutDirectoryName = GetString( Solver % Values, 'Channels OutPut Directory Name', Found )287IF (.NOT.Found) THEN288WRITE(Message,'(a)') 'Keyword > Channels OutPut Directory Name < not found'289WRITE(Message,'(a)') 'Output Files will be created in the .sif Directory'290END IF291OutPutFileName = GetString( Solver % Values, 'Channels OutPut File Name', Found )292IF (.NOT.Found) THEN293WRITE(Message,'(a)') 'Keyword > Channels OutPut File Name < not found'294CALL FATAL(SolverName, Message)295END IF296END IF297298! Save some information regarding the mesh for VTU output299! Number of nodes in the sheet layer: NodeSheet300! Number of channels (edges) in the sheet layer: EdgeSheet301! Permutation table for the NodeSheet nodes and global nodes302IF (FileVTU) THEN303NodeSheet = 0304TableNodeSheet = 0305DO i = 1, Model % NumberOfNodes306IF (HydPotPerm(i)>0) THEN307NodeSheet = NodeSheet + 1308TableNodeSheet(i) = NodeSheet309END IF310END DO311312EdgeSheet = 0313DO t=1, Solver % Mesh % NumberOfEdges314Edge => Solver % Mesh % Edges(t)315n = Edge % TYPE % NumberOfNodes316IF (.NOT.ASSOCIATED(Edge)) CYCLE317IF (ParEnv % PEs > 1) THEN318IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE319END IF320IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE321EdgeSheet = EdgeSheet + 1322END DO323WRITE(Message,'(a,i0)')'Number of Channels (edges): ', EdgeSheet324CALL INFO(SolverName, Message, level=3 )325WRITE(Message,'(a,i0)')'Number of nodes in the sheet layer: ', NodeSheet326CALL INFO(SolverName, Message, level=3 )327328NbMoulin = 0329TableMoulin = 0330! Moulins are located on 101 Boundary elements331DO t=1, Solver % Mesh % NumberOfBoundaryElements332Element => GetBoundaryElement(t)333! IF ( .NOT.ActiveBoundaryElement() ) CYCLE334IF (ParEnv % PEs > 1) THEN335IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE336END IF337n = GetElementNOFNodes()338339IF ( GetElementFamily() > 1 ) CYCLE340NbMoulin = NbMoulin + 1341j = Element % NodeIndexes(1)342TableMoulin(j) = NbMoulin343END DO344OutPutQm = .FALSE.345IF ((NbMoulin>0).AND.(.Not.ASSOCIATED(QmSol))) THEN346WRITE(Message,'(i0,a,i0)') &347NbMoulin, 'moulins found, but not variable >Flux from Moulins< associated, part ',ParEnv%myPe348CALL INFO(SolverName, Message, level=1 )349ELSE IF (NbMoulin==0) THEN350WRITE(Message,'(a,i0)')'No moulin found, part ',ParEnv%myPe351CALL INFO(SolverName, Message, level=3 )352ELSE353WRITE(Message,'(a,i0,a,i0)')'Qm will be saved for ',NbMoulin,' moulins in part ',ParEnv%myPe354CALL INFO(SolverName, Message, level=3 )355OutPutQm = .TRUE.356END IF357END IF358END IF ! FirstTime359360! Check the number of moulins on all partitions361CALL MPI_ALLREDUCE( NbMoulin, NbMoulinAll, 1, MPI_INTEGER, &362MPI_SUM, ELMER_COMM_WORLD, ierr )363WRITE(Message,'(a,i0,a)')'Qm will be saved for ',NbMoulinAll,' moulins in total'364CALL INFO(SolverName, Message, level=3 )365366! If we are here, it means we have to save367! assuming Exec Solver = After Saving is set in the solver section368! number of file is incremented by one369itOut = itOut + 1370371SaveVTU = FileVTU372373CALL Info( SolverName, ' Channels Output will be saved ', Level=4 )374375WRITE(Message,'(A,D15.7)')' Maximum Channel Area: ', &376MAXVAL(AreaSolution(AreaPerm(M+1:M+Solver%Mesh%NumberOfEdges)))377CALL INFO(SolverName, Message, level=4 )378379! Save results in VTU Format380IF (SaveVTU) THEN381lf = CHAR(10)382WRITE(nit,'(i4.4)')itOut383nit = ADJUSTL(nit)384385IF ( ParEnv%PEs >1 ) THEN386WRITE(proc_number,'(i4.4)') ParEnv%myPe+1387WRITE(number_procs,'(i4.4)') ParEnv%PEs388proc_number = ADJUSTL(proc_number)389! Add the number of procs as a suffix in case of multiple runs with different partitions390PVtuFile=TRIM(OutPutDirectoryName)//'/'//TRIM(OutPutFileName)//'_'//TRIM(number_procs)//'procs_'//TRIM(nit)//'.pvtu'391VtuFile=TRIM(OutPutDirectoryName)//'/'//TRIM(OutPutFileName)//'_'&392//TRIM(number_procs)//'procs_'//TRIM(proc_number)//'par'//TRIM(nit)//'.vtu'393VtuUnit = 1500 +ParEnv%myPe394ELSE395VtuUnit = 1500396VtuFile=TRIM(OutPutDirectoryName)//'/'//TRIM(OutPutFileName)//'_'//TRIM(nit)//'.vtu'397END IF398399IF (VtuBinary) THEN400VtuFileFormat="appended"401ELSE402VtuFileFormat="ascii"403ENDIF404405IF (ParEnv%myPe == 0 .AND. ParEnv%PEs >1 ) THEN406OPEN( UNIT=PVtuUnit, FILE=PVtuFile, FORM = 'formatted', STATUS='unknown' )407WRITE( PVtuUnit,'(A)') '<VTKFile type="PUnstructuredGrid" version="0.1" byte_order="LittleEndian">'408WRITE( PVtuUnit,'(A)') ' <PUnstructuredGrid>'409WRITE( PVtuUnit,'(A)') ' <PPoints>'410WRITE( PVtuUnit,'(A)') &411' <PDataArray type="Float64" NumberOfComponents="3" format="'//TRIM(VtuFileFormat)//'"/>'412WRITE( PVtuUnit,'(A)') ' </PPoints>'413WRITE( PVtuUnit,'(A)') ' <PCells>'414WRITE( PVtuUnit,'(A)') &415' <PDataArray type="Int32" Name="connectivity" NumberOfComponents="1" format="'//TRIM(VtuFileFormat)//'"/>'416WRITE( PVtuUnit,'(A)') &417' <PDataArray type="Int32" Name="offsets" NumberOfComponents="1" format="'//TRIM(VtuFileFormat)//'"/>'418WRITE( PVtuUnit,'(A)') &419' <PDataArray type="Int32" Name="types" NumberOfComponents="1" format="'//TRIM(VtuFileFormat)//'"/>'420WRITE( PVtuUnit,'(A)') ' </PCells>'421WRITE( PVtuUnit,'(A)') ' <PCellData >'422WRITE( PVtuUnit,'(A)') &423' <PDataArray type="Float64" Name="'//TRIM(ChAreaVarName)//'" format="'//TRIM(VtuFileFormat)//'"/>'424WRITE( PVtuUnit,'(A)') &425' <PDataArray type="Float64" Name="'//TRIM(ChFluxVarName)//'" format="'//TRIM(VtuFileFormat)//'"/>'426WRITE( PVtuUnit,'(A)') ' </PCellData>'427IF (ASSOCIATED(QmSol) .AND. NbMoulinAll >0 ) THEN428WRITE( PVtuUnit,'(A)') ' <PPointData>'429WRITE( PVtuUnit,'(A)') &430' <PDataArray type="Float64" Name="'//TRIM(QmVarName)//'" format="'//TRIM(VtuFileFormat)//'"/>'431WRITE( PVtuUnit,'(A)') ' </PPointData>'432END IF433DO i=1, ParEnv%PEs434WRITE(proc_number,'(i4.4)') i435proc_number = ADJUSTL(proc_number)436WRITE( PVtuUnit,'(A)') &437' <Piece Source="'//TRIM(OutPutFileName)//'_'&438//TRIM(number_procs)//'procs_'//TRIM(proc_number)//'par'//TRIM(nit)//'.vtu" />'439ENDDO440WRITE( PVtuUnit,'(A)') ' </PUnstructuredGrid>'441WRITE( PVtuUnit,'(A)') '</VTKFile>'442CLOSE(PVtuUnit)443END IF444445ALLOCATE(tmparray(3,NodeSheet))446tmparray(:,:)=0447448ALLOCATE(NodePointArray(3*NodeSheet))449NodePointArray(:)=0.0450451Cpt=0452DO i = 1, Model % NumberOfNodes453IF (TableNodeSheet(i)>0) THEN454x = Solver % Mesh % Nodes % x(i)455y = Solver % Mesh % Nodes % y(i)456z = Solver % Mesh % Nodes % z(i)457Cpt = Cpt +1458tmparray(1,Cpt)=x459tmparray(2,Cpt)=y460tmparray(3,Cpt)=z461END IF462END DO463464DO i=1,NodeSheet465DO j=1,3466kk=j+ (i-1)*3467NodePointArray(kk)=tmparray(j,i)468END DO469END DO470DEALLOCATE(tmparray)471472ALLOCATE(tmparray(2,EdgeSheet))473ALLOCATE(EdgePointArray(2*EdgeSheet))474ALLOCATE(EdgeOffsetArray(EdgeSheet))475ALLOCATE(EdgeTypeArray(EdgeSheet))476477tmparray(:,:)=0478EdgePointArray(:)=0479EdgeOffsetArray(:)=0480EdgeTypeArray(:)=0481482Cpt=0483DO t=1, Solver % Mesh % NumberOfEdges484Edge => Solver % Mesh % Edges(t)485IF (.NOT.ASSOCIATED(Edge)) CYCLE486IF (ParEnv % PEs > 1) THEN487IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE488END IF489n = Edge % TYPE % NumberOfNodes490IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE491492Cpt = Cpt+1493tmparray(1,Cpt) = TableNodeSheet(Edge % NodeIndexes(1))-1494tmparray(2,Cpt) = TableNodeSheet(Edge % NodeIndexes(2))-1495END DO496497DO i=1,EdgeSheet498DO j=1,2499kk=j+ (i-1)*2500EdgePointArray(kk)=tmparray(j,i)501END DO502END DO503504DO j=1,EdgeSheet505EdgeOffsetArray(j)= 2 * j506EdgeTypeArray(j) = 3507END DO508509DEALLOCATE(tmparray)510511ALLOCATE(ChannelAreaArray(EdgeSheet))512513! Loops to get the Channels Area variable514Cpt=0515DO t=1, Solver % Mesh % NumberOfEdges516Edge => Solver % Mesh % Edges(t)517IF (.NOT.ASSOCIATED(Edge)) CYCLE518IF (ParEnv % PEs > 1) THEN519IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE520END IF521n = Edge % TYPE % NumberOfNodes522IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE523524M = Solver % Mesh % NumberOfNodes525Cpt = Cpt+1526ChannelAreaArray(Cpt) = AreaSolution(AreaPerm(M+t))527END DO528529530! Loops to get the Channels Flux variable531IF (ASSOCIATED(QcSol)) THEN532ALLOCATE(ChannelFluxArray(EdgeSheet))533534Cpt=0535DO t=1, Solver % Mesh % NumberOfEdges536Edge => Solver % Mesh % Edges(t)537IF (.NOT.ASSOCIATED(Edge)) CYCLE538IF (ParEnv % PEs > 1) THEN539IF (ParEnv % myPe .NE. Solver % Mesh % ParallelInfo % EdgeNeighbourList(t) % Neighbours(1)) CYCLE540END IF541n = Edge % TYPE % NumberOfNodes542IF (ANY(HydPotPerm(Edge % NodeIndexes(1:n))==0)) CYCLE543544M = Solver % Mesh % NumberOfNodes545Cpt = Cpt+1546ChannelFluxArray(Cpt) = QcSolution(QcPerm(M+t))547END DO548END IF549550! Loops to get the Flux from Moulins variable551IF (OutPutQm) THEN552ALLOCATE(MoulinInputArray(NodeSheet))553Flux = 0.0_dp554DO t=1, Solver % Mesh % NumberOfBoundaryElements555Element => GetBoundaryElement(t)556n = GetElementNOFNodes()557558IF ( GetElementFamily() > 1 ) CYCLE559560BC => GetBC()561bc_id = GetBCId( Element )562CALL GetElementNodes( ElementNodes )563IF ( ASSOCIATED( BC ) ) THEN564j = Element % NodeIndexes(1)565IF (QmPerm(j) <= 0 ) CYCLE566Flux(j) = QmSolution(QmPerm(j))567END IF568END DO569570Cpt=0571DO i = 1, Model % NumberOfNodes572IF (TableNodeSheet(i)>0) THEN573Cpt = Cpt+1574MoulinInputArray(Cpt) = Flux(i)575END IF576END DO577END IF578579IF( VtuBinary) THEN580OPEN( UNIT=VtuUnit, FILE=VtuFile, FORM = 'unformatted', ACCESS = 'stream', STATUS='unknown')581WRITE( OutStr,'(A)' ) '<?xml version="1.0"?> '//lf582CALL VtuStrWrite( OutStr , VtuUnit )583WRITE( OutStr,'(A)' ) '<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'//lf584CALL VtuStrWrite( OutStr , VtuUnit )585WRITE( OutStr,'(A)' ) ' <UnstructuredGrid>'//lf586CALL VtuStrWrite( OutStr , VtuUnit )587WRITE( OutStr,'(A,I0,A,I0,A)') ' <Piece NumberOfPoints="',NodeSheet,'" NumberOfCells="',EdgeSheet,'" >'//lf588CALL VtuStrWrite( OutStr , VtuUnit )589WRITE( OutStr,'(A)' ) ' <Points>'//lf590CALL VtuStrWrite( OutStr , VtuUnit )591592offset=0593WRITE( OutStr,'(A,I0,A)') &594' <DataArray type="Float64" NumberOfComponents="3" format="appended" offset="',offset,'" />'//lf595CALL VtuStrWrite( OutStr , VtuUnit )596WRITE( OutStr,'(A)' ) ' </Points>'//lf597CALL VtuStrWrite( OutStr , VtuUnit )598WRITE( OutStr,'(A)' ) ' <Cells>'//lf599CALL VtuStrWrite( OutStr , VtuUnit )600601offset = offset + 8*NodeSheet*3 + 4602WRITE( OutStr,'(A,I0,A)') &603' <DataArray type="Int32" Name="connectivity" NumberOfComponents="1" &604& format="appended" offset="',offset,'" />'//lf605CALL VtuStrWrite( OutStr , VtuUnit )606607offset = offset + 4*EdgeSheet*2+4608WRITE( OutStr,'(A,I0,A)') &609' <DataArray type="Int32" Name="offsets" NumberOfComponents="1" &610& format="appended" offset="',offset,'" />'//lf611CALL VtuStrWrite( OutStr , VtuUnit )612613offset = offset + 4*EdgeSheet+4614WRITE( OutStr,'(A,I0,A)') &615' <DataArray type="Int32" Name="types" NumberOfComponents="1" &616& format="appended" offset="',offset,'" />'//lf617CALL VtuStrWrite( OutStr , VtuUnit )618619WRITE( OutStr,'(A)' ) ' </Cells>'//lf620CALL VtuStrWrite( OutStr , VtuUnit )621WRITE( OutStr,'(A)' ) ' <CellData>'//lf622CALL VtuStrWrite( OutStr , VtuUnit )623624offset = offset + 4*EdgeSheet+4625WRITE( OutStr,'(A,I0,A)') &626' <DataArray type="Float64" Name="'//TRIM(ChAreaVarName)//'" NumberOfComponents="1" &627& format="appended" offset="',offset,'" />'//lf628CALL VtuStrWrite( OutStr , VtuUnit )629630offset = offset + 8*EdgeSheet +4631WRITE( OutStr,'(A,I0,A)') &632' <DataArray type="Float64" Name="'//TRIM(ChFluxVarName)//'" NumberOfComponents="1" &633& format="appended" offset="',offset,'" />'//lf634CALL VtuStrWrite( OutStr , VtuUnit )635WRITE( OutStr,'(A)' ) ' </CellData>'//lf636CALL VtuStrWrite( OutStr , VtuUnit )637638IF (OutPutQm) THEN639WRITE( OutStr,'(A)' ) ' <PointData>'//lf640CALL VtuStrWrite( OutStr , VtuUnit )641offset = offset + 8*EdgeSheet + 4642WRITE( OutStr,'(A,I0,A)') &643' <DataArray type="Float64" Name="'//TRIM(QmVarName)//'" NumberOfComponents="1" &644& format="appended" offset="',offset,'" />'//lf645CALL VtuStrWrite( OutStr , VtuUnit )646WRITE( OutStr,'(A)' ) ' </PointData>'//lf647CALL VtuStrWrite( OutStr , VtuUnit )648END IF649650WRITE( OutStr,'(A)' ) ' </Piece>'//lf651CALL VtuStrWrite( OutStr , VtuUnit )652WRITE( OutStr,'(A)' ) ' </UnstructuredGrid>'//lf653CALL VtuStrWrite( OutStr , VtuUnit )654WRITE( OutStr,'(A)' ) '<AppendedData encoding="raw">'//lf655CALL VtuStrWrite( OutStr , VtuUnit )656IF (OutPutQm) THEN657WRITE(VtuUnit) '_', KIND(NodePointArray) *size(NodePointArray) , NodePointArray(:) ,&658KIND(EdgePointArray) *size(EdgePointArray) , EdgePointArray(:) ,&659KIND(EdgeOffsetArray) *size(EdgeOffsetArray) , EdgeOffsetArray(:) ,&660KIND(EdgeTypeArray) *size(EdgeTypeArray) , EdgeTypeArray(:) ,&661KIND(ChannelAreaArray)*size(ChannelAreaArray), ChannelAreaArray(:) ,&662KIND(ChannelFluxArray)*size(ChannelFluxArray), ChannelFluxArray(:) ,&663KIND(MoulinInputArray)*size(MoulinInputArray), MoulinInputArray(:)664ELSE665WRITE(VtuUnit) '_', KIND(NodePointArray) *size(NodePointArray) , NodePointArray(:) ,&666KIND(EdgePointArray) *size(EdgePointArray) , EdgePointArray(:) ,&667KIND(EdgeOffsetArray) *size(EdgeOffsetArray) , EdgeOffsetArray(:) ,&668KIND(EdgeTypeArray) *size(EdgeTypeArray) , EdgeTypeArray(:) ,&669KIND(ChannelAreaArray)*size(ChannelAreaArray), ChannelAreaArray(:) ,&670KIND(ChannelFluxArray)*size(ChannelFluxArray), ChannelFluxArray(:)671END IF672WRITE( OutStr,'(A)' ) lf//'</AppendedData>'//lf673CALL VtuStrWrite( OutStr , VtuUnit )674ELSE675OPEN( UNIT=VtuUnit, FILE=VtuFile, FORM = 'formatted', ACCESS = 'sequential', STATUS='unknown')676WRITE( OutStr,'(A)' ) '<?xml version="1.0"?> '//lf677CALL VtuStrWrite( OutStr , VtuUnit )678WRITE( OutStr,'(A)' ) '<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'//lf679CALL VtuStrWrite( OutStr , VtuUnit )680WRITE( OutStr,'(A)' ) ' <UnstructuredGrid>'//lf681CALL VtuStrWrite( OutStr , VtuUnit )682683WRITE( OutStr,'(A,I0,A,I0,A)') ' <Piece NumberOfPoints="',NodeSheet,'" NumberOfCells="',EdgeSheet,'" >'//lf684CALL VtuStrWrite( OutStr , VtuUnit )685686WRITE( OutStr,'(A)' ) ' <Points>'//lf687CALL VtuStrWrite( OutStr , VtuUnit )688689WRITE( OutStr,'(A)') ' <DataArray type="Float64" NumberOfComponents="3" format="ascii" >'//lf690CALL VtuStrWrite( OutStr , VtuUnit )691WRITE(VtuFormat,'(A,I0,A,A)') &692"(",size(NodePointArray), "ES16.7E3",")"693WRITE(VtuUnit,VtuFormat) NodePointArray(:)694WRITE( OutStr,'(A)') ' </DataArray>'//lf695CALL VtuStrWrite( OutStr , VtuUnit )696697WRITE( OutStr,'(A)' ) ' </Points>'//lf698CALL VtuStrWrite( OutStr , VtuUnit )699WRITE( OutStr,'(A)' ) ' <Cells>'//lf700CALL VtuStrWrite( OutStr , VtuUnit )701702WRITE( OutStr,'(A)') &703' <DataArray type="Int32" Name="connectivity" NumberOfComponents="1" format="ascii" >'//lf704CALL VtuStrWrite( OutStr , VtuUnit )705WRITE(VtuFormat,'(A,I0,A,A)') &706"(",size(EdgePointArray), '(" ",I0)',")"707WRITE(VtuUnit,VtuFormat) EdgePointArray(:)708WRITE( OutStr,'(A)') ' </DataArray>'//lf709CALL VtuStrWrite( OutStr , VtuUnit )710711WRITE( OutStr,'(A)') &712' <DataArray type="Int32" Name="offsets" NumberOfComponents="1" format="ascii" >'//lf713CALL VtuStrWrite( OutStr , VtuUnit )714WRITE(VtuFormat,'(A,I0,A,A)') &715"(",size(EdgeOffsetArray), '(" ",I0)',")"716WRITE(VtuUnit,VtuFormat) EdgeOffsetArray(:)717WRITE( OutStr,'(A)') ' </DataArray>'//lf718CALL VtuStrWrite( OutStr , VtuUnit )719720WRITE( OutStr,'(A)') &721' <DataArray type="Int32" Name="types" NumberOfComponents="1" format="ascii" >'//lf722CALL VtuStrWrite( OutStr , VtuUnit )723WRITE(VtuFormat,'(A,I0,A,A)') &724"(",size(EdgeTypeArray), '(" ",I0)',")"725WRITE(VtuUnit,VtuFormat) EdgeTypeArray(:)726WRITE( OutStr,'(A)') ' </DataArray>'//lf727CALL VtuStrWrite( OutStr , VtuUnit )728729WRITE( OutStr,'(A)' ) ' </Cells>'//lf730CALL VtuStrWrite( OutStr , VtuUnit )731WRITE( OutStr,'(A)' ) ' <CellData>'//lf732CALL VtuStrWrite( OutStr , VtuUnit )733734WRITE( OutStr,'(A)') &735' <DataArray type="Float64" Name="'//TRIM(ChAreaVarName)//'" NumberOfComponents="1" format="ascii" >'//lf736CALL VtuStrWrite( OutStr , VtuUnit )737WRITE(VtuFormat,'(A,I0,A,A)') &738"(",size(ChannelAreaArray), "E16.7",")"739WRITE(VtuUnit,VtuFormat) ChannelAreaArray(:)740WRITE( OutStr,'(A)') ' </DataArray>'//lf741CALL VtuStrWrite( OutStr , VtuUnit )742743WRITE( OutStr,'(A)') &744' <DataArray type="Float64" Name="'//TRIM(ChFluxVarName)//'" NumberOfComponents="1" format="ascii" >'//lf745CALL VtuStrWrite( OutStr , VtuUnit )746WRITE(VtuFormat,'(A,I0,A,A)') &747"(",size(ChannelFluxArray), "E16.7",")"748WRITE(VtuUnit,VtuFormat) ChannelFluxArray(:)749WRITE( OutStr,'(A)') ' </DataArray>'//lf750CALL VtuStrWrite( OutStr , VtuUnit )751752WRITE( OutStr,'(A)' ) ' </CellData>'//lf753CALL VtuStrWrite( OutStr , VtuUnit )754755IF (OutPutQm) THEN756WRITE( OutStr,'(A)' ) ' <PointData>'//lf757CALL VtuStrWrite( OutStr , VtuUnit )758WRITE( OutStr,'(A)') &759' <DataArray type="Float64" Name="'//TRIM(QmVarName)//'" NumberOfComponents="1" format="ascii" >'//lf760CALL VtuStrWrite( OutStr , VtuUnit )761WRITE(VtuFormat,'(A,I0,A,A)') &762"(",size(MoulinInputArray), "E16.7",")"763WRITE(VtuUnit,VtuFormat) MoulinInputArray(:)764WRITE( OutStr,'(A)') ' </DataArray>'//lf765CALL VtuStrWrite( OutStr , VtuUnit )766WRITE( OutStr,'(A)' ) ' </PointData>'//lf767CALL VtuStrWrite( OutStr , VtuUnit )768END IF769770WRITE( OutStr,'(A)' ) ' </Piece>'//lf771CALL VtuStrWrite( OutStr , VtuUnit )772WRITE( OutStr,'(A)' ) ' </UnstructuredGrid>'//lf773CALL VtuStrWrite( OutStr , VtuUnit )774ENDIF775WRITE( OutStr,'(A)' ) '</VTKFile>'//lf776CALL VtuStrWrite( OutStr , VtuUnit )777CLOSE(VtuUnit)778779DEALLOCATE(NodePointArray)780DEALLOCATE(EdgePointArray)781DEALLOCATE(EdgeOffsetArray)782DEALLOCATE(EdgeTypeArray)783DEALLOCATE(ChannelAreaArray)784DEALLOCATE(ChannelFluxArray)785IF (OutPutQm) DEALLOCATE(MoulinInputArray)786END IF ! Output VTU787788SubroutineVisited = .TRUE.789790CONTAINS791792SUBROUTINE VtuStrWrite( Str , VtuUnit )793794CHARACTER(LEN=1024) :: Str795INTEGER :: VtuUnit796797IF ( VtuBinary ) THEN798WRITE( VtuUnit ) TRIM(Str)799ELSE800WRITE( VtuUnit, '(A)' ) TRIM(Str)801END IF802803END SUBROUTINE VtuStrWrite804805!------------------------------------------------------------------------------806END SUBROUTINE GlaDSchannelOut807!------------------------------------------------------------------------------808809810