Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/FabricSolve.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, Olivier Gagliardini, Fabien Gillet-Chaulet
26
! * Email: [email protected]
27
! * Web: http://elmerice.elmerfem.org
28
! * Address: CSC - IT Center for Science Ltd.
29
! * Keilaranta 14
30
! * 02101 Espoo, Finland
31
! *
32
! * Date of modification: 03/05
33
! *
34
! *****************************************************************************/
35
!> Solver for fabric parameter equations
36
!------------------------------------------------------------------------------
37
RECURSIVE SUBROUTINE FabricSolver( Model,Solver,dt,TransientSimulation )
38
!------------------------------------------------------------------------------
39
40
USE DefUtils
41
42
IMPLICIT NONE
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 :: dim,n1,n2,i,j,k,l,n,t,iter,NDeg,STDOFs,LocalNodes,istat
75
76
TYPE(ValueList_t),POINTER :: Material, BC
77
TYPE(Nodes_t) :: ElementNodes
78
TYPE(Element_t),POINTER :: CurrentElement, Element, &
79
ParentElement, LeftParent, RightParent, Edge
80
81
REAL(KIND=dp) :: RelativeChange,UNorm,PrevUNorm,Gravity(3), &
82
Tdiff,Normal(3),NewtonTol,NonlinearTol,s,Wn(7)
83
84
85
INTEGER :: NewtonIter,NonlinearIter
86
87
TYPE(Variable_t), POINTER :: FabricSol, TempSol, FabricVariable, FlowVariable, &
88
EigenFabricVariable, MeshVeloVariable
89
90
REAL(KIND=dp), POINTER :: Temperature(:),Fabric(:), &
91
FabricValues(:), FlowValues(:), EigenFabricValues(:), &
92
MeshVeloValues(:), Solution(:), Ref(:)
93
94
INTEGER, POINTER :: TempPerm(:),FabricPerm(:),NodeIndexes(:), &
95
FlowPerm(:), MeshVeloPerm(:), EigenFabricPerm(:)
96
97
REAL(KIND=dp) :: rho,lambda !Interaction parameter,diffusion parameter
98
REAL(KIND=dp) :: A1plusA2
99
Real(KIND=dp), parameter :: Rad2deg=180._dp/Pi
100
REAL(KIND=dp) :: a2(6)
101
REAL(KIND=dp) :: ai(3), Angle(3)
102
103
LOGICAL :: GotForceBC,GotIt,NewtonLinearization = .FALSE.,UnFoundFatal=.TRUE.
104
105
INTEGER :: body_id,bf_id,eq_id, comp, Indexes(128)
106
!
107
INTEGER :: old_body = -1
108
109
REAL(KIND=dp) :: FabricGrid(4879)
110
111
LOGICAL :: AllocationsDone = .FALSE., FreeSurface
112
113
TYPE(Variable_t), POINTER :: TimeVar
114
115
REAL(KIND=dp), ALLOCATABLE:: MASS(:,:), STIFF(:,:), &
116
LocalFluidity(:), LOAD(:,:),Force(:), LocalTemperature(:), &
117
Alpha(:,:),Beta(:), K1(:), K2(:), E1(:), E2(:), E3(:), &
118
Velocity(:,:), MeshVelocity(:,:)
119
120
SAVE MASS, STIFF, LOAD, Force,ElementNodes,Alpha,Beta, &
121
LocalTemperature, LocalFluidity, AllocationsDone, K1, K2, &
122
E1, E2, E3, Wn, FabricGrid, rho, lambda, Velocity, &
123
MeshVelocity, old_body, dim, comp
124
!------------------------------------------------------------------------------
125
CHARACTER(LEN=MAX_NAME_LEN) :: viscosityFile
126
127
REAL(KIND=dp) :: Bu,Bv,Bw,RM(3,3), SaveTime = -1
128
REAL(KIND=dp), POINTER :: PrevFabric(:),CurrFabric(:),TempFabVal(:)
129
130
SAVE ViscosityFile, PrevFabric, CurrFabric,TempFabVal
131
REAL(KIND=dp) :: at, at0
132
!------------------------------------------------------------------------------
133
INTERFACE
134
Subroutine R2Ro(a2,dim,ai,angle)
135
USE Types
136
REAL(KIND=dp),intent(in) :: a2(6)
137
Integer :: dim
138
REAL(KIND=dp),intent(out) :: ai(3), Angle(3)
139
End Subroutine R2Ro
140
End Interface
141
!------------------------------------------------------------------------------
142
! Read constants from constants section of SIF file
143
!------------------------------------------------------------------------------
144
145
Wn(7) = ListGetConstReal( Model % Constants, 'Gas Constant', GotIt,UnFoundFatal=UnFoundFatal )
146
!Previous default value: Wn(7) = 8.314
147
WRITE(Message,'(A,F10.4)')'Gas Constant =',Wn(7)
148
CALL INFO('FabricSolve',Message,Level=4)
149
!------------------------------------------------------------------------------
150
! Get variables needed for solution
151
!------------------------------------------------------------------------------
152
IF ( .NOT. ASSOCIATED( Solver % Matrix ) ) RETURN
153
154
Solution => Solver % Variable % Values
155
STDOFs = Solver % Variable % DOFs
156
157
FabricSol => VariableGet( Solver % Mesh % Variables, 'Fabric' )
158
FabricPerm => FabricSol % Perm
159
FabricValues => FabricSol % Values
160
161
TempSol => VariableGet( Solver % Mesh % Variables, 'Temperature' )
162
IF ( ASSOCIATED( TempSol) ) THEN
163
TempPerm => TempSol % Perm
164
Temperature => TempSol % Values
165
END IF
166
167
FlowVariable => VariableGet( Solver % Mesh % Variables, 'AIFlow' )
168
IF ( ASSOCIATED( FlowVariable ) ) THEN
169
FlowPerm => FlowVariable % Perm
170
FlowValues => FlowVariable % Values
171
END IF
172
173
!!!!! Mesh Velo
174
MeshVeloVariable => VariableGet( Solver % Mesh % Variables, &
175
'Mesh Velocity' )
176
177
IF ( ASSOCIATED( MeshVeloVariable ) ) THEN
178
MeshVeloPerm => MeshVeloVariable % Perm
179
MeshVeloValues => MeshVeloVariable % Values
180
END IF
181
182
183
StiffMatrix => Solver % Matrix
184
! UNorm = Solver % Variable % Norm
185
Unorm = SQRT( SUM( FabricValues**2 ) / SIZE(FabricValues) )
186
!------------------------------------------------------------------------------
187
188
!------------------------------------------------------------------------------
189
! Allocate some permanent storage, this is done first time only
190
!------------------------------------------------------------------------------
191
IF ( .NOT. AllocationsDone .OR. Solver % Mesh % Changed) THEN
192
N = Model % MaxElementNodes
193
194
dim = CoordinateSystemDimension()
195
196
IF ( AllocationsDone ) THEN
197
DEALLOCATE( LocalTemperature, &
198
K1,K2,E1,E2,E3, &
199
Force, LocalFluidity, &
200
Velocity,MeshVelocity, &
201
MASS,STIFF, &
202
LOAD, Alpha, Beta, &
203
CurrFabric, TempFabVal )
204
END IF
205
206
ALLOCATE( LocalTemperature( N ), LocalFluidity( N ), &
207
K1( N ), K2( N ), E1( N ), E2( N ), E3( N ), &
208
Force( 2*STDOFs*N ), &
209
Velocity(4, N ),MeshVelocity(3,N), &
210
MASS( 2*STDOFs*N,2*STDOFs*N ), &
211
STIFF( 2*STDOFs*N,2*STDOFs*N ), &
212
LOAD( 4,N ), Alpha( 3,N ), Beta( N ), &
213
CurrFabric( 5*SIZE(Solver % Variable % Values)), &
214
TempFabVal( SIZE(FabricValues)), &
215
STAT=istat )
216
217
218
IF ( istat /= 0 ) THEN
219
CALL Fatal( 'FabricSolve', 'Memory allocation error.' )
220
END IF
221
222
CurrFabric = 0.
223
TempFabVal = 0.
224
IF ( TransientSimulation ) THEN
225
IF (AllocationsDone ) DEALLOCATE (PrevFabric)
226
ALLOCATE( PrevFabric( 5*SIZE(Solver % Variable % Values)) )
227
PrevFabric = 0.
228
END IF
229
230
DO i=1,Solver % NumberOFActiveElements
231
CurrentElement => GetActiveElement(i)
232
n = GetElementDOFs( Indexes )
233
n = GetElementNOFNodes()
234
NodeIndexes => CurrentElement % NodeIndexes
235
Indexes(1:n) = Solver % Variable % Perm( Indexes(1:n) )
236
DO COMP=1,5
237
IF ( TransientSimulation ) THEN
238
PrevFabric(5*(Indexes(1:n)-1)+COMP) = &
239
FabricValues(5*(FabricPerm(NodeIndexes(1:n))-1)+COMP)
240
END IF
241
CurrFabric(5*(Indexes(1:n)-1)+COMP) = &
242
FabricValues(5*(FabricPerm(NodeIndexes(1:n))-1)+COMP)
243
END DO
244
END DO
245
246
AllocationsDone = .TRUE.
247
END IF
248
249
IF( TransientSimulation ) THEN
250
TimeVar => VariableGet( Solver % Mesh % Variables, 'Time' )
251
IF ( SaveTime /= TimeVar % Values(1) ) THEN
252
SaveTime = TimeVar % Values(1)
253
PrevFabric = CurrFabric
254
END IF
255
END IF
256
257
!------------------------------------------------------------------------------
258
! Do some additional initialization, and go for it
259
!------------------------------------------------------------------------------
260
261
!------------------------------------------------------------------------------
262
NonlinearTol = ListGetConstReal( Solver % Values, &
263
'Nonlinear System Convergence Tolerance' )
264
265
NewtonTol = ListGetConstReal( Solver % Values, &
266
'Nonlinear System Newton After Tolerance' )
267
268
NewtonIter = ListGetInteger( Solver % Values, &
269
'Nonlinear System Newton After Iterations' )
270
271
NonlinearIter = ListGetInteger( Solver % Values, &
272
'Nonlinear System Max Iterations',GotIt )
273
274
IF ( .NOT.GotIt ) NonlinearIter = 1
275
!------------------------------------------------------------------------------
276
277
!------------------------------------------------------------------------------
278
279
!------------------------------------------------------------------------------
280
DO iter=1,NonlinearIter
281
!------------------------------------------------------------------------------
282
at = CPUTime()
283
at0 = RealTime()
284
285
286
CALL Info( 'FabricSolve', ' ', Level=4 )
287
CALL Info( 'FabricSolve', ' ', Level=4 )
288
CALL Info( 'FabricSolve', &
289
'-------------------------------------',Level=4 )
290
WRITE( Message, * ) 'Fabric solver iteration', iter
291
CALL Info( 'FabricSolve', Message,Level=4 )
292
CALL Info( 'FabricSolve', &
293
'-------------------------------------',Level=4 )
294
CALL Info( 'FabricSolve', ' ', Level=4 )
295
CALL Info( 'FabricSolve', 'Starting assembly...',Level=4 )
296
297
!------------------------------------------------------------------------------
298
299
PrevUNorm = UNorm
300
301
DO COMP=1,2*dim-1
302
303
Solver % Variable % Values = CurrFabric( COMP::5 )
304
IF ( TransientSimulation ) THEN
305
Solver % Variable % PrevValues(:,1) = PrevFabric( COMP::5 )
306
END IF
307
308
CALL DefaultInitialize()
309
!------------------------------------------------------------------------------
310
DO t=1,Solver % NumberOFActiveElements
311
!------------------------------------------------------------------------------
312
313
IF ( RealTime() - at0 > 1.0 ) THEN
314
WRITE(Message,'(a,i3,a)' ) ' Assembly: ', INT(100.0 - 100.0 * &
315
(Solver % NumberOfActiveElements-t) / &
316
(1.0*Solver % NumberOfActiveElements)), ' % done'
317
318
CALL Info( 'FabricSolve', Message, Level=5 )
319
at0 = RealTime()
320
END IF
321
322
CurrentElement => GetActiveElement(t)
323
CALL GetElementNodes( ElementNodes )
324
n = GetElementDOFs( Indexes )
325
n = GetElementNOFNodes()
326
NodeIndexes => CurrentElement % NodeIndexes
327
328
329
Material => GetMaterial()
330
body_id = CurrentElement % BodyId
331
!------------------------------------------------------------------------------
332
! Read in material constants from Material section
333
!------------------------------------------------------------------------------
334
IF (body_id /= old_body) Then
335
old_body = body_id
336
CALL GetMaterialDefs()
337
END IF
338
339
LocalFluidity(1:n) = ListGetReal( Material, &
340
'Fluidity Parameter', n, NodeIndexes, GotIt,&
341
UnFoundFatal=UnFoundFatal)
342
!Previous default value: LocalFluidity(1:n) = 1.0
343
!------------------------------------------------------------------------------
344
! Get element local stiffness & mass matrices
345
!------------------------------------------------------------------------------
346
LocalTemperature = 0.0D0
347
IF ( ASSOCIATED(TempSol) ) THEN
348
DO i=1,n
349
k = TempPerm(NodeIndexes(i))
350
LocalTemperature(i) = Temperature(k)
351
END DO
352
ELSE
353
LocalTemperature(1:n) = 0.0d0
354
END IF
355
356
K1(1:n) = CurrFabric( 5*(Solver % Variable % Perm(Indexes(1:n))-1)+1 )
357
K2(1:n) = CurrFabric( 5*(Solver % Variable % Perm(Indexes(1:n))-1)+2 )
358
E1(1:n) = CurrFabric( 5*(Solver % Variable % Perm(Indexes(1:n))-1)+3 )
359
E2(1:n) = CurrFabric( 5*(Solver % Variable % Perm(Indexes(1:n))-1)+4 )
360
E3(1:n) = CurrFabric( 5*(Solver % Variable % Perm(Indexes(1:n))-1)+5 )
361
362
k = FlowVariable % DOFs
363
Velocity = 0.0d0
364
DO i=1,k
365
Velocity(i,1:n) = FlowValues(k*(FlowPerm(NodeIndexes)-1)+i)
366
END DO
367
368
!------------meshvelocity
369
MeshVelocity=0._dp
370
IF (ASSOCIATED(MeshVeloVariable)) Then
371
k = MeshVeloVariable % DOFs
372
DO i=1,k
373
MeshVelocity(i,1:n) = MeshVeloValues(k*(MeshVeloPerm(NodeIndexes)-1)+i)
374
END DO
375
EndIF
376
!----------------------------------
377
378
CALL LocalMatrix( COMP, MASS, STIFF, FORCE, LOAD, K1, K2, E1, &
379
E2, E3, LocalTemperature, LocalFluidity, Velocity, &
380
MeshVelocity, CurrentElement, n, ElementNodes, Wn, rho, lambda )
381
382
!------------------------------------------------------------------------------
383
! Update global matrices from local matrices
384
!------------------------------------------------------------------------------
385
IF ( TransientSimulation ) CALL Default1stOrderTime(MASS,STIFF,FORCE)
386
CALL DefaultUpdateEquations( STIFF, FORCE )
387
!------------------------------------------------------------------------------
388
END DO
389
CALL Info( 'FabricSolve', 'Assembly done', Level=4 )
390
!------------------------------------------------------------------------------
391
392
!------------------------------------------------------------------------------
393
! Assembly of the edge terms
394
!------------------------------------------------------------------------------
395
!
396
!3D => Edges => Faces
397
If (dim.eq.3) then
398
DO t=1,Solver % Mesh % NumberOfFaces
399
Edge => Solver % Mesh % Faces(t)
400
IF ( .NOT. ActiveBoundaryElement(Edge) ) CYCLE
401
402
LeftParent => Edge % BoundaryInfo % Left
403
RightParent => Edge % BoundaryInfo % Right
404
IF ( ASSOCIATED(RightParent) .AND. ASSOCIATED(LeftParent) ) THEN
405
n = GetElementNOFNodes( Edge )
406
n1 = GetElementNOFNodes( LeftParent )
407
n2 = GetElementNOFNodes( RightParent )
408
409
k = FlowVariable % DOFs
410
Velocity = 0.0d0
411
DO i=1,k
412
Velocity(i,1:n) = FlowValues(k*(FlowPerm(Edge % NodeIndexes)-1)+i)
413
END DO
414
415
!-------------------mesh velo
416
MeshVelocity=0._dp
417
IF ( ASSOCIATED( MeshVeloVariable ) ) THEN
418
k = MeshVeloVariable % DOFs
419
DO i=1,k
420
MeshVelocity(i,1:n) = MeshVeloValues(k*(MeshVeloPerm(Edge % NodeIndexes)-1)+i)
421
END DO
422
END IF
423
!--------------------------
424
425
FORCE = 0.0d0
426
MASS = 0.0d0
427
CALL LocalJumps( STIFF,Edge,n,LeftParent,n1,RightParent,n2,Velocity,MeshVelocity )
428
IF ( TransientSimulation ) CALL Default1stOrderTime(MASS, STIFF, FORCE)
429
CALL DefaultUpdateEquations( STIFF, FORCE, Edge )
430
END IF
431
END DO
432
!
433
! 2D
434
Else
435
436
DO t=1,Solver % Mesh % NumberOfEdges
437
Edge => Solver % Mesh % Edges(t)
438
IF ( .NOT. ActiveBoundaryElement(Edge) ) CYCLE
439
440
LeftParent => Edge % BoundaryInfo % Left
441
RightParent => Edge % BoundaryInfo % Right
442
IF ( ASSOCIATED(RightParent) .AND. ASSOCIATED(LeftParent) ) THEN
443
n = GetElementNOFNodes( Edge )
444
n1 = GetElementNOFNodes( LeftParent )
445
n2 = GetElementNOFNodes( RightParent )
446
447
k = FlowVariable % DOFs
448
Velocity = 0.0d0
449
DO i=1,k
450
Velocity(i,1:n) = FlowValues(k*(FlowPerm(Edge % NodeIndexes(1:n))-1)+i)
451
END DO
452
453
!-------------------mesh velo
454
MeshVelocity=0._dp
455
IF ( ASSOCIATED( MeshVeloVariable ) ) THEN
456
k = MeshVeloVariable % DOFs
457
DO i=1,k
458
MeshVelocity(i,1:n) = MeshVeloValues(k*(MeshVeloPerm(Edge % NodeIndexes)-1)+i)
459
END DO
460
END IF
461
!--------------------------
462
463
FORCE = 0.0d0
464
MASS = 0.0d0
465
CALL LocalJumps( STIFF,Edge,n,LeftParent,n1,RightParent,n2,Velocity,MeshVelocity )
466
IF ( TransientSimulation ) CALL Default1stOrderTime(MASS, STIFF, FORCE)
467
CALL DefaultUpdateEquations( STIFF, FORCE, Edge )
468
END IF
469
END DO
470
471
END IF
472
473
CALL DefaultFinishBulkAssembly()
474
!------------------------------------------------------------------------------
475
! Loop over the boundary elements
476
!------------------------------------------------------------------------------
477
DO t = 1, Solver % Mesh % NumberOfBoundaryElements
478
!------------------------------------------------------------------------------
479
480
Element => GetBoundaryElement(t)
481
IF( .NOT. ActiveBoundaryElement() ) CYCLE
482
IF( GetElementFamily(Element) == 1 ) CYCLE
483
484
ParentElement => Element % BoundaryInfo % Left
485
IF ( .NOT. ASSOCIATED( ParentElement ) ) &
486
ParentElement => Element % BoundaryInfo % Right
487
488
n = GetElementNOFNodes( Element )
489
n1 = GetElementNOFnodes( ParentElement )
490
491
k = FlowVariable % DOFs
492
Velocity = 0.0d0
493
DO i=1,k
494
Velocity(i,1:n) = FlowValues(k*(FlowPerm(Element % NodeIndexes(1:n))-1)+i)
495
END DO
496
497
!-------------------mesh velo
498
MeshVelocity=0._dp
499
IF ( ASSOCIATED( MeshVeloVariable ) ) THEN
500
k = MeshVeloVariable % DOFs
501
DO i=1,k
502
MeshVelocity(i,1:n) = MeshVeloValues(k*(MeshVeloPerm(Element % NodeIndexes)-1)+i)
503
End do
504
END IF
505
!--------------------------
506
507
508
BC => GetBC()
509
LOAD = 0.0d0
510
GotIt = .FALSE.
511
IF ( ASSOCIATED(BC) ) THEN
512
LOAD(1,1:n) = GetReal( BC, ComponentName('Fabric', Comp) , GotIt )
513
END IF
514
515
MASS = 0.0d0
516
CALL LocalMatrixBoundary( STIFF, FORCE, LOAD(1,1:n), &
517
Element, n, ParentElement, n1, Velocity,MeshVelocity, GotIt )
518
519
IF ( TransientSimulation ) CALL Default1stOrderTime(MASS, STIFF, FORCE)
520
CALL DefaultUpdateEquations( STIFF, FORCE )
521
END DO
522
523
CALL DefaultFinishAssembly()
524
!------------------------------------------------------------------------------
525
CALL Info( 'FabricSolve', 'Set boundaries done', Level=4 )
526
527
!------------------------------------------------------------------------------
528
! Solve the system and check for convergence
529
!------------------------------------------------------------------------------
530
Unorm = DefaultSolve()
531
! CurrFabric( COMP::5 ) = Solver % Variable % Values
532
WRITE(Message,*) 'solve done', minval( solver % variable % values), maxval( Solver % variable % values)
533
CALL Info( 'FabricSolve', Message, Level=4 )
534
535
n1 = Solver % Mesh % NumberOfNodes
536
ALLOCATE( Ref(n1) )
537
Ref = 0
538
!
539
! FabricValues( COMP::5 ) = 0 !fab sinon remet toutes les
540
! fabriques � 0 dans le cas ou on a 2 domaines dont l'un a la
541
! fabrique fixe
542
TempFabVal(COMP::5 ) = 0. !fab
543
544
DO t=1,Solver % NumberOfActiveElements
545
Element => GetActiveElement(t)
546
n = GetElementDOFs( Indexes )
547
n = GetElementNOFNodes()
548
549
DO i=1,n
550
k = Element % NodeIndexes(i)
551
TempFabVal( 5*(FabricPerm(k)-1) + COMP ) = &
552
TempFabVal( 5*(FabricPerm(k)-1) + COMP ) + &
553
Solver % Variable % Values( Solver % Variable % Perm(Indexes(i)) )
554
FabricValues( 5*(FabricPerm(k)-1) + COMP ) = &
555
TempFabVal(5*(FabricPerm(k)-1) + COMP )
556
Ref(k) = Ref(k) + 1
557
END DO
558
END DO
559
560
DO i=1,n1
561
j=FabricPerm(i)
562
IF (j < 1) CYCLE
563
IF ( Ref(i) > 0 ) THEN
564
FabricValues( 5*(j-1)+COMP ) = &
565
FabricValues( 5*(j-1)+COMP ) / Ref(i)
566
END IF
567
END DO
568
569
DEALLOCATE( Ref )
570
571
SELECT CASE( Comp )
572
CASE(1)
573
FabricValues( COMP:SIZE(FabricValues):5 ) = &
574
MIN(MAX( FabricValues( COMP:SIZE(FabricValues):5 ) , 0._dp),1._dp)
575
576
CASE(2)
577
FabricValues( COMP:SIZE(FabricValues):5 ) = &
578
MIN(MAX( FabricValues( COMP:SIZE(FabricValues):5 ) , 0._dp),1._dp)
579
580
! !DO i=1,SIZE(FabricValues),5
581
! ! IF((FabricValues(i)+FabricValues(i+1)).GT.1._dp) THEN
582
! ! A1plusA2=FabricValues(i)+FabricValues(i+1)
583
! ! FabricValues(i)= &
584
! ! FabricValues(i)/A1plusA2
585
! ! FabricValues(i+1)= &
586
! ! FabricValues(i+1)/A1plusA2
587
! ! END IF
588
! ! END DO
589
!
590
591
! CASE(3:5)
592
! DO i=COMP,SIZE(FabricValues),5
593
! IF(FabricValues(i).GT.0._dp) THEN
594
! FabricValues(i) = MIN( FabricValues(i) , 0.5_dp)
595
! ELSE
596
! FabricValues(i) = MAX( FabricValues(i) , -0.5_dp)
597
! END IF
598
! END DO
599
END SELECT
600
601
END DO ! End DO Comp
602
603
DO i=1,Solver % NumberOFActiveElements
604
CurrentElement => GetActiveElement(i)
605
n = GetElementDOFs( Indexes )
606
n = GetElementNOFNodes()
607
NodeIndexes => CurrentElement % NodeIndexes
608
Indexes(1:n) = Solver % Variable % Perm( Indexes(1:n) )
609
DO COMP=1,5
610
CurrFabric(5*(Indexes(1:n)-1)+COMP) = &
611
FabricValues(5*(FabricPerm(NodeIndexes(1:n))-1)+COMP)
612
END DO
613
END DO
614
615
616
Unorm = SQRT( SUM( FabricValues**2 ) / SIZE(FabricValues) )
617
Solver % Variable % Norm = Unorm
618
619
IF ( PrevUNorm + UNorm /= 0.0d0 ) THEN
620
RelativeChange = 2.0d0 * ABS( PrevUNorm - UNorm) / ( PrevUnorm + UNorm)
621
ELSE
622
RelativeChange = 0.0d0
623
END IF
624
625
WRITE( Message, * ) 'Result Norm : ',UNorm
626
CALL Info( 'FabricSolve', Message, Level=4 )
627
WRITE( Message, * ) 'Relative Change : ',RelativeChange
628
CALL Info( 'FabricSolve', Message, Level=4 )
629
630
631
!------------------------------------------------------------------------------
632
IF ( RelativeChange < NewtonTol .OR. &
633
iter > NewtonIter ) NewtonLinearization = .TRUE.
634
635
IF ( RelativeChange < NonLinearTol ) EXIT
636
637
!------------------------------------------------------------------------------
638
EigenFabricVariable => &
639
VariableGet( Solver % Mesh % Variables, 'EigenV' )
640
IF ( ASSOCIATED( EigenFabricVariable ) ) THEN
641
EigenFabricPerm => EigenFabricVariable % Perm
642
EigenFabricValues => EigenFabricVariable % Values
643
644
DO t=1,Solver % NumberOFActiveElements
645
646
CurrentElement => GetActiveElement(t)
647
n = GetElementNOFNodes()
648
NodeIndexes => CurrentElement % NodeIndexes
649
650
K1(1:n) = FabricValues( 5*(FabricPerm(NodeIndexes(1:n))-1)+1 )
651
K2(1:n) = FabricValues( 5*(FabricPerm(NodeIndexes(1:n))-1)+2 )
652
E1(1:n) = FabricValues( 5*(FabricPerm(NodeIndexes(1:n))-1)+3 )
653
E2(1:n) = FabricValues( 5*(FabricPerm(NodeIndexes(1:n))-1)+4 )
654
E3(1:n) = FabricValues( 5*(FabricPerm(NodeIndexes(1:n))-1)+5 )
655
656
Do i=1,n
657
a2(1)=K1(i)
658
a2(2)=K2(i)
659
a2(3)=1._dp-a2(1)-a2(2)
660
a2(4)=E1(i)
661
a2(5)=E2(i)
662
a2(6)=E3(i)
663
664
call R2Ro(a2,dim,ai,angle)
665
666
angle(:)=angle(:)*rad2deg
667
If (angle(1).gt.90._dp) angle(1)=angle(1)-180._dp
668
If (angle(1).lt.-90._dp) angle(1)=angle(1)+180._dp
669
670
EigenFabricValues( 6 * (EigenFabricPerm(NodeIndexes(i))-1) + 1)=ai(1)
671
EigenFabricValues( 6 * (EigenFabricPerm(NodeIndexes(i))-1) + 2)=ai(2)
672
EigenFabricValues( 6 * (EigenFabricPerm(NodeIndexes(i))-1) + 3 )=ai(3)
673
EigenFabricValues( 6 * (EigenFabricPerm(NodeIndexes(i))-1) + 4 )=angle(1)
674
EigenFabricValues( 6 * (EigenFabricPerm(NodeIndexes(i))-1) + 5 )=angle(2)
675
EigenFabricValues( 6 * (EigenFabricPerm(NodeIndexes(i))-1) + 6 )=angle(3)
676
End do
677
END DO
678
679
END IF
680
!------------------------------------------------------------------------------
681
END DO ! of nonlinear iter
682
!------------------------------------------------------------------------------
683
CONTAINS
684
685
SUBROUTINE GetMaterialDefs()
686
687
viscosityFile = ListGetString( Material ,'Viscosity File',GotIt, UnFoundFatal)
688
OPEN( 1, File = viscosityFile)
689
DO i=1,813
690
READ( 1, '(6(e14.8))' ) FabricGrid( 6*(i-1)+1:6*(i-1)+6 )
691
END DO
692
READ(1 , '(e14.8)' ) FabricGrid(4879)
693
CLOSE(1)
694
695
rho = ListGetConstReal(Material, 'Interaction Parameter', GotIt )
696
IF (.NOT.GotIt) THEN
697
WRITE(Message,'(A)') 'Interaction Parameter notfound. &
698
&Setting to the value in ViscosityFile'
699
CALL INFO('AIFlowSolve', Message, Level = 20)
700
rho = FabricGrid(4879)
701
ELSE
702
WRITE(Message,'(A,F10.4)') 'Interaction Parameter = ', rho
703
CALL INFO('AIFlowSolve', Message, Level = 20)
704
END IF
705
706
lambda = ListGetConstReal( Material, 'Diffusion Parameter', GotIt,UnFoundFatal=UnFoundFatal)
707
!Previous default value: lambda = 0.0_dp
708
WRITE(Message,'(A,F10.4)') 'Diffusion Parameter = ', lambda
709
CALL INFO('AIFlowSolve', Message, Level = 20)
710
711
Wn(2) = ListGetConstReal( Material , 'Powerlaw Exponent', GotIt,UnFoundFatal=UnFoundFatal)
712
!Previous default value: Wn(2) = 1.0
713
WRITE(Message,'(A,F10.4)') 'Powerlaw Exponent = ', Wn(2)
714
CALL INFO('AIFlowSolve', Message, Level = 20)
715
716
Wn(3) = ListGetConstReal( Material, 'Activation Energy 1', GotIt,UnFoundFatal=UnFoundFatal)
717
!Previous default value: Wn(3) = 1.0
718
WRITE(Message,'(A,F10.4)') 'Activation Energy 1 = ', Wn(3)
719
CALL INFO('AIFlowSolve', Message, Level = 20)
720
721
Wn(4) = ListGetConstReal( Material, 'Activation Energy 2', GotIt,UnFoundFatal=UnFoundFatal)
722
!Previous default value: Wn(4) = 1.0
723
WRITE(Message,'(A,F10.4)') 'Activation Energy 2 = ', Wn(4)
724
CALL INFO('AIFlowSolve', Message, Level = 20)
725
726
Wn(5) = ListGetConstReal(Material, 'Reference Temperature', GotIt,UnFoundFatal=UnFoundFatal)
727
!Previous default value: Wn(5) = -10.0
728
WRITE(Message,'(A,F10.4)') 'Reference Temperature = ', Wn(5)
729
CALL INFO('AIFlowSolve', Message, Level = 20)
730
731
Wn(6) = ListGetConstReal( Material, 'Limit Temperature', GotIt,UnFoundFatal=UnFoundFatal)
732
!Previous default value: Wn(6) = -10.0
733
WRITE(Message,'(A,F10.4)') 'Limit Temperature = ', Wn(6)
734
CALL INFO('AIFlowSolve', Message, Level = 20)
735
!------------------------------------------------------------------------------
736
END SUBROUTINE GetMaterialDefs
737
!------------------------------------------------------------------------------
738
739
740
!------------------------------------------------------------------------------
741
SUBROUTINE LocalMatrix( Comp, MASS, STIFF, FORCE, LOAD, &
742
NodalK1, NodalK2, NodalEuler1, NodalEuler2, NodalEuler3, &
743
NodalTemperature, NodalFluidity, NodalVelo, NodMeshVel, &
744
Element, n, Nodes, Wn, rho,lambda )
745
!------------------------------------------------------------------------------
746
747
REAL(KIND=dp) :: STIFF(:,:),MASS(:,:)
748
REAL(KIND=dp) :: LOAD(:,:), NodalVelo(:,:),NodMeshVel(:,:)
749
REAL(KIND=dp), DIMENSION(:) :: FORCE, NodalK1, NodalK2, NodalEuler1, &
750
NodalEuler2, NodalEuler3, NodalTemperature, NodalFluidity
751
752
TYPE(Nodes_t) :: Nodes
753
TYPE(Element_t) :: Element
754
INTEGER :: n, Comp
755
!------------------------------------------------------------------------------
756
!
757
REAL(KIND=dp) :: Basis(2*n),ddBasisddx(1,1,1)
758
REAL(KIND=dp) :: dBasisdx(2*n,3),SqrtElementMetric
759
760
REAL(KIND=dp) :: A1, A2, A3, E1, E2, E3, Theta
761
762
REAL(KIND=dp) :: A,M, hK,tau,pe1,pe2,unorm,C0, SU(n), SW(n)
763
REAL(KIND=dp) :: LoadAtIp, Temperature
764
REAL(KIND=dp) :: rho,lambda,Deq, ai(6),a4(9),hmax
765
766
INTEGER :: i,j,k,p,q,t,dim,NBasis,ind(3), DOFs = 1
767
768
REAL(KIND=dp) :: s,u,v,w, Radius, B(6,3), G(3,6), C44,C55,C66
769
REAL(KIND=dp) :: Wn(:),Velo(3),DStress(6),StrainR(6),Spin(3),SD(6)
770
771
REAL(KIND=dp) :: LGrad(3,3),StrainRate(3,3),D(6),angle(3),epsi
772
REAL(KIND=dp) :: ap(3),C(6,6),Spin1(3,3),Stress(3,3)
773
Integer :: INDi(6),INDj(6)
774
LOGICAL :: CSymmetry
775
776
LOGICAL :: Fond
777
778
!
779
INTEGER :: N_Integ
780
REAL(KIND=dp), DIMENSION(:), POINTER :: U_Integ,V_Integ,W_Integ,S_Integ
781
782
LOGICAL :: stat
783
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
784
785
INTERFACE
786
FUNCTION BGlenT( Tc, W)
787
USE Types
788
REAL(KIND=dp) :: BGlenT,Tc,W(7)
789
END FUNCTION
790
791
SUBROUTINE IBOF(ai,a4)
792
USE Types
793
REAL(KIND=dp),intent(in) :: ai(6)
794
REAL(KIND=dp),intent(out) :: a4(9)
795
END SUBROUTINE
796
797
Subroutine R2Ro(ai,dim,a2,angle)
798
USE Types
799
REAL(KIND=dp),intent(in) :: ai(6)
800
Integer :: dim
801
REAL(KIND=dp),intent(out) :: a2(3), Angle(3)
802
End Subroutine R2Ro
803
804
Subroutine OPILGGE_ai_nl(a2,Angle,etaI,eta36)
805
USE Types
806
REAL(kind=dp), INTENT(in), DIMENSION(3) :: a2
807
REAL(kind=dp), INTENT(in), DIMENSION(3) :: Angle
808
REAL(kind=dp), INTENT(in), DIMENSION(:) :: etaI
809
REAL(kind=dp), INTENT(out), DIMENSION(6,6) :: eta36
810
END SUBROUTINE OPILGGE_ai_nl
811
812
END INTERFACE
813
!------------------------------------------------------------------------------
814
Fond=.False.
815
816
hmax = maxval (Nodes % y(1:n))
817
818
dim = CoordinateSystemDimension()
819
820
FORCE = 0.0D0
821
MASS = 0.0D0
822
STIFF = 0.0D0
823
!
824
! Integration stuff:
825
! ------------------
826
NBasis = n
827
IntegStuff = GaussPoints( Element )
828
829
U_Integ => IntegStuff % u
830
V_Integ => IntegStuff % v
831
W_Integ => IntegStuff % w
832
S_Integ => IntegStuff % s
833
N_Integ = IntegStuff % n
834
835
hk = ElementDiameter( Element, Nodes )
836
!
837
! Now we start integrating:
838
! -------------------------
839
DO t=1,N_Integ
840
841
u = U_Integ(t)
842
v = V_Integ(t)
843
w = W_Integ(t)
844
845
!------------------------------------------------------------------------------
846
! Basis function values & derivatives at the integration point
847
!------------------------------------------------------------------------------
848
stat = ElementInfo( Element,Nodes,u,v,w,SqrtElementMetric, &
849
Basis, dBasisdx, ddBasisddx, .FALSE. )
850
851
s = SqrtElementMetric * S_Integ(t)
852
!------------------------------------------------------------------------------
853
!
854
! Orientation parameters at the integration point:
855
! ------------------------------------------------
856
A1 = SUM( NodalK1(1:n) * Basis(1:n) )
857
A2 = SUM( NodalK2(1:n) * Basis(1:n) )
858
A3 = 1._dp - A1 - A2
859
860
E1 = SUM( NodalEuler1(1:n) * Basis(1:n) )
861
E2 = SUM( NodalEuler2(1:n) * Basis(1:n) )
862
E3 = SUM( NodalEuler3(1:n) * Basis(1:n) )
863
!
864
! Fluidity at the integration point:
865
!---------------------------------------------
866
! Wn(1)=SUM( NodalFluidity(1:n)*Basis(1:n) )
867
!
868
! Temperature at the integration point:
869
! -------------------------------------
870
! Temperature = SUM( NodalTemperature(1:n)*Basis(1:n) )
871
!
872
! Get theta parameter: (the (fluidity in the basal plane)/2,
873
! function of the Temperature )
874
! -----------------------------------------------------
875
Theta = 1._dp / ( FabricGrid(5) + FabricGrid(6) )
876
!Theta = Theta
877
878
! Strain-Rate, Stresses and Spin
879
880
CSymmetry = CurrentCoordinateSystem() == AxisSymmetric
881
882
Stress = 0.0
883
StrainRate = 0.0
884
Spin1 = 0.0
885
!
886
! Material parameters at that point
887
! ---------------------------------
888
!
889
ai(1)=A1
890
ai(2)=A2
891
ai(3)=A3
892
ai(4)=E1
893
ai(5)=E2
894
ai(6)=E3
895
896
! fourth order orientation tensor
897
call IBOF(ai,a4)
898
899
! A2 expressed in the orthotropic frame
900
!
901
call R2Ro(ai,dim,ap,angle)
902
903
! Get viscosity
904
905
CALL OPILGGE_ai_nl(ap, Angle, FabricGrid, C)
906
907
! Compute strainRate and Spin :
908
! -----------------------------
909
910
LGrad = MATMUL( NodalVelo(1:3,1:n), dBasisdx(1:n,1:3) )
911
912
StrainRate = 0.5 * ( LGrad + TRANSPOSE(LGrad) )
913
914
Spin1 = 0.5 * ( LGrad - TRANSPOSE(LGrad) )
915
916
IF ( CSymmetry ) THEN
917
StrainRate(1,3) = 0.0
918
StrainRate(2,3) = 0.0
919
StrainRate(3,1) = 0.0
920
StrainRate(3,2) = 0.0
921
StrainRate(3,3) = 0.0
922
923
Radius = SUM( Nodes % x(1:n) * Basis(1:n) )
924
925
IF ( Radius > 10*AEPS ) THEN
926
StrainRate(3,3) = SUM( Nodalvelo(1,1:n) * Basis(1:n) ) / Radius
927
END IF
928
929
epsi = StrainRate(1,1)+StrainRate(2,2)+StrainRate(3,3)
930
DO i=1,3
931
StrainRate(i,i) = StrainRate(i,i) - epsi/3.0
932
END DO
933
934
ELSE
935
epsi = StrainRate(1,1)+StrainRate(2,2)+StrainRate(3,3)
936
DO i=1,dim
937
StrainRate(i,i) = StrainRate(i,i) - epsi/dim
938
END DO
939
940
END IF
941
942
!
943
! Compute deviatoric stresses:
944
! ----------------------------
945
D(1) = StrainRate(1,1)
946
D(2) = StrainRate(2,2)
947
D(3) = StrainRate(3,3)
948
D(4) = 2. * StrainRate(1,2)
949
D(5) = 2. * StrainRate(2,3)
950
D(6) = 2. * StrainRate(3,1)
951
952
INDi(1:6) = (/ 1, 2, 3, 1, 2, 3 /)
953
INDj(1:6) = (/ 1, 2, 3, 2, 3, 1 /)
954
DO k = 1, 2*dim
955
DO j = 1, 2*dim
956
Stress( INDi(k),INDj(k) ) = &
957
Stress( INDi(k),INDj(k) ) + C(k,j) * D(j)
958
END DO
959
IF (k > 3) Stress( INDj(k),INDi(k) ) = Stress( INDi(k),INDj(k) )
960
END DO
961
962
963
! SD=(1-r)D + r psi/2 S :
964
! -----------------------
965
SD=0._dp
966
DO i=1,2*dim
967
SD(i)= (1._dp - rho)*StrainRate(INDi(i),INDj(i)) + rho *&
968
Theta * Stress(INDi(i),INDj(i))
969
END DO
970
Do i=1,2*dim-3
971
Spin(i)=Spin1(INDi(i+3),INDj(i+3))
972
End do
973
974
Deq=sqrt(2._dp*(SD(1)*SD(1)+SD(2)*SD(2)+SD(3)*SD(3)+2._dp* &
975
(SD(4)*SD(4)+SD(5)*SD(5)+SD(6)*SD(6)))/3._dp)
976
!
977
! Velocity :
978
! ----------
979
Velo = 0.0d0
980
DO i=1,dim
981
Velo(i) = SUM( Basis(1:n) * (NodalVelo(i,1:n) - NodMeshVel(i,1:n)) )
982
END DO
983
Unorm = SQRT( SUM( Velo**2._dp ) )
984
985
!
986
! Reaction coefficient:
987
! ---------------------
988
SELECT CASE(comp)
989
CASE(1)
990
!C0 = -2._dp*(SD(1)-SD(3))
991
C0=-2._dp*SD(1)-3._dp*lambda*Deq
992
CASE(2)
993
!C0 = -2._dp*(SD(2)-SD(3))
994
C0 = -2._dp*SD(2)-3._dp*lambda*Deq
995
996
CASE(3)
997
!C0 = -(SD(1)+SD(2)-2._dp*SD(3))
998
C0 = -(SD(1)+SD(2))-3._dp*lambda*Deq
999
1000
CASE(4)
1001
C0 = -(SD(2)-SD(3))-3._dp*lambda*Deq
1002
1003
CASE(5)
1004
C0 = -(SD(1)-SD(3))-3._dp*lambda*Deq
1005
1006
1007
END SELECT
1008
1009
If (Fond) C0=0._dp
1010
1011
! Loop over basis functions (of both unknowns and weights):
1012
! ---------------------------------------------------------
1013
DO p=1,NBasis
1014
DO q=1,NBasis
1015
A = 0.0d0
1016
M = Basis(p) * Basis(q)
1017
!
1018
! Reaction terms:
1019
! ---------------
1020
A = A - C0 * Basis(q) * Basis(p)
1021
1022
!
1023
! Advection terms:
1024
! ----------------
1025
DO j=1,dim
1026
A = A - Velo(j) * Basis(q) * dBasisdx(p,j)
1027
END DO
1028
1029
! Add nodal matrix to element matrix:
1030
! -----------------------------------
1031
MASS( p,q ) = MASS( p,q ) + s * M
1032
STIFF( p,q ) = STIFF( p,q ) + s * A
1033
END DO
1034
1035
1036
!
1037
! The righthand side...:
1038
! ----------------------
1039
SELECT CASE(comp)
1040
1041
CASE(1)
1042
1043
LoadAtIp = 2._dp*( Spin(1)*E1 + SD(4)*(2._dp*a4(7)-E1) + &
1044
SD(1)*a4(1) + SD(2)*a4(3) - SD(3)*(-A1+a4(1)+a4(3)) ) + &
1045
lambda*Deq
1046
1047
IF(dim == 3) THEN
1048
LoadAtIp = LoadAtIp + 2._dp*( -Spin(3)*E3 + &
1049
SD(6)*(2._dp*a4(6)-E3) + 2._dp*SD(5)*a4(4) )
1050
END IF
1051
1052
1053
CASE(2)
1054
LoadAtIp = 2._dp*( -Spin(1)*E1 + SD(4)*(2._dp*a4(9)-E1) + &
1055
SD(2)*a4(2) + SD(1)*a4(3) - SD(3)*(-A2+a4(2)+a4(3)) ) + &
1056
lambda*Deq
1057
1058
IF(dim == 3) THEN
1059
LoadAtIp = LoadAtIp + 2._dp*( Spin(2)*E2 + &
1060
SD(5)*(2._dp*a4(8)-E2) + 2._dp*SD(6)*a4(5) )
1061
END IF
1062
1063
1064
CASE(3)
1065
LoadAtIp = Spin(1)*(A2-A1) + SD(4)*(4._dp*a4(3)-A1-A2) + &
1066
2._dp* ( SD(1)*a4(7) + SD(2)*a4(9) - SD(3)*(-E1+a4(7)+a4(9)) )
1067
1068
IF(dim == 3) THEN
1069
LoadAtIp = LoadAtIp - Spin(3)*E2 + Spin(2)*E3 &
1070
+ SD(6)*(4._dp*a4(4)-E2) + SD(5)*(4._dp*a4(5)-E3)
1071
END IF
1072
1073
CASE(4)
1074
LoadAtIp = Spin(2)*(A3-A2) + Spin(3)*E1 - Spin(1)*E3 +&
1075
SD(4)*(4._dp*a4(5)-E3) + SD(5)*(3._dp*A2-A3-4._dp*(a4(2)+a4(3))) &
1076
+ SD(6)*(3._dp*E1-4._dp*(a4(7)+a4(9))) + &
1077
2._dp*( SD(1)*a4(4) + SD(2)*a4(8) - SD(3)*(a4(4)+a4(8)) )
1078
1079
CASE(5)
1080
LoadAtIp = Spin(3)*(A1-A3) + Spin(1)*E2 - Spin(2)*E1 +&
1081
SD(4)*(4._dp*a4(4)-E2) + &
1082
SD(6)*(3._dp*A1-A3-4.*(a4(1)+a4(3))) + SD(5)*(3._dp*E1-4._dp*(a4(7)+a4(9))) + &
1083
2._dp*( SD(1)*a4(6) + SD(2)*a4(5) - SD(3)*(a4(6)+a4(5)) )
1084
1085
1086
1087
END SELECT
1088
1089
If (Fond) LoadAtIp=0._dp
1090
LoadAtIp= LoadAtIp * Basis(p)
1091
FORCE(p) = FORCE(p) + s*LoadAtIp
1092
END DO
1093
1094
1095
END DO
1096
1097
1000 FORMAT((a),x,i2,x,6(e13.5,x))
1098
1001 FORMAT(6(e13.5,x))
1099
!------------------------------------------------------------------------------
1100
END SUBROUTINE LocalMatrix
1101
!------------------------------------------------------------------------------
1102
1103
!------------------------------------------------------------------------------
1104
SUBROUTINE LocalJumps( STIFF,Edge,n,LeftParent,n1,RightParent,n2,Velo,MeshVelo )
1105
!------------------------------------------------------------------------------
1106
REAL(KIND=dp) :: STIFF(:,:), Velo(:,:),MeshVelo(:,:)
1107
INTEGER :: n,n1,n2
1108
TYPE(Element_t), POINTER :: Edge, LeftParent, RightParent
1109
!------------------------------------------------------------------------------
1110
REAL(KIND=dp) :: EdgeBasis(n), EdgedBasisdx(n,3), EdgeddBasisddx(n,3,3)
1111
REAL(KIND=dp) :: LeftBasis(n1), LeftdBasisdx(n1,3), LeftddBasisddx(n1,3,3)
1112
REAL(KIND=dp) :: RightBasis(n2), RightdBasisdx(n2,3), RightddBasisddx(n2,3,3)
1113
REAL(KIND=dp) :: Jump(n1+n2), Average(n1+n2)
1114
REAL(KIND=dp) :: detJ, U, V, W, S, Udotn, xx, yy
1115
LOGICAL :: Stat
1116
INTEGER :: i, j, p, q, dim, t, nEdge, nParent
1117
TYPE(GaussIntegrationPoints_t) :: IntegStuff
1118
REAL(KIND=dp) :: hE, Normal(3), cu(3), LeftOut(3)
1119
1120
TYPE(Nodes_t) :: EdgeNodes, LeftParentNodes, RightParentNodes
1121
1122
Save EdgeNodes, LeftParentNodes, RightParentNodes
1123
!------------------------------------------------------------------------------
1124
dim = CoordinateSystemDimension()
1125
STIFF = 0.0d0
1126
1127
CALL GetElementNodes( EdgeNodes, Edge )
1128
CALL GetElementNodes( LeftParentNodes, LeftParent )
1129
CALL GetElementNodes( RightParentNodes, RightParent )
1130
!------------------------------------------------------------------------------
1131
! Numerical integration over the edge
1132
!------------------------------------------------------------------------------
1133
IntegStuff = GaussPoints( Edge )
1134
1135
LeftOut(1) = SUM( LeftParentNodes % x(1:n1) ) / n1
1136
LeftOut(2) = SUM( LeftParentNodes % y(1:n1) ) / n1
1137
LeftOut(3) = SUM( LeftParentNodes % z(1:n1) ) / n1
1138
LeftOut(1) = SUM( EdgeNodes % x(1:n) ) / n - LeftOut(1)
1139
LeftOut(2) = SUM( EdgeNodes % y(1:n) ) / n - LeftOut(2)
1140
LeftOut(3) = SUM( EdgeNodes % z(1:n) ) / n - LeftOut(3)
1141
1142
DO t=1,IntegStuff % n
1143
U = IntegStuff % u(t)
1144
V = IntegStuff % v(t)
1145
W = IntegStuff % w(t)
1146
S = IntegStuff % s(t)
1147
1148
! Basis function values & derivatives at the integration point:
1149
!--------------------------------------------------------------
1150
stat = ElementInfo( Edge, EdgeNodes, U, V, W, detJ, &
1151
EdgeBasis, EdgedBasisdx, EdgeddBasisddx, .FALSE. )
1152
1153
S = S * detJ
1154
1155
Normal = NormalVector( Edge, EdgeNodes, U, V, .FALSE. )
1156
IF ( SUM( LeftOut*Normal ) < 0 ) Normal = -Normal
1157
1158
! Find basis functions for the parent elements:
1159
! ---------------------------------------------
1160
CALL FindParentUVW( Edge,n,LeftParent,n1,U,V,W,EdgeBasis )
1161
stat = ElementInfo( LeftParent, LeftParentNodes, U, V, W, detJ, &
1162
LeftBasis, LeftdBasisdx, LeftddBasisddx, .FALSE. )
1163
1164
CALL FindParentUVW( Edge,n,RightParent,n2,U,V,W,EdgeBasis )
1165
stat = ElementInfo( RightParent, RightParentNodes, U, V, W, detJ, &
1166
RightBasis, RightdBasisdx, RightddBasisddx, .FALSE. )
1167
1168
! Integrate jump terms:
1169
! ---------------------
1170
Jump(1:n1) = LeftBasis(1:n1)
1171
Jump(n1+1:n1+n2) = -RightBasis(1:n2)
1172
1173
Average(1:n1) = LeftBasis(1:n1) / 2
1174
Average(n1+1:n1+n2) = RightBasis(1:n2) / 2
1175
1176
cu = 0.0d0
1177
DO i=1,dim
1178
cu(i) = SUM( (Velo(i,1:n)-MeshVelo(i,1:n)) * EdgeBasis(1:n) )
1179
END DO
1180
Udotn = SUM( Normal * cu )
1181
1182
DO p=1,n1+n2
1183
DO q=1,n1+n2
1184
STIFF(p,q) = STIFF(p,q) + s * Udotn * Average(q) * Jump(p)
1185
STIFF(p,q) = STIFF(p,q) + s * ABS(Udotn)/2 * Jump(q) * Jump(p)
1186
END DO
1187
END DO
1188
END DO
1189
!------------------------------------------------------------------------------
1190
END SUBROUTINE LocalJumps
1191
!------------------------------------------------------------------------------
1192
1193
1194
1195
!------------------------------------------------------------------------------
1196
SUBROUTINE LocalMatrixBoundary( STIFF, FORCE, LOAD, &
1197
Element, n, ParentElement, np, Velo,MeshVelo, InFlowBC )
1198
!------------------------------------------------------------------------------
1199
REAL(KIND=dp) :: STIFF(:,:), FORCE(:), LOAD(:), Velo(:,:),MeshVelo(:,:)
1200
INTEGER :: n, np
1201
LOGICAL :: InFlowBC
1202
TYPE(Element_t), POINTER :: Element, ParentElement
1203
!------------------------------------------------------------------------------
1204
REAL(KIND=dp) :: Basis(n), dBasisdx(n,3), ddBasisddx(n,3,3)
1205
REAL(KIND=dp) :: ParentBasis(np), ParentdBasisdx(np,3), ParentddBasisddx(np,3,3)
1206
INTEGER :: i,j,p,q,t,dim
1207
1208
REAL(KIND=dp) :: Normal(3), g, L, Udotn, UdotnA, cu(3), detJ,U,V,W,S
1209
LOGICAL :: Stat
1210
TYPE(GaussIntegrationPoints_t) :: IntegStuff
1211
1212
TYPE(Nodes_t) :: Nodes, ParentNodes
1213
SAVE Nodes, ParentNodes
1214
!------------------------------------------------------------------------------
1215
dim = CoordinateSystemDimension()
1216
FORCE = 0.0d0
1217
STIFF = 0.0d0
1218
1219
CALL GetElementNodes( Nodes, Element )
1220
CALL GetElementNodes( ParentNodes, ParentElement )
1221
1222
! Numerical integration:
1223
!-----------------------
1224
IntegStuff = GaussPoints( Element )
1225
!
1226
! Compute the average velocity.dot.Normal
1227
!
1228
UdotnA = 0.0
1229
DO t=1,IntegStuff % n
1230
U = IntegStuff % u(t)
1231
V = IntegStuff % v(t)
1232
W = IntegStuff % w(t)
1233
S = IntegStuff % s(t)
1234
1235
Normal = NormalVector( Element, Nodes, U, V, .TRUE. )
1236
1237
! Basis function values & derivatives at the integration point:
1238
! -------------------------------------------------------------
1239
stat = ElementInfo( Element, Nodes, U, V, W, detJ, &
1240
Basis, dBasisdx, ddBasisddx, .FALSE. )
1241
S = S * detJ
1242
cu = 0.0d0
1243
DO i=1,dim
1244
cu(i) = SUM( (Velo(i,1:n)-MeshVelo(i,1:n)) * Basis(1:n) )
1245
END DO
1246
UdotnA = UdotnA + s*SUM( Normal * cu )
1247
1248
END DO
1249
1250
DO t=1,IntegStuff % n
1251
U = IntegStuff % u(t)
1252
V = IntegStuff % v(t)
1253
W = IntegStuff % w(t)
1254
S = IntegStuff % s(t)
1255
1256
Normal = NormalVector( Element, Nodes, U, V, .TRUE. )
1257
1258
! Basis function values & derivatives at the integration point:
1259
! -------------------------------------------------------------
1260
stat = ElementInfo( Element, Nodes, U, V, W, detJ, &
1261
Basis, dBasisdx, ddBasisddx, .FALSE. )
1262
S = S * detJ
1263
1264
CALL FindParentUVW( Element, n, ParentElement, np, U, V, W, Basis )
1265
stat = ElementInfo( ParentElement, ParentNodes, U, V, W, &
1266
detJ, ParentBasis, ParentdBasisdx, ParentddBasisddx, .FALSE. )
1267
1268
L = SUM( LOAD(1:n) * Basis(1:n) )
1269
cu = 0.0d0
1270
DO i=1,dim
1271
cu(i) = SUM( (Velo(i,1:n)-MeshVelo(i,1:n)) * Basis(1:n) )
1272
END DO
1273
Udotn = SUM( Normal * cu )
1274
1275
DO p = 1,np
1276
IF (InFlowBC .And. (UdotnA < 0.) ) THEN
1277
FORCE(p) = FORCE(p) - s * Udotn*L*ParentBasis(p)
1278
ELSE
1279
DO q=1,np
1280
STIFF(p,q) = STIFF(p,q) + s*Udotn*ParentBasis(q)*ParentBasis(p)
1281
END DO
1282
END IF
1283
END DO
1284
END DO
1285
!------------------------------------------------------------------------------
1286
END SUBROUTINE LocalMatrixBoundary
1287
!------------------------------------------------------------------------------
1288
1289
1290
1291
!------------------------------------------------------------------------------
1292
END SUBROUTINE FabricSolver
1293
!------------------------------------------------------------------------------
1294
1295
1296