Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/AIFlowSolve_nlS2.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: April 08 => non linear
31
! * May 09 => N-T (see mail Juha 20 Feb 2006) OG
32
! * Dec 15 =>2.5D FlowWidth O. Passalacqua
33
! *
34
! *****************************************************************************
35
!> Module containing a solver for (primarily thermal) anisotropic flow
36
RECURSIVE SUBROUTINE AIFlowSolver_nlS2( Model,Solver,dt,TransientSimulation )
37
!------------------------------------------------------------------------------
38
39
USE DefUtils
40
41
IMPLICIT NONE
42
43
!------------------------------------------------------------------------------
44
!******************************************************************************
45
!
46
! Solve stress equations for one timestep
47
!
48
! ARGUMENTS:
49
!
50
! TYPE(Model_t) :: Model,
51
! INPUT: All model information (mesh,materials,BCs,etc...)
52
!
53
! TYPE(Solver_t) :: Solver
54
! INPUT: Linear equation solver options
55
!
56
! REAL(KIND=dp) :: dt,
57
! INPUT: Timestep size for time dependent simulations (NOTE: Not used
58
! currently)
59
!
60
!******************************************************************************
61
62
TYPE(Model_t) :: Model
63
TYPE(Solver_t), TARGET :: Solver
64
65
LOGICAL :: TransientSimulation
66
REAL(KIND=dp) :: dt
67
!------------------------------------------------------------------------------
68
! Local variables
69
!------------------------------------------------------------------------------
70
TYPE(Solver_t), POINTER :: PSolver
71
72
TYPE(Matrix_t),POINTER :: StiffMatrix
73
74
INTEGER :: i, j, k, l, n, t, iter, NDeg, STDOFs, LocalNodes, istat
75
INTEGER :: dim, comp
76
77
TYPE(ValueList_t),POINTER :: Material, BC, BodyForce
78
TYPE(Nodes_t) :: ElementNodes
79
TYPE(Element_t),POINTER :: CurrentElement
80
81
REAL(KIND=dp) :: RelativeChange, UNorm, PrevUNorm, Gravity(3), &
82
Normal(3), NewtonTol, NonlinearTol, s, Wn(7), MinSRInvariant
83
84
85
REAL(KIND=dp) :: NodalStresses(3,3), &
86
NodalStrainRate(3,3), NodalSpin(3,3)
87
88
REAL(KIND=dp), ALLOCATABLE :: Basis(:),ddBasisddx(:,:,:)
89
REAL(KIND=dp), ALLOCATABLE :: dBasisdx(:,:), SlipCoeff(:,:)
90
REAL(KIND=dp) :: u,v,w,detJ
91
92
LOGICAL :: stat, CSymmetry = .FALSE., VariableFlowWidth = .FALSE., &
93
VariableLocalFlowWidth
94
95
INTEGER, PARAMETER :: INDi(1:6) = (/ 1, 2, 3, 1, 2, 3 /) ,&
96
INDj(1:6)=(/ 1, 2, 3, 2, 3, 1 /)
97
98
INTEGER :: NewtonIter, NonlinearIter
99
100
TYPE(Variable_t), POINTER :: AIFlowSol, TempSol, Var, FabricVariable
101
TYPE(Variable_t), POINTER :: SpinVar
102
REAL(KIND=dp), POINTER :: SpinValues(:)
103
INTEGER, POINTER :: SpinPerm(:)
104
105
TYPE(Variable_t), POINTER :: DevStressVar
106
REAL(KIND=dp), POINTER :: DSValues(:)
107
INTEGER, POINTER :: DSPerm(:)
108
109
TYPE(Variable_t), POINTER :: StrainRateVar
110
REAL(KIND=dp), POINTER :: SRValues(:)
111
INTEGER, POINTER :: SRPerm(:)
112
113
REAL(KIND=dp), POINTER :: Temperature(:),AIFlow(:),Work(:,:), &
114
ForceVector(:), VonMises(:), NodalAIFlow(:), AIFlowComp(:), &
115
FabricValues(:)
116
117
CHARACTER(LEN=MAX_NAME_LEN) :: EquationName
118
119
INTEGER, POINTER :: TempPerm(:), AIFlowPerm(:), NodeIndexes(:), &
120
FabricPerm(:)
121
122
INTEGER :: AIFlowType
123
LOGICAL :: GotForceBC, GotIt, NewtonLinearization = .FALSE., &
124
NormalTangential=.FALSE.,UnFoundFatal=.TRUE.
125
126
INTEGER :: body_id,bf_id
127
INTEGER :: old_body = -1
128
LOGICAL :: Isotropic, AllocationsDone = .FALSE., FreeSurface, &
129
Requal0
130
131
REAL(KIND=dp) :: FabricGrid(4878)
132
133
REAL(KIND=dp), ALLOCATABLE:: LocalMassMatrix(:,:), &
134
LocalStiffMatrix(:,:), LoadVector(:,:), LocalForce(:), &
135
LocalTemperature(:), Alpha(:,:), Beta(:), &
136
ReferenceTemperature(:), BoundaryDispl(:), K1(:), K2(:), E1(:), &
137
E2(:), E3(:), TimeForce(:), RefS(:), RefD(:), RefSpin(:), &
138
LocalVelo(:,:), LocalFluidity(:), LocalFlowWidth(:)
139
140
INTEGER :: NumberOfBoundaryNodes
141
INTEGER, POINTER :: BoundaryReorder(:)
142
143
REAL(KIND=dp) :: Bu, Bv, Bw, RM(3,3)
144
REAL(KIND=dp), POINTER :: BoundaryNormals(:,:), &
145
BoundaryTangent1(:,:), BoundaryTangent2(:,:)
146
CHARACTER(LEN=MAX_NAME_LEN) :: viscosityFile
147
REAL(KIND=dp) :: Radius
148
149
REAL(KIND=dp) :: at, at0
150
!------------------------------------------------------------------------------
151
SAVE NumberOfBoundaryNodes,BoundaryReorder,BoundaryNormals, &
152
BoundaryTangent1, BoundaryTangent2, FabricGrid, viscosityFile
153
154
SAVE TimeForce, Basis, dBasisdx, ddBasisddx
155
SAVE LocalMassMatrix, LocalStiffMatrix, LoadVector, &
156
LocalForce, ElementNodes, Alpha, Beta, LocalTemperature, LocalFlowWidth, &
157
Isotropic,AllocationsDone,ReferenceTemperature,BoundaryDispl, &
158
NodalAIFlow, K1, K2, E1, E2, E3, Wn, MinSRInvariant, old_body, &
159
LocalFluidity
160
161
SAVE RefD, RefS, RefSpin, LocalVelo, SlipCoeff
162
!------------------------------------------------------------------------------
163
! Read constants from constants section of SIF file
164
!------------------------------------------------------------------------------
165
Wn(7) = GetConstReal( Model % Constants, 'Gas Constant', GotIt )
166
IF (.NOT.GotIt) THEN
167
WRITE(Message,'(A)') 'VariableGas Constant not found. &
168
&Setting to 8.314'
169
CALL INFO('AIFlowSolve', Message, level=20)
170
Wn(7) = 8.314
171
ELSE
172
WRITE(Message,'(A,F10.4)') 'Gas Constant = ', Wn(7)
173
CALL INFO('AIFlowSolve', Message , level = 20)
174
END IF
175
!------------------------------------------------------------------------------
176
! Get variables needed for solution
177
!------------------------------------------------------------------------------
178
IF ( .NOT. ASSOCIATED( Solver % Matrix ) ) RETURN
179
180
AIFlowSol => Solver % Variable
181
AIFlowPerm => AIFlowSol % Perm
182
STDOFs = AIFlowSol % DOFs
183
AIFlow => AIFlowSol % Values
184
185
LocalNodes = COUNT( AIFlowPerm > 0 )
186
IF ( LocalNodes <= 0 ) RETURN
187
188
TempSol => VariableGet( Solver % Mesh % Variables, 'Temperature' )
189
IF ( ASSOCIATED( TempSol) ) THEN
190
TempPerm => TempSol % Perm
191
Temperature => TempSol % Values
192
END IF
193
194
FabricVariable => VariableGet(Solver % Mesh % Variables, 'Fabric')
195
IF ( ASSOCIATED( FabricVariable ) ) THEN
196
FabricPerm => FabricVariable % Perm
197
FabricValues => FabricVariable % Values
198
END IF
199
200
SpinVar => VariableGet(Solver % Mesh %Variables,'Spin')
201
IF ( ASSOCIATED( SpinVar ) ) THEN
202
SpinPerm => SpinVar % Perm
203
SpinValues => SpinVar % Values
204
END IF
205
206
StrainRateVar => VariableGet(Solver % Mesh % Variables,'StrainRate')
207
IF ( ASSOCIATED( StrainRateVar ) ) THEN
208
SRPerm => StrainRateVar % Perm
209
SRValues => StrainRateVar % Values
210
END IF
211
212
DevStressVar => &
213
VariableGet(Solver % Mesh % Variables,'DeviatoricStress')
214
IF ( ASSOCIATED( DevStressVar ) ) THEN
215
DSPerm => DevStressVar % Perm
216
DSValues => DevStressVar % Values
217
END IF
218
219
IF ( CurrentCoordinateSystem() == AxisSymmetric ) THEN
220
CSymmetry = .TRUE.
221
VariableFlowWidth = .TRUE.
222
END IF
223
224
StiffMatrix => Solver % Matrix
225
ForceVector => StiffMatrix % RHS
226
UNorm = Solver % Variable % Norm
227
228
!------------------------------------------------------------------------------
229
! Allocate some permanent storage, this is done first time only
230
!------------------------------------------------------------------------------
231
IF ( .NOT. AllocationsDone .OR. Solver % Mesh % Changed) THEN
232
N = Model % MaxElementNodes
233
dim = CoordinateSystemDimension()
234
235
IF ( AllocationsDone ) THEN
236
DEALLOCATE( ElementNodes % x, &
237
ElementNodes % y, &
238
ElementNodes % z, &
239
BoundaryDispl, &
240
ReferenceTemperature, &
241
LocalTemperature, &
242
LocalFlowWidth, &
243
K1,K2,E1,E2,E3, &
244
LocalForce, &
245
RefD, RefS, RefSpin, &
246
LocalVelo, &
247
Basis,ddBasisddx,dBasisdx, &
248
TimeForce, &
249
LocalMassMatrix, &
250
LocalStiffMatrix, &
251
LoadVector, Alpha, Beta, &
252
SlipCoeff, LocalFluidity )
253
END IF
254
255
ALLOCATE( ElementNodes % x( N ), &
256
ElementNodes % y( N ), &
257
ElementNodes % z( N ), &
258
BoundaryDispl( N ), &
259
ReferenceTemperature( N ), &
260
LocalTemperature( N ), &
261
LocalFlowWidth (N), &
262
K1( N ), K2( N ), E1( N ), E2( N ), E3( N ), &
263
LocalForce( 2*STDOFs*N ),&
264
RefS(2*dim*LocalNodes ),&
265
RefD(2*dim*LocalNodes ),&
266
RefSpin((2*dim-3)*LocalNodes ),&
267
LocalVelo( 3,N ),&
268
Basis( 2*N ),ddBasisddx(1,1,1), dBasisdx( 2*N,3 ), &
269
TimeForce( 2*STDOFs*N ), &
270
LocalMassMatrix( 2*STDOFs*N,2*STDOFs*N ), &
271
LocalStiffMatrix( 2*STDOFs*N,2*STDOFs*N ), &
272
LoadVector( 4,N ), Alpha( 3,N ), Beta( N ), &
273
SlipCoeff(3,N), LocalFluidity(N), STAT=istat )
274
275
IF ( istat /= 0 ) THEN
276
CALL Fatal( 'AIFlowSolve', 'Memory allocation error.' )
277
END IF
278
!------------------------------------------------------------------------------
279
280
AllocationsDone = .TRUE.
281
END IF
282
283
!------------------------------------------------------------------------------
284
! Do some additional initialization, and go for it
285
!------------------------------------------------------------------------------
286
287
!------------------------------------------------------------------------------
288
NonlinearTol = GetConstReal( Solver % Values, &
289
'Nonlinear System Convergence Tolerance' )
290
291
NewtonTol = GetConstReal( Solver % Values, &
292
'Nonlinear System Newton After Tolerance' )
293
294
NewtonIter = GetInteger( Solver % Values, &
295
'Nonlinear System Newton After Iterations' )
296
297
NonlinearIter = GetInteger( Solver % Values, &
298
'Nonlinear System Max Iterations',GotIt )
299
300
IF ( .NOT.GotIt ) NonlinearIter = 1
301
!------------------------------------------------------------------------------
302
303
!------------------------------------------------------------------------------
304
305
EquationName = GetString( Solver % Values, 'Equation' )
306
307
FreeSurface = .FALSE.
308
309
!------------------------------------------------------------------------------
310
DO iter=1,NonlinearIter
311
312
at = CPUTime()
313
at0 = RealTime()
314
315
CALL Info( 'AIFlowSolve', ' ', Level=4 )
316
CALL Info( 'AIFlowSolve', ' ', Level=4 )
317
CALL Info( 'AIFlowSolve', &
318
'-------------------------------------',Level=4 )
319
WRITE( Message, * ) 'ANISOTROPIC FLOW SOLVER ITERATION', iter
320
CALL Info( 'AIFlowSolve', Message,Level=4 )
321
CALL Info( 'AIFlowSolve', &
322
'-------------------------------------',Level=4 )
323
CALL Info( 'AIFlowSolve', ' ', Level=4 )
324
CALL Info( 'AIFlowSolve', 'Starting assembly...',Level=4 )
325
!------------------------------------------------------------------------------
326
CALL DefaultInitialize()
327
!------------------------------------------------------------------------------
328
DO t=1,Solver % NumberOFActiveElements
329
330
IF ( RealTime() - at0 > 1.0 ) THEN
331
WRITE(Message,'(a,i3,a)' ) ' Assembly: ', &
332
INT(100.0 - 100.0 * (Solver % NumberOfActiveElements-t) / &
333
(1.0*Solver % NumberOfActiveElements)), ' % done'
334
CALL Info( 'AIFlowSolve', Message, Level=5 )
335
at0 = RealTime()
336
END IF
337
338
CurrentElement => GetActiveElement(t)
339
340
n = GetElementNOFNodes()
341
NodeIndexes => CurrentElement % NodeIndexes
342
343
ElementNodes % x(1:n) = Model % Nodes % x(NodeIndexes(1:n))
344
ElementNodes % y(1:n) = Model % Nodes % y(NodeIndexes(1:n))
345
ElementNodes % z(1:n) = Model % Nodes % z(NodeIndexes(1:n))
346
347
Material => GetMaterial()
348
349
!------------------------------------------------------------------------------
350
! Read in material constants from Material section
351
!------------------------------------------------------------------------------
352
body_id = CurrentElement % BodyId
353
IF (body_id /= old_body) Then
354
old_body = body_id
355
Call GetMaterialDefs()
356
END IF
357
358
LocalFluidity(1:n) = ListGetReal( Material, &
359
'Fluidity Parameter', n, NodeIndexes, GotIt,&
360
UnFoundFatal=UnFoundFatal)
361
!Previous default value: LocalFluidity(1:n) = 1.0
362
363
364
LocalFlowWidth(1:n) = ListGetReal ( Material, &
365
'FlowWidth', n, NodeIndexes, GotIt)
366
IF (.NOT. GotIt) THEN
367
IF (CSymmetry) THEN
368
DO i=1,n
369
LocalFlowWidth(i) = ElementNodes % x(i)
370
END DO
371
END IF
372
ELSE
373
VariableFlowWidth = .TRUE.
374
END IF
375
376
! Test if flow width is locally constant (infinite radius case)
377
VariableLocalFlowWidth = .TRUE.
378
IF (MAXVAL(LocalFlowWidth(1:n))- &
379
MINVAL(LocalFlowWidth(1:n)) == 0.0) &
380
VariableLocalFlowWidth = .FALSE.
381
382
!------------------------------------------------------------------------------
383
! Set body forces
384
!------------------------------------------------------------------------------
385
LoadVector = 0.0D0
386
387
BodyForce => GetBodyForce()
388
IF ( ASSOCIATED( BodyForce ) ) THEN
389
LoadVector(1,1:n) = LoadVector(1,1:n) + ListGetReal( &
390
BodyForce, 'AIFlow Force 1', n, NodeIndexes, gotIt)
391
LoadVector(2,1:n) = LoadVector(2,1:n) + ListGetReal( &
392
BodyForce, 'AIFlow Force 2', n, NodeIndexes, gotIt)
393
LoadVector(3,1:n) = LoadVector(3,1:n) + ListGetReal( &
394
BodyForce, 'AIFlow Force 3', n, NodeIndexes, gotIt)
395
END IF
396
!------------------------------------------------------------------------------
397
! Get element local stiffness & mass matrices
398
!------------------------------------------------------------------------------
399
LocalTemperature = 0.0D0
400
IF ( ASSOCIATED(TempSol) ) THEN
401
DO i=1,n
402
k = TempPerm(NodeIndexes(i))
403
LocalTemperature(i) = Temperature(k)
404
END DO
405
ELSE
406
LocalTemperature(1:n) = 0.0d0
407
END IF
408
409
! fabric not needed if isotropic
410
IF(.NOT.Isotropic) THEN
411
K1(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 1 )
412
K2(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 2 )
413
E1(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 3 )
414
E2(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 4 )
415
E3(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 5 )
416
ENDIF
417
418
LocalVelo = 0.0d0
419
DO i=1,STDOFs - 1
420
LocalVelo(i,1:n) = AIFlow( STDOFs*(AIFlowPerm(NodeIndexes(1:n))-1) + i)
421
END DO
422
423
CALL LocalMatrix( LocalMassMatrix, LocalStiffMatrix, &
424
LocalForce, LoadVector, K1, K2, E1, E2, E3, LocalVelo, &
425
LocalTemperature, LocalFlowWidth, LocalFluidity, CurrentElement, n, &
426
ElementNodes, Wn, MinSRInvariant, Isotropic, VariableFlowWidth, &
427
VariableLocalFlowWidth)
428
429
TimeForce = 0.0d0
430
CALL NSCondensate(N, N,STDOFs-1,LocalStiffMatrix,LocalForce,TimeForce )
431
!------------------------------------------------------------------------------
432
! Update global matrices from local matrices
433
!------------------------------------------------------------------------------
434
CALL DefaultUpdateEquations( LocalStiffMatrix, LocalForce )
435
END DO
436
437
CALL Info( 'AIFlowSolve', 'Assembly done', Level=4 )
438
CALL DefaultFinishBulkAssembly()
439
440
!------------------------------------------------------------------------------
441
! Neumann & Newton boundary conditions
442
!------------------------------------------------------------------------------
443
DO t = 1, Model % NumberOFBoundaryElements
444
445
CurrentElement => GetBoundaryElement(t)
446
447
IF ( GetElementFamily() == 101 ) CYCLE
448
IF ( .NOT. ActiveBoundaryElement() ) CYCLE
449
450
n = GetElementNOFNodes()
451
NodeIndexes => CurrentElement % NodeIndexes
452
453
ElementNodes % x(1:n) = Model % Nodes % x(NodeIndexes(1:n))
454
ElementNodes % y(1:n) = Model % Nodes % y(NodeIndexes(1:n))
455
ElementNodes % z(1:n) = Model % Nodes % z(NodeIndexes(1:n))
456
457
BC => GetBC()
458
IF ( ASSOCIATED( BC ) ) THEN
459
LoadVector = 0.0D0
460
Alpha = 0.0D0
461
Beta = 0.0D0
462
!------------------------------------------------------------------------------
463
! Force in given direction BC: \tau\cdot n = F
464
!------------------------------------------------------------------------------
465
GotForceBC = .FALSE.
466
467
LoadVector(1,1:n) = &
468
ListGetReal( BC, 'Force 1', n, NodeIndexes, GotIt )
469
GotForceBC = GotForceBC .OR. gotIt
470
471
LoadVector(2,1:n) = &
472
ListGetReal( BC, 'Force 2', n, NodeIndexes, GotIt )
473
GotForceBC = GotForceBC .OR. gotIt
474
475
LoadVector(3,1:n) = &
476
ListGetReal( BC, 'Force 3', n, NodeIndexes, GotIt )
477
GotForceBC = GotForceBC .OR. gotIt
478
479
480
Beta(1:n) = &
481
ListGetReal( BC, 'Normal Force', n, NodeIndexes, GotIt )
482
GotForceBC = GotForceBC .OR. gotIt
483
484
!------------------------------------------------------------------------------
485
! slip boundary condition BC: \tau\cdot n = R_k u_k
486
!------------------------------------------------------------------------------
487
488
SlipCoeff = 0.0d0
489
SlipCoeff(1,1:n) = ListGetReal( BC, &
490
'AIFlow Slip Coeff 1', n, NodeIndexes, GotIt )
491
GotForceBC = GotForceBC .OR. gotIt
492
493
SlipCoeff(2,1:n) = ListGetReal( BC, &
494
'AIFlow Slip Coeff 2', n, NodeIndexes, GotIt )
495
GotForceBC = GotForceBC .OR. gotIt
496
497
SlipCoeff(3,1:n) = ListGetReal( BC, &
498
'AIFlow Slip Coeff 3', n, NodeIndexes, GotIt )
499
GotForceBC = GotForceBC .OR. gotIt
500
501
NormalTangential = ListGetLogical( BC, &
502
'Normal-Tangential AIFlow', GotIt )
503
504
IF ( .NOT.GotForceBC ) CYCLE
505
506
!------------------------------------------------------------------------------
507
CALL LocalMatrixBoundary( LocalStiffMatrix, LocalForce, &
508
LoadVector, Alpha, Beta, SlipCoeff, NormalTangential, &
509
CurrentElement, n, ElementNodes, VariableFlowWidth, &
510
VariableLocalFlowWidth, LocalFlowWidth )
511
!------------------------------------------------------------------------------
512
!------------------------------------------------------------------------------
513
! Update global matrices from local matrices (will also affect
514
! LocalStiffMatrix and LocalForce if transientsimulation is on).
515
!------------------------------------------------------------------------------
516
CALL DefaultUpdateEquations( LocalStiffMatrix, LocalForce )
517
!------------------------------------------------------------------------------
518
END IF
519
END DO
520
!------------------------------------------------------------------------------
521
CALL DefaultFinishBoundaryAssembly()
522
CALL DefaultFinishAssembly()
523
524
!------------------------------------------------------------------------------
525
! Dirichlet boundary conditions
526
!------------------------------------------------------------------------------
527
CALL DefaultDirichletBCs()
528
!------------------------------------------------------------------------------
529
530
CALL Info( 'AIFlowSolve', 'Set boundaries done', Level=4 )
531
532
!------------------------------------------------------------------------------
533
! Solve the system and check for convergence
534
!------------------------------------------------------------------------------
535
PrevUNorm = UNorm
536
537
UNorm = DefaultSolve()
538
539
IF ( PrevUNorm + UNorm /= 0.0d0 ) THEN
540
RelativeChange = 2.0d0 * ABS( PrevUNorm - UNorm) / ( PrevUnorm + UNorm)
541
ELSE
542
RelativeChange = 0.0d0
543
END IF
544
545
WRITE( Message, * ) 'Result Norm : ',UNorm, PrevUNorm
546
CALL Info( 'AIFlowSolve', Message, Level=4 )
547
WRITE( Message, * ) 'Relative Change : ',RelativeChange
548
CALL Info( 'AIFlowSolve', Message, Level=4 )
549
550
!------------------------------------------------------------------------------
551
IF ( RelativeChange < NewtonTol .OR. &
552
iter > NewtonIter ) NewtonLinearization = .TRUE.
553
554
IF ( RelativeChange < NonLinearTol ) EXIT
555
556
!------------------------------------------------------------------------------
557
END DO ! of nonlinear iter
558
!------------------------------------------------------------------------------
559
560
!------------------------------------------------------------------------------
561
! Compute the StrainRate, Spin and deviatoric Stress
562
! Nodal values
563
!------------------------------------------------------------------------------
564
565
IF ((ASSOCIATED( StrainRateVar)).OR.(ASSOCIATED(DevStressVar))&
566
.OR.(ASSOCIATED(SpinVar))) THEN
567
RefD=0.
568
RefS=0.
569
RefSpin=0.
570
IF (ASSOCIATED(StrainRateVar)) SRValues = 0.
571
IF (ASSOCIATED(devStressVar)) DSValues = 0.
572
IF (ASSOCIATED(SPinVar)) SpinValues = 0.
573
574
DO t=1,Solver % NumberOFActiveElements
575
576
CurrentElement => GetActiveElement(t)
577
n = GetElementNOFNodes()
578
NodeIndexes => CurrentElement % NodeIndexes
579
580
body_id = CurrentElement % BodyId
581
dim = CoordinateSystemDimension()
582
583
!------------------------------------------------------------------------------
584
! Read in material constants from Material section
585
!------------------------------------------------------------------------------
586
IF (body_id /= old_body) Then
587
old_body = body_id
588
Call GetMaterialDefs()
589
END IF
590
591
LocalFluidity(1:n) = ListGetReal( Material, &
592
'Fluidity Parameter', n, NodeIndexes, GotIt,&
593
UnFoundFatal=UnFoundFatal)
594
! Previous default value: LocalFluidity(1:n) = 1.0
595
596
LocalFlowWidth(1:n) = ListGetReal ( Material, &
597
'FlowWidth', n, NodeIndexes, GotIt)
598
IF (.NOT. GotIt .AND. CSymmetry) THEN
599
DO i=1,n
600
LocalFlowWidth(i) = ElementNodes % x(i)
601
END DO
602
END IF
603
604
ElementNodes % x(1:n) = Model % Nodes % x(NodeIndexes(1:n))
605
ElementNodes % y(1:n) = Model % Nodes % y(NodeIndexes(1:n))
606
ElementNodes % z(1:n) = Model % Nodes % z(NodeIndexes(1:n))
607
608
! n nodale values of the temperature
609
610
LocalTemperature = 0.0D0
611
IF ( ASSOCIATED(TempSol) ) THEN
612
DO i=1,n
613
k = TempPerm(NodeIndexes(i))
614
LocalTemperature(i) = Temperature(k)
615
END DO
616
ELSE
617
LocalTemperature(1:n) = 0.0d0
618
END IF
619
620
! n nodales values of the 5 fabric parameters, not needed if isotropic
621
IF(.NOT.Isotropic) Then
622
K1(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 1 )
623
K2(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 2 )
624
E1(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 3 )
625
E2(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 4 )
626
E3(1:n) = FabricValues( 5 * (FabricPerm(NodeIndexes(1:n))-1) + 5 )
627
END IF
628
629
! 2D U,V,p STDOFs=3
630
! 3D U,V,W,p STDOFs=4
631
LocalVelo = 0.0d0
632
DO i=1,STDOFs - 1
633
LocalVelo(i,1:n) = AIFlow( STDOFs*(AIFlowPerm(NodeIndexes(1:n))-1) + i)
634
END DO
635
636
! Go for all nodes of the element
637
Do i=1,n
638
639
! u, v, w local coord of node i
640
u = CurrentElement % Type % NodeU(i)
641
v = CurrentElement % Type % NodeV(i)
642
w = CurrentElement % Type % NodeW(i)
643
644
stat = ElementInfo(CurrentElement,ELementNodes,u,v,w,detJ, &
645
Basis,dBasisdx,ddBasisddx,.FALSE.,.FALSE.)
646
647
! Variable flow width case when R=0 strain, stress not calculated exactly in
648
! x=0 (I agree it is not very nice, better solution ???)
649
Requal0 = .False.
650
IF (( VariableFlowWidth ) .And. &
651
(SUM(LocalFlowWidth (1:n) * Basis(1:n)) == 0.0)) THEN
652
Requal0 = .True.
653
u= u + 0.0001
654
stat = ElementInfo(CurrentElement,ELementNodes,u,v,w,detJ, &
655
Basis,dBasisdx,ddBasisddx,.FALSE.,.FALSE.)
656
END IF
657
658
CALL LocalSD(NodalStresses, NodalStrainRate, NodalSpin, &
659
LocalVelo, LocalTemperature, LocalFluidity, &
660
LocalFlowWidth, K1, K2, E1, E2, E3, Basis, dBasisdx, &
661
CurrentElement, n, ElementNodes, dim, Wn, &
662
MinSRInvariant, Isotropic, VariableFlowWidth, &
663
VariableLocalFlowWidth)
664
665
IF (Requal0) NodalSpin = 0.
666
667
IF (ASSOCIATED(StrainRateVar)) &
668
RefD(2*dim*(SRPerm(NodeIndexes(i))-1)+1 : &
669
2*dim*SRPerm(NodeIndexes(i))) &
670
=RefD(2*dim*(SRPerm(NodeIndexes(i))-1)+1 : &
671
2*dim*SRPerm(NodeIndexes(i))) + 1.
672
673
IF (ASSOCIATED(DevStressVar)) &
674
RefS(2*dim*(DSPerm(NodeIndexes(i))-1)+1 : &
675
2*dim*DSPerm(NodeIndexes(i))) &
676
=RefS(2*dim*(DSPerm(NodeIndexes(i))-1)+1 : &
677
2*dim*DSPerm(NodeIndexes(i))) + 1.
678
679
IF (ASSOCIATED(SpinVar)) &
680
RefSpin((2*dim-3)*(SpinPerm(NodeIndexes(i))-1)+1 : &
681
(2*dim-3)*SpinPerm(NodeIndexes(i))) &
682
=RefSpin((2*dim-3)*(SpinPerm(NodeIndexes(i))-1)+1 : &
683
(2*dim-3)*SpinPerm(NodeIndexes(i))) + 1.
684
685
686
IF (ASSOCIATED(StrainRateVar)) THEN
687
comp=0
688
DO j=1,2*dim
689
comp=comp+1
690
SRValues(2*dim*(SRPerm(NodeIndexes(i))-1)+comp)=&
691
SRValues(2*dim*(SRPerm(NodeIndexes(i))-1)+comp) + &
692
NodalStrainRate(INDi(j),INDj(j))
693
END DO
694
END IF
695
696
IF (ASSOCIATED(DevStressVar)) THEN
697
comp=0
698
DO j=1,2*dim
699
comp=comp+1
700
DSValues(2*dim*(DSPerm(NodeIndexes(i))-1)+comp)=&
701
DSValues(2*dim*(DSPerm(NodeIndexes(i))-1)+comp) + &
702
NodalStresses(INDi(j),INDj(j))
703
END DO
704
END IF
705
706
IF (ASSOCIATED(SpinVar)) THEN
707
comp=0
708
DO j=1,(2*dim-3)
709
comp=comp+1
710
SpinValues((2*dim-3)*(SpinPerm(NodeIndexes(i))-1)+comp)=&
711
SPinValues((2*dim-3)*(SpinPerm(NodeIndexes(i))-1)+comp) + &
712
NodalSpin(INDi(j+3),INDj(j+3))
713
END DO
714
END IF
715
716
END DO
717
END DO
718
719
IF (ASSOCIATED(StrainRateVar)) THEN
720
WHERE(RefD > 0.)
721
SRVAlues = SRValues / RefD
722
END WHERE
723
END IF
724
725
IF (ASSOCIATED(DevStressVar)) THEN
726
WHERE(RefS > 0.)
727
DSVAlues = DSValues / RefS
728
END WHERE
729
END IF
730
731
IF (ASSOCIATED(SpinVar)) THEN
732
WHERE(RefSpin > 0.)
733
SpinVAlues = SpinValues / RefSpin
734
END WHERE
735
END IF
736
737
END IF
738
739
!------------------------------------------------------------------------------
740
! END Compute the StrainRate and Deviatoric Stress
741
!------------------------------------------------------------------------------
742
743
CONTAINS
744
745
SUBROUTINE GetMaterialDefs()
746
! check if we are isotropic or not
747
Isotropic = ListGetLogical( Material , 'Isotropic',Gotit )
748
IF (.NOT.Gotit) Then
749
Isotropic = .False.
750
WRITE(Message,'(A)') 'Isotropic set to False'
751
CALL INFO('AIFlowSolve', Message, Level = 20)
752
ELSE
753
IF ( (ASSOCIATED( FabricVariable )).AND.Isotropic ) Then
754
WRITE(Message,'(A)') 'Be careful Isotropic is true &
755
& and Fabric is defined!'
756
CALL INFO('AIFlowSolve', Message, Level = 1)
757
END IF
758
END IF
759
760
IF (.NOT.Isotropic) Then
761
! Get the viscosity file and store the viscosities into FabricGrid
762
viscosityFile = ListGetString( Material ,'Viscosity File',GotIt,UnFoundFatal )
763
OPEN( 1, File = viscosityFile)
764
DO i=1,813
765
READ( 1, '(6(e14.8))' ) FabricGrid( 6*(i-1)+1:6*(i-1)+6 )
766
END DO
767
CLOSE(1)
768
ENDIF
769
770
Wn(2) = ListGetConstReal( Material , 'Powerlaw Exponent', GotIt,UnFoundFatal=UnFoundFatal)
771
!Previous default value: Wn(2) = 1.0
772
WRITE(Message,'(A,F10.4)') 'Powerlaw Exponent = ', Wn(2)
773
CALL INFO('AIFlowSolve', Message, Level = 20)
774
775
Wn(3) = ListGetConstReal( Material, 'Activation Energy 1', GotIt,UnFoundFatal=UnFoundFatal)
776
!Previous default value: Wn(3) = 1.0
777
WRITE(Message,'(A,F10.4)') 'Activation Energy 1 = ', Wn(3)
778
CALL INFO('AIFlowSolve', Message, Level = 20)
779
780
Wn(4) = ListGetConstReal( Material, 'Activation Energy 2', GotIt,UnFoundFatal=UnFoundFatal)
781
!Previous default value: Wn(4) = 1.0
782
WRITE(Message,'(A,F10.4)') 'Activation Energy 2 = ', Wn(4)
783
CALL INFO('AIFlowSolve', Message, Level = 20)
784
785
Wn(5) = ListGetConstReal(Material, 'Reference Temperature', GotIt,UnFoundFatal=UnFoundFatal)
786
!Previous default value: Wn(5) = -10.0 (Celsius)
787
WRITE(Message,'(A,F10.4)') 'Reference Temperature = ', Wn(5)
788
CALL INFO('AIFlowSolve', Message, Level = 20)
789
790
Wn(6) = ListGetConstReal( Material, 'Limit Temperature', GotIt,UnFoundFatal=UnFoundFatal)
791
!Previous default value: Wn(6) = -10.0 (Celsius)
792
WRITE(Message,'(A,F10.4)') 'Limit Temperature = ', Wn(6)
793
CALL INFO('AIFlowSolve', Message, Level = 20)
794
795
! Get the Minimum value of the Effective Strain rate
796
MinSRInvariant = 100.0*AEPS
797
798
IF ( Wn(2) > 1.0 ) THEN
799
MinSRInvariant = &
800
ListGetConstReal( Material, 'Min Second Invariant', GotIt )
801
IF (.NOT.GotIt) THEN
802
WRITE(Message,'(A)') 'Variable Min Second Invariant not &
803
&found. Setting to 100.0*AEPS )'
804
CALL INFO('AIFlowSolve', Message, Level = 20)
805
ELSE
806
WRITE(Message,'(A,E14.8)') 'Min Second Invariant = ', MinSRInvariant
807
CALL INFO('AIFlowSolve', Message, Level = 20)
808
END IF
809
END IF
810
811
!------------------------------------------------------------------------------
812
END SUBROUTINE GetMaterialDefs
813
!------------------------------------------------------------------------------
814
815
!------------------------------------------------------------------------------
816
SUBROUTINE LocalMatrix( MassMatrix, StiffMatrix, ForceVector, &
817
LoadVector, NodalK1, NodalK2, NodalEuler1, NodalEuler2, &
818
NodalEuler3, NodalVelo, NodalTemperature, NodalFlowWidth, &
819
NodalFluidity, Element, n, Nodes, Wn, MinSRInvariant, Isotropic, &
820
VariableFlowWidth, VariableLocalFlowWidth )
821
822
!------------------------------------------------------------------------------
823
824
REAL(KIND=dp) :: StiffMatrix(:,:), MassMatrix(:,:)
825
REAL(KIND=dp) :: LoadVector(:,:), NodalVelo(:,:)
826
REAL(KIND=dp) :: Wn(7), MinSRInvariant
827
REAL(KIND=dp), DIMENSION(:) :: ForceVector, NodalK1, NodalK2, &
828
NodalEuler1, NodalEuler2, NodalEuler3, NodalTemperature, &
829
NodalFluidity, NodalFlowWidth
830
TYPE(Nodes_t) :: Nodes
831
TYPE(Element_t) :: Element
832
LOGICAL :: Isotropic, VariableFlowWidth, VariableLocalFlowWidth
833
INTEGER :: n
834
!------------------------------------------------------------------------------
835
!
836
REAL(KIND=dp) :: Basis(2*n),ddBasisddx(1,1,1)
837
REAL(KIND=dp) :: dBasisdx(2*n,3),SqrtElementMetric
838
839
REAL(KIND=dp) :: Force(3), K1, K2, Euler1, Euler2, Euler3
840
Real(kind=dp) :: Bg, BGlenT
841
842
REAL(KIND=dp), DIMENSION(4,4) :: A,M
843
REAL(KIND=dp) :: Load(3),Temperature, C(6,6)
844
REAL(KIND=dp) :: nn, ss,pp, LGrad(3,3), SR(3,3), Stress(3,3), D(6), epsi
845
INTEGER :: INDi(6),INDj(6)
846
847
848
INTEGER :: i, j, k, p, q, t, dim, NBasis, ind(3)
849
850
REAL(KIND=dp) :: s,u,v,w, Radius, B(6,3), G(3,6), FW
851
852
REAL(KIND=dp) :: dDispldx(3,3), ai(3), Angle(3), a2(6)
853
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
854
855
INTEGER :: N_Integ
856
857
REAL(KIND=dp), DIMENSION(:), POINTER :: U_Integ,V_Integ,W_Integ,S_Integ
858
859
LOGICAL :: stat
860
861
INTERFACE
862
Subroutine R2Ro(a2,dim,ai,angle)
863
USE Types
864
REAL(KIND=dp),intent(in) :: a2(6)
865
Integer :: dim
866
REAL(KIND=dp),intent(out) :: ai(3), Angle(3)
867
End Subroutine R2Ro
868
869
Subroutine OPILGGE_ai_nl(ai,Angle,etaI,eta36)
870
USE Types
871
REAL(kind=dp), INTENT(in), DIMENSION(3) :: ai
872
REAL(kind=dp), INTENT(in), DIMENSION(3) :: Angle
873
REAL(kind=dp), INTENT(in), DIMENSION(:) :: etaI
874
REAL(kind=dp), INTENT(out), DIMENSION(6,6) :: eta36
875
END SUBROUTINE OPILGGE_ai_nl
876
877
END INTERFACE
878
!------------------------------------------------------------------------------
879
dim = CoordinateSystemDimension()
880
881
ForceVector = 0.0D0
882
StiffMatrix = 0.0D0
883
MassMatrix = 0.0D0
884
885
!
886
! Integration stuff
887
!
888
NBasis = 2*n
889
IntegStuff = GaussPoints( Element, Element % Type % GaussPoints2 )
890
891
U_Integ => IntegStuff % u
892
V_Integ => IntegStuff % v
893
W_Integ => IntegStuff % w
894
S_Integ => IntegStuff % s
895
N_Integ = IntegStuff % n
896
!
897
! Now we start integrating
898
!
899
DO t=1,N_Integ
900
901
u = U_Integ(t)
902
v = V_Integ(t)
903
w = W_Integ(t)
904
905
!------------------------------------------------------------------------------
906
! Basis function values & derivatives at the integration point
907
!------------------------------------------------------------------------------
908
stat = ElementInfo( Element,Nodes,u,v,w,SqrtElementMetric, &
909
Basis,dBasisdx,ddBasisddx,.FALSE.,.TRUE. )
910
911
s = SqrtElementMetric * S_Integ(t)
912
!------------------------------------------------------------------------------
913
!
914
! Force at integration point
915
!
916
Force = 0.0d0
917
DO i=1,dim
918
Force(i) = SUM( LoadVector(i,1:n)*Basis(1:n))
919
END DO
920
!
921
! Temperature at the integration point
922
!
923
Temperature = SUM( NodalTemperature(1:n)*Basis(1:n) )
924
Wn(1) = SUM( NodalFluidity(1:n)*Basis(1:n) )
925
Bg=BGlenT(Temperature,Wn)
926
ss=1.0_dp
927
928
! if not isotropic use GOLF
929
C = 0.0_dp
930
IF (.NOT.Isotropic) Then
931
a2(1) = SUM( NodalK1(1:n) * Basis(1:n) )
932
a2(2) = SUM( NodalK2(1:n) * Basis(1:n) )
933
a2(3) = 1.d0 - a2(1) - a2(2)
934
a2(4) = SUM( NodalEuler1(1:n) * Basis(1:n) )
935
a2(5) = SUM( NodalEuler2(1:n) * Basis(1:n) )
936
a2(6) = SUM( NodalEuler3(1:n) * Basis(1:n) )
937
938
CALL R2Ro(a2,dim,ai,angle)
939
CALL OPILGGE_ai_nl(ai,Angle,FabricGrid,C)
940
! else use isotropic law
941
ELSE
942
Do i=1,3
943
C(i,i)=2.0_dp
944
End do
945
Do i=4,6
946
C(i,i)=1.0_dp
947
End do
948
ENDIF
949
950
FW = SUM( NodalFlowWidth(1:n) * Basis(1:n) )
951
Radius = FW / (SUM( NodalFlowWidth(1:n) * dBasisdx(1:n,1)) )
952
IF (.NOT. VariableLocalFlowWidth) Radius = 10e7
953
IF (VariableFlowWidth ) s = s * FW
954
955
!
956
! Case non-linear
957
! -----------------------------
958
959
IF ( Wn(2) > 1.0 ) THEN
960
961
Bg=Bg**(1.0/Wn(2))
962
963
LGrad = MATMUL( NodalVelo(:,1:n), dBasisdx(1:n,:) )
964
SR = 0.5 * ( LGrad + TRANSPOSE(LGrad) )
965
966
IF ( VariableFlowWidth ) THEN
967
SR(1,3) = 0.0
968
SR(2,3) = 0.0
969
SR(3,1) = 0.0
970
SR(3,2) = 0.0
971
SR(3,3) = 0.0
972
IF ( Radius > 10*AEPS ) THEN
973
SR(3,3) = SUM( Nodalvelo(1,1:n) * Basis(1:n) ) /Radius
974
END IF
975
epsi = SR(1,1)+SR(2,2)+SR(3,3)
976
DO i=1,3
977
SR(i,i) = SR(i,i) - epsi/3.0
978
END DO
979
ELSE
980
epsi = SR(1,1)+SR(2,2)+SR(3,3)
981
DO i=1,dim
982
SR(i,i) = SR(i,i) - epsi/dim
983
END DO
984
END IF
985
986
! Compute the invariant
987
nn = (1.0 - Wn(2))/(2.0*Wn(2))
988
989
IF (.NOT.ISOTROPIC) then ! non linear and anisotropic
990
D(1) = SR(1,1)
991
D(2) = SR(2,2)
992
D(3) = SR(3,3)
993
D(4) = 2. * SR(1,2)
994
D(5) = 2. * SR(2,3)
995
D(6) = 2. * SR(3,1)
996
997
INDi(1:6) = (/ 1, 2, 3, 1, 2, 3 /)
998
INDj(1:6) = (/ 1, 2, 3, 2, 3, 1 /)
999
Stress = 0.
1000
DO k = 1, 2*dim
1001
DO j = 1, 2*dim
1002
Stress( INDi(k),INDj(k) ) = &
1003
Stress( INDi(k),INDj(k) ) + C(k,j) * D(j)
1004
END DO
1005
IF (k > 3) Stress( INDj(k),INDi(k) ) = Stress( INDi(k),INDj(k) )
1006
END DO
1007
ss = 0.0_dp
1008
pp=0._dp
1009
DO i = 1, 3
1010
DO j = 1, 3
1011
ss = ss + Stress(i,j)**2.
1012
pp=pp+SR(i,j)**2.
1013
END DO
1014
END DO
1015
ss=ss/4. ! pour avoir le meme resultat si Isotropic
1016
!if (Radius.lt.2000) write(*,*) ss,pp,Radius
1017
IF (ss < MinSRInvariant ) ss = MinSRInvariant
1018
ss = (2.*ss)**nn
1019
Else
1020
ss = 0.0_dp
1021
DO i = 1, 3
1022
DO j = 1, 3
1023
ss = ss + SR(i,j)**2.
1024
END DO
1025
END DO
1026
IF (ss < MinSRInvariant ) ss = MinSRInvariant
1027
ss = (2.*ss)**nn
1028
END IF
1029
1030
END IF
1031
1032
! Non relative viscosity matrix
1033
C = C * ss/Bg
1034
1035
!
1036
! Loop over basis functions (of both unknowns and weights)
1037
!
1038
A = 0.0d0
1039
M = 0.0d0
1040
B = 0.0d0
1041
1042
DO p=1,NBasis
1043
1044
G = 0.0d0
1045
1046
IF ( VariableFlowWidth ) THEN
1047
G(1,1) = dBasisdx(p,1)
1048
G(1,3) = Basis(p) / Radius
1049
G(1,4) = dBasisdx(p,2)
1050
G(2,2) = dBasisdx(p,2)
1051
G(2,4) = dBasisdx(p,1)
1052
ELSE
1053
G(1,1) = dBasisdx(p,1)
1054
G(2,2) = dBasisdx(p,2)
1055
G(3,3) = dBasisdx(p,3)
1056
G(1,4) = dBasisdx(p,2)
1057
G(2,4) = dBasisdx(p,1)
1058
G(2,5) = dBasisdx(p,3)
1059
G(3,5) = dBasisdx(p,2)
1060
G(1,6) = dBasisdx(p,3)
1061
G(3,6) = dBasisdx(p,1)
1062
END IF
1063
1064
G = MATMUL( G, C )
1065
1066
DO q=1,NBasis
1067
1068
B = 0.0d0
1069
1070
IF ( VariableFlowWidth ) THEN
1071
B(1,1) = dBasisdx(q,1)
1072
B(2,2) = dBasisdx(q,2)
1073
B(3,1) = Basis(q) / Radius
1074
B(4,1) = dBasisdx(q,2)
1075
B(4,2) = dBasisdx(q,1)
1076
ELSE
1077
B(1,1) = dBasisdx(q,1)
1078
B(2,2) = dBasisdx(q,2)
1079
B(3,3) = dBasisdx(q,3)
1080
B(4,1) = dBasisdx(q,2)
1081
B(4,2) = dBasisdx(q,1)
1082
B(5,2) = dBasisdx(q,3)
1083
B(5,3) = dBasisdx(q,2)
1084
B(6,1) = dBasisdx(q,3)
1085
B(6,3) = dBasisdx(q,1)
1086
END IF
1087
1088
A(1:3,1:3) = MATMUL( G, B )
1089
1090
! Pressure gradient
1091
DO i=1,dim
1092
A(i,dim+1) = -dBasisdx(p,i) * Basis(q)
1093
END DO
1094
IF ( VariableFlowWidth ) A(1,dim+1) = A(1,dim+1) - Basis(p) * Basis(q) / Radius
1095
1096
! Continuity equation:
1097
DO i=1,dim
1098
A(dim+1,i) = dBasisdx(q,i) * Basis(p)
1099
END DO
1100
IF ( VariableFlowWidth ) A(dim+1,1) = A(dim+1,1) + Basis(p) * Basis(q) / Radius
1101
A(dim+1, dim+1) = 0.0d0
1102
1103
! Add nodal matrix to element matrix
1104
DO i=1,dim+1
1105
DO j=1,dim+1
1106
StiffMatrix( (dim+1)*(p-1)+i,(dim+1)*(q-1)+j ) = &
1107
StiffMatrix( (dim+1)*(p-1)+i,(dim+1)*(q-1)+j ) + s*A(i,j)
1108
END DO
1109
END DO
1110
1111
END DO
1112
1113
! The righthand side...
1114
Load = 0.0d0
1115
1116
DO i=1,dim
1117
Load(i) = Load(i) + Force(i) * Basis(p)
1118
END DO
1119
1120
DO i=1,dim
1121
ForceVector((dim+1)*(p-1)+i) = ForceVector((dim+1)*(p-1)+i) + s*Load(i)
1122
END DO
1123
END DO
1124
1125
END DO
1126
!------------------------------------------------------------------------------
1127
END SUBROUTINE LocalMatrix
1128
!------------------------------------------------------------------------------
1129
1130
!------------------------------------------------------------------------------
1131
SUBROUTINE LocalMatrixBoundary( BoundaryMatrix, BoundaryVector, &
1132
LoadVector, NodalAlpha, NodalBeta, NodalSlipCoeff, &
1133
NormalTangential, Element, n, Nodes, &
1134
VariableFlowWidth, VariableLocalFlowWidth, NodalFlowWidth )
1135
1136
!------------------------------------------------------------------------------
1137
REAL(KIND=dp) :: BoundaryMatrix(:,:),BoundaryVector(:)
1138
REAL(KIND=dp) :: NodalAlpha(:,:),NodalBeta(:),LoadVector(:,:)
1139
REAL(KIND=dp) :: NodalSlipCoeff(:,:), NodalFlowWidth(:)
1140
TYPE(Element_t),POINTER :: Element
1141
TYPE(Nodes_t) :: Nodes
1142
LOGICAL :: NormalTangential
1143
INTEGER, POINTER :: NodeIndexes(:)
1144
INTEGER :: n
1145
!------------------------------------------------------------------------------
1146
REAL(KIND=dp) :: Basis(n),ddBasisddx(1,1,1)
1147
REAL(KIND=dp) :: dBasisdx(n,3),SqrtElementMetric, FW
1148
1149
REAL(KIND=dp) :: u,v,w,s
1150
REAL(KIND=dp) :: Force(3),Alpha(3),Beta,Normal(3)
1151
REAL(KIND=dp), POINTER :: U_Integ(:),V_Integ(:),W_Integ(:),S_Integ(:)
1152
REAL(KIND=dp) :: Tangent(3),Tangent2(3),Vect(3), SlipCoeff
1153
REAL(KIND=dp) :: Up,Vp,Wp
1154
INTEGER :: i,t,q,p,dim,N_Integ, c
1155
1156
LOGICAL :: stat, VariableFlowWidth, VariableLocalFlowWidth
1157
LOGICAL,SAVE :: AllocationDone=.False.
1158
1159
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
1160
!------------------------------------------------------------------------------
1161
1162
dim = CoordinateSystemDimension()
1163
c=dim+1
1164
1165
BoundaryVector = 0.0D0
1166
BoundaryMatrix = 0.0D0
1167
!
1168
! Integration stuff
1169
!
1170
IntegStuff = GaussPoints( element )
1171
U_Integ => IntegStuff % u
1172
V_Integ => IntegStuff % v
1173
W_Integ => IntegStuff % w
1174
S_Integ => IntegStuff % s
1175
N_Integ = IntegStuff % n
1176
1177
NodeIndexes => Element % NodeIndexes
1178
1179
NodalFlowWidth(1:n) = ListGetReal ( Material, &
1180
'FlowWidth', n, NodeIndexes, GotIt)
1181
IF (.NOT. GotIt .AND. CSymmetry) THEN
1182
DO i=1,n
1183
NodalFlowWidth(i) = Nodes % x(i)
1184
END DO
1185
END IF
1186
!
1187
! Now we start integrating
1188
!
1189
DO t=1,N_Integ
1190
1191
u = U_Integ(t)
1192
v = V_Integ(t)
1193
w = W_Integ(t)
1194
1195
!------------------------------------------------------------------------------
1196
! Basis function values & derivatives at the integration point
1197
!------------------------------------------------------------------------------
1198
stat = ElementInfo( Element, Nodes, u, v, w, SqrtElementMetric, &
1199
Basis, dBasisdx, ddBasisddx, .FALSE. )
1200
1201
FW = SUM( NodalFlowWidth(1:n) * Basis(1:n) )
1202
1203
s = SqrtElementMetric * S_Integ(t)
1204
1205
IF (.NOT. VariableLocalFlowWidth ) Radius = 10e7
1206
IF ( VariableFlowWidth ) s= s * FW
1207
1208
!------------------------------------------------------------------------------
1209
Force = 0.0D0
1210
DO i=1,dim
1211
Force(i) = SUM( LoadVector(i,1:n)*Basis(1:n) )
1212
Alpha(i) = SUM( NodalAlpha(i,1:n)*Basis(1:n) )
1213
END DO
1214
1215
Normal = NormalVector( Element,Nodes,u,v,.TRUE. )
1216
Force = Force + SUM( NodalBeta(1:n)*Basis(1:n) ) * Normal
1217
1218
SELECT CASE( Element % TYPE % DIMENSION )
1219
CASE(1)
1220
Tangent(1) = Normal(2)
1221
Tangent(2) = -Normal(1)
1222
Tangent(3) = 0.0d0
1223
CASE(2)
1224
CALL TangentDirections( Normal, Tangent, Tangent2 )
1225
END SELECT
1226
1227
IF ( ANY( NodalSlipCoeff(:,:) /= 0.0d0 ) ) THEN
1228
DO p=1,n
1229
DO q=1,n
1230
DO i=1,DIM
1231
SlipCoeff = SUM( NodalSlipCoeff(i,1:n) * Basis(1:n) )
1232
1233
IF (NormalTangential ) THEN
1234
SELECT CASE(i)
1235
CASE(1)
1236
Vect = Normal
1237
CASE(2)
1238
Vect = Tangent
1239
CASE(3)
1240
Vect = Tangent2
1241
END SELECT
1242
1243
DO j=1,DIM
1244
DO k=1,DIM
1245
BoundaryMatrix( (p-1)*c+j,(q-1)*c+k ) = &
1246
BoundaryMatrix( (p-1)*c+j,(q-1)*c+k ) + &
1247
s * SlipCoeff * Basis(q) * Basis(p) * Vect(j) * Vect(k)
1248
END DO
1249
END DO
1250
ELSE
1251
BoundaryMatrix( (p-1)*c+i,(q-1)*c+i ) = &
1252
BoundaryMatrix( (p-1)*c+i,(q-1)*c+i ) + &
1253
s * SlipCoeff * Basis(q) * Basis(p)
1254
END IF
1255
END DO
1256
END DO
1257
END DO
1258
END IF
1259
1260
1261
1262
DO p=1,N
1263
DO q=1,N
1264
DO i=1,dim
1265
BoundaryMatrix((p-1)*(dim+1)+i,(q-1)*(dim+1)+i) = &
1266
BoundaryMatrix((p-1)*(dim+1)+i,(q-1)*(dim+1)+i) + &
1267
s * Alpha(i) * Basis(q) * Basis(p)
1268
END DO
1269
END DO
1270
END DO
1271
1272
DO q=1,N
1273
DO i=1,dim
1274
BoundaryVector((q-1)*(dim+1)+i) = BoundaryVector((q-1)*(dim+1)+i) + &
1275
s * Basis(q) * Force(i)
1276
END DO
1277
END DO
1278
1279
END DO
1280
!------------------------------------------------------------------------------
1281
END SUBROUTINE LocalMatrixBoundary
1282
!------------------------------------------------------------------------------
1283
1284
1285
!------------------------------------------------------------------------------
1286
SUBROUTINE LocalSD( Stress, StrainRate, Spin, &
1287
NodalVelo, NodalTemp, NodalFluidity, NodalFlowWidth, &
1288
NodalK1, NodalK2, NodalE1, NodalE2, NodalE3, &
1289
Basis, dBasisdx, Element, n, Nodes, dim, Wn, MinSRInvariant, &
1290
Isotropic, VariableFlowWidth, VariableLocalFlowWidth )
1291
!------------------------------------------------------------------------------
1292
! Subroutine to compute the nodal Strain-Rate, Stress, ...
1293
!------------------------------------------------------------------------------
1294
INTEGER :: n, dim
1295
INTEGER :: INDi(6),INDj(6)
1296
REAL(KIND=dp) :: Stress(:,:), StrainRate(:,:), Spin(:,:)
1297
REAL(KIND=dp) :: NodalVelo(:,:), NodalTemp(:), NodalFluidity(:), &
1298
NodalFlowWidth(:)
1299
REAL(KIND=dp) :: Basis(2*n), ddBasisddx(1,1,1)
1300
REAL(KIND=dp) :: dBasisdx(2*n,3)
1301
REAL(KIND=dp) :: detJ
1302
REAL(KIND=dp) :: NodalK1(:), NodalK2(:)
1303
REAL(KIND=dp) :: NodalE1(:), NodalE2(:), NodalE3(:)
1304
REAL(KIND=dp) :: u, v, w
1305
REAL(KIND=dp) :: Wn(7), D(6), MinSRInvariant
1306
LOGICAL :: Isotropic,VariableFlowWidth, VariableLocalFlowWidth
1307
1308
TYPE(Nodes_t) :: Nodes
1309
TYPE(Element_t) :: Element
1310
!------------------------------------------------------------------------------
1311
LOGICAL :: stat
1312
INTEGER :: i,j,k,p,q
1313
REAL(KIND=dp) :: LGrad(3,3), Radius, Temp, ai(3), Angle(3),a2(6)
1314
REAL(KIND=dp) :: C(6,6), epsi
1315
Real(kind=dp) :: Bg, BGlenT, ss, nn
1316
!------------------------------------------------------------------------------
1317
INTERFACE
1318
Subroutine R2Ro(a2,dim,ai,angle)
1319
USE Types
1320
REAL(KIND=dp),intent(in) :: a2(6)
1321
Integer :: dim
1322
REAL(KIND=dp),intent(out) :: ai(3), Angle(3)
1323
End Subroutine R2Ro
1324
1325
Subroutine OPILGGE_ai_nl(ai,Angle,etaI,eta36)
1326
USE Types
1327
REAL(kind=dp), INTENT(in), DIMENSION(3) :: ai
1328
REAL(kind=dp), INTENT(in), DIMENSION(3) :: Angle
1329
REAL(kind=dp), INTENT(in), DIMENSION(:) :: etaI
1330
REAL(kind=dp), INTENT(out), DIMENSION(6,6) :: eta36
1331
END SUBROUTINE OPILGGE_ai_nl
1332
END INTERFACE
1333
!------------------------------------------------------------------------------
1334
1335
!
1336
! Temperature at the integration point
1337
Temp = SUM( NodalTemp(1:n)*Basis(1:n) )
1338
Wn(1) = SUM( NodalFluidity(1:n)*Basis(1:n) )
1339
1340
1341
Stress = 0.0
1342
StrainRate = 0.0
1343
Spin = 0.0
1344
!
1345
! Compute strainRate :
1346
! -------------------
1347
1348
LGrad = MATMUL( NodalVelo(:,1:n), dBasisdx(1:n,:) )
1349
1350
StrainRate = 0.5 * ( LGrad + TRANSPOSE(LGrad) )
1351
1352
IF ( VariableFlowWidth ) THEN
1353
1354
StrainRate(1,3) = 0.0
1355
StrainRate(2,3) = 0.0
1356
StrainRate(3,1) = 0.0
1357
StrainRate(3,2) = 0.0
1358
StrainRate(3,3) = 0.0
1359
1360
IF (SUM( NodalFlowWidth(1:n) * dBasisdx(1:n,1)) == 0) THEN
1361
Radius = 10e7
1362
ELSE
1363
Radius = SUM( NodalFlowWidth(1:n) * Basis(1:n) ) / &
1364
(SUM( NodalFlowWidth(1:n) * dBasisdx(1:n,1)) )
1365
END IF
1366
1367
IF ( Radius > 10*AEPS ) THEN
1368
StrainRate(3,3) = SUM( Nodalvelo(1,1:n) * Basis(1:n) ) / Radius
1369
END IF
1370
epsi = StrainRate(1,1)+StrainRate(2,2)+StrainRate(3,3)
1371
DO i=1,3
1372
StrainRate(i,i) = StrainRate(i,i) - epsi/3.0
1373
END DO
1374
ELSE
1375
epsi = StrainRate(1,1)+StrainRate(2,2)+StrainRate(3,3)
1376
DO i=1,dim
1377
StrainRate(i,i) = StrainRate(i,i) - epsi/dim
1378
END DO
1379
END IF
1380
1381
!
1382
! Compute Spin :
1383
! --------------
1384
1385
Spin = 0.5 * ( LGrad - TRANSPOSE(LGrad) )
1386
1387
!
1388
! Compute deviatoric stresses:
1389
! ----------------------------
1390
1391
IF (.Not.Isotropic) then
1392
C = 0.0_dp
1393
! Material parameters at that point
1394
a2(1) = SUM( NodalK1(1:n) * Basis(1:n) )
1395
a2(2) = SUM( NodalK2(1:n) * Basis(1:n) )
1396
a2(3) = 1.d0 - a2(1) - a2(2)
1397
a2(4) = SUM( NodalE1(1:n) * Basis(1:n) )
1398
a2(5) = SUM( NodalE2(1:n) * Basis(1:n) )
1399
a2(6) = SUM( NodalE3(1:n) * Basis(1:n) )
1400
1401
CALL R2Ro(a2,dim,ai,Angle)
1402
CALL OPILGGE_ai_nl(ai,Angle,FabricGrid,C)
1403
1404
!
1405
! Compute deviatoric stresses:
1406
! ----------------------------
1407
D(1) = StrainRate(1,1)
1408
D(2) = StrainRate(2,2)
1409
D(3) = StrainRate(3,3)
1410
D(4) = 2. * StrainRate(1,2)
1411
D(5) = 2. * StrainRate(2,3)
1412
D(6) = 2. * StrainRate(3,1)
1413
1414
INDi(1:6) = (/ 1, 2, 3, 1, 2, 3 /)
1415
INDj(1:6) = (/ 1, 2, 3, 2, 3, 1 /)
1416
DO k = 1, 2*dim
1417
DO j = 1, 2*dim
1418
Stress( INDi(k),INDj(k) ) = &
1419
Stress( INDi(k),INDj(k) ) + C(k,j) * D(j)
1420
END DO
1421
IF (k > 3) Stress( INDj(k),INDi(k) ) = Stress( INDi(k),INDj(k) )
1422
END DO
1423
1424
ELSE ! ISOTROPIC CASE
1425
Stress=2._dp * StrainRate
1426
END IF
1427
1428
1429
! non relative viscosities
1430
! Glen fluidity
1431
Bg=BGlenT(Temp,Wn)
1432
ss=1.0_dp
1433
! Case Non linear
1434
IF (Wn(2) > 1.0) THEN
1435
Bg=Bg**(1.0/Wn(2))
1436
1437
ss = 0.0_dp
1438
DO i = 1, 3
1439
DO j = 1, 3
1440
ss = ss + Stress(i,j)**2
1441
END DO
1442
END DO
1443
nn = (1.0 - Wn(2))/(2.0*Wn(2))
1444
ss = (ss / 2.0)**nn
1445
1446
IF (ss < MinSRInvariant ) ss = MinSRInvariant
1447
1448
1449
END IF
1450
1451
Stress=Stress*ss/Bg
1452
1453
1454
1455
!------------------------------------------------------------------------------
1456
END SUBROUTINE LocalSD
1457
!------------------------------------------------------------------------------
1458
!
1459
!------------------------------------------------------------------------------
1460
END SUBROUTINE AIFlowSolver_nlS2
1461
!------------------------------------------------------------------------------
1462
1463