Path: blob/devel/fem/tests/AdvReactDG_P/AdvReactDG_P.F90
3206 views
!/*****************************************************************************/1! *2! * Elmer, A Finite Element Software for Multiphysical Problems3! *4! * Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland5! *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! *25! * Authors: Mikko, Lyly, Juha Ruokolainen, Thomas Zwinger26! * Email: [email protected]27! * Web: http://www.csc.fi/elmer28! * Address: CSC - IT Center for Science Ltd.29! * Keilaranta 1430! * 02101 Espoo, Finland31! *32! * Original Date: 04 Apr 200433! *34! ****************************************************************************3536!------------------------------------------------------------------------------37!> Advection-reaction equation solver for scalar fields with discontinuous Galerkin method.38!> \ingroup Solvers39!------------------------------------------------------------------------------40SUBROUTINE AdvectionReactionSolver( Model,Solver,dt,Transient )41!------------------------------------------------------------------------------42USE DefUtils4344IMPLICIT NONE45!------------------------------------------------------------------------------46TYPE(Model_t) :: Model !< All model information (mesh, materials, BCs, etc...)47TYPE(Solver_t), TARGET :: Solver !< Linear & nonlinear equation solver options48REAL(KIND=dp) :: dt !< Timestep size for time dependent simulations49LOGICAL :: Transient !< Steady state or transient simulation50!------------------------------------------------------------------------------51! Local variables52!------------------------------------------------------------------------------53TYPE(ValueList_t), POINTER :: BC, BodyForce, Material,&54Equation, Constants, SolverParams5556TYPE(Element_t), POINTER :: Element, Face, &57ParentElement, P1, P25859LOGICAL :: AllocationsDone = .FALSE., Found, Stat, &60LimitSolution, FoundLowerLimit, FoundUpperLimit61INTEGER :: Active, DIM,NonLinearIterMin,NonlinearIterMax,iter,&62CorrectedLowerLimit,CorrectedUpperLimit63INTEGER :: n1,nd1,nd2,n2, k, n, nd,t, istat, i, j, dummyInt, NumberOfFAces, Indexes(128)64REAL(KIND=dp) :: Norm,RelativeChange,at,at0,totat,st,totst,&65OriginalValue66REAL(KIND=dp), ALLOCATABLE :: MASS(:,:), STIFF(:,:), LOAD(:), &67FORCE(:), Velo(:,:), MeshVelo(:,:), Gamma(:), Ref(:), &68UpperLimit(:), LowerLimit(:)69TYPE(Mesh_t), POINTER :: Mesh70TYPE(Variable_t), POINTER :: Var71CHARACTER(LEN=MAX_NAME_LEN) :: VariableName, SolverName, ExpVariableName7273SAVE MASS, STIFF, LOAD, FORCE, Velo, MeshVelo, Gamma, &74AllocationsDone, DIM, VariableName, SolverName, &75UpperLimit, LowerLimit76!*******************************************************************************7778TYPE( Element_t ), POINTER :: Faces(:)79TYPE(Nodes_t) :: ElementNodes8081INTEGER :: DOFs82!*******************************************************************************83SolverName = 'AdvectionReaction ('// TRIM(Solver % Variable % Name) // ')'84VariableName = TRIM(Solver % Variable % Name)85WRITE(Message,'(A,A)')&86'AdvectionReactionSolver for variable ', VariableName87CALL INFO(SolverName,Message,Level=1)8889Mesh => GetMesh()9091IF ( CoordinateSystemDimension() == 2 ) THEN92Faces => Mesh % Edges93NumberOfFaces = Mesh % NumberOfEdges94ELSE95Faces => Mesh % Faces96NumberOfFaces = Mesh % NumberOfFaces97END IF9899! Initialize & allocate some permanent storage, this is done first time only:100!----------------------------------------------------------------------------101IF ( .NOT. AllocationsDone ) THEN102103N = 2 * MAX(Mesh % MaxElementDOFs, Mesh % MaxElementNodes )104ALLOCATE( FORCE(N), MASS(n,n), STIFF(N,N), LOAD(N), &105Velo(3,N), MeshVelo( 3,N ), Gamma(n), &106UpperLimit(n), LowerLimit(n), STAT = istat )107108IF ( istat /= 0 ) THEN109CALL FATAL(SolverName,'Memory allocation error.' )110ELSE111CALL INFO(SolverName,'Memory allocation done',Level=1 )112END IF113DIM = CoordinateSystemDimension()114AllocationsDone = .TRUE.115END IF116117!------------------------------------------------------------------------------118! Read physical and numerical constants and initialize119!------------------------------------------------------------------------------120Constants => GetConstants()121SolverParams => GetSolverParams()122123NonlinearIterMax = GetInteger( SolverParams, &124'Nonlinear System Max Iterations', Found )125IF ( .NOT.Found ) THEN126CALL WARN(SolverName,'No > Nonlinear System Max Iterations < found. Setting 1')127NonlinearIterMax = 1128END IF129130NonlinearIterMin = GetInteger( SolverParams, &131'Nonlinear System Min Iterations', Found )132IF ( .NOT.Found ) THEN133CALL WARN(SolverName,'No >Nonlinear System Min Iterations< found. Setting 1')134NonlinearIterMin = 1135ELSE IF (NonlinearIterMin > NonlinearIterMax) THEN136CALL WARN(SolverName,&137'>Nonlinear System Min Iterations< is exceeding >Nonlinear System Max Iterations<.')138CALL WARN(SolverName,&139'First is being reset to the latter.')140NonlinearIterMin = NonlinearIterMax141END IF142143ExpVariableName = GetString(SolverParams , 'Exported Variable 1', Found )144IF (.NOT.Found) &145CALL FATAL(SolverName,'No value > Exported Variable 1 < found in Solver')146147!------------------------------------------------------------------------------148! non-linear system iteration loop149!------------------------------------------------------------------------------150totat = 0; totst = 0151DO iter=1,NonlinearIterMax152! Assembly of the bulk elements:153!-------------------------------154!------------------------------------------------------------------------------155! print out some information156!------------------------------------------------------------------------------157at = CPUTime()158at0 = RealTime()159160CALL Info( SolverName, ' ', Level=4 )161CALL Info( SolverName, ' ', Level=4 )162CALL Info( SolverName, '-------------------------------------',Level=4 )163WRITE( Message,'(A,I3,A,I3)') &164'Nonlinear iteration no.', iter,' of max',NonlinearIterMax165CALL Info( SolverName, Message, Level=4 )166CALL Info( SolverName, '-------------------------------------',Level=4 )167CALL Info( SolverName, ' ', Level=4 )168CALL Info( SolverName, 'Starting Assembly...', Level=4 )169170171CALL DefaultInitialize()172Active = GetNOFActive()173DO t = 1, Active174!------------------------------------------------------------------------------175! write some info on status of assembly176!------------------------------------------------------------------------------177IF ( RealTime() - at0 > 1.0 ) THEN178! WRITE(Message,'(a,i3,a)' ) ' Assembly: ', INT(100.0 - 100.0 * &179! (Active-t) / &180! (1.0*Active)), ' % done'181!182! CALL Info( SolverName, Message, Level=5 )183184at0 = RealTime()185END IF186!------------------------------------------------------------------------------187! assign pointers and get number of nodes in element188!------------------------------------------------------------------------------189Element => GetActiveElement(t)190n = GetElementNOfNodes(Element)191nd = GetElementNOfDOFs(Element)192193Material => GetMaterial(Element)194Equation => GetEquation(Element)195BodyForce => GetBodyForce(Element)196197!------------------------------------------------------------------------------198LOAD(1:n) = GetReal( BodyForce, TRIM(VariableName) // ' Source', Found )199200!------------------------------------------------------------------------------201! Get convection and mesh velocity202CALL GetLocalALEVelocity(Velo,MeshVelo,SolverName,Material,&203Equation,Solver,Model,Element)204205!--------------------------206! get reaction coefficient207!--------------------------208Gamma(1:n) = GetReal( Material, TRIM(VariableName)//' Gamma', Found )209210CALL LocalMatrix(MASS, STIFF, FORCE, LOAD, Velo, Gamma, Element, n,nd)211IF ( Transient ) CALL Default1stOrderTime(MASS, STIFF, FORCE)212CALL DefaultUpdateEquations(STIFF, FORCE)213END DO214215216! Assembly of the face terms:217!----------------------------218FORCE = 0.0_dp219DO t=1,NumberOfFaces220Face => Faces(t)221IF ( .NOT. ActiveBoundaryElement(Face) ) CYCLE222223P1 => Face % BoundaryInfo % Left224P2 => Face % BoundaryInfo % Right225IF ( ASSOCIATED(P2) .AND. ASSOCIATED(P1) ) THEN226n = GetElementNOFNodes(Face)227n1 = GetElementNOFNodes(P1)228n2 = GetElementNOFNodes(P2)229230nd = GetElementNOFDOFs(Face)231nd1 = GetElementNOFDOFs(P1)232nd2 = GetElementNOFDOFs(P2)233234!------------------------------------------------------------------------------235! Get convection and mesh velocity236!------------------------------------------------------------------------------237Material => GetMaterial(P1)238Equation => GetEquation(P1)239CALL GetLocalALEVelocity(Velo,MeshVelo,SolverName,Material,&240Equation,Solver,Model,Face)241242CALL LocalJumps( STIFF,Face,n,nd,P1,n1,nd1,P2,n2,nd2,Velo )243CALL DefaultUpdateEquations( STIFF, FORCE, Face )244END IF245END DO246247! Loop over the boundary elements:248!---------------------------------249DO t=1,Mesh % NumberOfBoundaryElements250Element => GetBoundaryElement(t)251IF( .NOT. ActiveBoundaryElement() ) CYCLE252IF( GetElementFamily(Element) < dim ) CYCLE253254ParentElement => Element % BoundaryInfo % Left255IF ( .NOT. ASSOCIATED( ParentElement ) ) &256ParentElement => Element % BoundaryInfo % Right257258n1 = GetElementNOFnodes(ParentElement)259n = GetElementNOFNodes(Element)260261nd = GetElementNOFDOFs(Element)262nd1 = GetElementNOFDOFs(ParentElement)263!------------------------------------------------------------------------------264! Get convection and mesh velocity265!------------------------------------------------------------------------------266Material => GetMaterial(ParentElement)267Equation => GetEquation(ParentElement)268CALL GetLocalALEVelocity(Velo,MeshVelo,SolverName,Material,&269Equation,Solver,Model,Element)270271BC => GetBC()272LOAD = 0.0_dp273Found = .FALSE.274IF ( ASSOCIATED(BC) ) THEN275LOAD(1:n) = GetReal(BC, Solver % Variable % Name, Found)276END IF277278MASS = 0.0_dp279CALL LocalMatrixBoundary( STIFF, FORCE, LOAD, &280Element, n, nd, ParentElement, n1, nd1, Velo, Found )281282IF ( Transient ) CALL Default1stOrderTime(MASS, STIFF, FORCE)283CALL DefaultUpdateEquations(STIFF, FORCE)284END DO285286CALL DefaultFinishAssembly()287CALL Info( SolverName, 'Assembly done', Level=4 )288289!------------------------------------------------------------------------------290! Solve the system and check for convergence291!------------------------------------------------------------------------------292at = CPUTime() - at293st = CPUTime()294295! Solve the system:296!------------------297Norm = DefaultSolve()298299st = CPUTIme()-st300totat = totat + at301totst = totst + st302WRITE(Message,'(a,i4,a,F8.2,F8.2)') 'iter: ',iter,' Assembly: (s)', at, totat303CALL Info( SolverName, Message, Level=4 )304WRITE(Message,'(a,i4,a,F8.2,F8.2)') 'iter: ',iter,' Solve: (s)', st, totst305CALL Info( SolverName, Message, Level=4 )306307RelativeChange = Solver % Variable % NonlinChange308309IF ( Solver % Variable % NonlinConverged == 1 ) THEN310WRITE(Message,'(A,I6,A,I6,A)') &311'Nonlinear iteration converged after ', iter, &312' out of max ',NonlinearIterMax,' iterations'313CALL INFO(SolverName,Message)314EXIT315ELSE IF ((iter .EQ. NonlinearIterMax) .AND. (NonlinearIterMax > 1)) THEN316CALL WARN(SolverName,'Maximum nonlinear iterations reached, but system not converged')317END IF318319!-----------------------------------------------320END DO ! End of nonlinear iteration loop321!----------------------------------------------322323324! Average the elemental results to nodal values:325!-----------------------------------------------326Var => VariableGet( Mesh % Variables,TRIM(ExpVariableName))327IF ( ASSOCIATED( Var ) ) THEN328n1 = Mesh % NumberOfNodes329ALLOCATE( Ref(n1) )330Ref = 0331Var % Type = Variable_on_nodes332333IF ( ASSOCIATED( Var % Perm, Solver % Variable % Perm ) ) THEN334ALLOCATE( Var % Perm(SIZE(Solver % Variable % Perm)) )335Var % Perm = 0336DO i = 1,n1337Var % Perm(i) = i338END DO339END IF340341Var % Values = 0.0d0342DO t=1,Active343Element => GetActiveElement(t)344n = GetElementDOFs(Indexes)345n = GetElementNOFNodes()346DO i=1,n347k = Element % NodeIndexes(i)348Var % Values(k) = Var % Values(k) + &349Solver % Variable % Values( Solver % Variable % Perm(Indexes(i)) )350Ref(k) = Ref(k) + 1351END DO352END DO353354WHERE( Ref > 0 )355Var % Values(1:n1) = Var % Values(1:n1) / Ref356END WHERE357DEALLOCATE( Ref )358ELSE359WRITE(Message,'(A,A,A)') 'Exported Variable >',TRIM(VariableName) // 'Nodal Result','< not found'360CALL FATAL(SolverName,Message)361END IF362363CONTAINS364365!------------------------------------------------------------------------------366SUBROUTINE LocalMatrix(MASS, STIFF, FORCE, LOAD, Velo, Gamma, Element, n,nd)367!------------------------------------------------------------------------------368REAL(KIND=dp) :: MASS(:,:), STIFF(:,:), FORCE(:), &369LOAD(:), Velo(:,:), Gamma(:)370INTEGER :: n,nd371TYPE(Element_t), POINTER :: Element372!------------------------------------------------------------------------------373REAL(KIND=dp) :: Basis(nd),dBasisdx(nd,3)374REAL(KIND=dp) :: detJ,U,V,W,S,A,L,cu(3),g375LOGICAL :: Stat376INTEGER :: i,p,q,t,dim377TYPE(GaussIntegrationPoints_t) :: IntegStuff378TYPE(Nodes_t), SAVE :: Nodes379!------------------------------------------------------------------------------380dim = CoordinateSystemDimension()381382FORCE = 0.0_dp383STIFF = 0.0_dp384MASS = 0.0_dp385386CALL GetElementNodes(Nodes, Element)387!------------------------------------------------------------------------------388! Numerical integration389!------------------------------------------------------------------------------390IntegStuff = GaussPoints(Element)391392DO t=1,IntegStuff % n393U = IntegStuff % u(t)394V = IntegStuff % v(t)395W = IntegStuff % w(t)396S = IntegStuff % s(t)397!------------------------------------------------------------------------------398! Basis function values & derivatives at the integration point399!------------------------------------------------------------------------------400stat = ElementInfo( Element, Nodes, U, V, W, detJ, &401Basis, dBasisdx )402403S = S * detJ404L = SUM( LOAD(1:n) * Basis(1:n) )405g = SUM( Basis(1:n) * Gamma(1:n) )406407cu = 0.0_dp408DO i=1,dim409cu(i) = SUM(Basis(1:n) * Velo(i,1:n))410END DO411!------------------------------------------------------------------------------412! The advection-reaction equation: dc/dt + grad(u . c) + gamma c = s413!------------------------------------------------------------------------------414DO p=1,nd415DO q=1,nd416MASS(p,q) = MASS(p,q) + s * Basis(q) * Basis(p)417STIFF(p,q) = STIFF(p,q) + s * g * Basis(q) * Basis(p)418DO i=1,dim419STIFF(p,q) = STIFF(p,q) - s * cu(i) * Basis(q) * dBasisdx(p,i)420END DO421END DO422END DO423FORCE(1:nd) = FORCE(1:nd) + s*L*Basis(1:nd)424!------------------------------------------------------------------------------425END DO426!------------------------------------------------------------------------------427END SUBROUTINE LocalMatrix428!------------------------------------------------------------------------------429430431!------------------------------------------------------------------------------432SUBROUTINE LocalJumps(STIFF,Face,n,nd,P1,n1,nd1,P2,n2,nd2,Velo)433!------------------------------------------------------------------------------434IMPLICIT NONE435REAL(KIND=dp) :: STIFF(:,:), Velo(:,:)436INTEGER :: n,n1,n2,nd,nd1,nd2437TYPE(Element_t), POINTER :: Face, P1, P2438!------------------------------------------------------------------------------439REAL(KIND=dp) :: Basis(nd),P1Basis(nd1),P2Basis(nd2)440REAL(KIND=dp) :: Jump(nd1+nd2), Average(nd1+nd2)441REAL(KIND=dp) :: detJ, U, V, W, S, Udotn, xx, yy442LOGICAL :: Stat443INTEGER :: i, j, p, q, dim, t, nFace, nParent444TYPE(GaussIntegrationPoints_t) :: IntegStuff445REAL(KIND=dp) :: Normal(3), cu(3), LeftOut(3)446447TYPE(Nodes_t), SAVE :: FaceNodes, P1Nodes, P2Nodes448!------------------------------------------------------------------------------449dim = CoordinateSystemDimension()450STIFF = 0.0_dp451452CALL GetElementNodes(P1Nodes, P1)453CALL GetElementNodes(P2Nodes, P2)454CALL GetElementNodes(FaceNodes, Face)455!------------------------------------------------------------------------------456! Numerical integration over the edge457!------------------------------------------------------------------------------458IntegStuff = GaussPoints(Face)459460LeftOut(1) = SUM(P1Nodes % x(1:n1)) / n1461LeftOut(2) = SUM(P1Nodes % y(1:n1)) / n1462LeftOut(3) = SUM(P1Nodes % z(1:n1)) / n1463LeftOut(1) = SUM(FaceNodes % x(1:n)) / n - LeftOut(1)464LeftOut(2) = SUM(FaceNodes % y(1:n)) / n - LeftOut(2)465LeftOut(3) = SUM(FaceNodes % z(1:n)) / n - LeftOut(3)466467DO t=1,IntegStuff % n468U = IntegStuff % u(t)469V = IntegStuff % v(t)470W = IntegStuff % w(t)471S = IntegStuff % s(t)472473! Basis function values & derivatives at the integration point:474!--------------------------------------------------------------475stat = ElementInfo(Face, FaceNodes, U, V, W, detJ,Basis)476S = S * detJ477478Normal = NormalVector(Face, FaceNodes, U, V, .FALSE.)479IF (SUM(LeftOut*Normal)<0) Normal = -Normal480481! Find basis functions for the parent elements:482! ---------------------------------------------483CALL FindParentUVW(Face,n,P1,n1,U,V,W,Basis)484stat = ElementInfo(P1, P1Nodes, U, V, W, detJ, P1Basis)485486CALL FindParentUVW(Face,n,P2,n2,U,V,W,Basis)487stat = ElementInfo(P2, P2Nodes, U, V, W, detJ, P2Basis)488489! Integrate jump terms:490! ---------------------491Jump(1:nd1) = P1Basis(1:nd1)492Jump(nd1+1:nd1+nd2) = -P2Basis(1:nd2)493494Average(1:nd1) = P1Basis(1:nd1) / 2495Average(nd1+1:nd1+nd2) = P2Basis(1:nd2) / 2496497cu = 0.0_dp498DO i=1,dim499cu(i) = SUM( Velo(i,1:n) * Basis(1:n) )500END DO501Udotn = SUM( Normal * cu )502503DO p=1,nd1+nd2504DO q=1,nd1+nd2505STIFF(p,q) = STIFF(p,q) + s * Udotn * Average(q) * Jump(p)506STIFF(p,q) = STIFF(p,q) + s * ABS(Udotn)/2 * Jump(q) * Jump(p)507END DO508END DO509END DO510!------------------------------------------------------------------------------511END SUBROUTINE LocalJumps512!------------------------------------------------------------------------------513514515516!------------------------------------------------------------------------------517SUBROUTINE LocalMatrixBoundary( STIFF, FORCE, LOAD, &518Element, n, nd, ParentElement, np, npd,Velo, InFlowBC )519!------------------------------------------------------------------------------520REAL(KIND=dp) :: STIFF(:,:), FORCE(:), LOAD(:), Velo(:,:)521INTEGER :: n, np,nd,npd522LOGICAL :: InFlowBC523TYPE(Element_t), POINTER :: Element, ParentElement524!------------------------------------------------------------------------------525REAL(KIND=dp) :: Basis(nd), ParentBasis(npd)526INTEGER :: i,j,k,m,p,q,t,dim527528REAL(KIND=dp) :: Normal(3), g, L, Udotn, cu(3), detJ,U,V,W,S529LOGICAL :: Stat, Inflow530TYPE(GaussIntegrationPoints_t) :: IntegStuff531532TYPE(Nodes_t) :: Nodes, ParentNodes533!------------------------------------------------------------------------------534dim = CoordinateSystemDimension()535FORCE = 0.0_dp536STIFF = 0.0_dp537538CALL GetElementNodes(Nodes, Element)539CALL GetElementNodes(ParentNodes, ParentElement)540541Normal = NormalVector( Element, Nodes, 0.0_dp, 0.0_dp, .TRUE. )542DO i=1,3543cu(i) = SUM(Velo(i,1:n)) / n544END DO545Inflow = InFlowBC .AND. SUM( Normal * cu ) < 0.0_dp546547! Numerical integration:548!-----------------------549IntegStuff = GaussPoints(Element)550551DO t=1,IntegStuff % n552U = IntegStuff % u(t)553V = IntegStuff % v(t)554W = IntegStuff % w(t)555S = IntegStuff % s(t)556557Normal = NormalVector(Element, Nodes, U, V, .TRUE.)558559! Basis function values & derivatives at the integration point:560! -------------------------------------------------------------561stat = ElementInfo(Element, Nodes, U, V, W, detJ,Basis)562S = S * detJ563564CALL FindParentUVW(Element, n, ParentElement, np, U, V, W, Basis)565stat = ElementInfo( ParentElement, ParentNodes, U, V, W, &566detJ, ParentBasis)567568L = SUM(LOAD(1:n) * Basis(1:n))569cu = 0.0_dp570DO i=1,dim571cu(i) = SUM(Velo(i,1:n) * Basis(1:n))572END DO573Udotn = SUM(Normal*cu)574575DO p = 1,npd576IF ( Inflow ) THEN577FORCE(p) = FORCE(p) - s*Udotn*L*ParentBasis(p)578ELSE579DO q=1,npd580STIFF(p,q) = STIFF(p,q) + s*Udotn*ParentBasis(q)*ParentBasis(p)581END DO582END IF583END DO584END DO585!------------------------------------------------------------------------------586END SUBROUTINE LocalMatrixBoundary587!------------------------------------------------------------------------------588!589!------------------------------------------------------------------------------590SUBROUTINE GetLocalALEVelocity(Velo,MeshVelo,SolverName,Material,&591Equation,Solver,Model,Element)592IMPLICIT NONE593!------------------------------------------------------------------------------594REAL (KIND=dp) :: Velo(:,:), MeshVelo(:,:)595CHARACTER(LEN=MAX_NAME_LEN) :: SolverName596TYPE(ValueList_t), POINTER :: Material,Equation597TYPE(Solver_t), TARGET :: Solver598TYPE(Model_t), TARGET :: Model599TYPE(Element_t),POINTER :: Element600!------------------------------------------------------------------------------601CHARACTER(LEN=MAX_NAME_LEN) :: ConvectionFlag, FlowSolName602INTEGER :: i,j,k,N,FlowDOFs603INTEGER, POINTER :: FlowPerm(:)604REAL(KIND=dp), POINTER :: FlowSolution(:)605TYPE(Variable_t), POINTER :: FlowSol606LOGICAL :: Found607!------------------------------------------------------------------------------608n = GetElementNOFNodes( Element )609ConvectionFlag = GetString( Equation, 'Convection', Found )610IF (.NOT. Found) &611CALL FATAL(SolverName, 'No string for keyword >Convection< found in Equation')612Velo = 0.0d00613! constant (i.e., in section Material given) velocity614!---------------------------------------------------615IF ( ConvectionFlag == 'constant' ) THEN616Velo(1,1:N) = GetReal( Material, 'Convection Velocity 1', Found, Element )617IF (.NOT.Found) Velo(1,1:N) = 0.0d0618Velo(2,1:N) = GetReal( Material, 'Convection Velocity 2', Found, Element )619IF (.NOT.Found) Velo(2,1:N) = 0.0d0620Velo(3,1:N) = GetReal( Material, 'Convection Velocity 3', Found, Element )621IF (.NOT.Found) Velo(3,1:N) = 0.0d0622! computed velocity623!------------------Equation => GetEquation()624ELSE IF (ConvectionFlag == 'computed' ) THEN625FlowSolName = GetString( Equation,'Flow Solution Name', Found)626IF(.NOT.Found) THEN627CALL WARN(SolverName,'Keyword >Flow Solution Name< not found in section >Equation<')628CALL WARN(SolverName,'Taking default value >Flow Solution<')629WRITE(FlowSolName,'(A)') 'Flow Solution'630END IF631FlowSol => VariableGet( Solver % Mesh % Variables, FlowSolName )632IF ( ASSOCIATED( FlowSol ) ) THEN633FlowPerm => FlowSol % Perm634FlowDOFs = FlowSol % DOFs635FlowSolution => FlowSol % Values636ELSE637WRITE(Message,'(A,A,A)') &638'Convection flag set to >computed<, but no variable >',FlowSolName,'< found'639CALL FATAL(SolverName,Message)640END IF641642643DO i=1,n644k = FlowPerm(Element % NodeIndexes(i))645IF ( k > 0 ) THEN646! Pressure = FlowSolution(FlowDOFs*k)647648SELECT CASE( FlowDOFs )649CASE(2)650Velo(1,i) = FlowSolution( FlowDOFs*k-1 )651Velo(2,i) = 0.0d0652Velo(3,i) = 0.0d0653CASE(3)654Velo(1,i) = FlowSolution( FlowDOFs*k-2 )655Velo(2,i) = FlowSolution( FlowDOFs*k-1 )656Velo(3,i) = 0.0d0657CASE(4)658Velo(1,i) = FlowSolution( FlowDOFs*k-3 )659Velo(2,i) = FlowSolution( FlowDOFs*k-2 )660Velo(3,i) = FlowSolution( FlowDOFs*k-1 )661END SELECT662END IF663END DO664ELSE IF (ConvectionFlag == 'none' ) THEN665Velo = 0.0d0666ELSE667WRITE(Message,'(A,A,A)') 'Convection flag >', ConvectionFlag ,'< not recognised'668CALL FATAL(SolverName,Message)669END IF670!-------------------------------------------------671! Add mesh velocity (if any) for ALE formulation672!-------------------------------------------------673MeshVelo = 0.0d0674CALL GetVectorLocalSolution( MeshVelo, 'Mesh Velocity', Element)675IF (ANY( MeshVelo /= 0.0d0 )) THEN676DO i=1,FlowDOFs677Velo(i,1:N) = Velo(i,1:N) - MeshVelo(i,1:N)678END DO679END IF680END SUBROUTINE GetLocalALEVelocity681682!------------------------------------------------------------------------------683END SUBROUTINE AdvectionReactionSolver684!------------------------------------------------------------------------------685686687