Path: blob/devel/elmerice/Solvers/CostSolver_Robin.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 Cost function of the Arhtern/Gudmundsson inverse Problem32! as Sum_Surface (vn-vd).(sigma_n-sigma_d).n33! with a regularization as Sum_bedrock 0.5 Lambda (dBeta/dx)^234!35! Serial/Parallel 2D/3D36!37! Need :38! - Name of the Cost Variable39! - Solutions of Neumann and Dirchlet problem40! (Velocities Only, Stresses are computed here)41! - Lambda and Beta for regularization42! - define in the sif Name='surface' and Name='bed' in appropriate BC.43!44! *****************************************************************************45SUBROUTINE CostSolver_Robin_init( Model,Solver,dt,TransientSimulation )46!------------------------------------------------------------------------------47USE DefUtils4849IMPLICIT NONE50!------------------------------------------------------------------------------51TYPE(Solver_t), TARGET :: Solver52TYPE(Model_t) :: Model53REAL(KIND=dp) :: dt54LOGICAL :: TransientSimulation55!------------------------------------------------------------------------------56! Local variables57!------------------------------------------------------------------------------58INTEGER :: NormInd, LineInd, i59LOGICAL :: GotIt, MarkFailed, AvoidFailed60CHARACTER(LEN=MAX_NAME_LEN) :: Name6162Name = ListGetString( Solver % Values, 'Equation',GotIt)63IF( .NOT. ListCheckPresent( Solver % Values,'Variable') ) THEN64CALL ListAddString( Solver % Values,'Variable',&65'-nooutput -global '//TRIM(Name)//'_var')66END IF67END68! *****************************************************************************69SUBROUTINE CostSolver_Robin( Model,Solver,dt,TransientSimulation )70!------------------------------------------------------------------------------71!******************************************************************************72USE DefUtils73USE MaterialModels74IMPLICIT NONE75!------------------------------------------------------------------------------76TYPE(Solver_t) :: Solver77TYPE(Model_t) :: Model7879REAL(KIND=dp) :: dt80LOGICAL :: TransientSimulation81!82CHARACTER(LEN=MAX_NAME_LEN), PARAMETER :: DefaultCostFile = 'CostOfT.dat'83CHARACTER(LEN=MAX_NAME_LEN) :: SolverName,NeumannSolName,DirichletSolName,CostFile84CHARACTER(LEN=MAX_NAME_LEN) :: BCName85CHARACTER(LEN=MAX_NAME_LEN) :: CostSolName, VarSolName86TYPE(Solver_t), POINTER :: ParSolver87TYPE(Element_t),POINTER :: Element,Parent88TYPE(Variable_t), POINTER :: TimeVar,CostVar89TYPE(ValueList_t), POINTER :: BC,SolverParams90TYPE(Nodes_t) :: ElementNodes,ParentNodes91TYPE(GaussIntegrationPoints_t) :: IntegStuff92INTEGER, POINTER :: NodeIndexes(:)9394Logical :: Firsttime=.true.,Found,Parallel,stat95integer :: i,j,k,l,t,n,np,NMAX,DIM,ierr9697real(kind=dp) :: Cost,Cost_surf,Cost_bed,Cost_S,Cost_surf_S,Cost_bed_S,Change98real(kind=dp),SAVE :: Oldf=0._dp99real(kind=dp) :: coeff,sTimesN100real(kind=dp) :: Viscosity,Viscosityn,Viscosityd101real(kind=dp) :: pressuren,pressured102real(kind=dp),dimension(3) :: Normal,vn,vd103real(kind=dp),dimension(3,3) :: LGradn,LGradd,SRn,SRd,Sn,Sd104real(kind=dp) :: Lambda105real(kind=dp) :: u,v,w,s,SqrtElementMetric,PSqrtElementMetric,x,y,z106REAL(KIND=dp),allocatable :: NodalBeta(:),NodalViscosity(:)107REAL(KIND=dp),allocatable :: Nodalvn(:,:),Nodalvd(:,:),Nodalvelon(:,:),Nodalvelod(:,:)108REAL(KIND=dp),allocatable :: Basis(:), PBasis(:),dBasisdx(:,:),PdBasisdx(:,:)109110CHARACTER*10 :: date,temps111112save Firsttime,Parallel,CostFile,DIM,ElementNodes,ParentNodes113save SolverName,NeumannSolName,DirichletSolName,VarSolname,CostSolName114save Lambda115save NodalBeta,NodalViscosity,Nodalvn,Nodalvd,Nodalvelon,Nodalvelod116save Basis,PBasis,dBasisdx,PdBasisdx117118119If (Firsttime) then120DIM = CoordinateSystemDimension()121WRITE(SolverName, '(A)') 'CostSolver_Robin'122123!!!!!!! Check for parallel run124Parallel = (ParEnv % PEs > 1 )125126NMAX= Model % MaxElementNodes127allocate(NodalBeta(NMAX),NodalViscosity(NMAX), &128Nodalvn(DIM+1,NMAX),Nodalvd(DIM+1,NMAX), Nodalvelon(3,NMAX),Nodalvelod(3,NMAX), &129Basis(NMAX),PBasis(NMAX),&130dBasisdx(NMAX,3),PdBasisdx(NMAX,3))131132!!!!!!!!!!! get Solver Variables133SolverParams => GetSolverParams()134135CostFile = ListGetString(Solver % Values,'Cost Filename',Found )136IF (.NOT. Found) CostFile = DefaultCostFile137CALL DATE_AND_TIME(date,temps)138If (Parallel) then139if (ParEnv % MyPe.EQ.0) then140OPEN (12, FILE=CostFile)141write(12,'(a1,a2,a1,a2,a1,a4,5x,a2,a1,a2,a1,a2)') '#',date(5:6),'/',date(7:8),'/',date(1:4), &142temps(1:2),':',temps(3:4),':',temps(5:6)143CLOSE(12)144End if145Else146OPEN (12, FILE=CostFile)147write(12,'(a1,a2,a1,a2,a1,a4,5x,a2,a1,a2,a1,a2)') '#',date(5:6),'/',date(7:8),'/',date(1:4), &148temps(1:2),':',temps(3:4),':',temps(5:6)149CLOSE(12)150End if151152153NeumannSolName = GetString( SolverParams,'Neumann Solution Name', Found)154IF(.NOT.Found) THEN155CALL WARN(SolverName,'Keyword >Neumann Solution Name< not found in section >Equation<')156CALL WARN(SolverName,'Taking default value >Flow Solution<')157WRITE(NeumannSolName,'(A)') 'Flow Solution'158END IF159160DirichletSolName = GetString( SolverParams,'Dirichlet Solution Name', Found)161IF(.NOT.Found) THEN162CALL WARN(SolverName,'Keyword >Dirichlet Solution Name< not found in section >Equation<')163CALL WARN(SolverName,'Taking default value >Flow Solution<')164WRITE(NeumannSolName,'(A)') 'Flow Solution'165End if166167Lambda = GetConstReal( SolverParams,'Lambda', Found)168IF(.NOT.Found) THEN169CALL WARN(SolverName,'Keyword >Lambda< not found in section >Equation<')170CALL WARN(SolverName,'Taking default value Lambda=0.0')171Lambda = 0.0172End if173CostSolName = 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 IF179VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)180IF(.NOT.Found) THEN181CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')182CALL WARN(SolverName,'Taking default value >Beta<')183WRITE(VarSolName,'(A)') 'Beta'184END IF185186187188!!! End of First visit189Firsttime=.false.190Endif191192193Cost=0._dp194Cost_surf=0.0_dp195Cost_bed=0.0_dp196197DO t=1,Solver % Mesh % NumberOfBoundaryElements198Element => GetBoundaryElement(t)199200BC => GetBC()201IF ( .NOT. ASSOCIATED(BC) ) CYCLE202203BCName = ListGetString( BC,'Name', Found)204IF((BCName /= 'surface').AND.(BCName /= 'bed')) CYCLE205206207CALL GetElementNodes( ElementNodes )208n = GetElementNOFNodes()209NodeIndexes => Element % NodeIndexes210211212IF (BCName == 'surface') THEN213Parent => Element % BoundaryInfo % Left214IF ( .NOT. ASSOCIATED(Parent) ) &215Parent => Element % BoundaryInfo % Right216217np = GetElementNOFDOFs(Parent)218CALL GetElementNodes( ParentNodes, Parent )219220NodalViscosity(1:np) = GetReal( GetMaterial(Parent),'Viscosity',UElement=Parent )221CALL GetVectorLocalSolution(Nodalvn,NeumannSolName,UElement=Parent )222CALL GetVectorLocalSolution(Nodalvd,DirichletSolName,UElement=Parent )223NodalVelon=0._dp224NodalVelod=0._dp225Do k=1,DIM226NodalVelon(k,1:np)=Nodalvn(k,1:np)227NodalVelod(k,1:np)=Nodalvd(k,1:np)228End do229230ELSE IF (BCName == 'bed') Then231CALL GetScalarLocalSolution(NodalBeta,VarSolName,Element)232END IF233234!------------------------------------------------------------------------------235! Numerical integration236!------------------------------------------------------------------------------237IntegStuff = GaussPoints( Element )238239DO i=1,IntegStuff % n240U = IntegStuff % u(i)241V = IntegStuff % v(i)242W = IntegStuff % w(i)243!------------------------------------------------------------------------------244! Basis function values & derivatives at the integration point245!------------------------------------------------------------------------------246stat = ElementInfo( Element,ElementNodes,U,V,W,SqrtElementMetric, &247Basis,dBasisdx )248249s = SqrtElementMetric * IntegStuff % s(i)250IF ( CurrentCoordinateSystem() /= Cartesian ) THEN251x = SUM( ElementNodes % x(1:n)*Basis(1:n) )252y = SUM( ElementNodes % y(1:n)*Basis(1:n) )253z = SUM( ElementNodes % z(1:n)*Basis(1:n) )254s = s * CoordinateSqrtMetric(x,y,z)255END IF256257IF (BCName == 'surface') THEN258Normal = NormalVector( Element, ElementNodes, U, V, .TRUE. )259260CALL GetParentUVW( Element,n,Parent,np,U,V,W,Basis )261stat = ElementInfo( Parent,ParentNodes,U,V,W,PSqrtElementMetric, &262PBasis,PdBasisdx )263264Viscosity = SUM( NodalViscosity(1:np)*PBasis(1:np) )265266Do k=1,3267vn(k)=SUM( Nodalvelon(k,1:np)*PBasis(1:np) )268vd(k)=SUM( Nodalvelod(k,1:np)*PBasis(1:np) )269End do270271Viscosityn = EffectiveViscosity( Viscosity, 1.0_dp, NodalVelon(1,1:np), Nodalvelon(2,1:np), Nodalvelon(3,1:np), &272Parent, ParentNodes, np, np, u, v, w, LocalIP=t )273LGradn = MATMUL( NodalVelon(:,1:np), PdBasisdx(1:np,:) )274SRn = 0.5 * ( LGradn + TRANSPOSE(LGradn) )275Pressuren = SUM( Nodalvn(DIM+1,1:np)*PBasis(1:np) )276sn=2.0*Viscosityn*SRn277Do k=1,3278sn(k,k)=sn(k,k)-Pressuren279End do280281282Viscosityd = EffectiveViscosity( Viscosity, 1.0_dp, Nodalvelod(1,1:np), Nodalvelod(2,1:np), Nodalvelod(3,1:np), &283Parent, ParentNodes, np, np, u, v, w, LocalIP=i )284LGradd = MATMUL( NodalVelod(:,1:np), PdBasisdx(1:np,:) )285SRd = 0.5 * ( LGradd + TRANSPOSE(LGradd) )286Pressured = SUM( Nodalvd(DIM+1,1:np)*PBasis(1:np) )287sd=2.0*Viscosityd*SRd288Do k=1,3289sd(k,k)=sd(k,k)-Pressured290End do291292coeff=0._dp293Do k=1,3294sTimesN=0.0_dp295Do l=1,3296sTimesN=sTimesN+(sn(k,l)-sd(k,l))*Normal(l)297End do298coeff=coeff+(Vn(k)-Vd(k))*sTimesN299End do300301Cost_surf=Cost_surf+coeff*s302303ELSE IF (BCName == 'bed') THEN304coeff=SUM(NodalBeta(1:n) * dBasisdx(1:n,1))305coeff=coeff*coeff306IF (DIM.eq.3) then307coeff=coeff+ &308SUM(NodalBeta(1:n)*dBasisdx(1:n,2))*SUM(NodalBeta(1:n) * dBasisdx(1:n,2))309END IF310Cost_bed=Cost_bed+coeff*s311312END IF313314End do315End do316317Cost=Cost_surf+0.5*Lambda*Cost_bed318319TimeVar => VariableGet( Solver % Mesh % Variables, 'Time' )320321322IF (Parallel) THEN323CALL MPI_ALLREDUCE(Cost,Cost_S,1,&324MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)325CALL MPI_ALLREDUCE(Cost_surf,Cost_surf_S,1,&326MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)327CALL MPI_ALLREDUCE(Cost_bed,Cost_bed_S,1,&328MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)329CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )330IF (ASSOCIATED(CostVar)) THEN331CostVar % Values(1)=Cost_S332END IF333IF (ParEnv % MyPE == 0) then334OPEN (12, FILE=CostFile,POSITION='APPEND')335write(12,'(e13.5,2x,e15.8,2x,e15.8,2x,e15.8)') TimeVar % Values(1),Cost_S,Cost_surf_S,Cost_bed_S336CLOSE(12)337End if338ELSE339CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )340IF (ASSOCIATED(CostVar)) THEN341CostVar % Values(1)=Cost342END IF343Cost_S=Cost344OPEN (10, FILE=CostFile,POSITION='APPEND')345write(10,'(e13.5,2x,e15.8,2x,e15.8,2x,e15.8)') TimeVar % Values(1),Cost,Cost_surf,Cost_bed346close(10)347END IF348349Solver % Variable % Values(1)=Cost_S350Solver % Variable % Norm = Cost_S351IF (SIZE(Solver%Variable % Values) == Solver%Variable % DOFs) THEN352!! MIMIC COMPUTE CHANGE STYLE353Change=2.*(Cost_S-Oldf)/(Cost_S+Oldf)354Change=abs(Change)355WRITE( Message, '(a,g15.8,g15.8,a)') &356'SS (ITER=1) (NRM,RELC): (',Cost_S, Change,&357' ) :: Cost'358CALL Info( 'ComputeChange', Message, Level=3 )359Oldf=Cost_S360ENDIF361362363Return364365366!------------------------------------------------------------------------------367END SUBROUTINE CostSolver_Robin368!------------------------------------------------------------------------------369! *****************************************************************************370371372