Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/ComputeStrainRate.F90
3203 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer/Ice, a glaciological add-on to Elmer
4
! * http://elmerice.elmerfem.org
5
! *
6
! *
7
! * This program is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU General Public License
9
! * as published by the Free Software Foundation; either version 2
10
! * of the License, or (at your option) any later version.
11
! *
12
! * This program is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
! * GNU General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU General Public License
18
! * along with this program (in file fem/GPL-2); if not, write to the
19
! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
! * Boston, MA 02110-1301, USA.
21
! *
22
! *****************************************************************************/
23
! ******************************************************************************
24
! *
25
! * Authors: Juha Ruokolainen, Olivier Gagliardini, Fabien Gillet-Chaulet
26
! * Email: [email protected]
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date: 8 July 1997
30
! * Date of modification: 13/10/05 from version 1.5
31
! *
32
! *****************************************************************************
33
!> Module containing a solver for computing the strain rate Eij and tr(Eij)
34
!> 2D SDOFs = 5 (E11, E22, E33, E12, Eii)
35
!> 3D SDOFs = 7 (E11, E22, E33, E12, E23, E31, Eii)
36
!> Keywords : Flow Solver Name (AIFlow, Flow Solution, Porous, ...)
37
!------------------------------------------------------------------------------
38
RECURSIVE SUBROUTINE ComputeStrainRate( Model,Solver,dt,TransientSimulation )
39
!------------------------------------------------------------------------------
40
41
USE DefUtils
42
43
IMPLICIT NONE
44
45
!------------------------------------------------------------------------------
46
!******************************************************************************
47
!
48
! Solve stress equations for one timestep
49
!
50
! ARGUMENTS:
51
!
52
! TYPE(Model_t) :: Model,
53
! INPUT: All model information (mesh,materials,BCs,etc...)
54
!
55
! TYPE(Solver_t) :: Solver
56
! INPUT: Linear equation solver options
57
!
58
! REAL(KIND=dp) :: dt,
59
! INPUT: Timestep size for time dependent simulations (NOTE: Not used
60
! currently)
61
!
62
!******************************************************************************
63
64
TYPE(Model_t) :: Model
65
TYPE(Solver_t), TARGET :: Solver
66
67
LOGICAL :: TransientSimulation
68
REAL(KIND=dp) :: dt
69
!------------------------------------------------------------------------------
70
! Local variables
71
!------------------------------------------------------------------------------
72
TYPE(Solver_t), POINTER :: PSolver
73
74
TYPE(Matrix_t),POINTER :: StiffMatrix
75
76
INTEGER :: i, j, k, l, n, t, iter, NDeg, STDOFs, EiiDOFs, LocalNodes, istat
77
INTEGER :: dim
78
79
TYPE(ValueList_t),POINTER :: Material, BC
80
TYPE(Nodes_t) :: ElementNodes
81
TYPE(Element_t),POINTER :: CurrentElement
82
83
REAL(KIND=dp) :: RelativeChange, UNorm, PrevUNorm, s
84
85
86
LOGICAL :: stat, CSymmetry
87
88
INTEGER :: NewtonIter, NonlinearIter, COMP
89
90
TYPE(Variable_t), POINTER :: EiiSol, FlowVariable
91
92
REAL(KIND=dp), POINTER :: Eii(:), FlowValues(:), Solution(:), &
93
ForceVector(:), NodalEii(:), EiiComp(:)
94
95
INTEGER, POINTER :: EiiPerm(:), NodeIndexes(:), &
96
FlowPerm(:)
97
98
LOGICAL :: GotIt, AllocationsDone = .FALSE.
99
100
REAL(KIND=dp), ALLOCATABLE:: LocalMassMatrix(:,:), &
101
LocalStiffMatrix(:,:), LocalForce(:), &
102
LocalVelo(:,:)
103
104
CHARACTER(LEN=MAX_NAME_LEN) :: FlowSolverName, StrainRateVariableName
105
106
REAL(KIND=dp) :: at, at0
107
108
!!-----------------------------------------------------------------------------
109
SAVE LocalMassMatrix, LocalStiffMatrix, LocalForce, &
110
ElementNodes, AllocationsDone
111
SAVE LocalVelo, dim
112
113
!------------------------------------------------------------------------------
114
! Read the name of the Flow Solver (NS, AIFlow, Porous, ...)
115
!------------------------------------------------------------------------------
116
117
FlowSolverName = GetString( Solver % Values, 'Flow Solver Name', GotIt )
118
IF (.NOT.Gotit) FlowSolverName = 'aiflow'
119
FlowVariable => VariableGet( Solver % Mesh % Variables, FlowSolverName )
120
IF ( ASSOCIATED( FlowVariable ) ) THEN
121
FlowPerm => FlowVariable % Perm
122
FlowValues => FlowVariable % Values
123
ELSE
124
CALL Info('ComputeStrainRate', &
125
& 'No variable for velocity associated.', Level=4)
126
END IF
127
!
128
!------------------------------------------------------------------------------
129
! Get variables needed for solution
130
!------------------------------------------------------------------------------
131
132
IF ( .NOT. ASSOCIATED( Solver % Matrix ) ) RETURN
133
134
Solution => Solver % Variable % Values
135
STDOFs = Solver % Variable % DOFs
136
137
IF ( STDOFs /=1 ) THEN
138
CALL Fatal( 'ComputeStrainRate', 'DOF must be equal to 1' )
139
END IF
140
141
StrainRateVariableName = GetString( Solver % Values, 'StrainRate Variable Name', GotIt )
142
IF (.NOT.Gotit) StrainRateVariableName = 'StrainRate'
143
144
EiiSol => VariableGet( Solver % Mesh % Variables, StrainRateVariableName )
145
EiiPerm => EiiSol % Perm
146
EiiDOFs = EiiSol % DOFs
147
Eii => EiiSol % Values
148
149
dim = CoordinateSystemDimension()
150
IF (EiiDOfs /= 2*dim+1) THEN
151
CALL Fatal( 'ComputeStrainRate', 'Bad dimension of StrainRate Variable (5 in 2D, 7 in 3D)' )
152
ENDIF
153
154
LocalNodes = COUNT( EiiPerm > 0 )
155
IF ( LocalNodes <= 0 ) RETURN
156
157
StiffMatrix => Solver % Matrix
158
ForceVector => StiffMatrix % RHS
159
Unorm = SQRT( SUM( Eii**2 ) / SIZE(Eii) )
160
161
!------------------------------------------------------------------------------
162
! Allocate some permanent storage, this is done first time only
163
!------------------------------------------------------------------------------
164
IF ( .NOT. AllocationsDone .OR. Solver % MeshChanged) THEN
165
N = Model % MaxElementNodes
166
167
IF ( AllocationsDone ) THEN
168
DEALLOCATE( ElementNodes % x, &
169
ElementNodes % y, &
170
ElementNodes % z, &
171
LocalVelo, &
172
LocalMassMatrix, &
173
LocalStiffMatrix, &
174
LocalForce )
175
END IF
176
177
ALLOCATE( ElementNodes % x( N ), &
178
ElementNodes % y( N ), &
179
ElementNodes % z( N ), &
180
LocalVelo( 3,N ), &
181
LocalMassMatrix( 2*STDOFs*N,2*STDOFs*N ), &
182
LocalStiffMatrix( 2*STDOFs*N,2*STDOFs*N ), &
183
LocalForce( 2*STDOFs*N ), STAT=istat )
184
185
IF ( istat /= 0 ) THEN
186
CALL Fatal( 'ComputeStrainRate', 'Memory allocation error.' )
187
END IF
188
!------------------------------------------------------------------------------
189
AllocationsDone = .TRUE.
190
END IF
191
192
193
!------------------------------------------------------------------------------
194
NonlinearIter = 1
195
DO iter=1,NonlinearIter
196
197
at = CPUTime()
198
at0 = RealTime()
199
200
CALL Info( 'ComputeStrainRate', ' ', Level=4 )
201
CALL Info( 'ComputeStrainRate', ' ', Level=4 )
202
CALL Info( 'ComputeStrainRate', ' ', Level=4 )
203
CALL Info( 'ComputeStrainRate', ' ', Level=4 )
204
CALL Info( 'ComputeStrainRate', 'Starting assembly...',Level=4 )
205
206
! Loop over the StrainRate components [Exx, Eyy, Ezz, Exy, Eyz, Ezx, Eii]
207
208
PrevUNorm = UNorm
209
210
DO COMP = 1, 2*dim+1
211
212
WRITE(Message,'(a,i3)' ) ' Component : ', COMP
213
CALL Info( 'ComputeStrainRate', Message, Level=5 )
214
215
!------------------------------------------------------------------------------
216
CALL DefaultInitialize()
217
!------------------------------------------------------------------------------
218
DO t=1,Solver % NumberOFActiveElements
219
220
IF ( RealTime() - at0 > 1.0 ) THEN
221
WRITE(Message,'(a,i3,a)' ) ' Assembly: ', &
222
INT(100.0 - 100.0 * (Solver % NumberOfActiveElements-t) / &
223
(1.0*Solver % NumberOfActiveElements)), ' % done'
224
CALL Info( 'ComputeStrainRate', Message, Level=5 )
225
at0 = RealTime()
226
END IF
227
228
CurrentElement => GetActiveElement(t)
229
n = GetElementNOFNodes()
230
NodeIndexes => CurrentElement % NodeIndexes
231
232
ElementNodes % x(1:n) = Model % Nodes % x(NodeIndexes(1:n))
233
ElementNodes % y(1:n) = Model % Nodes % y(NodeIndexes(1:n))
234
ElementNodes % z(1:n) = Model % Nodes % z(NodeIndexes(1:n))
235
236
Material => GetMaterial()
237
238
239
!------------------------------------------------------------------------------
240
! Get element local stiffness & mass matrices
241
!------------------------------------------------------------------------------
242
243
LocalVelo = 0.0d0
244
DO i=1, dim
245
LocalVelo(i,1:n) = FlowValues((dim+1)*(FlowPerm(NodeIndexes(1:n))-1) + i)
246
END DO
247
248
CALL LocalMatrix(COMP, LocalMassMatrix, LocalStiffMatrix, &
249
LocalForce, LocalVelo, CurrentElement, n, ElementNodes )
250
251
252
!------------------------------------------------------------------------------
253
! Update global matrices from local matrices
254
!------------------------------------------------------------------------------
255
CALL DefaultUpdateEquations( LocalStiffMatrix, LocalForce )
256
257
END DO
258
259
CALL Info( 'ComputeStrainRate', 'Assembly done', Level=4 )
260
261
262
CALL DefaultFinishAssembly()
263
264
!------------------------------------------------------------------------------
265
! Dirichlet boundary conditions
266
!------------------------------------------------------------------------------
267
CALL DefaultDirichletBCs()
268
269
!------------------------------------------------------------------------------
270
271
CALL Info( 'ComputeStrainRate', 'Set boundaries done', Level=4 )
272
273
!------------------------------------------------------------------------------
274
! Solve the system and check for convergence
275
!------------------------------------------------------------------------------
276
PrevUNorm = UNorm
277
278
UNorm = DefaultSolve()
279
280
DO t=1,Solver % NumberOfActiveElements
281
CurrentElement => GetActiveElement(t)
282
n = GetElementNOFNodes()
283
DO i=1,n
284
k = CurrentElement % NodeIndexes(i)
285
Eii( EiiDOFs*(EiiPerm(k)-1) + COMP ) = &
286
Solver % Variable % Values( Solver % Variable % Perm(k) )
287
END DO
288
END DO
289
290
END DO ! End DO Comp
291
292
293
Unorm = SQRT( SUM( Eii**2 ) / SIZE(Eii) )
294
Solver % Variable % Norm = Unorm
295
296
297
IF ( PrevUNorm + UNorm /= 0.0d0 ) THEN
298
RelativeChange = 2.0d0 * ABS( PrevUNorm - UNorm) / ( PrevUnorm + UNorm)
299
ELSE
300
RelativeChange = 0.0d0
301
END IF
302
303
WRITE( Message, * ) 'Result Norm : ',UNorm, PrevUNorm
304
CALL Info( 'ComputeStrainRate', Message, Level=4 )
305
WRITE( Message, * ) 'Relative Change : ',RelativeChange
306
CALL Info( 'ComputeStrainRate', Message, Level=4 )
307
308
309
!------------------------------------------------------------------------------
310
END DO ! of nonlinear iter
311
!------------------------------------------------------------------------------
312
313
314
CONTAINS
315
316
317
!------------------------------------------------------------------------------
318
SUBROUTINE LocalMatrix(COMP, MassMatrix, StiffMatrix, ForceVector, &
319
NodalVelo, Element, n, Nodes )
320
321
!------------------------------------------------------------------------------
322
323
REAL(KIND=dp) :: StiffMatrix(:,:), MassMatrix(:,:)
324
REAL(KIND=dp) :: NodalVelo(:,:), ForceVector(:)
325
TYPE(Nodes_t) :: Nodes
326
TYPE(Element_t) :: Element
327
INTEGER :: n, COMP
328
!------------------------------------------------------------------------------
329
!
330
REAL(KIND=dp) :: Basis(2*n), ddBasisddx(1,1,1)
331
REAL(KIND=dp) :: dBasisdx(2*n,3), detJ
332
333
REAL(KIND=dp) :: LGrad(3,3), SR(3,3), Eij(7)
334
335
INTEGER :: i, j, k, p, q, t, dim, cc
336
337
REAL(KIND=dp) :: s, u, v, w, Radius
338
339
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
340
341
INTEGER :: N_Integ
342
343
REAL(KIND=dp), DIMENSION(:), POINTER :: U_Integ, V_Integ, W_Integ, S_Integ
344
345
LOGICAL :: stat, CSymmetry
346
347
!------------------------------------------------------------------------------
348
dim = CoordinateSystemDimension()
349
cc = 2*dim + 1
350
351
ForceVector = 0.0D0
352
StiffMatrix = 0.0D0
353
MassMatrix = 0.0D0
354
355
IntegStuff = GaussPoints( Element )
356
357
U_Integ => IntegStuff % u
358
V_Integ => IntegStuff % v
359
W_Integ => IntegStuff % w
360
S_Integ => IntegStuff % s
361
N_Integ = IntegStuff % n
362
!
363
! Now we start integrating
364
!
365
DO t=1,N_Integ
366
367
u = U_Integ(t)
368
v = V_Integ(t)
369
w = W_Integ(t)
370
371
!------------------------------------------------------------------------------
372
! Basis function values & derivatives at the integration point
373
!------------------------------------------------------------------------------
374
stat = ElementInfo(Element,Nodes,u,v,w,detJ, &
375
Basis,dBasisdx,ddBasisddx,.FALSE.,.FALSE.)
376
377
378
s = detJ * S_Integ(t)
379
380
381
Radius = SUM( Nodes % x(1:n) * Basis(1:n) )
382
CSymmetry = CurrentCoordinateSystem() == AxisSymmetric
383
IF ( CSymmetry ) s = s * Radius
384
!
385
! Strain-Rate and Eii = tr(Eij)
386
!
387
SR = 0.0
388
Eij = 0.0
389
LGrad = MATMUL( NodalVelo(:,1:n), dBasisdx(1:n,:) )
390
SR = 0.5 * ( LGrad + TRANSPOSE(LGrad) )
391
IF ( CSymmetry ) THEN
392
SR(1,3) = 0.0
393
SR(2,3) = 0.0
394
SR(3,1) = 0.0
395
SR(3,2) = 0.0
396
SR(3,3) = 0.0
397
IF ( Radius > 10*AEPS ) THEN
398
SR(3,3) = SUM( Nodalvelo(1,1:n) * Basis(1:n) ) /Radius
399
400
END IF
401
END IF
402
Eij(1) = SR(1,1)
403
Eij(2) = SR(2,2)
404
Eij(3) = SR(3,3)
405
Eij(4) = SR(1,2)
406
IF (dim > 2) THEN
407
Eij(5) = SR(2,3)
408
Eij(6) = SR(3,1)
409
END IF
410
Eij(cc) = SR(1,1) + SR(2,2) + SR(3,3)
411
412
DO p=1,n
413
DO q=1,n
414
StiffMatrix(p,q) = &
415
StiffMatrix(p,q) + s*Basis(q)*Basis(p)
416
END DO
417
ForceVector(p) = &
418
ForceVector(p) + s*Eij(COMP)*Basis(p)
419
END DO
420
END DO
421
422
!------------------------------------------------------------------------------
423
END SUBROUTINE LocalMatrix
424
!------------------------------------------------------------------------------
425
426
!------------------------------------------------------------------------------
427
END SUBROUTINE ComputeStrainRate
428
!------------------------------------------------------------------------------
429
430