Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/tests/BlockLinElast1/BlockLinElast.f90
3206 views
1
2
!------------------------------------------------------------------------------
3
SUBROUTINE BulkAssembly( Model,Solver,dt,Transient, &
4
Mass, Damp, Stiff, Force, InElement, nrow, ncol )
5
!------------------------------------------------------------------------------
6
7
USE DefUtils
8
9
10
IMPLICIT NONE
11
!------------------------------------------------------------------------------
12
TYPE(Model_t) :: Model
13
TYPE(Solver_t) :: Solver
14
LOGICAL :: Transient
15
REAL(KIND=dp) :: dt
16
TYPE(Element_t):: InElement
17
INTEGER :: Nrow, Ncol
18
REAL(KIND=dp) :: Stiff(:,:), Damp(:,:), Mass(:,:), Force(:)
19
!------------------------------------------------------------------------------
20
! Local variables
21
!------------------------------------------------------------------------------
22
23
TYPE(GaussIntegrationPoints_t) :: IntegStuff
24
TYPE(Nodes_t) :: Nodes
25
REAL(KIND=dp), ALLOCATABLE :: Basis(:), dBasisdx(:,:)
26
REAL(KIND=dp), ALLOCATABLE :: Source(:)
27
REAL(KIND=dp) :: Young, Poisson, Lame1, Lame2
28
REAL(KIND=dp) :: SourceAtIP, Weight, DetJ
29
INTEGER :: i,j,k,t,p,q,n, nd,dim
30
LOGICAL :: Visited = .FALSE., Found
31
TYPE(Element_t), POINTER :: Element
32
TYPE(ValueList_t), POINTER :: Material, Params
33
34
SAVE Visited, Source, Nodes, Basis, dBasisdx, Params
35
36
dim = CoordinateSystemDimension()
37
38
IF( .NOT. Visited ) THEN
39
n = Solver % Mesh % MaxElementDOFs
40
ALLOCATE( Source(n), Basis(n), dBasisdx(n,3) )
41
CALL info('PoissonBulkAssembly','1st time')
42
Params => GetSolverParams()
43
Visited = .TRUE.
44
END IF
45
46
n = GetElementNOFNodes()
47
nd = GetElementNOFDOFs()
48
CALL GetElementNodes( Nodes )
49
Material => GetMaterial()
50
51
i = GetInteger( Params,'Block Matrix Row')
52
j = GetInteger( Params,'Block Matrix Column')
53
Source(1:n) = GetReal( Material,'Source',Found)
54
55
Young = GetCReal( Material, 'Youngs modulus', Found )
56
Poisson = GetCReal( Material, 'Poisson Ratio', Found )
57
58
Lame1 = Young*Poisson/((1+Poisson)*(1-2*Poisson))
59
Lame2 = Young/(2*(1+Poisson))
60
61
Element => GetCurrentElement()
62
IntegStuff = GaussPoints( Element )
63
64
65
DO t=1,IntegStuff % n
66
Found = ElementInfo( Element, Nodes, IntegStuff % u(t), &
67
IntegStuff % v(t), IntegStuff % w(t), detJ, Basis, dBasisdx )
68
69
Weight = IntegStuff % s(t) * detJ
70
71
SourceAtIP = SUM( Basis(1:n) * Source(1:n) )
72
73
IF ( i==j ) THEN
74
STIFF(1:nd,1:nd) = STIFF(1:nd,1:nd) + &
75
Weight*Lame2*MATMUL(dBasisdx,TRANSPOSE(dBasisdx))
76
FORCE(1:nd) = FORCE(1:nd) + Weight * SourceAtIP * Basis(1:nd)
77
END IF
78
79
DO p=1,nd
80
DO q=1,nd
81
STIFF(p,q) = STIFF(p,q) + &
82
Weight*Lame1*dBasisdx(q,j)*dBasisdx(p,i)
83
STIFF(p,q) = STIFF(p,q) + &
84
Weight*Lame2*dBasisdx(q,i)*dBasisdx(p,j)
85
END DO
86
END DO
87
END DO
88
!------------------------------------------------------------------------------
89
END SUBROUTINE BulkAssembly
90
!------------------------------------------------------------------------------
91
92
93
!------------------------------------------------------------------------------
94
SUBROUTINE BoundaryAssembly( Model,Solver,dt,Transient, &
95
Mass, Damp, Stiff, Force, InElement, nrow, ncol )
96
!------------------------------------------------------------------------------
97
98
USE DefUtils
99
100
IMPLICIT NONE
101
!------------------------------------------------------------------------------
102
TYPE(Model_t) :: Model
103
TYPE(Solver_t), TARGET :: Solver
104
LOGICAL :: Transient
105
REAL(KIND=dp) :: dt
106
REAL(KIND=dp) :: Stiff(:,:), Damp(:,:), Mass(:,:), Force(:)
107
TYPE(Element_t), TARGET :: InElement
108
INTEGER :: Nrow, Ncol
109
!------------------------------------------------------------------------------
110
! Local variables
111
!------------------------------------------------------------------------------
112
113
TYPE(GaussIntegrationPoints_t), TARGET :: IntegStuff
114
TYPE(Nodes_t) :: Nodes
115
REAL(KIND=dp), ALLOCATABLE :: Flux(:), Text(:), Coeff(:)
116
REAL(KIND=dp), ALLOCATABLE :: Basis(:), dBasisdx(:,:)
117
REAL(KIND=dp) :: FluxAtIP, TextAtIP, CoeffAtIP, Weight, DetJ
118
INTEGER :: i,j,t,p,q,n
119
LOGICAL :: Visited = .FALSE., Found, Found2
120
TYPE(ValueList_t), POINTER :: BC
121
TYPE(Element_t), POINTER :: Element
122
123
124
SAVE Visited, Flux, Text, Coeff, Nodes, Basis, dBasisdx
125
126
127
IF( .NOT. Visited ) THEN
128
N = Solver % Mesh % MaxElementNodes
129
ALLOCATE( Flux(n), Text(n), Coeff(n), Basis(n), dBasisdx(n,3), &
130
Nodes % x(n), Nodes % y(n), Nodes % z(n) )
131
CALL info('PoissonBoundaryAssembly','1st time')
132
Visited = .TRUE.
133
END IF
134
135
Element => GetCurrentElement()
136
n = Nrow
137
CALL GetElementNodes( Nodes )
138
139
BC => GetBC( )
140
141
Flux(1:n) = GetReal( BC,'Flux',Found )
142
Coeff(1:n) = GetReal( BC,'Coefficient',Found2 )
143
IF(.NOT. (Found .OR. Found2)) RETURN
144
Text(1:n) = GetReal( BC,'External',Found )
145
146
147
IntegStuff = GaussPoints( Element )
148
149
DO t=1,IntegStuff % n
150
151
Found = ElementInfo( Element, Nodes, IntegStuff % u(t), &
152
IntegStuff % v(t), IntegStuff % w(t), detJ, Basis, dBasisdx )
153
154
Weight = IntegStuff % s(t) * detJ
155
156
FluxAtIP = SUM( Basis(1:Nrow) * Flux(1:Nrow) )
157
CoeffAtIP = SUM( Basis(1:Nrow) * Coeff(1:Nrow) )
158
TextAtIP = SUM( Basis(1:Nrow) * Text(1:Nrow) )
159
160
DO p=1,n
161
DO q=1,n
162
STIFF(p,q) = STIFF(p,q) + Weight * CoeffAtIP * &
163
Basis(p)*Basis(q)
164
END DO
165
FORCE(p) = FORCE(p) + Weight * Basis(p) * &
166
( FluxAtIP + CoeffAtIP * TextAtIP )
167
END DO
168
END DO
169
170
!------------------------------------------------------------------------------
171
END SUBROUTINE BoundaryAssembly
172
!------------------------------------------------------------------------------
173
174
175