Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/AdjointSSA/AdjointSSA_SSASolver.F90
3206 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: Olivier Gagliardini
26
! * Email: [email protected]
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date: 30. April 2010
30
! *
31
! *****************************************************************************
32
!> SSolver to inquire the velocity from the SSA solution
33
SUBROUTINE AdjointSSA_SSASolver( Model,Solver,dt,TransientSimulation )
34
!------------------------------------------------------------------------------
35
!******************************************************************************
36
!
37
! Solve the in-plane basal velocity with the SSA solution !
38
! To be computed only at the base. Use then the SSASolver to export vertically
39
! the basal velocity and compute the vertical velocity and pressure (if needed)
40
!
41
! ARGUMENTS:
42
!
43
! TYPE(Model_t) :: Model,
44
! INPUT: All model information (mesh, materials, BCs, etc...)
45
!
46
! TYPE(Solver_t) :: Solver
47
! INPUT: Linear & nonlinear equation solver options
48
!
49
! REAL(KIND=dp) :: dt,
50
! INPUT: Timestep size for time dependent simulations
51
!
52
! LOGICAL :: TransientSimulation
53
! INPUT: Steady state or transient simulation
54
!
55
!******************************************************************************
56
USE DefUtils
57
58
IMPLICIT NONE
59
!------------------------------------------------------------------------------
60
TYPE(Solver_t) :: Solver
61
TYPE(Model_t) :: Model
62
63
REAL(KIND=dp) :: dt
64
LOGICAL :: TransientSimulation
65
!------------------------------------------------------------------------------
66
! Local variables
67
!------------------------------------------------------------------------------
68
TYPE(Nodes_t) :: ElementNodes
69
TYPE(Element_t),POINTER :: CurrentElement, Element, ParentElement, BoundaryElement
70
TYPE(Matrix_t),POINTER :: StiffMatrix
71
TYPE(ValueList_t), POINTER :: SolverParams, BodyForce, Material, BC
72
TYPE(Variable_t), POINTER :: PointerToVariable, ZsSol, ZbSol
73
74
LOGICAL :: AllocationsDone = .FALSE., Found, GotIt, CalvingFront
75
LOGICAL :: Newton
76
77
INTEGER :: i, n, m, t, istat, DIM, p, STDOFs
78
INTEGER :: NonlinearIter, NewtonIter, iter, other_body_id
79
80
INTEGER, POINTER :: Permutation(:), &
81
ZsPerm(:), ZbPerm(:), &
82
NodeIndexes(:)
83
84
REAL(KIND=dp), POINTER :: ForceVector(:)
85
REAL(KIND=dp), POINTER :: VariableValues(:), Zs(:), Zb(:)
86
87
REAL(KIND=dp) :: UNorm, cn, dd, NonlinearTol, NewtonTol, MinSRInv, rhow, sealevel, &
88
PrevUNorm, relativeChange,minv
89
90
REAL(KIND=dp), ALLOCATABLE,SAVE :: STIFF(:,:), LOAD(:), FORCE(:), &
91
NodalGravity(:), NodalViscosity(:), NodalDensity(:), &
92
NodalZs(:), NodalZb(:), NodalGM(:), NodalBed(:), &
93
NodalU(:), NodalV(:), NodalBeta(:),LocalLinVelo(:)
94
95
INTEGER :: iFriction
96
REAL(KIND=dp) :: fm
97
CHARACTER(LEN=MAX_NAME_LEN) :: Friction
98
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName
99
REAL(KIND=dp) :: at, at0
100
LOGICAL :: SEP ! Sub-element parametrization for Grounding line
101
INTEGER :: GLnIP ! number of Integ. Points for GL Sub-element parametrization
102
TYPE(Variable_t), POINTER :: GMSol,BedrockSol
103
104
SAVE rhow,sealevel
105
SAVE AllocationsDone, DIM, SolverName, ElementNodes
106
SAVE NodeIndexes
107
108
!------------------------------------------------------------------------------
109
PointerToVariable => Solver % Variable
110
Permutation => PointerToVariable % Perm
111
VariableValues => PointerToVariable % Values
112
STDOFs = PointerToVariable % DOFs
113
WRITE(SolverName, '(A)') 'SSASolver-SSABasalSolver'
114
115
!------------------------------------------------------------------------------
116
! Get variables needed for solution
117
!------------------------------------------------------------------------------
118
DIM = CoordinateSystemDimension()
119
120
121
ZbSol => VariableGet( Solver % Mesh % Variables, 'Zb', UnFoundFatal=.TRUE. )
122
Zb => ZbSol % Values
123
ZbPerm => ZbSol % Perm
124
125
ZsSol => VariableGet( Solver % Mesh % Variables, 'Zs' , UnFoundFatal=.TRUE. )
126
Zs => ZsSol % Values
127
ZsPerm => ZsSol % Perm
128
129
! Sub - element GL parameterisation
130
SEP=GetLogical( Solver % Values, 'Sub-Element GL parameterization',GotIt)
131
IF (.NOT.GotIt) SEP=.False.
132
IF (SEP) THEN
133
GLnIP=ListGetInteger( Solver % Values, &
134
'GL integration points number',UnFoundFatal=.TRUE. )
135
WRITE(Message,'(a,i0,a)') 'Sub-Element GL parameterization using ',GLnIP,' IPs'
136
CALL INFO(SolverName,TRIM(Message),level=4)
137
GMSol => VariableGet( Solver % Mesh % Variables, 'GroundedMask',UnFoundFatal=.TRUE. )
138
BedrockSol => VariableGet( Solver % Mesh % Variables, 'bedrock',UnFoundFatal=.TRUE. )
139
END IF
140
141
!--------------------------------------------------------------
142
!Allocate some permanent storage, this is done first time only:
143
!--------------------------------------------------------------
144
IF ( (.NOT. AllocationsDone) .OR. Solver % Mesh % Changed ) THEN
145
146
! Get some constants
147
rhow = ListGetConstReal( Model % Constants, 'Water Density', UnFoundFatal=.TRUE. )
148
sealevel = ListGetConstReal( Model % Constants, 'Sea Level', UnFoundFatal=.TRUE. )
149
150
! Allocate
151
N = Model % MaxElementNodes
152
M = Model % Mesh % NumberOfNodes
153
IF (AllocationsDone) DEALLOCATE(FORCE, LOAD, STIFF, NodalGravity, &
154
NodalViscosity, NodalDensity, &
155
NodalZb, NodalZs,NodalGM,NodalBed, NodalU, NodalV, &
156
NodalBeta,LocalLinVelo, ElementNodes % x, &
157
ElementNodes % y, ElementNodes % z )
158
159
ALLOCATE( FORCE(STDOFs*N), LOAD(N), STIFF(STDOFs*N,STDOFs*N), &
160
NodalGravity(N), NodalDensity(N), NodalViscosity(N), &
161
NodalZb(N), NodalZs(N) , NodalGM(N), NodalBed(N),&
162
NodalU(N), NodalV(N), NodalBeta(N),LocalLinVelo(N), &
163
ElementNodes % x(N), ElementNodes % y(N), ElementNodes % z(N), &
164
STAT=istat )
165
IF ( istat /= 0 ) THEN
166
CALL Fatal( SolverName, 'Memory allocation error.' )
167
END IF
168
169
AllocationsDone = .TRUE.
170
CALL INFO( SolverName, 'Memory allocation done.',Level=1 )
171
END IF
172
173
StiffMatrix => Solver % Matrix
174
ForceVector => StiffMatrix % RHS
175
176
!------------------------------------------------------------------------------
177
! Do some additional initialization, and go for it
178
!------------------------------------------------------------------------------
179
180
!------------------------------------------------------------------------------
181
NonlinearTol = GetConstReal( Solver % Values, &
182
'Nonlinear System Convergence Tolerance' )
183
184
NonlinearIter = GetInteger( Solver % Values, &
185
'Nonlinear System Max Iterations',GotIt )
186
187
IF ( .NOT.GotIt ) NonlinearIter = 1
188
189
NewtonTol = ListGetConstReal( Solver % Values, &
190
'Nonlinear System Newton After Tolerance', minv=0.0d0 )
191
192
NewtonIter = ListGetInteger( Solver % Values, &
193
'Nonlinear System Newton After Iterations', GotIt )
194
if (.NOT.Gotit) NewtonIter = NonlinearIter + 1
195
196
197
Newton=.False.
198
199
!------------------------------------------------------------------------------
200
DO iter=1,NonlinearIter
201
202
at = CPUTime()
203
at0 = RealTime()
204
205
CALL Info( SolverName, ' ', Level=4 )
206
CALL Info( SolverName, ' ', Level=4 )
207
CALL Info( SolverName, &
208
'-------------------------------------',Level=4 )
209
WRITE( Message, * ) 'SSA BASAL VELOCITY NON-LINEAR ITERATION', iter
210
CALL Info( SolverName, Message, Level=4 )
211
If (Newton) Then
212
WRITE( Message, * ) 'Newton linearisation is used'
213
CALL Info( SolverName, Message, Level=4 )
214
Endif
215
CALL Info( SolverName, ' ', Level=4 )
216
CALL Info( SolverName, &
217
'-------------------------------------',Level=4 )
218
CALL Info( SolverName, ' ', Level=4 )
219
220
221
!Initialize the system and do the assembly:
222
!------------------------------------------
223
CALL DefaultInitialize()
224
225
! bulk assembly
226
DO t=1,Solver % NumberOfActiveElements
227
Element => GetActiveElement(t)
228
IF (ParEnv % myPe .NE. Element % partIndex) CYCLE
229
n = GetElementNOFNodes()
230
231
NodeIndexes => Element % NodeIndexes
232
233
! set coords of highest occurring dimension to zero (to get correct path element)
234
!-------------------------------------------------------------------------------
235
ElementNodes % x(1:n) = Solver % Mesh % Nodes % x(NodeIndexes)
236
IF (STDOFs == 1) THEN !1D SSA
237
ElementNodes % y(1:n) = 0.0_dp
238
ElementNodes % z(1:n) = 0.0_dp
239
ELSE IF (STDOFs == 2) THEN !2D SSA
240
ElementNodes % y(1:n) = Solver % Mesh % Nodes % y(NodeIndexes)
241
ElementNodes % z(1:n) = 0.0_dp
242
ELSE
243
WRITE(Message,'(a,i1,a)')&
244
'It is not possible to compute SSA problems with DOFs=',&
245
STDOFs, ' . Aborting'
246
CALL Fatal( SolverName, Message)
247
STOP
248
END IF
249
250
! Read the gravity in the Body Force Section
251
BodyForce => GetBodyForce()
252
NodalGravity = 0.0_dp
253
IF ( ASSOCIATED( BodyForce ) ) THEN
254
IF (STDOFs==1) THEN
255
NodalGravity(1:n) = ListGetReal( &
256
BodyForce, 'Flow BodyForce 2', n, NodeIndexes, UnFoundFatal=.TRUE.)
257
ELSE
258
NodalGravity(1:n) = ListGetReal( &
259
BodyForce, 'Flow BodyForce 3', n, NodeIndexes, UnFoundFatal=.TRUE.)
260
END IF
261
END IF
262
263
! Read the Viscosity eta, density, and exponent m in MMaterial Section
264
! Same definition as NS Solver in Elmer - n=1/m , A = 1/ (2 eta^n)
265
Material => GetMaterial(Element)
266
267
cn = ListGetConstReal( Material, 'Viscosity Exponent',UnFoundFatal=.TRUE.)
268
MinSRInv = ListGetConstReal( Material, 'Critical Shear Rate',UnFoundFatal=.TRUE.)
269
270
271
NodalDensity=0.0_dp
272
NodalDensity(1:n) = ListGetReal( Material, 'SSA Mean Density',n,NodeIndexes,UnFoundFatal=.TRUE.)
273
274
NodalViscosity=0.0_dp
275
NodalViscosity(1:n) = ListGetReal( Material, 'SSA Mean Viscosity',n, NodeIndexes,UnFoundFatal=.TRUE.)
276
277
Friction = ListGetString(Material, 'SSA Friction Law', Found,UnFoundFatal=.TRUE.)
278
279
SELECT CASE(Friction)
280
CASE('linear')
281
iFriction = 1
282
fm = 1.0_dp
283
CASE('weertman')
284
iFriction = 2
285
CASE DEFAULT
286
CALL FATAL(SolverName,'Friction should be linear or Weertman')
287
END SELECT
288
289
290
NodalBeta(1:n) = ListGetReal( Material, 'SSA Friction Parameter', n, NodeIndexes,UnFoundFatal=.TRUE.)
291
IF (iFriction > 1) THEN
292
fm = ListGetConstReal( Material, 'SSA Friction Exponent', UnFoundFatal=.TRUE.)
293
LocalLinVelo = 0.0_dp
294
LocalLinVelo(1:n) = ListGetReal(Material, 'SSA Friction Linear Velocity', n, NodeIndexes,UnFoundFatal=.TRUE.)
295
END IF
296
297
IF (SEP) THEN
298
NodalGM(1:n)=GMSol%Values(GMSol%Perm(NodeIndexes(1:n)))
299
NodalBed(1:n)=BedrockSol%Values(BedrockSol%Perm(NodeIndexes(1:n)))
300
ENDIF
301
302
! Get the Nodal value of Zb and Zs
303
NodalZb(1:n) = Zb(ZbPerm(NodeIndexes(1:n)))
304
NodalZs(1:n) = Zs(ZsPerm(NodeIndexes(1:n)))
305
306
! Previous Velocity
307
NodalU(1:n) = VariableValues(STDOFs*(Permutation(NodeIndexes(1:n))-1)+1)
308
NodalV = 0.0
309
IF (STDOFs.EQ.2) NodalV(1:n) = VariableValues(STDOFs*(Permutation(NodeIndexes(1:n))-1)+2)
310
311
312
CALL LocalMatrixUVSSA ( STIFF, FORCE, Element, n, ElementNodes, NodalGravity, &
313
NodalDensity, NodalViscosity, NodalZb, NodalZs,&
314
NodalU, NodalV, NodalBeta,iFriction,fm,LocalLinVelo, cn,&
315
NodalGM,NodalBed,SEP,GLnIP,sealevel,rhow,&
316
MinSRInv , STDOFs, Newton)
317
318
CALL DefaultUpdateEquations( STIFF, FORCE )
319
320
END DO
321
CALL DefaultFinishBulkAssembly()
322
323
!
324
! Neumann condition
325
!
326
DO t=1,GetNOFBoundaryElements()
327
BoundaryElement => GetBoundaryElement(t)
328
IF ( .NOT. ActiveBoundaryElement() ) CYCLE
329
IF ( GetElementFamily() == 1 ) CYCLE
330
331
NodeIndexes => BoundaryElement % NodeIndexes
332
IF (ParEnv % myPe .NE. BoundaryElement % partIndex) CYCLE
333
334
n = GetElementNOFNodes()
335
FORCE = 0.0e0
336
STIFF = 0.0e0
337
338
! set coords of highest occurring dimension to zero (to get correct path element)
339
!-------------------------------------------------------------------------------
340
ElementNodes % x(1:n) = Solver % Mesh % Nodes % x(NodeIndexes)
341
IF (STDOFs == 1) THEN
342
ElementNodes % y(1:n) = 0.0_dp
343
ElementNodes % z(1:n) = 0.0_dp
344
ELSE IF (STDOFs == 2) THEN
345
ElementNodes % y(1:n) = Solver % Mesh % Nodes % y(NodeIndexes)
346
ElementNodes % z(1:n) = 0.0_dp
347
ELSE
348
WRITE(Message,'(a,i1,a)')&
349
'It is not possible to compute SSA with SSA var DOFs=',&
350
STDOFs, '. Aborting'
351
CALL Fatal( SolverName, Message)
352
STOP
353
END IF
354
355
356
BC => GetBC()
357
IF (.NOT.ASSOCIATED( BC ) ) CYCLE
358
359
! Find the nodes for which 'Calving Front' = True
360
CalvingFront=.False.
361
CalvingFront = ListGetLogical( BC, 'Calving Front', GotIt )
362
IF (CalvingFront) THEN
363
NodalZs(1:n) = Zs(ZsPerm(NodeIndexes(1:n)))
364
NodalZb(1:n) = Zb(ZbPerm(NodeIndexes(1:n)))
365
366
! Need to access Parent Element to get Material properties
367
other_body_id = BoundaryElement % BoundaryInfo % outbody
368
IF (other_body_id < 1) THEN ! only one body in calculation
369
ParentElement => BoundaryElement % BoundaryInfo % Right
370
IF ( .NOT. ASSOCIATED(ParentElement) ) ParentElement => BoundaryElement % BoundaryInfo % Left
371
ELSE ! we are dealing with a body-body boundary and assume that the normal is pointing outwards
372
ParentElement => BoundaryElement % BoundaryInfo % Right
373
IF (ParentElement % BodyId == other_body_id) ParentElement => BoundaryElement % BoundaryInfo % Left
374
END IF
375
376
! Read Density in the Material Section
377
Material => GetMaterial(ParentElement)
378
379
NodalDensity=0.0_dp
380
NodalDensity(1:n) = ListGetReal( Material, 'SSA Mean Density',n, NodeIndexes,UnFoundFatal=.TRUE.)
381
382
! Read the gravity in the Body Force Section
383
BodyForce => GetBodyForce(ParentElement)
384
NodalGravity = 0.0_dp
385
IF ( ASSOCIATED( BodyForce ) ) THEN
386
IF (STDOFs==1) THEN
387
NodalGravity(1:n) = ListGetReal( &
388
BodyForce, 'Flow BodyForce 2', n, NodeIndexes,UnFoundFatal=.TRUE.)
389
ELSE
390
NodalGravity(1:n) = ListGetReal( &
391
BodyForce, 'Flow BodyForce 3', n, NodeIndexes,UnFoundFatal=.TRUE.)
392
END IF
393
END IF
394
395
CALL LocalMatrixBCSSA( STIFF, FORCE, BoundaryElement, n, ElementNodes,&
396
NodalDensity, NodalGravity, NodalZb, NodalZs, rhow, sealevel )
397
CALL DefaultUpdateEquations( STIFF, FORCE )
398
END IF
399
END DO
400
401
CALL DefaultFinishAssembly()
402
403
! Dirichlet
404
CALL DefaultDirichletBCs()
405
406
407
!------------------------------------------------------------------------------
408
! Solve the system and check for convergence
409
!------------------------------------------------------------------------------
410
PrevUNorm = UNorm
411
412
UNorm = DefaultSolve()
413
414
415
RelativeChange = Solver % Variable % NonlinChange
416
417
WRITE( Message, * ) 'Result Norm : ', UNorm, PrevUNorm
418
CALL Info(SolverName, Message, Level=4 )
419
WRITE( Message, * ) 'Relative Change : ', RelativeChange
420
CALL Info(SolverName, Message, Level=4 )
421
422
423
IF ( RelativeChange < NewtonTol .OR. &
424
iter > NewtonIter ) Newton = .TRUE.
425
426
!------------------------------------------------------------------------------
427
IF ( RelativeChange < NonLinearTol ) EXIT
428
!------------------------------------------------------------------------------
429
430
END DO ! Loop Non-Linear Iterations
431
432
CONTAINS
433
434
!------------------------------------------------------------------------------
435
SUBROUTINE LocalMatrixUVSSA( STIFF, FORCE, Element, n, Nodes, gravity, &
436
Density, Viscosity, LocalZb, LocalZs, LocalU, &
437
LocalV, LocalBeta,iFriction,fm,LocalLinVelo, cm,&
438
NodalGM,NodalBed,SEP,GLnIP,sealevel,rhow,&
439
MinSRInv, STDOFs , Newton )
440
!------------------------------------------------------------------------------
441
REAL(KIND=dp) :: STIFF(:,:), FORCE(:), gravity(:), Density(:), &
442
Viscosity(:), LocalZb(:), LocalZs(:), &
443
LocalU(:), LocalV(:) , LocalBeta(:), LocalLinVelo(:)
444
INTEGER :: n, cp , STDOFs
445
INTEGER :: iFriction
446
REAL(KIND=dp) :: cm,fm
447
TYPE(Element_t), POINTER :: Element
448
LOGICAL :: Newton
449
REAL(KIND=dp) :: NodalGM(:),NodalBed(:)
450
REAL(KIND=dp) :: sealevel,rhow
451
LOGICAL :: SEP
452
INTEGER :: GLnIP
453
!------------------------------------------------------------------------------
454
REAL(KIND=dp) :: Basis(n), dBasisdx(n,3), ddBasisddx(n,3,3), detJ
455
REAL(KIND=dp) :: g, rho, eta, h, dhdx, dhdy , muder, bedrock,Hf
456
REAL(KIND=dp) :: gradS(2),Slip,A(2,2), StrainA(2,2),StrainB(2,2), Exx, Eyy, Exy, Ezz, Ee, MinSRInv
457
REAL(KIND=dp) :: beta,Slip2,Velo(2),LinVelo,ub
458
REAL(KIND=dp) :: Jac(2*n,2*n),SOL(2*n)
459
LOGICAL :: Stat, NewtonLin,fNewtonLin
460
INTEGER :: i, j, t, p, q , dim
461
TYPE(GaussIntegrationPoints_t) :: IP
462
LOGICAL :: PartlyGroundedElement
463
464
TYPE(Nodes_t) :: Nodes
465
!------------------------------------------------------------------------------
466
dim = CoordinateSystemDimension()
467
468
STIFF = 0.0d0
469
FORCE = 0.0d0
470
Jac=0.0d0
471
472
! Use Newton Linearisation
473
NewtonLin=(Newton.AND.(cm.NE.1.0_dp))
474
fNewtonLin = (Newton.AND.(fm.NE.1.0_dp))
475
476
IF (SEP) THEN
477
PartlyGroundedElement=(ANY(NodalGM(1:n).GE.0._dp).AND.ANY(NodalGM(1:n).LT.0._dp))
478
IF (PartlyGroundedElement) THEN
479
IP = GaussPoints( Element , np=GLnIP )
480
ELSE
481
IP = GaussPoints( Element )
482
ENDIF
483
ELSE
484
IP = GaussPoints( Element )
485
ENDIF
486
487
DO t=1,IP % n
488
stat = ElementInfo( Element, Nodes, IP % U(t), IP % V(t), &
489
IP % W(t), detJ, Basis, dBasisdx, ddBasisddx, .FALSE. )
490
491
! Needed Integration Point value
492
493
g = ABS(SUM( Gravity(1:n) * Basis(1:n) ))
494
rho = SUM( Density(1:n) * Basis(1:n) )
495
eta = SUM( Viscosity(1:n) * Basis(1:n) )
496
gradS = 0._dp
497
gradS(1) = SUM( LocalZs(1:n) * dBasisdx(1:n,1) )
498
if (STDOFs == 2) gradS(2) = SUM( LocalZs(1:n) * dBasisdx(1:n,2) )
499
h = SUM( (LocalZs(1:n)-LocalZb(1:n)) * Basis(1:n) )
500
501
beta = SUM( LocalBeta(1:n) * Basis(1:n) )
502
IF (SEP) THEN
503
IF (ALL(NodalGM(1:n).LT.0._dp)) THEN
504
beta=0._dp
505
ELSE IF (PartlyGroundedElement) THEN
506
bedrock = SUM( NodalBed(1:n) * Basis(1:n) )
507
Hf= rhow * (sealevel-bedrock) / rho
508
if (h.lt.Hf) beta=0._dp
509
END IF
510
END IF
511
512
IF (iFriction > 1) THEN
513
LinVelo = SUM( LocalLinVelo(1:n) * Basis(1:n) )
514
IF ((iFriction == 2).AND.(fm==1.0_dp)) iFriction=1
515
Velo = 0.0_dp
516
Velo(1) = SUM(LocalU(1:n) * Basis(1:n))
517
IF (STDOFs == 2) Velo(2) = SUM(LocalV(1:n) * Basis(1:n))
518
ub = SQRT(Velo(1)*Velo(1)+Velo(2)*Velo(2))
519
Slip2=1.0_dp
520
IF (ub < LinVelo) then
521
ub = LinVelo
522
Slip2=0.0_dp
523
ENDIF
524
END IF
525
IF (iFriction==1) THEN
526
Slip = beta
527
fNewtonLin = .FALSE.
528
ELSE IF (iFriction==2) THEN
529
Slip = beta * ub**(fm-1.0_dp)
530
Slip2 = Slip2*Slip*(fm-1.0_dp)/(ub*ub)
531
END IF
532
533
534
!------------------------------------------------------------------------------
535
! In the non-linear case, effective viscosity
536
IF (cm.NE.1.0_dp) THEN
537
Exx = SUM(LocalU(1:n)*dBasisdx(1:n,1))
538
Eyy = 0.0
539
Exy = 0.0
540
IF (STDOFs.EQ.2) THEN
541
Eyy = SUM(LocalV(1:n)*dBasisdx(1:n,2))
542
Ezz = -Exx - Eyy
543
Exy = SUM(LocalU(1:n)*dBasisdx(1:n,2))
544
Exy = 0.5*(Exy + SUM(LocalV(1:n)*dBasisdx(1:n,1)))
545
Ee = 0.5*(Exx**2.0 + Eyy**2.0 + Ezz**2.0) + Exy**2.0
546
!Ee = SQRT(Ee)
547
ELSE
548
!Ee = ABS(Exx)
549
Ee = Exx * Exx
550
END IF
551
muder = eta * 0.5 * (2**cm) * ((cm-1.0)/2.0) * Ee**((cm-1.0)/2.0 - 1.0)
552
IF (sqrt(Ee) < MinSRInv) then
553
Ee = MinSRInv*MinSRInv
554
muder = 0.0_dp
555
Endif
556
eta = eta * 0.5 * (2**cm) * Ee**((cm-1.0)/2.0)
557
END IF
558
559
StrainA=0.0_dp
560
StrainB=0.0_dp
561
If (NewtonLin) then
562
StrainA(1,1)=SUM(2.0*dBasisdx(1:n,1)*LocalU(1:n))
563
564
IF (STDOFs.EQ.2) THEN
565
StrainB(1,1)=SUM(0.5*dBasisdx(1:n,2)*LocalU(1:n))
566
567
StrainA(1,2)=SUM(dBasisdx(1:n,2)*LocalV(1:n))
568
StrainB(1,2)=SUM(0.5*dBasisdx(1:n,1)*LocalV(1:n))
569
570
StrainA(2,1)=SUM(dBasisdx(1:n,1)*LocalU(1:n))
571
StrainB(2,1)=SUM(0.5*dBasisdx(1:n,2)*LocalU(1:n))
572
573
StrainA(2,2)=SUM(2.0*dBasisdx(1:n,2)*LocalV(1:n))
574
StrainB(2,2)=SUM(0.5*dBasisdx(1:n,1)*LocalV(1:n))
575
576
End if
577
Endif
578
579
A = 0.0_dp
580
DO p=1,n
581
DO q=1,n
582
A(1,1) = 2.0*dBasisdx(q,1)*dBasisdx(p,1)
583
IF (STDOFs.EQ.2) THEN
584
A(1,1) = A(1,1) + 0.5*dBasisdx(q,2)*dBasisdx(p,2)
585
A(1,2) = dBasisdx(q,2)*dBasisdx(p,1) + &
586
0.5*dBasisdx(q,1)*dBasisdx(p,2)
587
A(2,1) = dBasisdx(q,1)*dBasisdx(p,2) + &
588
0.5*dBasisdx(q,2)*dBasisdx(p,1)
589
A(2,2) = 2.0*dBasisdx(q,2)*dBasisdx(p,2) +&
590
0.5*dBasisdx(q,1)*dBasisdx(p,1)
591
END IF
592
A = 2.0 * h * eta * A
593
DO i=1,STDOFs
594
STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+i) = STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+i) +&
595
slip * Basis(q) * Basis(p) * IP % S(t) * detJ
596
DO j=1,STDOFs
597
STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) = STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) +&
598
A(i,j) * IP % S(t) * detJ
599
END DO
600
END DO
601
602
IF ((fNewtonLin).AND.(iFriction > 1)) THEN
603
DO i=1,STDOFs
604
Do j=1,STDOFs
605
STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) = STIFF((STDOFs)*(p-1)+i,(STDOFs)*(q-1)+j) +&
606
Slip2 * Velo(i) * Velo(j) * Basis(q) * Basis(p) * IP % S(t) * detJ
607
End do
608
END DO
609
END IF
610
611
If (NewtonLin) then
612
! Maybe a more elegant formulation to get the Jacobian??.......
613
IF (STDOFs.EQ.1) THEN
614
Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) = Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) +&
615
IP % S(t) * detJ * 2.0 * h * StrainA(1,1)*dBasisdx(p,1) * &
616
muder * 2.0 * Exx*dBasisdx(q,1)
617
618
ELSE IF (STDOFs.EQ.2) THEN
619
Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) = Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+1) +&
620
IP % S(t) * detJ * 2.0 * h * ((StrainA(1,1)+StrainA(1,2))*dBasisdx(p,1)+(StrainB(1,1)+StrainB(1,2))*dBasisdx(p,2)) * &
621
muder *((2.0*Exx+Eyy)*dBasisdx(q,1)+Exy*dBasisdx(q,2))
622
623
Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+2) = Jac((STDOFs)*(p-1)+1,(STDOFs)*(q-1)+2) +&
624
IP % S(t) * detJ * 2.0 * h * ((StrainA(1,1)+StrainA(1,2))*dBasisdx(p,1)+(StrainB(1,1)+StrainB(1,2))*dBasisdx(p,2)) * &
625
muder *((2.0*Eyy+Exx)*dBasisdx(q,2)+Exy*dBasisdx(q,1))
626
627
Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+1) = Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+1) +&
628
IP % S(t) * detJ * 2.0 * h * ((StrainA(2,1)+StrainA(2,2))*dBasisdx(p,2)+(StrainB(2,1)+StrainB(2,2))*dBasisdx(p,1)) * &
629
muder *((2.0*Exx+Eyy)*dBasisdx(q,1)+Exy*dBasisdx(q,2))
630
631
Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+2) = Jac((STDOFs)*(p-1)+2,(STDOFs)*(q-1)+2) +&
632
IP % S(t) * detJ * 2.0 * h * ((StrainA(2,1)+StrainA(2,2))*dBasisdx(p,2)+(StrainB(2,1)+StrainB(2,2))*dBasisdx(p,1)) * &
633
muder *((2.0*Eyy+Exx)*dBasisdx(q,2)+Exy*dBasisdx(q,1))
634
End if
635
Endif
636
637
END DO
638
639
DO i=1,STDOFs
640
FORCE((STDOFs)*(p-1)+i) = FORCE((STDOFs)*(p-1)+i) - &
641
rho*g*h*gradS(i) * IP % s(t) * detJ * Basis(p)
642
END DO
643
644
IF ((fNewtonLin).AND.(iFriction>1)) THEN
645
DO i=1,STDOFs
646
FORCE((STDOFs)*(p-1)+i) = FORCE((STDOFs)*(p-1)+i) + &
647
Slip2 * Velo(i) * ub * ub * IP % s(t) * detJ * Basis(p)
648
END DO
649
END IF
650
651
END DO
652
END DO
653
654
If (NewtonLin) then
655
SOL(1:STDOFs*n:STDOFs)=LocalU(1:n)
656
If (STDOFs.EQ.2) SOL(2:STDOFs*n:STDOFs)=LocalV(1:n)
657
658
STIFF(1:STDOFs*n,1:STDOFs*n) = STIFF(1:STDOFs*n,1:STDOFs*n) + &
659
Jac(1:STDOFs*n,1:STDOFs*n)
660
FORCE(1:STDOFs*n) = FORCE(1:STDOFs*n) + &
661
MATMUL(Jac(1:STDOFs*n,1:STDOFs*n),SOL(1:STDOFs*n))
662
Endif
663
!------------------------------------------------------------------------------
664
END SUBROUTINE LocalMatrixUVSSA
665
!------------------------------------------------------------------------------
666
667
!------------------------------------------------------------------------------
668
SUBROUTINE LocalMatrixBCSSA( STIFF, FORCE, Element, n, ENodes, Density, &
669
Gravity, LocalZb, LocalZs, rhow, sealevel)
670
!------------------------------------------------------------------------------
671
TYPE(Element_t), POINTER :: Element
672
TYPE(Nodes_t) :: ENodes
673
REAL(KIND=dp) :: STIFF(:,:), FORCE(:), density(:), Gravity(:), LocalZb(:),&
674
LocalZs(:),rhow, sealevel
675
INTEGER :: n
676
!------------------------------------------------------------------------------
677
REAL(KIND=dp) :: Basis(n),dBasisdx(n,3),ddBasisddx(n,3,3), &
678
DetJ,Normal(3), rhoi, g, alpha, h, h_im,norm
679
LOGICAL :: Stat
680
INTEGER :: t, i
681
TYPE(GaussIntegrationPoints_t) :: IP
682
683
!------------------------------------------------------------------------------
684
STIFF = 0.0d0
685
FORCE = 0.0d0
686
687
! The front force is a concentrated nodal force in 1D-SSA and
688
! a force distributed along a line in 2D-SSA
689
690
! 1D-SSA Case : concentrated force at each nodes
691
IF (STDOFs==1) THEN !1D SSA but should be 2D problem (does elmer work in 1D?)
692
DO i = 1, n
693
g = ABS( Gravity(i) )
694
rhoi = Density(i)
695
h = LocalZs(i)-LocalZb(i)
696
h_im=max(0._dp,sealevel-LocalZb(i))
697
alpha=0.5 * g * (rhoi * h**2.0 - rhow * h_im**2.0)
698
FORCE(i) = FORCE(i) + alpha
699
END DO
700
701
! 2D-SSA Case : force distributed along the line
702
! This will work in DIM=3D only if working with Extruded Mesh and Preserve
703
! Baseline as been set to True to keep the 1D-BC
704
ELSE IF (STDOFs==2) THEN
705
706
IP = GaussPoints( Element )
707
DO t=1,IP % n
708
stat = ElementInfo( Element, ENodes, IP % U(t), IP % V(t), &
709
IP % W(t), detJ, Basis, dBasisdx, ddBasisddx, .FALSE. )
710
711
g = ABS(SUM( Gravity(1:n) * Basis(1:n) ))
712
rhoi = SUM( Density(1:n) * Basis(1:n) )
713
h = SUM( (LocalZs(1:n)-LocalZb(1:n)) * Basis(1:n))
714
h_im = max(0.0_dp , SUM( (sealevel-LocalZb(1:n)) * Basis(1:n)) )
715
alpha=0.5 * g * (rhoi * h**2.0 - rhow * h_im**2.0)
716
717
! Normal in the (x,y) plane
718
Normal = NormalVector( Element, ENodes, IP % U(t), IP % V(t), .TRUE.)
719
norm=SQRT(normal(1)**2.0+normal(2)**2.0)
720
Normal(1) = Normal(1)/norm
721
Normal(2) = Normal(2)/norm
722
723
DO p=1,n
724
DO i=1,STDOFs
725
FORCE(STDOFs*(p-1)+i) = FORCE(STDOFs*(p-1)+i) +&
726
alpha * Normal(i) * IP % s(t) * detJ * Basis(p)
727
END DO
728
END DO
729
END DO
730
731
ELSE
732
733
CALL FATAL('SSASolver-SSABasalSolver','Do not work for STDOFs <> 1 or 2')
734
735
END IF
736
!------------------------------------------------------------------------------
737
END SUBROUTINE LocalMatrixBCSSA
738
739
740
!------------------------------------------------------------------------------
741
END SUBROUTINE AdjointSSA_SSASolver
742
!------------------------------------------------------------------------------
743
744
745