Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/ComputeDevStress.F90
3204 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, Fabien Gillet-Chaulet, Olivier Gagliardini
26
! * Email: [email protected]
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date: 08 Jun 1997
30
! * Date of modification: 16/01/2024
31
! * Last modification by Julien Brondex (IGE) to make it compatible with
32
! * Porous Solver
33
! *****************************************************************************
34
!> Module containing a solver for computing deviatoric or Cauchy
35
!> stress from flow solution (NS or Porous solver)
36
!> 2D SDOFs = 4 (S11, S22, S33, S12)
37
!> 3D SDOFs = 6 (S11, S22, S33, S12, S23, S31)
38
!> Keywords : Cauchy (Logical),
39
!------------------------------------------------------------------------------
40
RECURSIVE SUBROUTINE ComputeDevStress( Model,Solver,dt,TransientSimulation )
41
!------------------------------------------------------------------------------
42
43
USE DefUtils
44
45
IMPLICIT NONE
46
47
!------------------------------------------------------------------------------
48
!******************************************************************************
49
!
50
! Solve stress equations for one timestep
51
!
52
! ARGUMENTS:
53
!
54
! TYPE(Model_t) :: Model,
55
! INPUT: All model information (mesh,materials,BCs,etc...)
56
!
57
! TYPE(Solver_t) :: Solver
58
! INPUT: Linear equation solver options
59
!
60
! REAL(KIND=dp) :: dt,
61
! INPUT: Timestep size for time dependent simulations (NOTE: Not used
62
! currently)
63
!
64
!******************************************************************************
65
66
TYPE(Model_t) :: Model
67
TYPE(Solver_t), TARGET :: Solver
68
69
LOGICAL :: TransientSimulation
70
REAL(KIND=dp) :: dt
71
!------------------------------------------------------------------------------
72
! Local variables
73
!------------------------------------------------------------------------------
74
TYPE(Solver_t), POINTER :: PSolver
75
76
TYPE(Matrix_t),POINTER :: StiffMatrix
77
78
INTEGER :: i, j, k, l, n, t, iter, NDeg, iSolverName
79
INTEGER :: dim, STDOFs, StressDOFs, LocalNodes, istat
80
81
TYPE(ValueList_t),POINTER :: Material, BC, BodyForce, Constants
82
TYPE(Nodes_t) :: ElementNodes
83
TYPE(Element_t),POINTER :: CurrentElement
84
85
REAL(KIND=dp) :: RelativeChange, UNorm, PrevUNorm
86
87
REAL(KIND=dp), ALLOCATABLE :: Basis(:),ddBasisddx(:,:,:)
88
REAL(KIND=dp), ALLOCATABLE :: dBasisdx(:,:)
89
REAL(KIND=dp) :: u, v, w, detJ
90
91
LOGICAL :: stat, CSymmetry
92
93
INTEGER :: NewtonIter, NonlinearIter
94
95
TYPE(Variable_t), POINTER :: StressSol, FlowVariable, DensityVariable, VMisesVariable
96
97
REAL(KIND=dp), POINTER :: Stress(:), Solution(:), &
98
ForceVector(:), FlowValues(:), DensityValues(:), VMisesValues(:)
99
100
INTEGER, POINTER :: StressPerm(:), NodeIndexes(:), &
101
FlowPerm(:), DensityPerm(:), VMisesPerm(:)
102
103
LOGICAL :: Isotropic, AllocationsDone = .FALSE., &
104
Requal0, ComputeVMises
105
LOGICAL :: GotIt, GotIt_CT, GotIt_TFV, OldKeyword, Cauchy = .FALSE.,UnFoundFatal=.TRUE.,OutOfPlaneFlow
106
107
REAL(KIND=dp), ALLOCATABLE:: LocalMassMatrix(:,:), &
108
LocalStiffMatrix(:,:), LocalForce(:), &
109
LocalP(:), &
110
LocalVelo(:,:), LocalViscosity(:), &
111
LocalFluidity(:), LocalDensity(:), &
112
RelativeT(:), ConstantT(:)
113
114
INTEGER :: NumberOfBoundaryNodes, COMP
115
INTEGER, POINTER :: BoundaryReorder(:)
116
117
REAL(KIND=dp), POINTER :: BoundaryNormals(:,:), &
118
BoundaryTangent1(:,:), BoundaryTangent2(:,:)
119
CHARACTER(LEN=MAX_NAME_LEN) :: FlowSolverName, StressSolverName, TempName, DensityName, VMisesName
120
121
REAL(KIND=dp) :: at, at0
122
!------------------------------------------------------------------------------
123
SAVE NumberOfBoundaryNodes, BoundaryReorder, BoundaryNormals, &
124
BoundaryTangent1, BoundaryTangent2
125
126
SAVE Basis, dBasisdx, ddBasisddx
127
SAVE LocalMassMatrix, LocalStiffMatrix, LocalForce, &
128
ElementNodes, &
129
AllocationsDone, &
130
LocalViscosity, Cauchy, &
131
LocalFluidity, LocalDensity, &
132
OldKeyword, RelativeT, ConstantT
133
134
SAVE LocalVelo, LocalP, dim
135
136
! NULLIFY(StressSol, FlowVariable)
137
138
!------------------------------------------------------------------------------
139
! Read the name of the Flow Solver (NS or Porous)
140
!------------------------------------------------------------------------------
141
FlowSolverName = GetString( Solver % Values, 'Flow Solver Name', GotIt )
142
IF (.NOT.Gotit) THEN
143
CALL FATAL('ComputeDevStress', '>Flow Solver Name< must be prescribed in Solver &
144
and set to "Flow Solution" or "Porous".')
145
ELSE
146
FlowVariable => VariableGet( Solver % Mesh % Variables, FlowSolverName)
147
IF ( ASSOCIATED( FlowVariable ) ) THEN
148
FlowPerm => FlowVariable % Perm
149
FlowValues => FlowVariable % Values
150
OutOfPlaneFlow = GetLogical(Solver % Values , 'Out of Plane flow', GotIt)
151
IF ( .NOT. GotIt ) OutOfPlaneFlow = .FALSE.
152
ELSE
153
CALL FATAL('ComputeDevStress', 'Flow Variable not associated. Check consistency between used flow solver &
154
and prescribed >Flow Solver Name< !')
155
END IF
156
END IF
157
158
!!!Switch to integer indice to avoid case sensitivity issues
159
SELECT CASE(FlowSolverName)
160
CASE('Flow Solution','flow solution')
161
iSolverName = 1
162
CASE('Porous', 'porous')
163
iSolverName = 2
164
CASE DEFAULT
165
CALL FATAL('ComputeDevStress', '>Flow Solver Name< must be either "Flow Solution" or "Porous"')
166
END SELECT
167
!------------------------------------------------------------------------------
168
! Read the name of the Density Variable when using Porous solver
169
!------------------------------------------------------------------------------
170
IF (iSolverName == 2) THEN
171
Constants => GetConstants()
172
DensityName = GetString(Constants,'Density Name', GotIt)
173
IF (.NOT.GotIt) THEN
174
CALL WARN('ComputeDevStress', 'No Keyword >Density Name< defined despite using Porous Solver.&
175
Using "Density" as default.')
176
WRITE(DensityName,'(A)') 'Density'
177
ELSE
178
WRITE(Message,'(a,a)') 'Variable Name for density: ', DensityName
179
CALL INFO('ComputeDevStress',Message,Level=12)
180
END IF
181
182
DensityVariable => VariableGet(Solver % Mesh %Variables, Densityname)
183
IF ( ASSOCIATED( DensityVariable ) ) THEN
184
DensityPerm => DensityVariable % Perm
185
DensityValues => DensityVariable % Values
186
ELSE
187
CALL FATAL('ComputeDevStress', 'Density not associated. Required as viscosity=f(D) for Porous !')
188
END IF
189
END IF
190
191
ComputeVMises = GetLogical( Solver % Values, 'Compute von Mises Stress', GotIt )
192
IF (.NOT.GotIt) THEN
193
ComputeVMises = .FALSE.
194
ELSE IF (ComputeVMises) THEN
195
CALL INFO('ComputeDevStress', 'Computing von Mises stress', Level=5)
196
VMisesName = GetString(Solver % Values,'Von Mises Stress Name', GotIt)
197
IF (.NOT.GotIT) THEN
198
WRITE(VMisesName,'(A)') 'Von Mises Stress'
199
END IF
200
VMisesVariable => VariableGet(Solver % Mesh % Variables, VMisesname)
201
IF ( ASSOCIATED( VMisesVariable ) ) THEN
202
VMisesPerm => VMisesVariable % Perm
203
VMisesValues => VMisesVariable % Values
204
CALL INFO('ComputeDevStress', 'Output of von Mises stress to ' // TRIM(VMisesname), Level=3)
205
ELSE
206
CALL FATAL('ComputeDevStress', TRIM(VMisesName) // ' not associated, but output requested')
207
END IF
208
ELSE
209
ComputeVMises = .FALSE.
210
END IF
211
212
!------------------------------------------------------------------------------
213
! Read constants from constants section of SIF file
214
!------------------------------------------------------------------------------
215
!------------------------------------------------------------------------------
216
! Get variables needed for solution
217
!------------------------------------------------------------------------------
218
IF ( .NOT. ASSOCIATED( Solver % Matrix ) ) RETURN
219
220
Solution => Solver % Variable % Values
221
STDOFs = Solver % Variable % DOFs
222
223
IF ( STDOFs /=1 ) THEN
224
CALL Fatal( 'ComputeDevStress', 'DOF must be equal to 1' )
225
END IF
226
227
StressSolverName = GetString( Solver % Values, 'Stress Variable Name', GotIt )
228
IF (.NOT.Gotit) CALL FATAL('ComputeDevStress', &
229
'Stress Variable Name not defined')
230
231
StressSol => VariableGet( Solver % Mesh % Variables, TRIM(StressSolverName),&
232
UnFoundFatal=UnFoundFatal )
233
StressPerm => StressSol % Perm
234
StressDOFs = StressSol % DOFs
235
Stress => StressSol % Values
236
237
dim = CoordinateSystemDimension()
238
IF (StressDOfs /= 2*dim) THEN
239
CALL Fatal( 'ComputeDesStress', 'Bad dimension of Stress Variable (4 in 2D, 6 in 3D)' )
240
ENDIF
241
242
StiffMatrix => Solver % Matrix
243
ForceVector => StiffMatrix % RHS
244
Unorm = SQRT( SUM( Stress**2 ) / SIZE(Stress) )
245
!------------------------------------------------------------------------------
246
! Allocate some permanent storage, this is done first time only
247
!------------------------------------------------------------------------------
248
IF ( .NOT. AllocationsDone .OR. Solver % MeshChanged) THEN
249
N = Model % MaxElementNodes
250
251
IF ( AllocationsDone ) THEN
252
DEALLOCATE( ElementNodes % x, &
253
ElementNodes % y, &
254
ElementNodes % z, &
255
LocalVelo, LocalP, &
256
Basis, ddBasisddx, &
257
dBasisdx, &
258
LocalMassMatrix, &
259
LocalStiffMatrix, &
260
LocalForce, &
261
LocalViscosity, &
262
LocalFluidity, &
263
LocalDensity, &
264
RelativeT, &
265
ConstantT )
266
END IF
267
268
ALLOCATE( ElementNodes % x( N ), &
269
ElementNodes % y( N ), &
270
ElementNodes % z( N ), &
271
LocalVelo( 3,N ), LocalP( N ), &
272
Basis( 2*N ),ddBasisddx(1,1,1), dBasisdx( 2*N,3 ), &
273
LocalMassMatrix( 2*STDOFs*N,2*STDOFs*N ), &
274
LocalStiffMatrix( 2*STDOFs*N,2*STDOFs*N ), &
275
LocalForce( 2*STDOFs*N ), &
276
LocalViscosity(N), &
277
LocalFluidity(N), LocalDensity(N), &
278
RelativeT(N), ConstantT(N), STAT=istat )
279
280
IF ( istat /= 0 ) THEN
281
CALL Fatal( 'ComputeDevStress', 'Memory allocation error.' )
282
END IF
283
!------------------------------------------------------------------------------
284
285
AllocationsDone = .TRUE.
286
END IF
287
288
289
!------------------------------------------------------------------------------
290
NonlinearIter = 1
291
DO iter=1,NonlinearIter
292
293
at = CPUTime()
294
at0 = RealTime()
295
296
CALL Info( 'ComputeDevStress', ' ', Level=4 )
297
CALL Info( 'ComputeDevStress', ' ', Level=4 )
298
CALL Info( 'ComputeDevStress', ' ', Level=4 )
299
CALL Info( 'ComputeDevStress', ' ', Level=4 )
300
CALL Info( 'ComputeDevStress', 'Starting assembly...',Level=4 )
301
302
! Loop over the Stress components [Sxx, Syy, Szz, Sxy, Syz, Szx]
303
304
PrevUNorm = UNorm
305
306
DO COMP = 1, 2*dim
307
308
WRITE(Message,'(a,i3)' ) ' Component : ', COMP
309
CALL Info( 'ComputeDevStress', Message, Level=5 )
310
311
312
!------------------------------------------------------------------------------
313
CALL DefaultInitialize()
314
!------------------------------------------------------------------------------
315
DO t=1,Solver % NumberOFActiveElements
316
317
IF ( RealTime() - at0 > 1.0 ) THEN
318
WRITE(Message,'(a,i3,a)' ) ' Assembly: ', &
319
INT(100.0 - 100.0 * (Solver % NumberOfActiveElements-t) / &
320
(1.0*Solver % NumberOfActiveElements)), ' % done'
321
CALL Info( 'ComputeDevStress', Message, Level=5 )
322
at0 = RealTime()
323
END IF
324
325
CurrentElement => GetActiveElement(t)
326
n = GetElementNOFNodes()
327
NodeIndexes => CurrentElement % NodeIndexes
328
329
ElementNodes % x(1:n) = Model % Nodes % x(NodeIndexes(1:n))
330
ElementNodes % y(1:n) = Model % Nodes % y(NodeIndexes(1:n))
331
ElementNodes % z(1:n) = Model % Nodes % z(NodeIndexes(1:n))
332
333
Material => GetMaterial()
334
335
!------------------------------------------------------------------------------
336
! Read in material constants from Material section
337
!------------------------------------------------------------------------------
338
!!!! When the Flow Solver is Stokes:
339
IF (iSolverName == 1) THEN
340
!! Check for the presence of keywords related to the new vectorized Stokes solver
341
RelativeT(1:n) = ListGetReal( Material, 'Relative Temperature', n, NodeIndexes, GotIt )
342
IF (GotIt) THEN
343
OldKeyword = ListGetLogical( Material, 'Glen Allow Old Keywords', GotIt)
344
IF (.NOT.(GotIt .AND. OldKeyword)) THEN
345
CALL FATAL('ComputeDevStress', 'When using ComputeDevStress with IncompressibleNSVec &
346
>Glen Allow Old Keywords< must be set to True in Material')
347
END IF
348
ConstantT(1:n) = ListGetReal( Material, 'Constant Temperature', n, NodeIndexes, GotIt_CT )
349
TempName = GetString( Material, 'Temperature Field Variable', GotIt_TFV)
350
IF (.NOT.(GotIt_CT .OR. GotIt_TFV)) THEN
351
CALL FATAL('ComputeDevStress', '>Constant Temperature< or >Temperature Field Variable< &
352
must be prescribed in Material')
353
END IF
354
!!! In the case of constant T check for consistency between prescribed relative and constant T
355
IF (GotIt_CT .AND. (.NOT. all(abs(RelativeT(1:n) - ConstantT(1:n))<AEPS))) THEN
356
CALL FATAL('ComputeDevStress', 'When considering constant temperature, >Constant Temperature< and >Relative &
357
Temperature< must be consistent')
358
END IF
359
END IF
360
!Get Viscosity at nodes
361
LocalViscosity(1:n) = GetReal( Material, 'Viscosity', GotIt)
362
IF(.NOT.GotIt) CALL FATAL('ComputeDevStress','Variable >Viscosity Parameter< not found.')
363
!Give dummy default nodal values for rheology parameters associated to Porous:
364
LocalFluidity(1:n) = 1.0_dp
365
LocalDensity(1:n) = 1.0_dp
366
367
!!!! When the Flow Solver is Porous:
368
ELSE IF (iSolverName ==2) THEN
369
! Get fluidity at nodes
370
LocalFluidity(1:n) = GetReal( Material, 'Fluidity Parameter', GotIt )
371
IF(.NOT.GotIt) CALL FATAL('ComputeDevStress','Variable >Fluidity Parameter< not found.')
372
! Get Density at element nodes
373
! The Density can be a DG variable and it is then safe to call it
374
! using the permutation vector
375
IF (DensityVariable%TYPE == Variable_on_nodes_on_elements) THEN
376
LocalDensity(1:n) = DensityValues(DensityPerm(CurrentElement % DGIndexes(1:n)))
377
ELSE
378
LocalDensity(1:n) = DensityValues(DensityPerm(CurrentElement % NodeIndexes(1:n)))
379
END IF
380
!Give dummy default nodal values for rheology parameters associated to Stokes:
381
LocalViscosity(1:n) = 1.0_dp
382
END IF
383
!-------------------------------------------------------------------------------------
384
!Independently of Flow Solver, get nodal velo, nodal pressure and cauchy stress option
385
!-------------------------------------------------------------------------------------
386
387
! Do we want to return Cauchy or deviatoric stresses ? Deviatoric by default
388
Cauchy = ListGetLogical( Material , 'Cauchy', Gotit )
389
IF (.NOT.Gotit) THEN
390
Cauchy = .FALSE.
391
WRITE(Message,'(A)') 'Cauchy set to False'
392
CALL INFO('ComputeDevStress', Message, Level = 20)
393
END IF
394
395
LocalVelo = 0.0_dp
396
DO i=1, dim
397
LocalVelo(i,1:n) = FlowValues((dim+1)*(FlowPerm(NodeIndexes(1:n))-1) + i)
398
END DO
399
BodyForce => GetBodyForce()
400
IF ( dim < 3 .AND. OutOfPlaneFlow ) THEN
401
LocalVelo(DIM+1,1:n) = ListGetReal(BodyForce,'Out Of Plane Velocity',&
402
n, NodeIndexes(1:n),GotIt)
403
IF (.NOT.GotIt) &
404
CALL WARN('ComputeDevStress',"Out of plane velocity not found")
405
END IF
406
407
! Get Pressure at element nodes, i.e FlowValues((dim+1)*(FlowPerm(NodeIndexes(1:n))-1) + (dim +1))
408
LocalP(1:n) = FlowValues((dim+1)*FlowPerm(NodeIndexes(1:n)))
409
410
411
CALL LocalMatrix(COMP, LocalMassMatrix, LocalStiffMatrix, &
412
LocalForce, LocalVelo, LocalP, &
413
LocalViscosity, LocalFluidity, LocalDensity, &
414
CurrentElement, n, &
415
ElementNodes, Cauchy, iSolverName)
416
417
!------------------------------------------------------------------------------
418
! Update global matrices from local matrices
419
!------------------------------------------------------------------------------
420
CALL DefaultUpdateEquations( LocalStiffMatrix, LocalForce )
421
422
END DO
423
424
CALL Info( 'ComputeDevStress', 'Assembly done', Level=4 )
425
426
427
CALL DefaultFinishAssembly()
428
429
!------------------------------------------------------------------------------
430
! Dirichlet boundary conditions
431
!------------------------------------------------------------------------------
432
CALL DefaultDirichletBCs()
433
434
!------------------------------------------------------------------------------
435
436
CALL Info( 'ComputeDevStress', 'Set boundaries done', Level=4 )
437
438
!------------------------------------------------------------------------------
439
! Solve the system and check for convergence
440
!------------------------------------------------------------------------------
441
PrevUNorm = UNorm
442
443
UNorm = DefaultSolve()
444
445
DO t=1,Solver % NumberOfActiveElements
446
CurrentElement => GetActiveElement(t)
447
n = GetElementNOFNodes()
448
DO i=1,n
449
k = CurrentElement % NodeIndexes(i)
450
Stress( StressDOFs*(StressPerm(k)-1) + COMP ) = &
451
Solver % Variable % Values( Solver % Variable % Perm(k) )
452
END DO
453
END DO
454
455
END DO ! End DO Comp
456
457
458
IF (ComputeVMises) THEN
459
VMisesValues = 0.0_dp
460
DO k=1,Solver % Mesh % NumberOfNodes
461
IF (VMisesPerm(k) > 0) THEN
462
IF (DIM == 3) THEN
463
DO COMP = 1, 3
464
i = COMP + 1
465
IF (COMP == 3) i = 1
466
VMisesValues(VMisesPerm(k)) = VMisesValues(VMisesPerm(k)) &
467
+ 0.5_dp *( Stress( StressDOFs*(StressPerm(k)-1) + COMP ) &
468
- Stress( StressDOFs*(StressPerm(k)-1) + i ) )**2.0_dp &
469
+ 3.0_dp * (Stress( StressDOFs*(StressPerm(k)-1) + COMP + 3))**2.0_dp
470
END DO
471
ELSE IF (DIM == 2) THEN
472
DO COMP = 1, 2
473
VMisesValues(VMisesPerm(k)) = VMisesValues(VMisesPerm(k)) &
474
+ (Stress( StressDOFs*(StressPerm(k)-1) + COMP))**2.0_dp
475
END DO
476
VMisesValues(VMisesPerm(k)) = VMisesValues(VMisesPerm(k)) &
477
- (Stress( StressDOFs*(StressPerm(k)-1) + 1)) &
478
* (Stress( StressDOFs*(StressPerm(k)-1) + 2)) &
479
+ 3.0_dp * (Stress( StressDOFs*(StressPerm(k)-1) + 4))**2.0_dp
480
END IF
481
VMisesValues(VMisesPerm(k)) = SQRT(VMisesValues(VMisesPerm(k)))
482
END IF
483
END DO
484
END IF
485
486
Unorm = SQRT( SUM( Stress**2 ) / SIZE(Stress) )
487
Solver % Variable % Norm = Unorm
488
489
IF ( PrevUNorm + UNorm /= 0.0d0 ) THEN
490
RelativeChange = 2.0d0 * ABS( PrevUNorm - UNorm) / ( PrevUnorm + UNorm)
491
ELSE
492
RelativeChange = 0.0d0
493
END IF
494
495
WRITE( Message, * ) 'Result Norm : ',UNorm, PrevUNorm
496
CALL Info( 'ComputeDevStress', Message, Level=4 )
497
WRITE( Message, * ) 'Relative Change : ',RelativeChange
498
CALL Info( 'ComputeDevStress', Message, Level=4 )
499
500
501
!------------------------------------------------------------------------------
502
END DO ! of nonlinear iter
503
!------------------------------------------------------------------------------
504
505
506
CONTAINS
507
508
509
!------------------------------------------------------------------------------
510
SUBROUTINE LocalMatrix(COMP, MassMatrix, StiffMatrix, ForceVector, &
511
NodalVelo, NodalP, NodalViscosity, NodalFluidity, NodalDensity, &
512
Element, n, Nodes, Cauchy, iSolverName )
513
!------------------------------------------------------------------------------
514
515
USE MaterialModels
516
USE PorousMaterialModels
517
518
REAL(KIND=dp) :: StiffMatrix(:,:), MassMatrix(:,:)
519
REAL(KIND=dp) :: NodalVelo(:,:)
520
REAL(KIND=dp), DIMENSION(:) :: ForceVector, &
521
NodalViscosity, NodalP, NodalFluidity, NodalDensity
522
TYPE(Nodes_t) :: Nodes
523
TYPE(Element_t), POINTER :: Element
524
LOGICAL :: Cauchy
525
INTEGER :: n, COMP
526
INTEGER :: iSolverName
527
!------------------------------------------------------------------------------
528
!
529
REAL(KIND=dp) :: Basis(2*n),ddBasisddx(1,1,1)
530
REAL(KIND=dp) :: dBasisdx(2*n,3),detJ, pBasis(n)
531
532
REAL(KIND=dp) :: Stress, epsi
533
534
REAL(KIND=dp) :: Pressure
535
REAL(KIND=dp) :: LGrad(3,3), SR(3,3)
536
537
INTEGER :: i, j, k, p, q, t, dim, cc, NBasis, LinearBasis
538
539
REAL(KIND=dp) :: s, u, v, w, Radius
540
541
REAL(KIND=dp) :: Viscosity, Fluidity, Density, mu(2)
542
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
543
544
INTEGER :: N_Integ, nd
545
INTEGER, DIMENSION(6), PARAMETER :: indx = (/1, 2, 3, 1, 2, 3/), &
546
indy = (/1, 2, 3, 2, 3, 1/)
547
548
REAL(KIND=dp), DIMENSION(:), POINTER :: U_Integ,V_Integ,W_Integ,S_Integ
549
550
LOGICAL :: stat, CSymmetry
551
552
!------------------------------------------------------------------------------
553
dim = CoordinateSystemDimension()
554
cc=2*dim
555
556
ForceVector = 0.0_dp
557
StiffMatrix = 0.0_dp
558
MassMatrix = 0.0_dp
559
560
IntegStuff = GaussPoints( Element )
561
562
U_Integ => IntegStuff % u
563
V_Integ => IntegStuff % v
564
W_Integ => IntegStuff % w
565
S_Integ => IntegStuff % s
566
N_Integ = IntegStuff % n
567
!
568
! Now we start integrating
569
!
570
DO t=1,N_Integ
571
572
u = U_Integ(t)
573
v = V_Integ(t)
574
w = W_Integ(t)
575
576
!------------------------------------------------------------------------------
577
! Basis function values & derivatives at the integration point
578
!------------------------------------------------------------------------------
579
stat = ElementInfo(Element,Nodes,u,v,w,detJ, &
580
Basis,dBasisdx,ddBasisddx,.FALSE.,.FALSE.)
581
582
s = detJ * S_Integ(t)
583
584
Radius = SUM( Nodes % x(1:n) * Basis(1:n) )
585
CSymmetry = CurrentCoordinateSystem() == AxisSymmetric
586
IF ( CSymmetry ) s = s * Radius
587
!
588
! Deviatoric Strain-Rate at IP
589
!
590
LGrad = 0.0_dp
591
LGrad = MATMUL( NodalVelo(:,1:n), dBasisdx(1:n,:) )
592
SR = 0.5 * ( LGrad + TRANSPOSE(LGrad) )
593
IF ( CSymmetry ) THEN
594
SR(1,3) = 0.0_dp
595
SR(2,3) = 0.0_dp
596
SR(3,1) = 0.0_dp
597
SR(3,2) = 0.0_dp
598
SR(3,3) = 0.0_dp
599
IF ( Radius > 10*AEPS ) THEN
600
SR(3,3) = SUM( Nodalvelo(1,1:n) * Basis(1:n) ) /Radius
601
602
END IF
603
epsi = SR(1,1)+SR(2,2)+SR(3,3)
604
DO i=1,3
605
SR(i,i) = SR(i,i) - epsi/3.0_dp
606
END DO
607
ELSE
608
epsi = SR(1,1)+SR(2,2)+SR(3,3)
609
DO i=1,dim
610
SR(i,i) = SR(i,i) - epsi/dim !Deviatoric SR
611
END DO
612
END IF
613
!
614
! Get Effective Viscosity at IP
615
!
616
!!! For the Stokes
617
IF (iSolverName == 1) THEN
618
Viscosity = SUM( NodalViscosity(1:n)*Basis(1:n) )
619
Viscosity = EffectiveViscosity( Viscosity, 1.0_dp, NodalVelo(1,1:n), NodalVelo(2,1:n), NodalVelo(3,1:n), &
620
Element, Nodes, n, n, u, v, w, LocalIP=t )
621
!!! For the Porous
622
ELSE IF (iSolverName == 2) THEN
623
Fluidity = SUM( NodalFluidity(1:n)*Basis(1:n) )
624
Density = SUM( NodalDensity(1:n)*Basis(1:n) )
625
mu = PorousEffectiveViscosity( Fluidity, Density, SR, epsi, &
626
Element, Nodes, n, n, u, v, w, LocalIP=t ) !!mu=[eta, Kcp]
627
Viscosity = mu(1)
628
END IF
629
630
!
631
! Compute deviatoric stresses or Cauchy stresses at IP for current COMP:
632
! ----------------------------
633
634
Stress = 2.0 * Viscosity * SR(indx(COMP),indy(COMP))
635
636
IF ((Cauchy).AND.(COMP.LE.3)) THEN
637
Pressure = SUM( NodalP(1:n)*Basis(1:n) )
638
Stress = Stress - Pressure
639
END IF
640
641
DO p=1,n
642
DO q=1,n
643
StiffMatrix(p,q) = &
644
StiffMatrix(p,q) + s*Basis(q)*Basis(p)
645
END DO
646
ForceVector(p) = &
647
ForceVector(p) + s*Stress*Basis(p)
648
END DO
649
650
END DO
651
652
!------------------------------------------------------------------------------
653
END SUBROUTINE LocalMatrix
654
!------------------------------------------------------------------------------
655
656
!------------------------------------------------------------------------------
657
END SUBROUTINE ComputeDevStress
658
!------------------------------------------------------------------------------
659
660