Path: blob/devel/elmerice/Solvers/AdjointSSA/AdjointSSA_SSASolver.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: Olivier Gagliardini25! * Email: [email protected]26! * Web: http://elmerice.elmerfem.org27! *28! * Original Date: 30. April 201029! *30! *****************************************************************************31!> SSolver to inquire the velocity from the SSA solution32SUBROUTINE AdjointSSA_SSASolver( Model,Solver,dt,TransientSimulation )33!------------------------------------------------------------------------------34!******************************************************************************35!36! Solve the in-plane basal velocity with the SSA solution !37! To be computed only at the base. Use then the SSASolver to export vertically38! the basal velocity and compute the vertical velocity and pressure (if needed)39!40! ARGUMENTS:41!42! TYPE(Model_t) :: Model,43! INPUT: All model information (mesh, materials, BCs, etc...)44!45! TYPE(Solver_t) :: Solver46! INPUT: Linear & nonlinear equation solver options47!48! REAL(KIND=dp) :: dt,49! INPUT: Timestep size for time dependent simulations50!51! LOGICAL :: TransientSimulation52! INPUT: Steady state or transient simulation53!54!******************************************************************************55USE DefUtils5657IMPLICIT NONE58!------------------------------------------------------------------------------59TYPE(Solver_t) :: Solver60TYPE(Model_t) :: Model6162REAL(KIND=dp) :: dt63LOGICAL :: TransientSimulation64!------------------------------------------------------------------------------65! Local variables66!------------------------------------------------------------------------------67TYPE(Nodes_t) :: ElementNodes68TYPE(Element_t),POINTER :: CurrentElement, Element, ParentElement, BoundaryElement69TYPE(Matrix_t),POINTER :: StiffMatrix70TYPE(ValueList_t), POINTER :: SolverParams, BodyForce, Material, BC71TYPE(Variable_t), POINTER :: PointerToVariable, ZsSol, ZbSol7273LOGICAL :: AllocationsDone = .FALSE., Found, GotIt, CalvingFront74LOGICAL :: Newton7576INTEGER :: i, n, m, t, istat, DIM, p, STDOFs77INTEGER :: NonlinearIter, NewtonIter, iter, other_body_id7879INTEGER, POINTER :: Permutation(:), &80ZsPerm(:), ZbPerm(:), &81NodeIndexes(:)8283REAL(KIND=dp), POINTER :: ForceVector(:)84REAL(KIND=dp), POINTER :: VariableValues(:), Zs(:), Zb(:)8586REAL(KIND=dp) :: UNorm, cn, dd, NonlinearTol, NewtonTol, MinSRInv, rhow, sealevel, &87PrevUNorm, relativeChange,minv8889REAL(KIND=dp), ALLOCATABLE,SAVE :: STIFF(:,:), LOAD(:), FORCE(:), &90NodalGravity(:), NodalViscosity(:), NodalDensity(:), &91NodalZs(:), NodalZb(:), NodalGM(:), NodalBed(:), &92NodalU(:), NodalV(:), NodalBeta(:),LocalLinVelo(:)9394INTEGER :: iFriction95REAL(KIND=dp) :: fm96CHARACTER(LEN=MAX_NAME_LEN) :: Friction97CHARACTER(LEN=MAX_NAME_LEN) :: SolverName98REAL(KIND=dp) :: at, at099LOGICAL :: SEP ! Sub-element parametrization for Grounding line100INTEGER :: GLnIP ! number of Integ. Points for GL Sub-element parametrization101TYPE(Variable_t), POINTER :: GMSol,BedrockSol102103SAVE rhow,sealevel104SAVE AllocationsDone, DIM, SolverName, ElementNodes105SAVE NodeIndexes106107!------------------------------------------------------------------------------108PointerToVariable => Solver % Variable109Permutation => PointerToVariable % Perm110VariableValues => PointerToVariable % Values111STDOFs = PointerToVariable % DOFs112WRITE(SolverName, '(A)') 'SSASolver-SSABasalSolver'113114!------------------------------------------------------------------------------115! Get variables needed for solution116!------------------------------------------------------------------------------117DIM = CoordinateSystemDimension()118119120ZbSol => VariableGet( Solver % Mesh % Variables, 'Zb', UnFoundFatal=.TRUE. )121Zb => ZbSol % Values122ZbPerm => ZbSol % Perm123124ZsSol => VariableGet( Solver % Mesh % Variables, 'Zs' , UnFoundFatal=.TRUE. )125Zs => ZsSol % Values126ZsPerm => ZsSol % Perm127128! Sub - element GL parameterisation129SEP=GetLogical( Solver % Values, 'Sub-Element GL parameterization',GotIt)130IF (.NOT.GotIt) SEP=.False.131IF (SEP) THEN132GLnIP=ListGetInteger( Solver % Values, &133'GL integration points number',UnFoundFatal=.TRUE. )134WRITE(Message,'(a,i0,a)') 'Sub-Element GL parameterization using ',GLnIP,' IPs'135CALL INFO(SolverName,TRIM(Message),level=4)136GMSol => VariableGet( Solver % Mesh % Variables, 'GroundedMask',UnFoundFatal=.TRUE. )137BedrockSol => VariableGet( Solver % Mesh % Variables, 'bedrock',UnFoundFatal=.TRUE. )138END IF139140!--------------------------------------------------------------141!Allocate some permanent storage, this is done first time only:142!--------------------------------------------------------------143IF ( (.NOT. AllocationsDone) .OR. Solver % Mesh % Changed ) THEN144145! Get some constants146rhow = ListGetConstReal( Model % Constants, 'Water Density', UnFoundFatal=.TRUE. )147sealevel = ListGetConstReal( Model % Constants, 'Sea Level', UnFoundFatal=.TRUE. )148149! Allocate150N = Model % MaxElementNodes151M = Model % Mesh % NumberOfNodes152IF (AllocationsDone) DEALLOCATE(FORCE, LOAD, STIFF, NodalGravity, &153NodalViscosity, NodalDensity, &154NodalZb, NodalZs,NodalGM,NodalBed, NodalU, NodalV, &155NodalBeta,LocalLinVelo, ElementNodes % x, &156ElementNodes % y, ElementNodes % z )157158ALLOCATE( FORCE(STDOFs*N), LOAD(N), STIFF(STDOFs*N,STDOFs*N), &159NodalGravity(N), NodalDensity(N), NodalViscosity(N), &160NodalZb(N), NodalZs(N) , NodalGM(N), NodalBed(N),&161NodalU(N), NodalV(N), NodalBeta(N),LocalLinVelo(N), &162ElementNodes % x(N), ElementNodes % y(N), ElementNodes % z(N), &163STAT=istat )164IF ( istat /= 0 ) THEN165CALL Fatal( SolverName, 'Memory allocation error.' )166END IF167168AllocationsDone = .TRUE.169CALL INFO( SolverName, 'Memory allocation done.',Level=1 )170END IF171172StiffMatrix => Solver % Matrix173ForceVector => StiffMatrix % RHS174175!------------------------------------------------------------------------------176! Do some additional initialization, and go for it177!------------------------------------------------------------------------------178179!------------------------------------------------------------------------------180NonlinearTol = GetConstReal( Solver % Values, &181'Nonlinear System Convergence Tolerance' )182183NonlinearIter = GetInteger( Solver % Values, &184'Nonlinear System Max Iterations',GotIt )185186IF ( .NOT.GotIt ) NonlinearIter = 1187188NewtonTol = ListGetConstReal( Solver % Values, &189'Nonlinear System Newton After Tolerance', minv=0.0d0 )190191NewtonIter = ListGetInteger( Solver % Values, &192'Nonlinear System Newton After Iterations', GotIt )193if (.NOT.Gotit) NewtonIter = NonlinearIter + 1194195196Newton=.False.197198!------------------------------------------------------------------------------199DO iter=1,NonlinearIter200201at = CPUTime()202at0 = RealTime()203204CALL Info( SolverName, ' ', Level=4 )205CALL Info( SolverName, ' ', Level=4 )206CALL Info( SolverName, &207'-------------------------------------',Level=4 )208WRITE( Message, * ) 'SSA BASAL VELOCITY NON-LINEAR ITERATION', iter209CALL Info( SolverName, Message, Level=4 )210If (Newton) Then211WRITE( Message, * ) 'Newton linearisation is used'212CALL Info( SolverName, Message, Level=4 )213Endif214CALL Info( SolverName, ' ', Level=4 )215CALL Info( SolverName, &216'-------------------------------------',Level=4 )217CALL Info( SolverName, ' ', Level=4 )218219220!Initialize the system and do the assembly:221!------------------------------------------222CALL DefaultInitialize()223224! bulk assembly225DO t=1,Solver % NumberOfActiveElements226Element => GetActiveElement(t)227IF (ParEnv % myPe .NE. Element % partIndex) CYCLE228n = GetElementNOFNodes()229230NodeIndexes => Element % NodeIndexes231232! set coords of highest occurring dimension to zero (to get correct path element)233!-------------------------------------------------------------------------------234ElementNodes % x(1:n) = Solver % Mesh % Nodes % x(NodeIndexes)235IF (STDOFs == 1) THEN !1D SSA236ElementNodes % y(1:n) = 0.0_dp237ElementNodes % z(1:n) = 0.0_dp238ELSE IF (STDOFs == 2) THEN !2D SSA239ElementNodes % y(1:n) = Solver % Mesh % Nodes % y(NodeIndexes)240ElementNodes % z(1:n) = 0.0_dp241ELSE242WRITE(Message,'(a,i1,a)')&243'It is not possible to compute SSA problems with DOFs=',&244STDOFs, ' . Aborting'245CALL Fatal( SolverName, Message)246STOP247END IF248249! Read the gravity in the Body Force Section250BodyForce => GetBodyForce()251NodalGravity = 0.0_dp252IF ( ASSOCIATED( BodyForce ) ) THEN253IF (STDOFs==1) THEN254NodalGravity(1:n) = ListGetReal( &255BodyForce, 'Flow BodyForce 2', n, NodeIndexes, UnFoundFatal=.TRUE.)256ELSE257NodalGravity(1:n) = ListGetReal( &258BodyForce, 'Flow BodyForce 3', n, NodeIndexes, UnFoundFatal=.TRUE.)259END IF260END IF261262! Read the Viscosity eta, density, and exponent m in MMaterial Section263! Same definition as NS Solver in Elmer - n=1/m , A = 1/ (2 eta^n)264Material => GetMaterial(Element)265266cn = ListGetConstReal( Material, 'Viscosity Exponent',UnFoundFatal=.TRUE.)267MinSRInv = ListGetConstReal( Material, 'Critical Shear Rate',UnFoundFatal=.TRUE.)268269270NodalDensity=0.0_dp271NodalDensity(1:n) = ListGetReal( Material, 'SSA Mean Density',n,NodeIndexes,UnFoundFatal=.TRUE.)272273NodalViscosity=0.0_dp274NodalViscosity(1:n) = ListGetReal( Material, 'SSA Mean Viscosity',n, NodeIndexes,UnFoundFatal=.TRUE.)275276Friction = ListGetString(Material, 'SSA Friction Law', Found,UnFoundFatal=.TRUE.)277278SELECT CASE(Friction)279CASE('linear')280iFriction = 1281fm = 1.0_dp282CASE('weertman')283iFriction = 2284CASE DEFAULT285CALL FATAL(SolverName,'Friction should be linear or Weertman')286END SELECT287288289NodalBeta(1:n) = ListGetReal( Material, 'SSA Friction Parameter', n, NodeIndexes,UnFoundFatal=.TRUE.)290IF (iFriction > 1) THEN291fm = ListGetConstReal( Material, 'SSA Friction Exponent', UnFoundFatal=.TRUE.)292LocalLinVelo = 0.0_dp293LocalLinVelo(1:n) = ListGetReal(Material, 'SSA Friction Linear Velocity', n, NodeIndexes,UnFoundFatal=.TRUE.)294END IF295296IF (SEP) THEN297NodalGM(1:n)=GMSol%Values(GMSol%Perm(NodeIndexes(1:n)))298NodalBed(1:n)=BedrockSol%Values(BedrockSol%Perm(NodeIndexes(1:n)))299ENDIF300301! Get the Nodal value of Zb and Zs302NodalZb(1:n) = Zb(ZbPerm(NodeIndexes(1:n)))303NodalZs(1:n) = Zs(ZsPerm(NodeIndexes(1:n)))304305! Previous Velocity306NodalU(1:n) = VariableValues(STDOFs*(Permutation(NodeIndexes(1:n))-1)+1)307NodalV = 0.0308IF (STDOFs.EQ.2) NodalV(1:n) = VariableValues(STDOFs*(Permutation(NodeIndexes(1:n))-1)+2)309310311CALL LocalMatrixUVSSA ( STIFF, FORCE, Element, n, ElementNodes, NodalGravity, &312NodalDensity, NodalViscosity, NodalZb, NodalZs,&313NodalU, NodalV, NodalBeta,iFriction,fm,LocalLinVelo, cn,&314NodalGM,NodalBed,SEP,GLnIP,sealevel,rhow,&315MinSRInv , STDOFs, Newton)316317CALL DefaultUpdateEquations( STIFF, FORCE )318319END DO320CALL DefaultFinishBulkAssembly()321322!323! Neumann condition324!325DO t=1,GetNOFBoundaryElements()326BoundaryElement => GetBoundaryElement(t)327IF ( .NOT. ActiveBoundaryElement() ) CYCLE328IF ( GetElementFamily() == 1 ) CYCLE329330NodeIndexes => BoundaryElement % NodeIndexes331IF (ParEnv % myPe .NE. BoundaryElement % partIndex) CYCLE332333n = GetElementNOFNodes()334FORCE = 0.0e0335STIFF = 0.0e0336337! set coords of highest occurring dimension to zero (to get correct path element)338!-------------------------------------------------------------------------------339ElementNodes % x(1:n) = Solver % Mesh % Nodes % x(NodeIndexes)340IF (STDOFs == 1) THEN341ElementNodes % y(1:n) = 0.0_dp342ElementNodes % z(1:n) = 0.0_dp343ELSE IF (STDOFs == 2) THEN344ElementNodes % y(1:n) = Solver % Mesh % Nodes % y(NodeIndexes)345ElementNodes % z(1:n) = 0.0_dp346ELSE347WRITE(Message,'(a,i1,a)')&348'It is not possible to compute SSA with SSA var DOFs=',&349STDOFs, '. Aborting'350CALL Fatal( SolverName, Message)351STOP352END IF353354355BC => GetBC()356IF (.NOT.ASSOCIATED( BC ) ) CYCLE357358! Find the nodes for which 'Calving Front' = True359CalvingFront=.False.360CalvingFront = ListGetLogical( BC, 'Calving Front', GotIt )361IF (CalvingFront) THEN362NodalZs(1:n) = Zs(ZsPerm(NodeIndexes(1:n)))363NodalZb(1:n) = Zb(ZbPerm(NodeIndexes(1:n)))364365! Need to access Parent Element to get Material properties366other_body_id = BoundaryElement % BoundaryInfo % outbody367IF (other_body_id < 1) THEN ! only one body in calculation368ParentElement => BoundaryElement % BoundaryInfo % Right369IF ( .NOT. ASSOCIATED(ParentElement) ) ParentElement => BoundaryElement % BoundaryInfo % Left370ELSE ! we are dealing with a body-body boundary and assume that the normal is pointing outwards371ParentElement => BoundaryElement % BoundaryInfo % Right372IF (ParentElement % BodyId == other_body_id) ParentElement => BoundaryElement % BoundaryInfo % Left373END IF374375! Read Density in the Material Section376Material => GetMaterial(ParentElement)377378NodalDensity=0.0_dp379NodalDensity(1:n) = ListGetReal( Material, 'SSA Mean Density',n, NodeIndexes,UnFoundFatal=.TRUE.)380381! Read the gravity in the Body Force Section382BodyForce => GetBodyForce(ParentElement)383NodalGravity = 0.0_dp384IF ( ASSOCIATED( BodyForce ) ) THEN385IF (STDOFs==1) THEN386NodalGravity(1:n) = ListGetReal( &387BodyForce, 'Flow BodyForce 2', n, NodeIndexes,UnFoundFatal=.TRUE.)388ELSE389NodalGravity(1:n) = ListGetReal( &390BodyForce, 'Flow BodyForce 3', n, NodeIndexes,UnFoundFatal=.TRUE.)391END IF392END IF393394CALL LocalMatrixBCSSA( STIFF, FORCE, BoundaryElement, n, ElementNodes,&395NodalDensity, NodalGravity, NodalZb, NodalZs, rhow, sealevel )396CALL DefaultUpdateEquations( STIFF, FORCE )397END IF398END DO399400CALL DefaultFinishAssembly()401402! Dirichlet403CALL DefaultDirichletBCs()404405406!------------------------------------------------------------------------------407! Solve the system and check for convergence408!------------------------------------------------------------------------------409PrevUNorm = UNorm410411UNorm = DefaultSolve()412413414RelativeChange = Solver % Variable % NonlinChange415416WRITE( Message, * ) 'Result Norm : ', UNorm, PrevUNorm417CALL Info(SolverName, Message, Level=4 )418WRITE( Message, * ) 'Relative Change : ', RelativeChange419CALL Info(SolverName, Message, Level=4 )420421422IF ( RelativeChange < NewtonTol .OR. &423iter > NewtonIter ) Newton = .TRUE.424425!------------------------------------------------------------------------------426IF ( RelativeChange < NonLinearTol ) EXIT427!------------------------------------------------------------------------------428429END DO ! Loop Non-Linear Iterations430431CONTAINS432433!------------------------------------------------------------------------------434SUBROUTINE LocalMatrixUVSSA( STIFF, FORCE, Element, n, Nodes, gravity, &435Density, Viscosity, LocalZb, LocalZs, LocalU, &436LocalV, LocalBeta,iFriction,fm,LocalLinVelo, cm,&437NodalGM,NodalBed,SEP,GLnIP,sealevel,rhow,&438MinSRInv, STDOFs , Newton )439!------------------------------------------------------------------------------440REAL(KIND=dp) :: STIFF(:,:), FORCE(:), gravity(:), Density(:), &441Viscosity(:), LocalZb(:), LocalZs(:), &442LocalU(:), LocalV(:) , LocalBeta(:), LocalLinVelo(:)443INTEGER :: n, cp , STDOFs444INTEGER :: iFriction445REAL(KIND=dp) :: cm,fm446TYPE(Element_t), POINTER :: Element447LOGICAL :: Newton448REAL(KIND=dp) :: NodalGM(:),NodalBed(:)449REAL(KIND=dp) :: sealevel,rhow450LOGICAL :: SEP451INTEGER :: GLnIP452!------------------------------------------------------------------------------453REAL(KIND=dp) :: Basis(n), dBasisdx(n,3), ddBasisddx(n,3,3), detJ454REAL(KIND=dp) :: g, rho, eta, h, dhdx, dhdy , muder, bedrock,Hf455REAL(KIND=dp) :: gradS(2),Slip,A(2,2), StrainA(2,2),StrainB(2,2), Exx, Eyy, Exy, Ezz, Ee, MinSRInv456REAL(KIND=dp) :: beta,Slip2,Velo(2),LinVelo,ub457REAL(KIND=dp) :: Jac(2*n,2*n),SOL(2*n)458LOGICAL :: Stat, NewtonLin,fNewtonLin459INTEGER :: i, j, t, p, q , dim460TYPE(GaussIntegrationPoints_t) :: IP461LOGICAL :: PartlyGroundedElement462463TYPE(Nodes_t) :: Nodes464!------------------------------------------------------------------------------465dim = CoordinateSystemDimension()466467STIFF = 0.0d0468FORCE = 0.0d0469Jac=0.0d0470471! Use Newton Linearisation472NewtonLin=(Newton.AND.(cm.NE.1.0_dp))473fNewtonLin = (Newton.AND.(fm.NE.1.0_dp))474475IF (SEP) THEN476PartlyGroundedElement=(ANY(NodalGM(1:n).GE.0._dp).AND.ANY(NodalGM(1:n).LT.0._dp))477IF (PartlyGroundedElement) THEN478IP = GaussPoints( Element , np=GLnIP )479ELSE480IP = GaussPoints( Element )481ENDIF482ELSE483IP = GaussPoints( Element )484ENDIF485486DO t=1,IP % n487stat = ElementInfo( Element, Nodes, IP % U(t), IP % V(t), &488IP % W(t), detJ, Basis, dBasisdx, ddBasisddx, .FALSE. )489490! Needed Integration Point value491492g = ABS(SUM( Gravity(1:n) * Basis(1:n) ))493rho = SUM( Density(1:n) * Basis(1:n) )494eta = SUM( Viscosity(1:n) * Basis(1:n) )495gradS = 0._dp496gradS(1) = SUM( LocalZs(1:n) * dBasisdx(1:n,1) )497if (STDOFs == 2) gradS(2) = SUM( LocalZs(1:n) * dBasisdx(1:n,2) )498h = SUM( (LocalZs(1:n)-LocalZb(1:n)) * Basis(1:n) )499500beta = SUM( LocalBeta(1:n) * Basis(1:n) )501IF (SEP) THEN502IF (ALL(NodalGM(1:n).LT.0._dp)) THEN503beta=0._dp504ELSE IF (PartlyGroundedElement) THEN505bedrock = SUM( NodalBed(1:n) * Basis(1:n) )506Hf= rhow * (sealevel-bedrock) / rho507if (h.lt.Hf) beta=0._dp508END IF509END IF510511IF (iFriction > 1) THEN512LinVelo = SUM( LocalLinVelo(1:n) * Basis(1:n) )513IF ((iFriction == 2).AND.(fm==1.0_dp)) iFriction=1514Velo = 0.0_dp515Velo(1) = SUM(LocalU(1:n) * Basis(1:n))516IF (STDOFs == 2) Velo(2) = SUM(LocalV(1:n) * Basis(1:n))517ub = SQRT(Velo(1)*Velo(1)+Velo(2)*Velo(2))518Slip2=1.0_dp519IF (ub < LinVelo) then520ub = LinVelo521Slip2=0.0_dp522ENDIF523END IF524IF (iFriction==1) THEN525Slip = beta526fNewtonLin = .FALSE.527ELSE IF (iFriction==2) THEN528Slip = beta * ub**(fm-1.0_dp)529Slip2 = Slip2*Slip*(fm-1.0_dp)/(ub*ub)530END IF531532533!------------------------------------------------------------------------------534! In the non-linear case, effective viscosity535IF (cm.NE.1.0_dp) THEN536Exx = SUM(LocalU(1:n)*dBasisdx(1:n,1))537Eyy = 0.0538Exy = 0.0539IF (STDOFs.EQ.2) THEN540Eyy = SUM(LocalV(1:n)*dBasisdx(1:n,2))541Ezz = -Exx - Eyy542Exy = SUM(LocalU(1:n)*dBasisdx(1:n,2))543Exy = 0.5*(Exy + SUM(LocalV(1:n)*dBasisdx(1:n,1)))544Ee = 0.5*(Exx**2.0 + Eyy**2.0 + Ezz**2.0) + Exy**2.0545!Ee = SQRT(Ee)546ELSE547!Ee = ABS(Exx)548Ee = Exx * Exx549END IF550muder = eta * 0.5 * (2**cm) * ((cm-1.0)/2.0) * Ee**((cm-1.0)/2.0 - 1.0)551IF (sqrt(Ee) < MinSRInv) then552Ee = MinSRInv*MinSRInv553muder = 0.0_dp554Endif555eta = eta * 0.5 * (2**cm) * Ee**((cm-1.0)/2.0)556END IF557558StrainA=0.0_dp559StrainB=0.0_dp560If (NewtonLin) then561StrainA(1,1)=SUM(2.0*dBasisdx(1:n,1)*LocalU(1:n))562563IF (STDOFs.EQ.2) THEN564StrainB(1,1)=SUM(0.5*dBasisdx(1:n,2)*LocalU(1:n))565566StrainA(1,2)=SUM(dBasisdx(1:n,2)*LocalV(1:n))567StrainB(1,2)=SUM(0.5*dBasisdx(1:n,1)*LocalV(1:n))568569StrainA(2,1)=SUM(dBasisdx(1:n,1)*LocalU(1:n))570StrainB(2,1)=SUM(0.5*dBasisdx(1:n,2)*LocalU(1:n))571572StrainA(2,2)=SUM(2.0*dBasisdx(1:n,2)*LocalV(1:n))573StrainB(2,2)=SUM(0.5*dBasisdx(1:n,1)*LocalV(1:n))574575End if576Endif577578A = 0.0_dp579DO p=1,n580DO q=1,n581A(1,1) = 2.0*dBasisdx(q,1)*dBasisdx(p,1)582IF (STDOFs.EQ.2) THEN583A(1,1) = A(1,1) + 0.5*dBasisdx(q,2)*dBasisdx(p,2)584A(1,2) = dBasisdx(q,2)*dBasisdx(p,1) + &5850.5*dBasisdx(q,1)*dBasisdx(p,2)586A(2,1) = dBasisdx(q,1)*dBasisdx(p,2) + &5870.5*dBasisdx(q,2)*dBasisdx(p,1)588A(2,2) = 2.0*dBasisdx(q,2)*dBasisdx(p,2) +&5890.5*dBasisdx(q,1)*dBasisdx(p,1)590END IF591A = 2.0 * h * eta * A592DO i=1,STDOFs593STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+i) = STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+i) +&594slip * Basis(q) * Basis(p) * IP % S(t) * detJ595DO j=1,STDOFs596STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) = STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) +&597A(i,j) * IP % S(t) * detJ598END DO599END DO600601IF ((fNewtonLin).AND.(iFriction > 1)) THEN602DO i=1,STDOFs603Do j=1,STDOFs604STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) = STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) +&605Slip2 * Velo(i) * Velo(j) * Basis(q) * Basis(p) * IP % S(t) * detJ606End do607END DO608END IF609610If (NewtonLin) then611! Maybe a more elegant formulation to get the Jacobian??.......612IF (STDOFs.EQ.1) THEN613Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) = Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) +&614IP % S(t) * detJ * 2.0 * h * StrainA(1,1)*dBasisdx(p,1) * &615muder * 2.0 * Exx*dBasisdx(q,1)616617ELSE IF (STDOFs.EQ.2) THEN618Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) = Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) +&619IP % S(t) * detJ * 2.0 * h * ((StrainA(1,1)+StrainA(1,2))*dBasisdx(p,1)+(StrainB(1,1)+StrainB(1,2))*dBasisdx(p,2)) * &620muder *((2.0*Exx+Eyy)*dBasisdx(q,1)+Exy*dBasisdx(q,2))621622Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+2) = Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+2) +&623IP % S(t) * detJ * 2.0 * h * ((StrainA(1,1)+StrainA(1,2))*dBasisdx(p,1)+(StrainB(1,1)+StrainB(1,2))*dBasisdx(p,2)) * &624muder *((2.0*Eyy+Exx)*dBasisdx(q,2)+Exy*dBasisdx(q,1))625626Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+1) = Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+1) +&627IP % S(t) * detJ * 2.0 * h * ((StrainA(2,1)+StrainA(2,2))*dBasisdx(p,2)+(StrainB(2,1)+StrainB(2,2))*dBasisdx(p,1)) * &628muder *((2.0*Exx+Eyy)*dBasisdx(q,1)+Exy*dBasisdx(q,2))629630Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+2) = Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+2) +&631IP % S(t) * detJ * 2.0 * h * ((StrainA(2,1)+StrainA(2,2))*dBasisdx(p,2)+(StrainB(2,1)+StrainB(2,2))*dBasisdx(p,1)) * &632muder *((2.0*Eyy+Exx)*dBasisdx(q,2)+Exy*dBasisdx(q,1))633End if634Endif635636END DO637638DO i=1,STDOFs639FORCE((STDOFs)*(p-1)+i) = FORCE((STDOFs)*(p-1)+i) - &640rho*g*h*gradS(i) * IP % s(t) * detJ * Basis(p)641END DO642643IF ((fNewtonLin).AND.(iFriction>1)) THEN644DO i=1,STDOFs645FORCE((STDOFs)*(p-1)+i) = FORCE((STDOFs)*(p-1)+i) + &646Slip2 * Velo(i) * ub * ub * IP % s(t) * detJ * Basis(p)647END DO648END IF649650END DO651END DO652653If (NewtonLin) then654SOL(1:STDOFs*n:STDOFs)=LocalU(1:n)655If (STDOFs.EQ.2) SOL(2:STDOFs*n:STDOFs)=LocalV(1:n)656657STIFF(1:STDOFs*n,1:STDOFs*n) = STIFF(1:STDOFs*n,1:STDOFs*n) + &658Jac(1:STDOFs*n,1:STDOFs*n)659FORCE(1:STDOFs*n) = FORCE(1:STDOFs*n) + &660MATMUL(Jac(1:STDOFs*n,1:STDOFs*n),SOL(1:STDOFs*n))661Endif662!------------------------------------------------------------------------------663END SUBROUTINE LocalMatrixUVSSA664!------------------------------------------------------------------------------665666!------------------------------------------------------------------------------667SUBROUTINE LocalMatrixBCSSA( STIFF, FORCE, Element, n, ENodes, Density, &668Gravity, LocalZb, LocalZs, rhow, sealevel)669!------------------------------------------------------------------------------670TYPE(Element_t), POINTER :: Element671TYPE(Nodes_t) :: ENodes672REAL(KIND=dp) :: STIFF(:,:), FORCE(:), density(:), Gravity(:), LocalZb(:),&673LocalZs(:),rhow, sealevel674INTEGER :: n675!------------------------------------------------------------------------------676REAL(KIND=dp) :: Basis(n),dBasisdx(n,3),ddBasisddx(n,3,3), &677DetJ,Normal(3), rhoi, g, alpha, h, h_im,norm678LOGICAL :: Stat679INTEGER :: t, i680TYPE(GaussIntegrationPoints_t) :: IP681682!------------------------------------------------------------------------------683STIFF = 0.0d0684FORCE = 0.0d0685686! The front force is a concentrated nodal force in 1D-SSA and687! a force distributed along a line in 2D-SSA688689! 1D-SSA Case : concentrated force at each nodes690IF (STDOFs==1) THEN !1D SSA but should be 2D problem (does elmer work in 1D?)691DO i = 1, n692g = ABS( Gravity(i) )693rhoi = Density(i)694h = LocalZs(i)-LocalZb(i)695h_im=max(0._dp,sealevel-LocalZb(i))696alpha=0.5 * g * (rhoi * h**2.0 - rhow * h_im**2.0)697FORCE(i) = FORCE(i) + alpha698END DO699700! 2D-SSA Case : force distributed along the line701! This will work in DIM=3D only if working with Extruded Mesh and Preserve702! Baseline as been set to True to keep the 1D-BC703ELSE IF (STDOFs==2) THEN704705IP = GaussPoints( Element )706DO t=1,IP % n707stat = ElementInfo( Element, ENodes, IP % U(t), IP % V(t), &708IP % W(t), detJ, Basis, dBasisdx, ddBasisddx, .FALSE. )709710g = ABS(SUM( Gravity(1:n) * Basis(1:n) ))711rhoi = SUM( Density(1:n) * Basis(1:n) )712h = SUM( (LocalZs(1:n)-LocalZb(1:n)) * Basis(1:n))713h_im = max(0.0_dp , SUM( (sealevel-LocalZb(1:n)) * Basis(1:n)) )714alpha=0.5 * g * (rhoi * h**2.0 - rhow * h_im**2.0)715716! Normal in the (x,y) plane717Normal = NormalVector( Element, ENodes, IP % U(t), IP % V(t), .TRUE.)718norm=SQRT(normal(1)**2.0+normal(2)**2.0)719Normal(1) = Normal(1)/norm720Normal(2) = Normal(2)/norm721722DO p=1,n723DO i=1,STDOFs724FORCE(STDOFs*(p-1)+i) = FORCE(STDOFs*(p-1)+i) +&725alpha * Normal(i) * IP % s(t) * detJ * Basis(p)726END DO727END DO728END DO729730ELSE731732CALL FATAL('SSASolver-SSABasalSolver','Do not work for STDOFs <> 1 or 2')733734END IF735!------------------------------------------------------------------------------736END SUBROUTINE LocalMatrixBCSSA737738739!------------------------------------------------------------------------------740END SUBROUTINE AdjointSSA_SSASolver741!------------------------------------------------------------------------------742743744745