Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/FrontDisplacement.F90
3203 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer, A Finite Element Software for Multiphysical Problems
4
! *
5
! * Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
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
! *
26
! * Slightly modified version of MeshSolve.F90 for computing mesh update for
27
! * 2D calving simulations. The main difference is that this solver stores
28
! * the initial model mesh (Mesh0) and computes displacements relative to this
29
! * mesh, to avoid the progressive mesh degeneracy associated with repeated
30
! * calls to Mesh Update.
31
! *
32
33
!/******************************************************************************
34
! *
35
! * Authors: Juha Ruokolainen, Joe Todd
36
! * Email: [email protected]
37
! * Web: http://www.csc.fi/elmer
38
! * Address: CSC - IT Center for Science Ltd.
39
! * Keilaranta 14
40
! * 02101 Espoo, Finland
41
! *
42
! * Original Date: 10 May 2000
43
! *
44
! *****************************************************************************/
45
46
!------------------------------------------------------------------------------
47
!> Initialization for the primary solver i.e. MeshSolver.
48
!------------------------------------------------------------------------------
49
SUBROUTINE FDMeshSolver_Init( Model,Solver,dt,TransientSimulation )
50
!------------------------------------------------------------------------------
51
USE DefUtils
52
IMPLICIT NONE
53
!------------------------------------------------------------------------------
54
TYPE(Model_t) :: Model
55
TYPE(Solver_t), TARGET :: Solver
56
LOGICAL :: TransientSimulation
57
REAL(KIND=dp) :: dt
58
!------------------------------------------------------------------------------
59
TYPE(ValueList_t), POINTER :: Params
60
INTEGER :: dim
61
LOGICAL :: Found, Calculate
62
63
Params => Solver % Values
64
dim = CoordinateSystemDimension()
65
66
Calculate = ListGetLogical( Params,'Compute Front Displacement Velocity',Found )
67
IF(.NOT. Found ) Calculate = .TRUE.
68
69
IF( Calculate ) THEN
70
IF( TransientSimulation ) THEN
71
IF( dim == 2 ) THEN
72
CALL ListAddString( Params,&
73
NextFreeKeyword('Exported Variable',Params),&
74
'-dofs 2 Front Displacement Velocity')
75
ELSE
76
CALL ListAddString( Params,&
77
NextFreeKeyword('Exported Variable',Params),&
78
'-dofs 3 Front Displacement Velocity')
79
END IF
80
END IF
81
END IF
82
83
END SUBROUTINE FDMeshSolver_Init
84
85
86
!------------------------------------------------------------------------------
87
!> Subroutine for extending displacement in mesh smoothly over
88
!> the domain. The intended use of the solver is in fluid-structure interaction,
89
!> for example. In transient cases the solver also computes the mesh velocity.
90
!> This is a dynamically loaded solver with a standard interface.
91
!> May be also loaded internally to mimic the old static implementation.
92
!> \ingroup Solvers
93
94
!This has been modified by Joe Todd as a secondary mesh displacement solver for
95
!calving events.
96
!------------------------------------------------------------------------------
97
SUBROUTINE FDMeshSolver( Model,Solver,dt,TransientSimulation )
98
!------------------------------------------------------------------------------
99
USE DefUtils
100
IMPLICIT NONE
101
!------------------------------------------------------------------------------
102
TYPE(Model_t) :: Model
103
TYPE(Solver_t), TARGET :: Solver
104
LOGICAL :: TransientSimulation
105
REAL(KIND=dp) :: dt
106
!------------------------------------------------------------------------------
107
! Local variables
108
!------------------------------------------------------------------------------
109
INTEGER :: i,j,k,n,nd,nb,t,STDOFs,LocalNodes,istat,NoNodes
110
111
TYPE(Element_t),POINTER :: Element
112
TYPE(ValueList_t),POINTER :: Material, BC
113
TYPE(Mesh_t),POINTER :: Mesh0 => Null()
114
TYPE(Nodes_t),POINTER :: Nodes0
115
REAL(KIND=dp) :: RelativeChange, UNorm, PrevUNorm, maxu
116
117
TYPE(Variable_t), POINTER :: MeshSol, InitXVar, InitYVar
118
119
REAL(KIND=dp), POINTER :: MeshUpdate(:), MeshVelocity(:)
120
121
INTEGER, POINTER :: MeshPerm(:)
122
123
LOGICAL :: AllocationsDone = .FALSE., Isotropic = .TRUE., &
124
GotForceBC, Found, ComputeMeshVelocity, FirstTime = .TRUE.
125
126
REAL(KIND=dp),ALLOCATABLE:: STIFF(:,:),&
127
LOAD(:,:),FORCE(:), ElasticModulus(:,:,:),PoissonRatio(:), &
128
Alpha(:,:), Beta(:)
129
130
SAVE STIFF, LOAD, FORCE, MeshVelocity, AllocationsDone, &
131
ElasticModulus, PoissonRatio, Alpha, Beta, FirstTime, &
132
Mesh0, Nodes0
133
134
!------------------------------------------------------------------------------
135
REAL(KIND=dp) :: at,at0
136
!------------------------------------------------------------------------------
137
138
!------------------------------------------------------------------------------
139
! Get variables needed for solution
140
!------------------------------------------------------------------------------
141
IF ( .NOT. ASSOCIATED( Solver % Matrix ) ) RETURN
142
143
NULLIFY( MeshVelocity )
144
IF ( TransientSimulation ) THEN
145
MeshSol => VariableGet( Solver % Mesh % Variables, 'Front Displacement Velocity' )
146
IF( ASSOCIATED( MeshSol ) ) THEN
147
MeshVelocity => MeshSol % Values
148
END IF
149
END IF
150
151
MeshSol => Solver % Variable
152
MeshPerm => MeshSol % Perm
153
STDOFs = MeshSol % DOFs
154
MeshUpdate => MeshSol % Values
155
156
LocalNodes = COUNT( MeshPerm > 0 )
157
IF ( LocalNodes <= 0 ) RETURN
158
159
!------------------------------------------------------------------------------
160
161
UNorm = Solver % Variable % Norm
162
163
IF(FirstTime) THEN
164
FirstTime = .FALSE.
165
166
InitXVar => VariableGet( Solver % Mesh % Variables, "InitX", UnfoundFatal=.TRUE.)
167
InitYVar => VariableGet( Solver % Mesh % Variables, "InitY", UnfoundFatal=.TRUE.)
168
169
NoNodes = Solver % Mesh % NumberOfNodes
170
ALLOCATE( Nodes0 )
171
ALLOCATE( Nodes0 % x(NoNodes), Nodes0 % y(NoNodes),Nodes0 % z(NoNodes))
172
DO i=1,NoNodes
173
Nodes0 % x(i) = Solver % Mesh % Nodes % x(i)
174
Nodes0 % y(i) = Solver % Mesh % Nodes % y(i)
175
176
!Save initial coordinates to variables too, for dirichlet condition
177
InitXVar % Values(InitXVar % Perm(i)) = Solver % Mesh % Nodes % x(i)
178
InitYVar % Values(InitYVar % Perm(i)) = Solver % Mesh % Nodes % y(i)
179
END DO
180
181
Mesh0 => AllocateMesh()
182
Mesh0 = Solver % Mesh
183
Mesh0 % Nodes => Nodes0
184
Mesh0 % Name = TRIM(Solver % Mesh % Name)//'_reference'
185
186
CALL INFO('FrontDisplacement','Saved the initial mesh for remeshing')
187
END IF
188
Solver % Mesh => Mesh0
189
190
191
!------------------------------------------------------------------------------
192
! Allocate some permanent storage, this is done first time only
193
!------------------------------------------------------------------------------
194
IF ( .NOT. AllocationsDone .OR. Solver % Mesh % Changed ) THEN
195
N = Solver % Mesh % MaxElementDOFs
196
197
IF ( AllocationsDone ) THEN
198
DEALLOCATE( ElasticModulus, PoissonRatio, &
199
FORCE, Alpha, Beta, STIFF, LOAD, STAT=istat )
200
END IF
201
202
ALLOCATE( &
203
Alpha(3,N), Beta(N), &
204
ElasticModulus( 6,6,N ), PoissonRatio( N ), &
205
FORCE( STDOFs*N ), STIFF( STDOFs*N,STDOFs*N ), &
206
LOAD( 4,N ),STAT=istat )
207
208
IF ( istat /= 0 ) THEN
209
CALL Fatal( 'MeshSolve', 'Memory allocation error.' )
210
END IF
211
212
!------------------------------------------------------------------------------
213
AllocationsDone = .TRUE.
214
!------------------------------------------------------------------------------
215
END IF
216
!------------------------------------------------------------------------------
217
!------------------------------------------------------------------------------
218
! Do some additional initialization, and go for it
219
!------------------------------------------------------------------------------
220
at = CPUTime()
221
at0 = RealTime()
222
223
CALL Info( 'MeshSolve', ' ', Level=4 )
224
CALL Info( 'MeshSolve', '-------------------------------------', Level=4 )
225
CALL Info( 'MeshSolve', 'MESH UPDATE SOLVER:', Level=4 )
226
CALL Info( 'MeshSolve', '-------------------------------------', Level=4 )
227
CALL Info( 'MeshSolve', ' ', Level=4 )
228
CALL Info( 'MeshSolve', 'Starting assembly...', Level=4 )
229
!------------------------------------------------------------------------------
230
CALL DefaultInitialize()
231
!------------------------------------------------------------------------------
232
DO t=1,Solver % NumberOfActiveElements
233
234
IF ( RealTime() - at0 > 1.0 ) THEN
235
WRITE(Message,'(a,i3,a)' ) ' Assembly: ', INT(100.0 - 100.0 * &
236
(Solver % NumberOfActiveElements-t) / &
237
(1.0*Solver % NumberOfActiveElements)), ' % done'
238
239
CALL Info( 'MeshSolve', Message, Level=5 )
240
241
at0 = RealTime()
242
END IF
243
244
Element => GetActiveElement(t)
245
nd = GetElementNOFDOFs()
246
nb = GetElementNOFBDOFs()
247
n = GetElementNOFNodes()
248
249
Material => GetMaterial()
250
251
ElasticModulus(1,1,1:n) = GetReal( Material, &
252
'Mesh Elastic Modulus', Found )
253
IF ( .NOT. Found ) THEN
254
ElasticModulus(1,1,1:n) = GetReal( Material, &
255
'Youngs Modulus', Found )
256
END IF
257
IF ( .NOT. Found ) ElasticModulus(1,1,1:n) = 1.0d0
258
259
PoissonRatio(1:n) = GetReal( Material, &
260
'Mesh Poisson Ratio', Found )
261
IF ( .NOT. Found ) THEN
262
PoissonRatio(1:n) = GetReal( Material, &
263
'Poisson Ratio', Found )
264
END IF
265
IF ( .NOT. Found ) PoissonRatio(1:n) = 0.25d0
266
267
!------------------------------------------------------------------------------
268
! Get element local stiffness & mass matrices
269
!------------------------------------------------------------------------------
270
CALL LocalMatrix( STIFF, FORCE, ElasticModulus, &
271
PoissonRatio, .FALSE., Isotropic, Element, n, nd, nb )
272
273
!------------------------------------------------------------------------------
274
! Update global matrices from local matrices
275
!------------------------------------------------------------------------------
276
CALL DefaultUpdateEquations( STIFF, FORCE )
277
END DO
278
279
280
!------------------------------------------------------------------------------
281
! Neumann & Newton boundary conditions
282
!------------------------------------------------------------------------------
283
DO t = 1, Solver % Mesh % NumberOfBoundaryElements
284
285
Element => GetBoundaryElement(t)
286
IF ( .NOT.ActiveBoundaryElement() ) CYCLE
287
IF ( GetElementFamily() == 1 ) CYCLE
288
289
BC => GetBC()
290
IF ( .NOT. ASSOCIATED(BC) ) CYCLE
291
292
!------------------------------------------------------------------------------
293
! Force in given direction BC: \tau\cdot n = F
294
!------------------------------------------------------------------------------
295
nd = GetElementNOFDOFs()
296
n = GetElementNOFNodes()
297
nb = GetElementNOFBDOFs()
298
299
LOAD = 0.0D0
300
Alpha = 0.0D0
301
Beta = 0.0D0
302
303
GotForceBC = .FALSE.
304
LOAD(1,1:n) = GetReal( BC, 'Mesh Force 1', Found )
305
GotForceBC = GotForceBC.OR.Found
306
LOAD(2,1:n) = GetReal( BC, 'Mesh Force 2', Found )
307
GotForceBC = GotForceBC.OR.Found
308
LOAD(3,1:n) = GetReal( BC, 'Mesh Force 3', Found )
309
GotForceBC = GotForceBC.OR.Found
310
311
Beta(1:n) = GetReal( BC, 'Mesh Normal Force',Found )
312
GotForceBC = GotForceBC.OR.Found
313
314
IF ( .NOT.GotForceBC ) CYCLE
315
316
CALL MeshBoundary( STIFF,FORCE, LOAD,Alpha,Beta,Element,n,nd,nb )
317
318
!------------------------------------------------------------------------------
319
320
CALL DefaultUpdateEquations( STIFF, FORCE )
321
END DO
322
!------------------------------------------------------------------------------
323
324
CALL DefaultFinishAssembly()
325
CALL Info( 'MeshSolve', 'Assembly done', Level=4 )
326
327
!------------------------------------------------------------------------------
328
! Dirichlet boundary conditions
329
!------------------------------------------------------------------------------
330
CALL DefaultDirichletBCs()
331
332
!------------------------------------------------------------------------------
333
CALL Info( 'MeshSolve', 'Set boundaries done', Level=4 )
334
!------------------------------------------------------------------------------
335
! Solve the system and check for convergence
336
!------------------------------------------------------------------------------
337
PrevUNorm = UNorm
338
339
UNorm = DefaultSolve()
340
341
IF ( UNorm + PrevUNorm /= 0.0d0 ) THEN
342
RelativeChange = 2*ABS( PrevUNorm - UNorm ) / (PrevUNorm + UNorm)
343
ELSE
344
RelativeChange = 0.0d0
345
END IF
346
347
WRITE( Message, * ) 'Result Norm : ',UNorm
348
CALL Info( 'MeshSolve', Message, Level=4 )
349
WRITE( Message, * ) 'Relative Change : ',RelativeChange
350
CALL Info( 'MeshSolve', Message, Level=4 )
351
352
353
IF ( TransientSimulation ) THEN
354
ComputeMeshVelocity = ListGetLogical( Solver % Values, 'Compute Front Displacement Velocity', Found )
355
IF ( .NOT. Found ) ComputeMeshVelocity = .TRUE.
356
357
IF ( ComputeMeshVelocity ) THEN
358
k = MIN( SIZE(Solver % Variable % PrevValues,2), Solver % DoneTime )
359
360
j = ListGetInteger( Solver % Values,'Compute Front Displacement Velocity Order', Found)
361
IF( Found ) THEN
362
k = MIN( k, j )
363
ELSE
364
k = 1
365
END IF
366
367
SELECT CASE(k)
368
CASE(0)
369
MeshVelocity = 0._dp
370
CASE(1)
371
MeshVelocity = ( MeshUpdate - Solver % Variable % PrevValues(:,1) ) / dt
372
CASE(2)
373
MeshVelocity = ( &
374
MeshUpdate - (4.0d0/3.0d0)*Solver % Variable % PrevValues(:,1) &
375
+ (1.0d0/3.0d0)*Solver % Variable % PrevValues(:,2) ) / dt
376
CASE DEFAULT
377
MeshVelocity = ( &
378
MeshUpdate - (18.0d0/11.0d0)*Solver % Variable % PrevValues(:,1) &
379
+ ( 9.0d0/11.0d0)*Solver % Variable % PrevValues(:,2) &
380
- ( 2.0d0/11.0d0)*Solver % Variable % PrevValues(:,3) ) / dt
381
END SELECT
382
383
ELSE IF( ASSOCIATED( MeshVelocity ) ) THEN
384
MeshVelocity = 0.0d0
385
END IF
386
END IF
387
388
Solver % Mesh => Model % Mesh
389
NoNodes = Solver % Mesh % NumberOfNodes
390
391
DO i=1,NoNodes
392
k = MeshPerm(i)
393
IF(k>0) THEN
394
k = 2 * (k-1)
395
MeshUpdate(k+1) = Mesh0 % Nodes % x(i) - Solver % Mesh % Nodes % x(i) + MeshUpdate(k+1)
396
MeshUpdate(k+1) = MIN(MeshUpdate(k+1),0.0_dp) !Ensure <= 0 (epsilon issues)
397
398
MeshUpdate(k+2) = Mesh0 % Nodes % y(i) - Solver % Mesh % Nodes % y(i) + MeshUpdate(k+2)
399
ELSE
400
CALL FATAL('Front Displacement','This is almost certainly a permutation error')
401
END IF
402
END DO
403
404
405
CONTAINS
406
407
!------------------------------------------------------------------------------
408
SUBROUTINE LocalMatrix( STIFF,FORCE,NodalYoung, NodalPoisson, &
409
PlaneStress, Isotropic, Element,n, nd, nb )
410
!------------------------------------------------------------------------------
411
IMPLICIT NONE
412
413
REAL(KIND=dp) :: NodalPoisson(:), NodalYoung(:,:,:)
414
REAL(KIND=dp), TARGET :: STIFF(:,:), FORCE(:)
415
416
INTEGER :: n,nd,nb
417
418
TYPE(Element_t) :: Element
419
LOGICAL :: PlaneStress, Isotropic
420
!------------------------------------------------------------------------------
421
!
422
REAL(KIND=dp) :: Basis(nd)
423
REAL(KIND=dp) :: dBasisdx(nd,3),detJ
424
425
REAL(KIND=dp) :: NodalLame1(n),NodalLame2(n),Lame1,Lame2, &
426
Poisson, Young
427
428
REAL(KIND=dp), POINTER :: A(:,:)
429
REAL(KIND=dp) :: s,u,v,w
430
INTEGER :: i,j,k,p,q,t,dim
431
432
LOGICAL :: stat
433
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
434
435
TYPE(Nodes_t) :: Nodes
436
SAVE Nodes
437
!------------------------------------------------------------------------------
438
439
CALL GetElementNodes( Nodes )
440
dim = CoordinateSystemDimension()
441
442
IF ( PlaneStress ) THEN
443
NodalLame1(1:n) = NodalYoung(1,1,1:n) * NodalPoisson(1:n) / &
444
((1.0d0 - NodalPoisson(1:n)**2))
445
ELSE
446
NodalLame1(1:n) = NodalYoung(1,1,1:n) * NodalPoisson(1:n) / &
447
((1.0d0 + NodalPoisson(1:n)) * (1.0d0 - 2.0d0*NodalPoisson(1:n)))
448
END IF
449
450
NodalLame2(1:n) = NodalYoung(1,1,1:n) / (2* (1.0d0 + NodalPoisson(1:n)))
451
452
STIFF = 0.0d0
453
FORCE = 0.0d0
454
455
! Integration stuff:
456
! ------------------
457
IntegStuff = GaussPoints( Element )
458
459
! Now we start integrating:
460
! -------------------------
461
DO t=1,IntegStuff % n
462
u = IntegStuff % u(t)
463
v = IntegStuff % v(t)
464
w = IntegStuff % w(t)
465
466
! Basis function values & derivatives at the integration point:
467
!--------------------------------------------------------------
468
stat = ElementInfo( Element,Nodes, u, v, w, detJ, &
469
Basis, dBasisdx )
470
471
s = detJ * IntegStuff % s(t)
472
473
! Lame parameters at the integration point:
474
! -----------------------------------------
475
Lame1 = SUM( NodalLame1(1:n)*Basis(1:n) )
476
Lame2 = SUM( NodalLame2(1:n)*Basis(1:n) )
477
478
479
! Loop over basis functions (of both unknowns and weights):
480
! ---------------------------------------------------------
481
DO p=1,nd
482
DO q=p,nd
483
A => STIFF( dim*(p-1)+1:dim*p,dim*(q-1)+1:dim*q )
484
DO i=1,dim
485
DO j = 1,dim
486
A(i,j) = A(i,j) + s * Lame1 * dBasisdx(q,j) * dBasisdx(p,i)
487
A(i,i) = A(i,i) + s * Lame2 * dBasisdx(q,j) * dBasisdx(p,j)
488
A(i,j) = A(i,j) + s * Lame2 * dBasisdx(q,i) * dBasisdx(p,j)
489
END DO
490
END DO
491
END DO
492
END DO
493
END DO
494
495
! Assign the symmetric block:
496
! ---------------------------
497
DO p=1,dim*nd
498
DO q=1,p-1
499
STIFF(p,q)=STIFF(q,p)
500
END DO
501
END DO
502
503
IF ( nb == 0 ) THEN
504
DO p=MAX(n+1,nd-Element % BDOFs+1),nd
505
DO i=1,dim
506
j = (p-1)*dim + i
507
STIFF( j,: ) = 0.0d0
508
STIFF( :,j ) = 0.0d0
509
STIFF( j,j ) = 1.0d0
510
FORCE( j ) = 0.0d0
511
END DO
512
END DO
513
END IF
514
!------------------------------------------------------------------------------
515
END SUBROUTINE LocalMatrix
516
!------------------------------------------------------------------------------
517
518
519
!------------------------------------------------------------------------------
520
SUBROUTINE MeshBoundary( STIFF,FORCE,LOAD,NodalAlpha,NodalBeta,Element,n,nd,nb )
521
!------------------------------------------------------------------------------
522
REAL(KIND=dp) :: STIFF(:,:),FORCE(:)
523
REAL(KIND=dp) :: NodalAlpha(:,:),NodalBeta(:),LOAD(:,:)
524
TYPE(Element_t),POINTER :: Element
525
INTEGER :: n,nd,nb
526
!------------------------------------------------------------------------------
527
REAL(KIND=dp) :: Basis(nd)
528
REAL(KIND=dp) :: dBasisdx(nd,3),detJ
529
530
REAL(KIND=dp) :: u,v,w,s
531
REAL(KIND=dp) :: Alpha(3),Beta,Normal(3),LoadAtIP(3)
532
533
INTEGER :: i,t,q,p,dim
534
535
LOGICAL :: stat
536
537
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
538
539
TYPE(Nodes_t) :: Nodes
540
SAVE Nodes
541
!------------------------------------------------------------------------------
542
543
dim = Element % TYPE % DIMENSION + 1
544
CALL GetElementNodes( Nodes )
545
546
FORCE = 0.0D0
547
STIFF = 0.0D0
548
!
549
! Integration stuff
550
!
551
IntegStuff = GaussPoints( Element )
552
!
553
! Now we start integrating
554
!
555
DO t=1,IntegStuff % n
556
557
u = IntegStuff % u(t)
558
v = IntegStuff % v(t)
559
w = IntegStuff % w(t)
560
561
!------------------------------------------------------------------------------
562
! Basis function values & derivatives at the integration point
563
!------------------------------------------------------------------------------
564
stat = ElementInfo( Element, Nodes, u, v, w, detJ, &
565
Basis, dBasisdx )
566
567
s = detJ * IntegStuff % s(t)
568
!------------------------------------------------------------------------------
569
LoadAtIP = 0.0D0
570
DO i=1,dim
571
LoadAtIP(i) = SUM( LOAD(i,1:n)*Basis )
572
Alpha(i) = SUM( NodalAlpha(i,1:n)*Basis )
573
END DO
574
575
Normal = NormalVector( Element,Nodes,u,v,.TRUE. )
576
LoadAtIP = LoadAtIP + SUM( NodalBeta(1:n)*Basis ) * Normal
577
578
DO p=1,nd
579
DO q=1,nd
580
DO i=1,dim
581
STIFF((p-1)*dim+i,(q-1)*dim+i) = &
582
STIFF((p-1)*dim+i,(q-1)*dim+i) + &
583
s * Alpha(i) * Basis(q) * Basis(p)
584
END DO
585
END DO
586
END DO
587
588
DO q=1,nd
589
DO i=1,dim
590
FORCE((q-1)*dim+i) = FORCE((q-1)*dim+i) + &
591
s * Basis(q) * LoadAtIP(i)
592
END DO
593
END DO
594
595
END DO
596
597
IF ( nb == 0 ) THEN
598
DO p=MAX(n+1,nd-Element % BDOFs+1),nd
599
DO i=1,dim
600
j = (p-1)*dim + i
601
STIFF( j,: ) = 0.0d0
602
STIFF( :,j ) = 0.0d0
603
STIFF( j,j ) = 1.0d0
604
FORCE( j ) = 0.0d0
605
END DO
606
END DO
607
END IF
608
609
!------------------------------------------------------------------------------
610
END SUBROUTINE MeshBoundary
611
!------------------------------------------------------------------------------
612
613
!------------------------------------------------------------------------------
614
END SUBROUTINE FDMeshSolver
615
!------------------------------------------------------------------------------
616
617