Path: blob/devel/elmerice/Solvers/Adjoint/Adjoint_CostContSolver.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: f. Gillet-Chaulet (IGE, Grenoble,France)25! * Email:26! * Web: http://elmerice.elmerfem.org27! *28! * Original Date:29! *30! *****************************************************************************31SUBROUTINE Adjoint_CostContSolver_init0(Model,Solver,dt,TransientSimulation )32!------------------------------------------------------------------------------33USE DefUtils34IMPLICIT NONE35!------------------------------------------------------------------------------36TYPE(Solver_t), TARGET :: Solver37TYPE(Model_t) :: Model38REAL(KIND=dp) :: dt39LOGICAL :: TransientSimulation40!------------------------------------------------------------------------------41! Local variables42!------------------------------------------------------------------------------43CHARACTER(LEN=MAX_NAME_LEN) :: Name4445Name = ListGetString( Solver % Values, 'Equation',UnFoundFatal=.TRUE.)46CALL ListAddNewString( Solver % Values,'Variable',&47'-nooutput '//TRIM(Name)//'_var')48CALL ListAddLogical(Solver % Values, 'Optimize Bandwidth',.FALSE.)49CALL ListAddInteger(Solver % Values, 'Nonlinear System Norm Degree',0)50END SUBROUTINE Adjoint_CostContSolver_init051!----------------------------------------------------------------------52! *****************************************************************************53SUBROUTINE Adjoint_CostContSolver( Model,Solver,dt,TransientSimulation )54!------------------------------------------------------------------------------55!Compute a Cost function as: Integral Node_Cost ds56!57! OUTPUT are : J and xb (sensitivity of J w.r.t. u)5859! !! Be careful this solver will reset the cost and xb to 0;60! so it has to be used as the first cost solver in an inverse problem sequence61!62! see documentation under : elmerice/Solvers/Documentation/Adjoint_CostContSolver.md63!******************************************************************************64USE DefUtils65IMPLICIT NONE66!------------------------------------------------------------------------------67TYPE(Solver_t) :: Solver68TYPE(Model_t) :: Model6970REAL(KIND=dp) :: dt71LOGICAL :: TransientSimulation72!73CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="Adjoint_CostContSolver"74CHARACTER(LEN=MAX_NAME_LEN), PARAMETER :: DefaultCostFile = 'CostOfT.dat'75CHARACTER(LEN=MAX_NAME_LEN),SAVE :: CostFile76CHARACTER(LEN=MAX_NAME_LEN),SAVE :: CostSolName77CHARACTER(LEN=MAX_NAME_LEN),SAVE :: VbName78CHARACTER(LEN=MAX_NAME_LEN) :: DerName7980TYPE(Variable_t), POINTER :: TimeVar,CostVar81TYPE(Variable_t), POINTER :: VbSol82REAL(KIND=dp), POINTER :: Vb(:)83INTEGER, POINTER :: VbPerm(:)84INTEGER,SAVE :: VDOFs8586TYPE(ValueList_t), POINTER :: SolverParams,BodyForce8788TYPE(Element_t),POINTER :: Element89TYPE(Nodes_t),SAVE :: ElementNodes90TYPE(GaussIntegrationPoints_t) :: IntegStuff91INTEGER, POINTER :: NodeIndexes(:)92REAL(KIND=dp),ALLOCATABLE,SAVE :: Basis(:),dBasisdx(:,:)93REAL(KIND=dp) :: u,v,w,SqrtElementMetric,x,s94INTEGER :: n9596LOGICAL,SAVE :: Firsttime=.TRUE.97LOGICAL,SAVE :: Parallel98LOGICAL :: BoundarySolver99100LOGICAL :: Found,stat101integer :: i,j,k,t102INTEGER :: ierr103real(kind=dp) :: Cost,Cost_S104real(kind=dp) :: Area,Area_S105real(kind=dp) :: coeff106107REAL(KIND=dp),ALLOCATABLE,SAVE :: NodeCost(:)108REAL(KIND=dp),ALLOCATABLE,SAVE :: NodeCostb(:),NodeCost_der(:,:)109110INTEGER, SAVE :: DIM111112CHARACTER*10 :: date,temps113114115SolverParams => GetSolverParams()116117If (Firsttime) then118N = model % MaxElementNodes119allocate(ElementNodes % x(N), ElementNodes % y(N), ElementNodes % z(N))120allocate(Basis(N),dBasisdx(N,3))121122!!!!!!! Check for parallel run123!Parallel = .FALSE.124!IF ( ASSOCIATED( Solver % Matrix % ParMatrix ) ) THEN125! IF ( Solver % Matrix % ParMatrix % ParEnv % PEs > 1 ) THEN126! Parallel = .TRUE.127! END IF128!END IF129Parallel = ParEnv % PEs > 1130131IF(ASSOCIATED(Solver % ActiveElements)) THEN132!! check if we are on a boundary or in the bulk133BoundarySolver = ( Solver % ActiveElements(1) > Model % Mesh % NumberOfBulkElements )134ELSE135BoundarySolver = .TRUE. ! must be true for other parts if no elements present136! if not boundarysolver would have active elements137END IF138139IF (BoundarySolver) THEN140DIM = CoordinateSystemDimension() - 1141ELSE142DIM = CoordinateSystemDimension()143ENDIF144145!!!!!!!!!!! get Solver Variables146CostFile = ListGetString(Solver % Values,'Cost Filename',Found )147IF (.NOT. Found) CostFile = DefaultCostFile148CALL DATE_AND_TIME(date,temps)149If (Parallel) then150if (ParEnv % MyPe.EQ.0) then151OPEN (12, FILE=CostFile)152write(12,1000) date(5:6),date(7:8),date(1:4),temps(1:2),temps(3:4),temps(5:6)153write(12,'(A)') '#, 1.0'154write(12,'(A)') '# iter, J0, sqrt(2J0/Area)'155CLOSE(12)156End if157Else158OPEN (12, FILE=CostFile)159write(12,1000) date(5:6),date(7:8),date(1:4),temps(1:2),temps(3:4),temps(5:6)160write(12,'(A)') '#, 1.0'161write(12,'(A)') '# iter, J0, sqrt(2J0/Area)'162CLOSE(12)163End if164165CostSolName = GetString( SolverParams,'Cost Variable Name', Found)166IF(.NOT.Found) THEN167CALL WARN(SolverName,'Keyword >Cost Variable Name< not found in section >Solver<')168CALL WARN(SolverName,'Taking default value >CostValue<')169WRITE(CostSolName,'(A)') 'CostValue'170END IF171172VbName = ListGetString(SolverParams,'Sensitivity Variable Name', UnFoundFatal=.TRUE.)173VbSol => VariableGet( Solver % Mesh % Variables,TRIM(VbName), UnFoundFatal=.TRUE. )174VDOFs = VbSol % DOFs175allocate(NodeCost(N),NodeCostb(N),NodeCost_der(VDOFs,N))176177!!! End of First visit178Firsttime=.false.179Endif180181VbSol => VariableGet( Solver % Mesh % Variables,TRIM(VbName), UnFoundFatal=.TRUE. )182Vb => VbSol % Values183VbPerm => VbSol % Perm184Vb=0.0_dp185186Cost=0._dp187Area=0._dp188189DO t=1,Solver % NumberOfActiveElements190Element => GetActiveElement(t)191IF (CheckPassiveElement(Element)) CYCLE192n = GetElementNOFNodes()193194NodeIndexes => Element % NodeIndexes195196! set coords of highest occurring dimension to zero (to get correct path element)197!-------------------------------------------------------------------------------198ElementNodes % x(1:n) = Solver % Mesh % Nodes % x(NodeIndexes)199IF (DIM == 1) THEN !1D200ElementNodes % y(1:n) = 0.0_dp201ElementNodes % z(1:n) = 0.0_dp202ELSE IF (DIM == 2) THEN !2D203ElementNodes % y(1:n) = Solver % Mesh % Nodes % y(NodeIndexes)204ElementNodes % z(1:n) = 0.0_dp205ELSE IF (DIM == 3) THEN206ElementNodes % y(1:n) = Solver % Mesh % Nodes % y(NodeIndexes)207ElementNodes % z(1:n) = Solver % Mesh % Nodes % z(NodeIndexes)208END IF209210BodyForce => GetBodyForce(Element)211212NodeCost=0.0_dp213NodeCost(1:n) = ListGetReal( BodyForce, 'Adjoint Cost', n, NodeIndexes, UnFoundFatal=.TRUE.)214NodeCost_der=0.0_dp215216IF (VDOFs.EQ.1) THEN217DerName='Adjoint Cost der'218IF(.NOT. ListCheckPresent( BodyForce,TRIM(DerName))) &219DerName='Adjoint Cost der ' // I2S(1)220NodeCost_der(1,1:n)=ListGetReal( BodyForce,DerName, n, NodeIndexes, UnFoundFatal=.TRUE.)221ELSE222DO k=1,VDOFs223DerName=ComponentName("Adjoint Cost der",k)224NodeCost_der(k,1:n)=ListGetReal( BodyForce,TRIM(DerName), n, NodeIndexes, Found)225IF (.NOT.Found) NodeCost_der(k,1:n)=0._dp226END DO227END IF228229!------------------------------------------------------------------------------230! Numerical integration231!------------------------------------------------------------------------------232IntegStuff = GaussPoints( Element )233234NodeCostb=0.0_dp235236DO i=1,IntegStuff % n237U = IntegStuff % u(i)238V = IntegStuff % v(i)239W = IntegStuff % w(i)240!------------------------------------------------------------------------------241! Basis function values & derivatives at the integration point242!------------------------------------------------------------------------------243stat = ElementInfo( Element,ElementNodes,U,V,W,SqrtElementMetric, &244Basis,dBasisdx )245246x = SUM( ElementNodes % x(1:n) * Basis(1:n) )247s = 1.0d0248249IF ( CurrentCoordinateSystem() /= Cartesian ) THEN250s = 2.0d0 * PI * x251END IF252s = s * SqrtElementMetric * IntegStuff % s(i)253254coeff = SUM(NodeCost(1:n) * Basis(1:n))255Cost=Cost+coeff*s256Area=Area+s257258NodeCostb(1:n)=NodeCostb(1:n) + s*Basis(1:n)259260End do261262Do j=1,n263Do i=1,VDOFs264k=(VbPerm(NodeIndexes(j))-1)*VDOFs+i265Vb(k)=Vb(k)+NodeCostb(j)*NodeCost_der(i,j)266End Do267End Do268End do269270TimeVar => VariableGet( Solver % Mesh % Variables, 'Time' )271272IF (Parallel) THEN273CALL MPI_ALLREDUCE(Cost,Cost_S,1,&274MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)275276CALL MPI_ALLREDUCE(Area,Area_S,1,&277MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)278279CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )280IF (ASSOCIATED(CostVar)) THEN281CostVar % Values(1)=Cost_S282END IF283IF (ParEnv % MyPE == 0) then284OPEN (12, FILE=CostFile,POSITION='APPEND')285write(12,'(3(ES20.11E3))') TimeVar % Values(1),Cost_S,sqrt(2*Cost_S/Area_S)286CLOSE(12)287End if288ELSE289CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )290IF (ASSOCIATED(CostVar)) THEN291CostVar % Values(1)=Cost292END IF293OPEN (12, FILE=CostFile,POSITION='APPEND')294write(12,'(3(ES20.11E3))') TimeVar % Values(1),Cost,sqrt(2*Cost/Area)295close(12)296Cost_S=Cost297END IF298299Solver % Variable % Values(1)=Cost_S300301Return3023031000 format('#date,time,',a2,'/',a2,'/',a4,',',a2,':',a2,':',a2)304!------------------------------------------------------------------------------305END SUBROUTINE Adjoint_CostContSolver306!------------------------------------------------------------------------------307! *****************************************************************************308309310