Path: blob/devel/elmerice/Solvers/AdjointSSA/AdjointSSA_CostTaubSolver.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! *****************************************************************************/22SUBROUTINE AdjointSSA_CostTaubSolver_init0(Model,Solver,dt,TransientSimulation )23!------------------------------------------------------------------------------24USE DefUtils25IMPLICIT NONE26!------------------------------------------------------------------------------27TYPE(Solver_t), TARGET :: Solver28TYPE(Model_t) :: Model29REAL(KIND=dp) :: dt30LOGICAL :: TransientSimulation31!------------------------------------------------------------------------------32! Local variables33!------------------------------------------------------------------------------34CHARACTER(LEN=MAX_NAME_LEN) :: Name3536Name = ListGetString( Solver % Values, 'Equation',UnFoundFatal=.TRUE.)37CALL ListAddNewString( Solver % Values,'Variable',&38'-nooutput '//TRIM(Name)//'_var')39CALL ListAddLogical(Solver % Values, 'Optimize Bandwidth',.FALSE.)4041END SUBROUTINE AdjointSSA_CostTaubSolver_init042! ******************************************************************************43! *****************************************************************************44SUBROUTINE AdjointSSA_CostTaubSolver( Model,Solver,dt,TransientSimulation )45! *****************************************************************************46!------------------------------------------------------------------------------47!48! Compute a cost function that penalises 1rst derivative of the basal shear stress49! J=int_{Pb dimension} 0.5 * ( dTau_b/dx )**250!51! The basal friction is computed at the nodes following:52! Tau_b=beta Velocity_nom**fm53! with fm the friction exponent54!55! and provides the derivatives with respect to beta en velocity56!57! Be Careful, by default, this solver58! - reset derivatives wrt beta to 0 (Set Reset DJDBeta = Logical False,59! if values have been computed in a previous cost function)60! - do not reset Cost and derivatives wrt velocity to 0 (Set Reset Cost value = Logical True,61! if values have been computed in a previous cost function)62!63! OUTPUT are : J ; DJDBeta ; Velocityb64!65! INPUT PARAMETERS are:66!67! In solver section:68! Reset Cost Value = Logical (default = .FALSE.)69! Reset DJDBeta = Logical (default = .True.)70! Cost Filename = File (default = 'CostTaub.dat')71! Cost Variable Name = String (default= 'CostValue')72! DJDBeta Name = String (default= 'DJDBeta')73! Lambda = Real (default = 1.0)74!75!76! Variables77! SSAVelocity (solution of the SSA pb)78! Velocityb (forcing for the adjoint pb)79!80! In Material:81! Keywords related to SSA Friction law (only linear and Weertman)82!------------------------------------------------------------------------------83!******************************************************************************84USE DefUtils85IMPLICIT NONE86!------------------------------------------------------------------------------87TYPE(Solver_t) :: Solver88TYPE(Model_t) :: Model8990REAL(KIND=dp) :: dt91LOGICAL :: TransientSimulation92!93TYPE(Variable_t), POINTER :: CostVar94TYPE(Variable_t), POINTER :: TimeVar95TYPE(Variable_t), POINTER :: DJDVariable !derivée/beta96TYPE(Variable_t), POINTER :: VVar ! ssavelocity97TYPE(Variable_t), POINTER :: VbVar ! velocityb98REAL(KIND=dp),POINTER :: DJDValues(:),VValues(:),VbValues(:)99INTEGER,POINTER :: DJDPerm(:),VPerm(:),VbPerm(:)100INTEGER :: DOFs101TYPE(Nodes_t),SAVE :: ElementNodes102INTEGER :: N103TYPE(ValueList_t), POINTER :: SolverParams104TYPE(ValueList_t), POINTER :: Material105TYPE(Element_t), POINTER :: Element106INTEGER, POINTER :: NodeIndexes(:)107TYPE(GaussIntegrationPoints_t) :: IntegStuff108REAL(KIND=dp) :: U,V,W,SqrtElementMetric109REAL(KIND=dp),ALLOCATABLE,SAVE :: Basis(:), dBasisdx(:,:)110REAL(KIND=dp),ALLOCATABLE,SAVE :: Beta(:),Vnode(:,:),Vn(:),Taub(:),NodalBetaDer(:)111REAL(KIND=dp),ALLOCATABLE,SAVE :: Betab(:),Vnodeb(:,:),Vnb(:),Taubb(:)112REAL(KIND=dp) :: Cost,Cost_S113REAL(KIND=dp) :: coeff,coeffb,s,Lambda114REAL(KIND=dp) :: fm115116CHARACTER(LEN=MAX_NAME_LEN),SAVE :: CostSolName117CHARACTER(LEN=MAX_NAME_LEN),SAVE :: CostFile118CHARACTER(LEN=MAX_NAME_LEN) :: DefaultCostFile="CostTaub.dat"119CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="CostTaub"120CHARACTER(LEN=MAX_NAME_LEN) :: SName121CHARACTER(LEN=MAX_NAME_LEN) :: Friction122CHARACTER*10 :: date,temps123124LOGICAL :: Reset125LOGICAL :: ResetCost126LOGICAL :: Found127LOGICAL :: stat128LOGICAL :: HaveBetaDer129LOGICAL, SAVE :: Parallel130LOGICAL, SAVE :: Firsttime=.TRUE.131132INTEGER :: i,t,p,j133INTEGER :: ierr134135136SolverParams => GetSolverParams()137138Lambda = GetConstReal( SolverParams,'Lambda', Found)139IF(.NOT.Found) THEN140CALL WARN(SolverName,'Keyword >Lambda< not found in section >Solver<')141CALL WARN(SolverName,'Taking default value Lambda=1.0')142Lambda = 1.0143End if144145ResetCost = GetLogical( SolverParams,'Reset Cost Value', Found)146IF(.NOT.Found) ResetCost=.FALSE.147148!!! SOME INITIALISATION AT FIRST TIME149If (Firsttime) then150N = model % MaxElementNodes151allocate(ElementNodes % x(N), ElementNodes % y(N), ElementNodes % z(N))152allocate( Basis(N),dBasisdx(N,3))153allocate( Beta(N),Vnode(N,3),Vn(N),Taub(N),NodalBetaDer(N))154allocate( Betab(N),Vnodeb(N,3),Vnb(N),Taubb(N))155156!!!!!!! Check for parallel run157Parallel = .FALSE.158IF ( ASSOCIATED( Solver % Matrix % ParMatrix ) ) THEN159IF ( Solver % Matrix % ParMatrix % ParEnv % PEs > 1 ) THEN160Parallel = .TRUE.161END IF162END IF163164!! check some kws165SName = GetString( SolverParams,'DJDBeta Name', Found)166IF(.NOT.Found) THEN167CALL WARN(SolverName,'Keyword >DJDBeta Name< not found in section >Solver<')168CALL WARN(SolverName,'Taking default value >DJDBeta<')169WRITE(SName,'(A)') 'DJDBeta'170CALL ListAddString( SolverParams, 'DJDBeta Name', TRIM(SName))171END IF172!!173CostSolName = GetString( SolverParams,'Cost Variable Name', Found)174IF(.NOT.Found) THEN175CALL WARN(SolverName,'Keyword >Cost Variable Name< not found in section >Solver<')176CALL WARN(SolverName,'Taking default value >CostValue<')177WRITE(CostSolName,'(A)') 'CostValue'178END IF179180181CostFile = ListGetString(Solver % Values,'Cost Filename',Found )182IF (.NOT. Found) CostFile = DefaultCostFile183CALL DATE_AND_TIME(date,temps)184If (Parallel) then185if (ParEnv % MyPe.EQ.0) then186OPEN (12, FILE=CostFile)187write(12,1000) date(5:6),date(7:8),date(1:4),temps(1:2),temps(3:4),temps(5:6)188write(12,1001) Lambda189write(12,'(A)') '# iter, Jreg'190CLOSE(12)191End if192Else193OPEN (12, FILE=CostFile)194write(12,1000) date(5:6),date(7:8),date(1:4),temps(1:2),temps(3:4),temps(5:6)195write(12,1001) Lambda196write(12,'(A)') '# iter, Jreg'197CLOSE(12)198End if199200!!! End of First visit201Firsttime=.false.202Endif203!!!! INITIALISATION DONE204205SName = ListGetString( SolverParams,'DJDBeta Name', UnFoundFatal=.TRUE.)206DJDVariable => VariableGet( Solver % Mesh % Variables,TRIM(SName),UnFoundFatal=.TRUE.)207DJDValues => DJDVariable % Values208DJDPerm => DJDVariable % Perm209Reset = ListGetLogical( SolverParams,'Reset DJDBeta', Found)210if (Reset.OR.(.NOT.Found)) DJDValues=0.0_dp ! reset to zero herz!211212213VVar => VariableGet( Solver % Mesh % Variables, 'ssavelocity',UnFoundFatal=.TRUE.)214VValues => VVar % Values215VPerm => VVar % Perm216DOFs = VVar % DOFs217218VbVar => VariableGet( Solver % Mesh % Variables, 'velocityb',UnFoundFatal=.TRUE.)219VbValues => VbVar % Values220VbPerm => VbVar % Perm221IF (ResetCost) VbValues = 0._dp222IF (VbVar%DOFs.NE.DOFs) CALL FATAL(SolverName,'Dimension error')223224Cost=0._dp225226DO t=1,Solver % NumberOfActiveElements227Element => GetActiveElement(t)228IF (CheckPassiveElement(Element)) THEN229CYCLE230END IF231n = GetElementNOFNodes(Element)232233NodeIndexes => Element % NodeIndexes234235! set coords of highest occurring dimension to zero (to get correct path element)236!-------------------------------------------------------------------------------237ElementNodes % x(1:n) = Solver % Mesh % Nodes % x(NodeIndexes(1:n))238IF (DOFs.EQ.2 ) THEN239ElementNodes % y(1:n) = Solver % Mesh % Nodes % y(NodeIndexes(1:n))240ELSE241ElementNodes % y(1:n) = 0.0_dp242ENDIF243ElementNodes % z(1:n) = 0.0_dp244245! Get Friction coefficient246Material => GetMaterial(Element)247Friction = ListGetString(Material, 'SSA Friction Law', Found,UnFoundFatal=.TRUE.)248249SELECT CASE(Friction)250CASE('linear')251fm = 1.0_dp252CASE('weertman')253fm = ListGetConstReal( Material, 'SSA Friction Exponent', UnFoundFatal=.TRUE.)254CASE DEFAULT255CALL FATAL(SolverName,'Friction should be linear or Weertman')256END SELECT257258Beta(1:n) = ListGetReal( Material, 'SSA Friction Parameter', n, NodeIndexes,UnFoundFatal=.TRUE.)259NodalBetaDer(1:n) = ListGetReal( Material, 'SSA Friction Parameter Derivative',n, NodeIndexes,Found=HaveBetaDer)260DO i=1,n261Vn(i)=0._dp262Do j=1,DOFs263Vnode(i,j)=VValues(VVar%DOFs*(VPerm(NodeIndexes(i))-1)+j)264Vn(i)=Vn(i)+Vnode(i,j)*Vnode(i,j)265END DO266IF (Vn(i).GT.AEPS) THEN267Taub(i)=Beta(i)*Vn(i)**(fm/2)268ELSE269Taub(i)=0._dp270END IF271END DO272273!------------------------------------------------------------------------------274! Numerical integration275!------------------------------------------------------------------------------276IntegStuff = GaussPoints( Element )277278Taubb=0._dp279DO p=1,IntegStuff % n280U = IntegStuff % u(p)281V = IntegStuff % v(p)282W = IntegStuff % w(p)283!------------------------------------------------------------------------------284! Basis function values & derivatives at the integration point285!------------------------------------------------------------------------------286stat = ElementInfo( Element,ElementNodes,U,V,W,SqrtElementMetric, &287Basis,dBasisdx )288289s = SqrtElementMetric * IntegStuff % s(p)290291DO j=1,DOFs292coeff=0._dp293DO i=1,n294coeff=coeff+Taub(i)*dbasisdx(i,j)295END DO296Cost=Cost+0.5*s*coeff*coeff297298coeffb=s*Lambda*coeff299DO i=1,n300Taubb(i)=Taubb(i)+coeffb*dbasisdx(i,j)301END DO302303END DO304305End do !IP306307DO i=1,n308IF (Vn(i).GT.AEPS) THEN309Vnb(i)=Taubb(i)*Beta(i)*0.5*fm*Vn(i)**(fm/2-1._dp)310Betab(i)=Taubb(i)*Vn(i)**(fm/2)311IF (HaveBetaDer) Betab(i)=Betab(i)*NodalBetaDer(i)312ELSE313Vnb(i)=0._dp314Betab(i)=0._dp315END IF316317DO j=1,DOFs318Vnodeb(i,j)=Vnb(i)*2*Vnode(i,j)319VbValues(VbVar%DOFs*(VbPerm(NodeIndexes(i))-1)+j)=&320VbValues(VbVar%DOFs*(VbPerm(NodeIndexes(i))-1)+j)+Vnodeb(i,j)321END DO322323DJDValues(DJDPerm(NodeIndexes(i)))=&324DJDValues(DJDPerm(NodeIndexes(i)))+Betab(i)325END DO326327End do !Elements328329TimeVar => VariableGet( Solver % Mesh % Variables, 'Time' )330IF (Parallel) THEN331CALL MPI_ALLREDUCE(Cost,Cost_S,1,&332MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)333CostVar => VariableGet( Solver % Mesh % Variables, TRIM(CostSolName) ,UnFoundFatal=.TRUE.)334IF (ResetCost) then335CostVar % Values(1)=Lambda*Cost_S336Else337CostVar % Values(1)=CostVar % Values(1)+Lambda*Cost_S338Endif339IF (Solver % Matrix % ParMatrix % ParEnv % MyPE == 0) then340OPEN (12, FILE=TRIM(CostFile),POSITION='APPEND')341WRITE(12,'(e13.5,2x,e15.8)') TimeVar % Values(1),Cost_S342CLOSE(12)343End if344ELSE345CostVar => VariableGet( Solver % Mesh % Variables, TRIM(CostSolName),UnFoundFatal=.TRUE. )346IF (ResetCost) then347CostVar % Values(1)=Lambda*Cost348Else349CostVar % Values(1)=CostVar % Values(1)+Lambda*Cost350Endif351OPEN (12, FILE=TRIM(CostFile),POSITION='APPEND')352WRITE(12,'(e13.5,2x,e15.8)') TimeVar % Values(1),Cost353CLOSE(12)354END IF355356RETURN3573581000 format('#date,time,',a2,'/',a2,'/',a4,',',a2,':',a2,':',a2)3591001 format('#lambda,',e15.8)360!------------------------------------------------------------------------------361END SUBROUTINE AdjointSSA_CostTaubSolver362!------------------------------------------------------------------------------363! *****************************************************************************364365366