Path: blob/devel/elmerice/Solvers/ComputeStrainRate.F90
3203 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: Juha Ruokolainen, Olivier Gagliardini, Fabien Gillet-Chaulet25! * Email: [email protected]26! * Web: http://elmerice.elmerfem.org27! *28! * Original Date: 8 July 199729! * Date of modification: 13/10/05 from version 1.530! *31! *****************************************************************************32!> Module containing a solver for computing the strain rate Eij and tr(Eij)33!> 2D SDOFs = 5 (E11, E22, E33, E12, Eii)34!> 3D SDOFs = 7 (E11, E22, E33, E12, E23, E31, Eii)35!> Keywords : Flow Solver Name (AIFlow, Flow Solution, Porous, ...)36!------------------------------------------------------------------------------37RECURSIVE SUBROUTINE ComputeStrainRate( Model,Solver,dt,TransientSimulation )38!------------------------------------------------------------------------------3940USE DefUtils4142IMPLICIT NONE4344!------------------------------------------------------------------------------45!******************************************************************************46!47! Solve stress equations for one timestep48!49! ARGUMENTS:50!51! TYPE(Model_t) :: Model,52! INPUT: All model information (mesh,materials,BCs,etc...)53!54! TYPE(Solver_t) :: Solver55! INPUT: Linear equation solver options56!57! REAL(KIND=dp) :: dt,58! INPUT: Timestep size for time dependent simulations (NOTE: Not used59! currently)60!61!******************************************************************************6263TYPE(Model_t) :: Model64TYPE(Solver_t), TARGET :: Solver6566LOGICAL :: TransientSimulation67REAL(KIND=dp) :: dt68!------------------------------------------------------------------------------69! Local variables70!------------------------------------------------------------------------------71TYPE(Solver_t), POINTER :: PSolver7273TYPE(Matrix_t),POINTER :: StiffMatrix7475INTEGER :: i, j, k, l, n, t, iter, NDeg, STDOFs, EiiDOFs, LocalNodes, istat76INTEGER :: dim7778TYPE(ValueList_t),POINTER :: Material, BC79TYPE(Nodes_t) :: ElementNodes80TYPE(Element_t),POINTER :: CurrentElement8182REAL(KIND=dp) :: RelativeChange, UNorm, PrevUNorm, s838485LOGICAL :: stat, CSymmetry8687INTEGER :: NewtonIter, NonlinearIter, COMP8889TYPE(Variable_t), POINTER :: EiiSol, FlowVariable9091REAL(KIND=dp), POINTER :: Eii(:), FlowValues(:), Solution(:), &92ForceVector(:), NodalEii(:), EiiComp(:)9394INTEGER, POINTER :: EiiPerm(:), NodeIndexes(:), &95FlowPerm(:)9697LOGICAL :: GotIt, AllocationsDone = .FALSE.9899REAL(KIND=dp), ALLOCATABLE:: LocalMassMatrix(:,:), &100LocalStiffMatrix(:,:), LocalForce(:), &101LocalVelo(:,:)102103CHARACTER(LEN=MAX_NAME_LEN) :: FlowSolverName, StrainRateVariableName104105REAL(KIND=dp) :: at, at0106107!!-----------------------------------------------------------------------------108SAVE LocalMassMatrix, LocalStiffMatrix, LocalForce, &109ElementNodes, AllocationsDone110SAVE LocalVelo, dim111112!------------------------------------------------------------------------------113! Read the name of the Flow Solver (NS, AIFlow, Porous, ...)114!------------------------------------------------------------------------------115116FlowSolverName = GetString( Solver % Values, 'Flow Solver Name', GotIt )117IF (.NOT.Gotit) FlowSolverName = 'aiflow'118FlowVariable => VariableGet( Solver % Mesh % Variables, FlowSolverName )119IF ( ASSOCIATED( FlowVariable ) ) THEN120FlowPerm => FlowVariable % Perm121FlowValues => FlowVariable % Values122ELSE123CALL Info('ComputeStrainRate', &124& 'No variable for velocity associated.', Level=4)125END IF126!127!------------------------------------------------------------------------------128! Get variables needed for solution129!------------------------------------------------------------------------------130131IF ( .NOT. ASSOCIATED( Solver % Matrix ) ) RETURN132133Solution => Solver % Variable % Values134STDOFs = Solver % Variable % DOFs135136IF ( STDOFs /=1 ) THEN137CALL Fatal( 'ComputeStrainRate', 'DOF must be equal to 1' )138END IF139140StrainRateVariableName = GetString( Solver % Values, 'StrainRate Variable Name', GotIt )141IF (.NOT.Gotit) StrainRateVariableName = 'StrainRate'142143EiiSol => VariableGet( Solver % Mesh % Variables, StrainRateVariableName )144EiiPerm => EiiSol % Perm145EiiDOFs = EiiSol % DOFs146Eii => EiiSol % Values147148dim = CoordinateSystemDimension()149IF (EiiDOfs /= 2*dim+1) THEN150CALL Fatal( 'ComputeStrainRate', 'Bad dimension of StrainRate Variable (5 in 2D, 7 in 3D)' )151ENDIF152153LocalNodes = COUNT( EiiPerm > 0 )154IF ( LocalNodes <= 0 ) RETURN155156StiffMatrix => Solver % Matrix157ForceVector => StiffMatrix % RHS158Unorm = SQRT( SUM( Eii**2 ) / SIZE(Eii) )159160!------------------------------------------------------------------------------161! Allocate some permanent storage, this is done first time only162!------------------------------------------------------------------------------163IF ( .NOT. AllocationsDone .OR. Solver % MeshChanged) THEN164N = Model % MaxElementNodes165166IF ( AllocationsDone ) THEN167DEALLOCATE( ElementNodes % x, &168ElementNodes % y, &169ElementNodes % z, &170LocalVelo, &171LocalMassMatrix, &172LocalStiffMatrix, &173LocalForce )174END IF175176ALLOCATE( ElementNodes % x( N ), &177ElementNodes % y( N ), &178ElementNodes % z( N ), &179LocalVelo( 3,N ), &180LocalMassMatrix( 2*STDOFs*N,2*STDOFs*N ), &181LocalStiffMatrix( 2*STDOFs*N,2*STDOFs*N ), &182LocalForce( 2*STDOFs*N ), STAT=istat )183184IF ( istat /= 0 ) THEN185CALL Fatal( 'ComputeStrainRate', 'Memory allocation error.' )186END IF187!------------------------------------------------------------------------------188AllocationsDone = .TRUE.189END IF190191192!------------------------------------------------------------------------------193NonlinearIter = 1194DO iter=1,NonlinearIter195196at = CPUTime()197at0 = RealTime()198199CALL Info( 'ComputeStrainRate', ' ', Level=4 )200CALL Info( 'ComputeStrainRate', ' ', Level=4 )201CALL Info( 'ComputeStrainRate', ' ', Level=4 )202CALL Info( 'ComputeStrainRate', ' ', Level=4 )203CALL Info( 'ComputeStrainRate', 'Starting assembly...',Level=4 )204205! Loop over the StrainRate components [Exx, Eyy, Ezz, Exy, Eyz, Ezx, Eii]206207PrevUNorm = UNorm208209DO COMP = 1, 2*dim+1210211WRITE(Message,'(a,i3)' ) ' Component : ', COMP212CALL Info( 'ComputeStrainRate', Message, Level=5 )213214!------------------------------------------------------------------------------215CALL DefaultInitialize()216!------------------------------------------------------------------------------217DO t=1,Solver % NumberOFActiveElements218219IF ( RealTime() - at0 > 1.0 ) THEN220WRITE(Message,'(a,i3,a)' ) ' Assembly: ', &221INT(100.0 - 100.0 * (Solver % NumberOfActiveElements-t) / &222(1.0*Solver % NumberOfActiveElements)), ' % done'223CALL Info( 'ComputeStrainRate', Message, Level=5 )224at0 = RealTime()225END IF226227CurrentElement => GetActiveElement(t)228n = GetElementNOFNodes()229NodeIndexes => CurrentElement % NodeIndexes230231ElementNodes % x(1:n) = Model % Nodes % x(NodeIndexes(1:n))232ElementNodes % y(1:n) = Model % Nodes % y(NodeIndexes(1:n))233ElementNodes % z(1:n) = Model % Nodes % z(NodeIndexes(1:n))234235Material => GetMaterial()236237238!------------------------------------------------------------------------------239! Get element local stiffness & mass matrices240!------------------------------------------------------------------------------241242LocalVelo = 0.0d0243DO i=1, dim244LocalVelo(i,1:n) = FlowValues((dim+1)*(FlowPerm(NodeIndexes(1:n))-1) + i)245END DO246247CALL LocalMatrix(COMP, LocalMassMatrix, LocalStiffMatrix, &248LocalForce, LocalVelo, CurrentElement, n, ElementNodes )249250251!------------------------------------------------------------------------------252! Update global matrices from local matrices253!------------------------------------------------------------------------------254CALL DefaultUpdateEquations( LocalStiffMatrix, LocalForce )255256END DO257258CALL Info( 'ComputeStrainRate', 'Assembly done', Level=4 )259260261CALL DefaultFinishAssembly()262263!------------------------------------------------------------------------------264! Dirichlet boundary conditions265!------------------------------------------------------------------------------266CALL DefaultDirichletBCs()267268!------------------------------------------------------------------------------269270CALL Info( 'ComputeStrainRate', 'Set boundaries done', Level=4 )271272!------------------------------------------------------------------------------273! Solve the system and check for convergence274!------------------------------------------------------------------------------275PrevUNorm = UNorm276277UNorm = DefaultSolve()278279DO t=1,Solver % NumberOfActiveElements280CurrentElement => GetActiveElement(t)281n = GetElementNOFNodes()282DO i=1,n283k = CurrentElement % NodeIndexes(i)284Eii( EiiDOFs*(EiiPerm(k)-1) + COMP ) = &285Solver % Variable % Values( Solver % Variable % Perm(k) )286END DO287END DO288289END DO ! End DO Comp290291292Unorm = SQRT( SUM( Eii**2 ) / SIZE(Eii) )293Solver % Variable % Norm = Unorm294295296IF ( PrevUNorm + UNorm /= 0.0d0 ) THEN297RelativeChange = 2.0d0 * ABS( PrevUNorm - UNorm) / ( PrevUnorm + UNorm)298ELSE299RelativeChange = 0.0d0300END IF301302WRITE( Message, * ) 'Result Norm : ',UNorm, PrevUNorm303CALL Info( 'ComputeStrainRate', Message, Level=4 )304WRITE( Message, * ) 'Relative Change : ',RelativeChange305CALL Info( 'ComputeStrainRate', Message, Level=4 )306307308!------------------------------------------------------------------------------309END DO ! of nonlinear iter310!------------------------------------------------------------------------------311312313CONTAINS314315316!------------------------------------------------------------------------------317SUBROUTINE LocalMatrix(COMP, MassMatrix, StiffMatrix, ForceVector, &318NodalVelo, Element, n, Nodes )319320!------------------------------------------------------------------------------321322REAL(KIND=dp) :: StiffMatrix(:,:), MassMatrix(:,:)323REAL(KIND=dp) :: NodalVelo(:,:), ForceVector(:)324TYPE(Nodes_t) :: Nodes325TYPE(Element_t) :: Element326INTEGER :: n, COMP327!------------------------------------------------------------------------------328!329REAL(KIND=dp) :: Basis(2*n), ddBasisddx(1,1,1)330REAL(KIND=dp) :: dBasisdx(2*n,3), detJ331332REAL(KIND=dp) :: LGrad(3,3), SR(3,3), Eij(7)333334INTEGER :: i, j, k, p, q, t, dim, cc335336REAL(KIND=dp) :: s, u, v, w, Radius337338TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff339340INTEGER :: N_Integ341342REAL(KIND=dp), DIMENSION(:), POINTER :: U_Integ, V_Integ, W_Integ, S_Integ343344LOGICAL :: stat, CSymmetry345346!------------------------------------------------------------------------------347dim = CoordinateSystemDimension()348cc = 2*dim + 1349350ForceVector = 0.0D0351StiffMatrix = 0.0D0352MassMatrix = 0.0D0353354IntegStuff = GaussPoints( Element )355356U_Integ => IntegStuff % u357V_Integ => IntegStuff % v358W_Integ => IntegStuff % w359S_Integ => IntegStuff % s360N_Integ = IntegStuff % n361!362! Now we start integrating363!364DO t=1,N_Integ365366u = U_Integ(t)367v = V_Integ(t)368w = W_Integ(t)369370!------------------------------------------------------------------------------371! Basis function values & derivatives at the integration point372!------------------------------------------------------------------------------373stat = ElementInfo(Element,Nodes,u,v,w,detJ, &374Basis,dBasisdx,ddBasisddx,.FALSE.,.FALSE.)375376377s = detJ * S_Integ(t)378379380Radius = SUM( Nodes % x(1:n) * Basis(1:n) )381CSymmetry = CurrentCoordinateSystem() == AxisSymmetric382IF ( CSymmetry ) s = s * Radius383!384! Strain-Rate and Eii = tr(Eij)385!386SR = 0.0387Eij = 0.0388LGrad = MATMUL( NodalVelo(:,1:n), dBasisdx(1:n,:) )389SR = 0.5 * ( LGrad + TRANSPOSE(LGrad) )390IF ( CSymmetry ) THEN391SR(1,3) = 0.0392SR(2,3) = 0.0393SR(3,1) = 0.0394SR(3,2) = 0.0395SR(3,3) = 0.0396IF ( Radius > 10*AEPS ) THEN397SR(3,3) = SUM( Nodalvelo(1,1:n) * Basis(1:n) ) /Radius398399END IF400END IF401Eij(1) = SR(1,1)402Eij(2) = SR(2,2)403Eij(3) = SR(3,3)404Eij(4) = SR(1,2)405IF (dim > 2) THEN406Eij(5) = SR(2,3)407Eij(6) = SR(3,1)408END IF409Eij(cc) = SR(1,1) + SR(2,2) + SR(3,3)410411DO p=1,n412DO q=1,n413StiffMatrix(p,q) = &414StiffMatrix(p,q) + s*Basis(q)*Basis(p)415END DO416ForceVector(p) = &417ForceVector(p) + s*Eij(COMP)*Basis(p)418END DO419END DO420421!------------------------------------------------------------------------------422END SUBROUTINE LocalMatrix423!------------------------------------------------------------------------------424425!------------------------------------------------------------------------------426END SUBROUTINE ComputeStrainRate427!------------------------------------------------------------------------------428429430