Path: blob/devel/elmerice/Solvers/DJDBeta_Adjoint.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:25! * Email:26! * Web: http://elmerice.elmerfem.org27! *28! * Original Date:29! *30! *****************************************************************************31! Compute the integrated gradient of the Cost function for the32! Adjoint Inverse Problem33!34! Serial/Parallel(not halo?) and 2D/3D35!36! Need:37! - Navier-stokes and Adjoint Problems Solutions38! - Name of Beta variable and Grad Variable39! - Power formulation if 'Slip Coef'=10^Beta and optimization on Beta40! - Beta2 formulation if 'Slip Coef'=Beta^2 and optimization on Beta41! - Lambda : the regularization coefficient (Jr=0.5 Lambda (dBeta/dx)^2)42!43! If DJDBeta should be set to zero for floating ice shelves the following is44! to be used (default is not to do this):45! - FreeSlipShelves (logical, default false)46! - mask name (string, default GroundedMask)47! Note that if FreeSlipShelves is true not only is DJDBeta set to zero for48! floating ice, but also the regularisation term NodalRegb.49!50! *****************************************************************************51SUBROUTINE DJDBeta_Adjoint( Model,Solver,dt,TransientSimulation )52!------------------------------------------------------------------------------53!******************************************************************************54USE DefUtils55IMPLICIT NONE56!------------------------------------------------------------------------------57TYPE(Solver_t) :: Solver58TYPE(Model_t) :: Model5960REAL(KIND=dp) :: dt61LOGICAL :: TransientSimulation62!63TYPE(ValueList_t), POINTER :: BC6465CHARACTER(LEN=MAX_NAME_LEN) :: SolverName,NeumannSolName,AdjointSolName66CHARACTER(LEN=MAX_NAME_LEN) :: VarSolName,GradSolName67TYPE(Element_t),POINTER :: Element68TYPE(Variable_t), POINTER :: PointerToVariable, BetaVariable, VeloSolN,VeloSolD69TYPE(ValueList_t), POINTER :: SolverParams70TYPE(Nodes_t) :: ElementNodes71TYPE(GaussIntegrationPoints_t) :: IntegStuff7273REAL(KIND=dp), POINTER :: VariableValues(:),VelocityN(:),VelocityD(:),BetaValues(:)74INTEGER, POINTER :: Permutation(:), VeloNPerm(:),VeloDPerm(:),BetaPerm(:),NodeIndexes(:)7576real(kind=dp),allocatable :: VisitedNode(:),db(:),Basis(:),dBasisdx(:,:)77real(kind=dp),allocatable :: nodalbetab(:),NodalRegb(:)78real(kind=dp) :: betab79real(kind=dp) :: u,v,w,SqrtElementMetric,s80real(kind=dp) :: Lambda81REAL(KIND=dp) :: Normal(3),Tangent(3),Tangent2(3),Vect(3)8283integer :: i,j,k,e,t,n,NMAX,NActiveNodes,DIM84integer :: p,q8586logical :: PowerFormulation,Beta2Formulation87Logical :: Firsttime=.true.,Found,stat,UnFoundFatal=.TRUE.88Logical :: NormalTangential1,NormalTangential28990! Variables for setting DJDBeta to zero for ice shelves.91TYPE(Variable_t), POINTER :: PointerToMask => NULL()92REAL(KIND=dp), POINTER :: MaskValues(:) => NULL()93INTEGER, POINTER :: MaskPerm(:) => NULL()94LOGICAL :: FreeSlipShelves95CHARACTER(LEN=MAX_NAME_LEN) :: MaskName9697save FreeSlipShelves,MaskName98save SolverName,NeumannSolName,AdjointSolName,VarSolName,GradSolName99save VisitedNode,db,Basis,dBasisdx,nodalbetab,NodalRegb100save Firsttime,DIM,Lambda101save ElementNodes102save PowerFormulation,Beta2Formulation103104If (Firsttime) then105106DIM = CoordinateSystemDimension()107WRITE(SolverName, '(A)') 'DJDBeta_Adjoint'108109CALL Info(SolverName,'***********************',level=0)110CALL Info(SolverName,' This solver has been replaced by:',level=0)111CALL Info(SolverName,' AdjointStokes_GradientBetaSolver ',level=0)112CALL Info(SolverName,' See documentation under: ',level=0)113CALL Info(SolverName,' elmerice/Solvers/Documentation ',level=0)114CALL Info(SolverName,'***********************',level=0)115CALL FATAL(SolverName,' Use new solver !!')116117NMAX=Solver % Mesh % NumberOfNodes118allocate(VisitedNode(NMAX),db(NMAX), &119nodalbetab(Model % MaxElementNodes),&120NodalRegb(Model % MaxElementNodes),&121Basis(Model % MaxElementNodes), &122dBasisdx(Model % MaxElementNodes,3))123124!!!!!!!!!!! get Solver Variables125SolverParams => GetSolverParams()126127NeumannSolName = GetString( SolverParams,'Flow Solution Name', Found)128IF(.NOT.Found) THEN129CALL WARN(SolverName,'Keyword >Neumann Solution Name< not found in section >Solver<')130CALL WARN(SolverName,'Taking default value >Flow Solution<')131WRITE(NeumannSolName,'(A)') 'Flow Solution'132END IF133AdjointSolName = GetString( SolverParams,'Adjoint Solution Name', Found)134IF(.NOT.Found) THEN135CALL WARN(SolverName,'Keyword >Adjoint Solution Name< not found in section >Solver<')136CALL WARN(SolverName,'Taking default value >Adjoint<')137WRITE(AdjointSolName,'(A)') 'Adjoint'138END IF139VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)140IF(.NOT.Found) THEN141CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')142CALL WARN(SolverName,'Taking default value >Beta<')143WRITE(VarSolName,'(A)') 'Beta'144END IF145GradSolName = GetString( SolverParams,'Gradient Variable Name', Found)146IF(.NOT.Found) THEN147CALL WARN(SolverName,'Keyword >Gradient Variable Name< not found in section >Solver<')148CALL WARN(SolverName,'Taking default value >DJDB<')149WRITE(GradSolName,'(A)') 'DJDB'150END IF151PowerFormulation=GetLogical( SolverParams, 'PowerFormulation', Found)152IF(.NOT.Found) THEN153CALL WARN(SolverName,'Keyword >PowerFormulation< not found in section >Equation<')154CALL WARN(SolverName,'Taking default value >FALSE<')155PowerFormulation=.FALSE.156END IF157Beta2Formulation=GetLogical( SolverParams, 'Beta2Formulation', Found)158IF(.NOT.Found) THEN159CALL WARN(SolverName,'Keyword >Beta2Formulation< not found in section >Equation<')160CALL WARN(SolverName,'Taking default value >FALSE<')161Beta2Formulation=.FALSE.162END IF163IF (PowerFormulation.and.Beta2Formulation) then164WRITE(Message,'(A)') 'Can t be PowerFormulation and Beta2Formulation in the same time'165CALL FATAL(SolverName,Message)166End if167Lambda = GetConstReal( SolverParams,'Lambda', Found)168IF(.NOT.Found) THEN169CALL WARN(SolverName,'Keyword >Lambda< not found in section >Solver<')170CALL WARN(SolverName,'Taking default value Lambda=0.0')171Lambda = 0.0172End if173174FreeSlipShelves=GetLogical( SolverParams, 'FreeSlipShelves', Found)175IF(.NOT.Found) THEN176CALL WARN(SolverName,'Keyword >FreeSlipShelves< not found in solver params')177CALL WARN(SolverName,'Taking default value >FALSE<')178FreeSlipShelves=.FALSE.179END IF180IF (FreeSlipShelves) THEN181MaskName = GetString( SolverParams,'mask name', Found)182IF(.NOT.Found) THEN183CALL WARN(SolverName,'Keyword >mask name< not found in solver section')184CALL WARN(SolverName,'Taking default value >GroundedMask<')185WRITE(MaskName,'(A)') 'GroundedMask'186END IF187END IF188189!!! End of First visit190Firsttime=.false.191Endif192193PointerToVariable => VariableGet( Model % Mesh % Variables, GradSolName,UnFoundFatal=UnFoundFatal)194VariableValues => PointerToVariable % Values195Permutation => PointerToVariable % Perm196VariableValues=0._dp197198BetaVariable => VariableGet( Model % Mesh % Variables, VarSolName,UnFoundFatal=UnFoundFatal)199BetaValues => BetaVariable % Values200BetaPerm => BetaVariable % Perm201202VeloSolN => VariableGet( Model % Mesh % Variables, NeumannSolName,UnFoundFatal=UnFoundFatal)203VelocityN => VeloSolN % Values204VeloNPerm => VeloSolN % Perm205206VeloSolD => VariableGet( Model % Mesh % Variables, AdjointSolName,UnFoundFatal=UnFoundFatal)207VelocityD => VeloSolD % Values208VeloDPerm => VeloSolD % Perm209210IF (FreeSlipShelves) THEN211PointerToMask => VariableGet( Model % Variables, MaskName, UnFoundFatal=.TRUE.)212MaskValues => PointerToMask % Values213MaskPerm => PointerToMask % Perm214END IF215216VisitedNode=0.0_dp217db=0.0_dp218219DO e=1,Solver % NumberOfActiveElements220Element => GetActiveElement(e)221CALL GetElementNodes( ElementNodes )222n = GetElementNOFNodes()223NodeIndexes => Element % NodeIndexes224225! Compute Nodal Value of DJDBeta226BC => GetBC()227if (.NOT.ASSOCIATED(BC)) CYCLE228229NormalTangential1 = GetLogical( BC, &230'Normal-Tangential Velocity', Found )231IF (.NOT.Found) then232NormalTangential1 = GetLogical( BC, &233'Normal-Tangential '//trim(NeumannSolName), Found)234END IF235NormalTangential2 = GetLogical( BC, &236'Normal-Tangential '//trim(AdjointSolName), Found)237IF (NormalTangential1.NEQV.NormalTangential2) then238WRITE(Message,'(A,I1,A,I1)') &239'NormalTangential Velocity is : ',NormalTangential1, &240'But NormalTangential Adjoint is : ',NormalTangential2241CALL FATAL(SolverName,Message)242ENDIF243IF (.NOT.NormalTangential1) then244WRITE(Message,'(A)') &245'ALWAYS USE Normal-Tangential COORDINATES with SlipCoef 2=SlipCoef 3'246CALL FATAL(SolverName,Message)247ENDIF248249VisitedNode(NodeIndexes(1:n))=VisitedNode(NodeIndexes(1:n))+1.0_dp250251! Compute Integrated Nodal Value of DJDBeta252nodalbetab=0.0_dp253NodalRegb=0.0_dp254255256IntegStuff = GaussPoints( Element )257DO t=1,IntegStuff % n258U = IntegStuff % u(t)259V = IntegStuff % v(t)260W = IntegStuff % w(t)261stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &262Basis,dBasisdx )263264s = SqrtElementMetric * IntegStuff % s(t)265266! compute gradient from Stokes and adjoint computation267! follow the computation of the stiffMatrix as done in the NS solver268Normal = NormalVector( Element, ElementNodes, u,v,.TRUE. )269SELECT CASE( Element % TYPE % DIMENSION )270CASE(1)271Tangent(1) = Normal(2)272Tangent(2) = -Normal(1)273Tangent(3) = 0.0_dp274Tangent2 = 0.0_dp275CASE(2)276CALL TangentDirections( Normal, Tangent, Tangent2 )277END SELECT278279280betab=0.0_dp281Do p=1,n282Do q=1,n283284Do i=2,dim285SELECT CASE(i)286CASE(2)287Vect = Tangent288CASE(3)289Vect = Tangent2290END SELECT291292Do j=1,DIM293Do k=1,DIM294betab = betab + s * Basis(q) * Basis(p) * Vect(j) * Vect(k) * &295(- VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(q))-1)+k) * &296VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(p))-1)+j))297End Do !on k298End Do !on j299End Do !on i300End Do !on q301End Do !on p302303nodalbetab(1:n)=nodalbetab(1:n)+betab*Basis(1:n)304305If (Lambda /= 0.0) then306NodalRegb(1:n)=NodalRegb(1:n)+&307s*Lambda*(SUM(dBasisdx(1:n,1)*BetaValues(BetaPerm(NodeIndexes(1:n))))*dBasisdx(1:n,1))308IF (DIM.eq.3) then309NodalRegb(1:n)=NodalRegb(1:n)+&310s*Lambda*(SUM(dBasisdx(1:n,2)*BetaValues(BetaPerm(NodeIndexes(1:n))))*dBasisdx(1:n,2))311End if312End if313End DO ! on IPs314315IF (PowerFormulation) then316nodalbetab(1:n)=nodalbetab(1:n)*(10**(BetaValues(BetaPerm(NodeIndexes(1:n)))))*log(10.0)317ENDIF318IF (Beta2Formulation) then319nodalbetab(1:n)=nodalbetab(1:n)*2.0_dp*BetaValues(BetaPerm(NodeIndexes(1:n)))320END IF321322! Set regularisation to zero for floating points323IF (FreeSlipShelves) THEN324DO t=1,n325IF ( MaskValues(MaskPerm(NodeIndexes(t))).LT.0.0_dp ) THEN326NodalRegb(t) = 0.0_dp327END IF328END DO329END IF330331db(NodeIndexes(1:n)) = db(NodeIndexes(1:n)) + nodalbetab(1:n) + NodalRegb(1:n)332End do ! on elements333334Do t=1,Solver % Mesh % NumberOfNodes335if (VisitedNode(t).lt.1.0_dp) cycle336VariableValues(Permutation(t)) = db(t)337IF (FreeSlipShelves) THEN338IF ( MaskValues(MaskPerm(t)).LT.0.0_dp ) THEN339VariableValues(Permutation(t)) = 0.0_dp340END IF341END IF342End do343344IF (FreeSlipShelves) THEN345NULLIFY(PointerToMask)346NULLIFY(MaskValues)347NULLIFY(MaskPerm)348END IF349350Return351352CONTAINS353354function calcNorm(v) result(v2)355implicit none356real(kind=dp) :: v(3),v2357358v2=v(1)*v(1)+v(2)*v(2)+v(3)*v(3)359end function calcNorm360361function scalar(v1,v2) result(vr)362implicit none363real(kind=dp) :: v2(3),v1(3),vr364365vr=v1(1)*v2(1)+v1(2)*v2(2)+v1(3)*v2(3)366end function scalar367368!------------------------------------------------------------------------------369END SUBROUTINE DJDBeta_Adjoint370!------------------------------------------------------------------------------371372373374375