Path: blob/devel/elmerice/Solvers/AdjointStokes/AdjointStokes_GradientBetaSolver.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! * Authors:25! * Email:26! * Web: http://elmerice.elmerfem.org27! *28! * Original Date:29! *30! *****************************************************************************31! Adjoint of the Stokes problem for the slip coefficient32! Provide the derivative with respect to the slip coef.33!34! Serial/Parallel(not halo?) and 2D/3D35!36! Need:37! - Navier-stokes and Adjoint Problems Solutions38! - Grad Variable39!40! *****************************************************************************41SUBROUTINE AdjointStokes_GradientBetaSolver_init0(Model,Solver,dt,TransientSimulation )42!------------------------------------------------------------------------------43USE DefUtils44IMPLICIT NONE45!------------------------------------------------------------------------------46TYPE(Solver_t), TARGET :: Solver47TYPE(Model_t) :: Model48REAL(KIND=dp) :: dt49LOGICAL :: TransientSimulation50!------------------------------------------------------------------------------51! Local variables52!------------------------------------------------------------------------------53CHARACTER(LEN=MAX_NAME_LEN) :: Name5455Name = ListGetString( Solver % Values, 'Equation',UnFoundFatal=.TRUE.)56CALL ListAddNewString( Solver % Values,'Variable',&57'-nooutput '//TRIM(Name)//'_var')58CALL ListAddLogical(Solver % Values, 'Optimize Bandwidth',.FALSE.)5960END SUBROUTINE AdjointStokes_GradientBetaSolver_init061! *****************************************************************************62SUBROUTINE AdjointStokes_GradientBetaSolver( Model,Solver,dt,TransientSimulation )63!------------------------------------------------------------------------------64!******************************************************************************65USE DefUtils66IMPLICIT NONE67!------------------------------------------------------------------------------68TYPE(Solver_t) :: Solver69TYPE(Model_t) :: Model7071REAL(KIND=dp) :: dt72LOGICAL :: TransientSimulation73!74TYPE(ValueList_t), POINTER :: SolverParams75TYPE(ValueList_t), POINTER :: BC7677CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="AdjointStokes_GradientBeta"7879INTEGER,SAVE :: DIM8081CHARACTER(LEN=MAX_NAME_LEN),SAVE :: NeumannSolName,AdjointSolName82TYPE(Variable_t), POINTER :: VeloSolN,VeloSolD83REAL(KIND=dp), POINTER :: VelocityN(:),VelocityD(:)84INTEGER, POINTER :: VeloNPerm(:),VeloDPerm(:)8586CHARACTER(LEN=MAX_NAME_LEN),SAVE :: GradSolName87TYPE(Variable_t), POINTER :: PointerToVariable88REAL(KIND=dp), POINTER :: VariableValues(:)89INTEGER, POINTER :: Permutation(:)9091TYPE(Element_t),POINTER :: Element92TYPE(Nodes_t),SAVE :: ElementNodes93INTEGER, POINTER :: NodeIndexes(:)94TYPE(GaussIntegrationPoints_t) :: IntegStuff95REAL(kind=dp) :: u,v,w,SqrtElementMetric,s96REAL(kind=dp),allocatable,SAVE :: Basis(:),dBasisdx(:,:)97INTEGER :: n9899LOGICAL :: NormalTangential1,NormalTangential2100REAL(KIND=dp) :: Normal(3),Tangent(3),Tangent2(3),Vect(3)101REAL(kind=dp) :: betab102REAL(kind=dp),allocatable,SAVE :: NodalDer(:),NodalGrad(:)103LOGICAL :: HaveDer104105INTEGER :: NMAX106107integer :: i,j,k,p,q,e,t108109LOGICAL :: Found,stat110LOGICAL :: Reset111LOGICAL, SAVE :: Firsttime=.true.112LOGICAL,PARAMETER :: UnFoundFatal=.TRUE.113114TYPE(ValueHandle_t), SAVE :: WeertmanCoeff_h,WeertmanExp_h,FrictionUt0_h,FrictionNormal_h115TYPE(VariableHandle_t), SAVE :: Velo_v116LOGICAL :: HaveFrictionW117REAL(KIND=dp) :: wut0118LOGICAL :: FrictionNormal119REAL(KIND=dp) :: Velo(3),un,ut,TanFrictionCoeff,wexp, wcoeff120121122SolverParams => GetSolverParams()123124If (Firsttime) then125126DIM = CoordinateSystemDimension()127128NMAX=Model % MaxElementNodes129allocate(Basis(NMAX),dBasisdx(NMAX,3))130allocate(NodalDer(NMAX),NodalGrad(NMAX))131!!!!!!!!!!! get Solver Variables132133NeumannSolName = GetString( SolverParams,'Flow Solution Name', Found)134IF(.NOT.Found) THEN135CALL WARN(SolverName,'Keyword >Neumann Solution Name< not found in section >Solver<')136CALL WARN(SolverName,'Taking default value >Flow Solution<')137WRITE(NeumannSolName,'(A)') 'Flow Solution'138END IF139AdjointSolName = GetString( SolverParams,'Adjoint Solution Name', Found)140IF(.NOT.Found) THEN141CALL WARN(SolverName,'Keyword >Adjoint Solution Name< not found in section >Solver<')142CALL WARN(SolverName,'Taking default value >Adjoint<')143WRITE(AdjointSolName,'(A)') 'Adjoint'144END IF145146GradSolName = GetString( SolverParams,'Gradient Variable Name', Found)147IF(.NOT.Found) THEN148CALL WARN(SolverName,'Keyword >Gradient Variable Name< not found in section >Solver<')149CALL WARN(SolverName,'Taking default value >DJDB<')150WRITE(GradSolName,'(A)') 'DJDB'151END IF152153!!!! Handles initialisation154CALL ListInitElementKeyword( WeertmanCoeff_h,'Boundary Condition','Weertman Friction Coefficient')155CALL ListInitElementKeyword( WeertmanExp_h,'Boundary Condition','Weertman Exponent')156CALL ListInitElementKeyword( FrictionUt0_h,'Boundary Condition','Friction Linear Velocity')157CALL ListInitElementKeyword( FrictionNormal_h,'Boundary Condition','Friction Normal Velocity Zero')158CALL ListInitElementVariable( Velo_v , NeumannSolName , Found=Found)159IF (.NOT.Found) &160CALL FATAL(SolverName,TRIM(NeumannSolName)//' Variable not found')161162!!! End of First visit163Firsttime=.false.164Endif165166PointerToVariable => VariableGet( Model % Mesh % Variables, GradSolName,UnFoundFatal=UnFoundFatal)167VariableValues => PointerToVariable % Values168Permutation => PointerToVariable % Perm169Reset = ListGetLogical( SolverParams,'Reset Gradient Variable', Found)170if (Reset.OR.(.NOT.Found)) VariableValues=0._dp171172VeloSolN => VariableGet( Model % Mesh % Variables, NeumannSolName,UnFoundFatal=UnFoundFatal)173VelocityN => VeloSolN % Values174VeloNPerm => VeloSolN % Perm175176VeloSolD => VariableGet( Model % Mesh % Variables, AdjointSolName,UnFoundFatal=UnFoundFatal)177VelocityD => VeloSolD % Values178VeloDPerm => VeloSolD % Perm179180181182DO e=1,Solver % NumberOfActiveElements183Element => GetActiveElement(e)184CALL GetElementNodes( ElementNodes )185n = GetElementNOFNodes(Element)186NodeIndexes => Element % NodeIndexes187188! Compute Nodal Value of DJDBeta189BC => GetBC(Element)190if (.NOT.ASSOCIATED(BC)) &191CALL FATAL(SolverName,'This solver is intended to be executed on a BC')192193NormalTangential1 = GetLogical( BC, &194'Normal-Tangential Velocity', Found )195IF (.NOT.Found) then196NormalTangential1 = GetLogical( BC, &197'Normal-Tangential '//trim(NeumannSolName), Found)198END IF199NormalTangential2 = GetLogical( BC, &200'Normal-Tangential '//trim(AdjointSolName), Found)201IF (NormalTangential1.NEQV.NormalTangential2) then202WRITE(Message,'(A,I1,A,I1)') &203'NormalTangential Velocity is : ',NormalTangential1, &204'But NormalTangential Adjoint is : ',NormalTangential2205CALL FATAL(SolverName,Message)206ENDIF207IF (.NOT.NormalTangential1) then208WRITE(Message,'(A)') &209'ALWAYS USE Normal-Tangential COORDINATES with SlipCoef 2=SlipCoef 3'210CALL FATAL(SolverName,Message)211ENDIF212213HaveFrictionW = ListCheckPresent( BC,'Weertman Friction Coefficient')214IF (HaveFrictionW) THEN215wut0 = ListGetElementReal( FrictionUt0_h, Element = Element )216FrictionNormal = ListGetElementLogical( FrictionNormal_h, Element )217END IF218219NodalDer(1:n) = ListGetReal(BC,'Slip Coefficient derivative',n,NodeIndexes,Found=HaveDer)220221222! Compute Integrated Nodal Value of DJDBeta223IntegStuff = GaussPoints( Element )224DO t=1,IntegStuff % n225U = IntegStuff % u(t)226V = IntegStuff % v(t)227W = IntegStuff % w(t)228stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &229Basis,dBasisdx )230231s = SqrtElementMetric * IntegStuff % s(t)232233! compute gradient from Stokes and adjoint computation234! follow the computation of the stiffMatrix as done in the NS solver235Normal = NormalVector( Element, ElementNodes, u,v,.TRUE. )236SELECT CASE( Element % TYPE % DIMENSION )237CASE(1)238Tangent(1) = Normal(2)239Tangent(2) = -Normal(1)240Tangent(3) = 0.0_dp241Tangent2 = 0.0_dp242CASE(2)243CALL TangentDirections( Normal, Tangent, Tangent2 )244END SELECT245246247betab=0.0_dp248Do p=1,n249Do q=1,n250251Do i=2,dim252SELECT CASE(i)253CASE(2)254Vect = Tangent255CASE(3)256Vect = Tangent2257END SELECT258259Do j=1,DIM260Do k=1,DIM261betab = betab + s * Basis(q) * Basis(p) * Vect(j) * Vect(k) * &262(- VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(q))-1)+k) * &263VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(p))-1)+j))264End Do !on k265End Do !on j266End Do !on i267End Do !on q268End Do !on p269270IF (HaveDer) THEN271NodalGrad(1:n)=Basis(1:n)*NodalDer(1:n)272ELSE273NodalGrad(1:n)=Basis(1:n)274ENDIF275276IF( HaveFrictionW) THEN277! Velocity at integration point for nonlinear friction laws278Velo = ListGetElementVectorSolution( Velo_v, Basis, Element, dofs = dim )279IF(.NOT. FrictionNormal ) THEN280un = SUM( Normal(1:dim) * Velo(1:dim) )281velo(1:dim) = velo(1:dim)-un*normal(1:dim)282END IF283ut = MAX(wut0, SQRT(SUM(Velo(1:dim)**2)))284285!TanFrictionCoeff = MIN(wcoeff * ut**(wexp-1.0_dp),1.0e20)286wcoeff = ListGetElementReal( WeertmanCoeff_h, Basis, Element, GaussPoint = t )287wexp = ListGetElementReal( WeertmanExp_h, Basis, Element, GaussPoint = t )288TanFrictionCoeff=wcoeff * ut**(wexp-1.0_dp)289IF (TanFrictionCoeff.GE.1.0e20) THEN290betab=0._dp291ELSE292betab=betab*ut**(wexp-1.0_dp)293END IF294END IF295296VariableValues(Permutation(NodeIndexes(1:n))) = VariableValues(Permutation(NodeIndexes(1:n))) &297+ betab*NodalGrad(1:n)298299End DO ! on IPs300301End do ! on elements302303Return304305!------------------------------------------------------------------------------306END SUBROUTINE AdjointStokes_GradientBetaSolver307!------------------------------------------------------------------------------308309310311312