Path: blob/devel/elmerice/IceSheet/Greenland/SSA/Scalar_OUTPUT.F90
3206 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! * Author: F. Gillet-Chaulet (IGE)25! * Email: [email protected]26! * Web: http://elmerice.elmerfem.org27! *28! * Original Date: 03-2018,29! *****************************************************************************30!!! Compute standard 1D variables:31! 1: Time32! 2: Volume33! 3: Volume Above Floatation34! 4: Volume rate of change35! 5: SMB Flux36! 6: BMB Flux37! 7: Residual Flux38! 8: Ice Discharge39! 9: Ice flux at Grounding Line40! 10: Grounded ice area41! 11: Floating ice area42! 12: Ice Free area43! *****************************************************************************44SUBROUTINE Scalar_OUTPUT( Model,Solver,dt,TransientSimulation )45USE DefUtils46IMPLICIT NONE4748TYPE(Model_t) :: Model49TYPE(Solver_t):: Solver50REAL(KIND=dp) :: dt51LOGICAL :: TransientSimulation5253TYPE(Variable_t),POINTER :: GMVAR,FlowVar,HVar,HRVar,BedVar,DHDTVar54INTEGER,POINTER :: Permutation(:)5556REAL(KIND=dp) :: Volume,VAF57REAL(KIND=dp) :: DHDTFlux,SMBFlux,BMBFlux,HMinFlux58REAL(KIND=dp) :: GroundedArea,FloatingArea,FreeArea59REAL(KIND=dp) :: CalvingFlux60REAL(KIND=dp) :: GLFlux61REAL(KIND=dp),SAVE :: zsea,rhow6263REAL (KIND=dp), ALLOCATABLE, DIMENSION(:),SAVE :: NodeArea64REAL (KIND=dp), ALLOCATABLE, DIMENSION(:),SAVE :: LocalArea65REAL (KIND=dp), ALLOCATABLE, DIMENSION(:),SAVE :: NodalH,NodalDHDT,MinH,NodalGM66REAL (KIND=dp), ALLOCATABLE, DIMENSION(:),SAVE :: NodalSMB,NodalBMB,NodalMB67REAL (KIND=dp), ALLOCATABLE, DIMENSION(:),SAVE :: NodalHf68REAL (KIND=dp), ALLOCATABLE, DIMENSION(:),SAVE :: rhoi69REAL (KIND=dp), ALLOCATABLE, DIMENSION(:),SAVE :: Val,ParVal70REAL(KIND=dp),ALLOCATABLE,SAVE :: Basis(:), dBasisdx(:,:)7172INTEGER :: i73INTEGER :: ierr74INTEGER,PARAMETER :: NVal=1175INTEGER, PARAMETER :: io=1276INTEGER,PARAMETER :: DIM=2 !dimension of the pb restricted to 2 currently7778INTEGER :: FlowDofs7980LOGICAL,SAVE :: Firsttime=.TRUE.8182CHARACTER(LEN=MAX_NAME_LEN) :: SolverName='INITMIP_Scalar_OUTPUT'83CHARACTER(LEN=MAX_NAME_LEN),SAVE :: OUTPUT_FName84CHARACTER(LEN=MAX_NAME_LEN),ALLOCATABLE,SAVE :: ValueNames(:)8586CALL GET_VARIABLES()8788IF (Firsttime.OR.Solver%Mesh%Changed) THEN8990IF (.NOT.ASSOCIATED(Solver%Variable)) &91CALL FATAL(SolverName,'Solver%Variable Not associated')92IF (.NOT.ASSOCIATED(Solver%Matrix)) &93CALL FATAL(SolverName,'Solver%Matrix Not associated')9495IF ( CurrentCoordinateSystem() /= Cartesian ) &96CALL FATAL(SolverName,'Only For cartesian system')9798IF ( Model % Mesh % MeshDim /= DIM ) &99CALL FATAL(SolverName,'Only For 2D plan view')100101!## DO SOME ALLOCATION102CALL DO_ALLOCATION(Firsttime)103104!## Name of Saved variables105ValueNames(1)='Volume'106ValueNames(2)='Volume Above Floatation'107ValueNames(3)='Volume rate of change'108ValueNames(4)='SMB Flux'109ValueNames(5)='BMB Flux'110ValueNames(6)='Residual Flux'111ValueNames(7)='Ice Discharge'112ValueNames(8)='Ice flux at Grounding Line'113ValueNames(9)='Grounded ice area'114ValueNames(10)='Floating ice area'115ValueNames(11)='Ice Free area'116117IF (Firsttime) CALL GET_CONSTANTS(zsea,rhow)118IF (Firsttime) CALL INIT_OUTPUT_FILE(OUTPUT_FName)119IF (Firsttime) CALL COMPUTE_NodeArea(NodeArea)120Firsttime=.FALSE.121END IF122123124CALL BODY_INTEGRATION(Volume,VAF,DHDTFlux,SMBFlux,BMBFlux,HMinFlux,&125GroundedArea,FloatingArea,FreeArea)126127CALL BC_INTEGRATION(CalvingFlux)128129CALL COMPUTE_GL_FLUX(GLFlux)130131132Val(1)=Volume133Val(2)=VAF134135Val(3)=DHDTFlux136Val(4)=SMBFlux137Val(5)=BMBFlux138Val(6)=HMinFlux139140Val(7)=CalvingFlux141Val(8)= GLFlux142143Val(9)=GroundedArea144Val(10)=FloatingArea145Val(11)=FreeArea146147IF (ParEnv % PEs > 1 ) THEN148DO i=1,NVal149CALL MPI_ALLREDUCE(Val(i),ParVal(i),1,&150MPI_DOUBLE_PRECISION,MPI_SUM,MPI_COMM_WORLD,ierr)151END DO152Val(1:NVal)=ParVal(1:NVal)153END IF154155IF ((ParEnv % PEs > 1 ).AND.(ParEnv % MyPe.NE.0)) RETURN156157IF( Solver % TimesVisited > 0 ) THEN158OPEN(io,file=TRIM(OUTPUT_FName),position='append')159ELSE160OPEN(io,file=TRIM(OUTPUT_FName))161END IF162163write(io,'(ES22.12E3)',advance='no') GetTime()164Do i=1,NVal-1165write(io,'(ES22.12E3)',advance='no') Val(i)166End do167write(io,'(ES22.12E3)') Val(NVal)168CLOSE(io)169170CONTAINS171172SUBROUTINE DO_ALLOCATION(Firsttime)173LOGICAL,INTENT(IN) :: Firsttime174INTEGER :: M175INTEGER :: N176IF (.NOT.Firsttime) &177DEALLOCATE(NodalH,NodalDHDT,NodalHf,MinH,NodalGM,NodalSMB,NodalBMB,NodalMB,rhoi,&178LocalArea, &179Basis,dBasisdx,&180Val,ParVal,ValueNames,&181NodeArea)182N=Model % Mesh % NumberOfNodes183M=Model % MaxElementNodes184ALLOCATE(Basis(M),&185dBasisdx(M,3),&186NodalH(M),&187NodalDHDT(M),&188NodalHf(M),&189MinH(M),&190NodalGM(M),&191NodalSMB(M),&192NodalBMB(M),&193NodalMB(M),&194rhoi(M),&195LocalArea(M),&196Val(NVal),ParVal(NVal),ValueNames(NVal),&197NodeArea(N))198END SUBROUTINE DO_ALLOCATION199200SUBROUTINE GET_CONSTANTS(zsea,rhow)201IMPLICIT NONE202REAL(KIND=dp),INTENT(OUT) :: zsea,rhow203LOGICAL :: Found204205zsea = GetCReal( Model % Constants, 'Sea Level', Found )206IF (.NOT.Found) CALL FATAL(SolverName,'<Sea Level> not found')207rhow = GetCReal( Model % Constants, 'water density', Found )208IF (.NOT.Found) CALL FATAL(SolverName,'<water density not found')209END SUBROUTINE GET_CONSTANTS210211SUBROUTINE INIT_OUTPUT_FILE(OUTPUT_FName)212USE GeneralUtils213IMPLICIT NONE214CHARACTER(LEN=MAX_NAME_LEN),INTENT(OUT) :: OUTPUT_FName215216CHARACTER(LEN=MAX_NAME_LEN) ::NamesFile,&217OUTPUT_FName_D='INITMIP_Scalar_OUTPUT.dat'218219CHARACTER(LEN=MAX_NAME_LEN) :: DateStr220TYPE(ValueList_t), POINTER :: SolverParams221LOGICAL :: Found222INTEGER :: i223224SolverParams=>GetSolverParams(Solver)225OUTPUT_FName = ListGetString(SolverParams,'File Name',Found)226IF (.NOT.Found) OUTPUT_FName=OUTPUT_FName_D227228NamesFile = TRIM(OUTPUT_FName) // '.' // TRIM("names")229230IF ((ParEnv % PEs >1).AND.(ParEnv%MyPe.NE.0)) RETURN231232DateStr = FormatDate()233234OPEN(io,file=TRIM(NamesFile))235WRITE(io,'(A)') 'File started at: '//TRIM(DateStr)236WRITE(io,'(A)') ' '237WRITE(io,'(A)') 'Elmer version: '//TRIM(GetVersion())238WRITE(io,'(A)') 'Elmer revision: '//TRIM(GetRevision())239WRITE(io,'(A)') 'Elmer Compilation Date: '//TRIM(GetCompilationDate())240WRITE(io,'(A)') ' '241WRITE(io,'(A)') 'Variables in columns of matrix:'//TRIM(OUTPUT_FName)242WRITE(io,'(I4,": ",A)') 1,'Time'243DO i=1,NVal244WRITE(io,'(I4,": ",A)') i+1,TRIM(ValueNames(i))245END DO246CLOSE(io)247END SUBROUTINE INIT_OUTPUT_FILE248249SUBROUTINE GET_VARIABLES()250HVar => VariableGet(Solver%Mesh%Variables,'h',UnfoundFatal=.TRUE.)251252DHDTVar => VariableGet(Solver%Mesh%Variables,'dhdt',UnfoundFatal=.TRUE.)253254HRVar => VariableGet(Solver%Mesh%Variables,'h loads')255IF (.NOT.ASSOCIATED(HRVar)) &256HRVar => VariableGet(Solver%Mesh%Variables,'h residual',UnfoundFatal=.TRUE.)257258BedVar => VariableGet(Solver%Mesh%Variables,'bedrock',UnfoundFatal=.TRUE.)259260GMVar => VariableGet(Solver%Mesh%Variables,'GroundedMask',UnfoundFatal=.TRUE.)261262FlowVar => VariableGet(Solver%Mesh%Variables,'SSAVelocity',UnfoundFatal=.TRUE.)263FlowDofs = FlowVar % DOFs264265Permutation => Solver%Variable%Perm266END SUBROUTINE GET_VARIABLES267268SUBROUTINE COMPUTE_NodeArea(NodeArea)269IMPLICIT NONE270REAL(KIND=dp),INTENT(OUT) :: NodeArea(:)271272TYPE(Element_t), POINTER :: Element273TYPE(Nodes_t),SAVE :: ElementNodes274TYPE(GaussIntegrationPoints_t) :: IntegStuff275REAL(KIND=dp) :: U,V,W,SqrtElementMetric276INTEGER,POINTER :: Indexes(:)277INTEGER :: n278INTEGER :: t,i279LOGICAL :: stat280281282NodeArea=0._dp283284Do t=1,GetNOFActive()285286Element => GetActiveElement(t)287n = GetElementNOFNodes(Element)288Indexes => Element % NodeIndexes289CALL GetElementNodes( ElementNodes, Element )290IntegStuff = GaussPoints( Element )291292Do i=1,IntegStuff % n293U = IntegStuff % u(i)294V = IntegStuff % v(i)295W = IntegStuff % w(i)296stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &297Basis,dBasisdx )298299NodeArea(Permutation(Indexes(1:n)))=NodeArea(Permutation(Indexes(1:n)))+&300SqrtElementMetric*IntegStuff % s(i) * Basis(1:n)301302End do303End do304IF (ParEnv % PEs > 1 ) CALL ParallelSumVector( Solver % Matrix, NodeArea, 0 )305306END SUBROUTINE COMPUTE_NodeArea307308SUBROUTINE BODY_INTEGRATION(Volume,VAF,DHDTFlux,SMBFlux,BMBFlux,HMinFlux,&309GroundedArea,FloatingArea,FreeArea)310IMPLICIT NONE311REAL(KIND=dp),INTENT(OUT) :: Volume,VAF,&312DHDTFlux,SMBFlux,BMBFlux,HMinFlux,&313GroundedArea,FloatingArea,FreeArea314REAL(KIND=dp),parameter :: Fsmall=100.0*EPSILON(1.0)315316TYPE(Element_t),POINTER :: Element317TYPE(ValueList_t), POINTER :: BodyForce,Material318TYPE(GaussIntegrationPoints_t) :: IntegStuff319TYPE(Nodes_t),SAVE :: ElementNodes320321REAL(KIND=dp) :: U,V,W,SqrtElementMetric322REAL(KIND=dp) :: Normal(3),Flow(3)323REAL(KIND=dp) :: cellarea324REAL(KIND=dp) :: HAtIP,SMBAtIP,BMBAtIP325326LOGICAL :: CalvingFront327LOGICAL :: IsFloating,IceFree328LOGICAL :: stat329330INTEGER,POINTER :: NodeIndexes(:)331INTEGER :: t332INTEGER :: i333INTEGER :: n334INTEGER :: ne335336ne=GetNOFActive()337338Volume=0._dp339VAF=0._dp340341DHDTFlux=0._dp342SMBFlux=0._dp343BMBFlux=0._dp344HMinFlux=0._dp345346GroundedArea=0._dp347FloatingArea=0._dp348FreeArea=0._dp349350DO t = 1,ne351352Element => GetActiveElement(t)353354IF ( CheckPassiveElement(Element) ) CYCLE355356n = GetElementNOFNodes(Element)357NodeIndexes => Element % NodeIndexes358CALL GetElementNodes( ElementNodes )359360BodyForce => GetBodyForce(Element)361IF (.NOT.ASSOCIATED(BodyForce)) &362CALL FATAL(SolverName,'No BodyForce Found')363Material => GetMaterial(Element)364IF (.NOT.ASSOCIATED(Material)) &365CALL FATAL(SolverName,'No Material Found')366367NodalH(1:n) = HVar%Values(HVar%Perm(NodeIndexes(1:n)))368NodalDHDT(1:n) = DHDTVar%Values(DHDTVar%Perm(NodeIndexes(1:n)))369370rhoi(1:n) = ListGetReal(Material,'SSA Mean Density',n,NodeIndexes,UnfoundFatal=.TRUE. )371372Do i=1,n373NodalHf(i)=Max(0._dp,NodalH(i)-&374Max(0._dp,(zsea-BedVar%Values(BedVar%Perm(NodeIndexes(i))))*rhow/rhoi(i)))375End do376377MinH=0._dp378MinH(1:n) = ListGetReal(Material,'Min H',n,NodeIndexes,UnfoundFatal=.TRUE. )379380381! FLOATING OR GROUNDED CELL382NodalGM(1:n) = GMVar%Values(GMVar%Perm(NodeIndexes(1:n)))383IsFloating=ANY(NodalGM(1:n).LT.0._dp)384385! TOP ACCUMULATION386NodalSMB=0._dp387NodalSMB(1:n) = &388ListGetReal(BodyForce,'Top Surface Accumulation', n,NodeIndexes,UnfoundFatal=.TRUE. )389390! Bottom ACCUMULATION391NodalBMB=0._dp392NodalBMB(1:n) = &393ListGetReal(BodyForce,'Bottom Surface Accumulation', n,NodeIndexes,UnfoundFatal=.TRUE. )394395! Total ACCUMULATION396NodalMB(1:n) = NodalSMB(1:n) + NodalBMB(1:n)397398! CELL IS NOT ACTIVE ALL H VALUES BELOW MinH Value399IceFree=.FALSE.400IF (ALL((NodalH(1:n)-MinH(1:n)).LE.Fsmall).AND.ALL(NodalMB(1:n).LT.0._dp)) IceFree=.TRUE.401402! GO TO INTEGRATION403cellarea=0._dp404LocalArea=0._dp405406IntegStuff = GaussPoints( Element )407DO i=1,IntegStuff % n408U = IntegStuff % u(i)409V = IntegStuff % v(i)410W = IntegStuff % w(i)411412stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &413Basis,dBasisdx )414! cell area415cellarea=cellarea+SqrtElementMetric*IntegStuff % s(i)416! the area seen by each node417LocalArea(1:n)=LocalArea(1:n)+SqrtElementMetric*IntegStuff % s(i) * Basis(1:n)418419IF (IceFree) CYCLE420421! Integrate H422HAtIP=SUM(NodalH(1:n)*Basis(1:n))423Volume=Volume+HAtIP*SqrtElementMetric*IntegStuff % s(i)424425VAF=VAF+SUM(NodalHf(1:n)*Basis(1:n))*SqrtElementMetric*IntegStuff % s(i)426427SMBAtIP=SUM(NodalSMB(1:n)*Basis(1:n))428BMBAtIP=SUM(NodalBMB(1:n)*Basis(1:n))429430DHDTFlux=DHDTFlux+SUM(NodalDHDT(1:n)*Basis(1:n))*SqrtElementMetric*IntegStuff % s(i)431SMBFlux=SMBFlux+SMBAtIP*SqrtElementMetric*IntegStuff % s(i)432BMBFlux=BMBFlux+BMBAtIP*SqrtElementMetric*IntegStuff % s(i)433434End DO435436IF (.NOT.IceFree) THEN437Do i=1,n438HMinFlux = HMinFlux + &439HRVar%Values(HRVar%Perm(NodeIndexes(i)))*LocalArea(i)/NodeArea(Permutation(NodeIndexes(i)))440End do441IF (IsFloating) THEN442FloatingArea=FloatingArea+cellarea443ELSE444GroundedArea=GroundedArea+cellarea445END IF446ELSE447FreeArea=FreeArea+cellarea448END IF449End do450END SUBROUTINE BODY_INTEGRATION451452SUBROUTINE BC_INTEGRATION(CalvingFlux)453IMPLICIT NONE454REAL(KIND=dp),INTENT(OUT) :: CalvingFlux455456TYPE(Element_t),POINTER :: Element457TYPE(ValueList_t), POINTER :: BC458TYPE(GaussIntegrationPoints_t) :: IntegStuff459TYPE(Nodes_t),SAVE :: ElementNodes460461REAL(KIND=dp) :: U,V,W,SqrtElementMetric462REAL(KIND=dp) :: Normal(3),Flow(3)463464LOGICAL :: CalvingFront465LOGICAL :: Found466LOGICAL :: stat467468INTEGER,POINTER :: NodeIndexes(:)469INTEGER :: t470INTEGER :: i,j471INTEGER :: n472473CalvingFlux=0._dp474DO t = 1,GetNOFBoundaryElements()475Element => GetBoundaryElement(t)476477IF ( .NOT. ActiveBoundaryElement() ) CYCLE478IF ( GetElementFamily() == 1 ) CYCLE479480BC => GetBC()481IF ( .NOT. ASSOCIATED(BC) ) CYCLE482CalvingFront=.FALSE.483CalvingFront=ListGetLogical(BC,'Calving Front', Found)484IF (.NOT.CalvingFront) CYCLE485486n = GetElementNOFNodes()487NodeIndexes => Element % NodeIndexes488CALL GetElementNodes( ElementNodes )489490NodalH(1:n) = HVar%Values(HVar%Perm(NodeIndexes(1:n)))491492IntegStuff = GaussPoints( Element )493DO i=1,IntegStuff % n494U = IntegStuff % u(i)495V = IntegStuff % v(i)496W = IntegStuff % w(i)497stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &498Basis,dBasisdx )499Normal=0._dp500Normal = NormalVector( Element,ElementNodes,u,v,.TRUE. )501502Flow=0._dp503DO j=1,FlowDofs504Flow(j) = SUM( FlowVar % Values(FlowDofs*(FlowVar % Perm(NodeIndexes(1:n)) -1)+j) * Basis(1:n) )505END DO506CalvingFlux=CalvingFlux+&507SUM(NodalH(1:n)*Basis(1:n))*SUM(Normal * Flow)*SqrtElementMetric*IntegStuff % s(i)508END DO509END DO510END SUBROUTINE BC_INTEGRATION511512513SUBROUTINE COMPUTE_GL_FLUX( GLFlux )514IMPLICIT NONE515REAL(KIND=DP),INTENT(OUT) :: GLFlux516517TYPE(Mesh_t),POINTER :: Mesh518TYPE(Element_t),DIMENSION(:),POINTER :: Edges519TYPE(Element_t),POINTER :: Edge,Parent520521REAL(KIND=DP),ALLOCATABLE,SAVE :: LocalGM(:),LocalFlow(:,:),LocalH(:)522523INTEGER, POINTER :: NodeIndexes(:)524INTEGER :: Ne525INTEGER :: n526INTEGER :: i,j527INTEGER :: M528529LOGICAL, SAVE :: Firsttime=.TRUE.530531532IF (Firsttime) THEN533M=Model % MaxElementNodes534ALLOCATE(LocalGM(M),LocalFlow(3,M),LocalH(M))535Firsttime=.FALSE.536END IF537538Mesh => GetMesh()539540541CALL FindMeshEdges(Mesh,.FALSE.)542543Edges => Mesh % Edges544Ne = Mesh % NumberOfEdges545546GLFlux=0._dp547548DO i=1,Ne549Edge => Edges(i)550n=Edge % TYPE % NumberOfNodes551NodeIndexes(1:n) => Edge % NodeIndexes(1:n)552553LocalGM(1:n)=GMVar % Values ( GMVar % Perm ( NodeIndexes(1:n) ) )554! Edge is GL if all GM=0555IF ( ANY( abs(LocalGM(1:n)) .GT. AEPS ) ) CYCLE556557DO j=1,DIM558LocalFlow(j,1:n) = FlowVar % Values ( DIM*(FlowVar % Perm ( NodeIndexes(1:n) ) - 1) + j )559END DO560LocalH(1:n) = HVar % Values ( HVar % Perm ( NodeIndexes(1:n) ) )561562Parent => Edge % BoundaryInfo % Right563CALL AddLocalFlux(GLFlux,LocalFlow,LocalH,Edge,Parent,Mesh)564Parent => Edge % BoundaryInfo % Left565CALL AddLocalFlux(GLFlux,LocalFlow,LocalH,Edge,Parent,Mesh)566END DO567568END SUBROUTINE COMPUTE_GL_FLUX569570SUBROUTINE AddLocalFlux(Flux,LocalFlow,LocalH,Edge,Parent,Mesh)571IMPLICIT NONE572TYPE(Element_t),POINTER :: Edge,Parent573TYPE(Mesh_t), POINTER :: Mesh574REAL(KIND=dp),INTENT(INOUT) :: Flux575REAL(KIND=dp),INTENT(IN) :: LocalFlow(:,:),LocalH(:)576577TYPE(Nodes_t),SAVE :: EdgeNodes578TYPE(GaussIntegrationPoints_t) :: IntegStuff579REAL(KIND=dp) :: U,V,W,SqrtElementMetric580REAL(KIND=dp),ALLOCATABLE,SAVE :: Basis(:), dBasisdx(:,:)581582REAL(KIND=dp),DIMENSION(3) :: dx, Normal,Flow583REAL(KIND=dp) :: h584585INTEGER :: i,j586INTEGER :: n,np587INTEGER :: M588589LOGICAL :: stat590LOGICAL,SAVE :: FirstVisit=.TRUE.591592IF (FirstVisit) THEN593M=Model % MaxElementNodes594ALLOCATE(Basis(M),dBasisdx(M,3))595FirstVisit=.FALSE.596END IF597598! Parent not associated599IF (.NOT.ASSOCIATED(Parent)) RETURN600! Parent is halo element601IF( Parent % PartIndex /= ParEnv % MyPe ) RETURN602!603n = Edge % TYPE % NumberOfNodes604np = Parent % TYPE % NumberOfNodes605606! GL could be a boundary; compute flux from gounded parent607! Parent is Grounded if ANY GM > 0608IF (.NOT.( ANY( GMVar % Values( GMVar % Perm( Parent % NodeIndexes(1:np) ) ) .GT. AEPS ) ) ) RETURN609! a vector from the center of the edge to the center of the parent to check that normal points outside parent610dx = ElementCenter(Mesh,Parent) - ElementCenter(Mesh,Edge)611612CALL GetElementNodes(EdgeNodes, Edge)613614IntegStuff = GaussPoints( Edge )615DO i=1,IntegStuff % n616U = IntegStuff % u(i)617V = IntegStuff % v(i)618W = IntegStuff % w(i)619stat = ElementInfo( Edge,EdgeNodes,U,V,W,SqrtElementMetric, &620Basis,dBasisdx )621622DO j=1,DIM623Flow(j) = SUM(LocalFlow(j,1:n)*Basis(1:n))624END DO625h = SUM(LocalH(1:n)*Basis(1:n))626627Normal = NormalVector( Edge,EdgeNodes,U,V,.FALSE. )628629IF ( SUM(dx(1:DIM)*Normal(1:DIM)).GT.0._dp ) Normal=-Normal630631Flux = Flux + SqrtElementMetric * IntegStuff % s(i) * h * SUM(Normal(1:DIM)*Flow(1:DIM))632END DO633634END SUBROUTINE AddLocalFlux635!636!637FUNCTION ElementCenter(Mesh,Element) RESULT(xc)638IMPLICIT NONE639TYPE(Mesh_t), POINTER :: Mesh640TYPE(Element_t),POINTER :: Element641REAL(KIND=dp),DIMENSION(3) :: xc642INTEGER :: n643644n = Element % TYPE % NumberOfNodes645xc=0._dp646SELECT CASE( Element % TYPE % ElementCode / 100 )647CASE(2,4,8)648xc(1) = InterpolateInElement( Element, Mesh % Nodes % x(Element % NodeIndexes(1:n)), 0.0d0, 0.0d0, 0.0d0 )649xc(2) = InterpolateInElement( Element, Mesh % Nodes % y(Element % NodeIndexes(1:n)), 0.0d0, 0.0d0, 0.0d0 )650CASE(3)651xc(1) = InterpolateInElement( Element, Mesh % Nodes % x(Element % NodeIndexes(1:n)), 1.0d0/3, 1.0d0/3, 0.0d0 )652xc(2) = InterpolateInElement( Element, Mesh % Nodes % y(Element % NodeIndexes(1:n)), 1.0d0/3, 1.0d0/3, 0.0d0 )653CASE DEFAULT654CALL FATAL(SolverName,'Element type not supported')655END SELECT656657END FUNCTION ElementCenter658659660661662END663664665