Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/examples/turing/Turing.f90
5227 views
1
SUBROUTINE TuringSolver( Model,Solver,dt,TransientSimulation )
2
!DEC$ATTRIBUTES DLLEXPORT :: TuringSolver
3
!------------------------------------------------------------------------------
4
!******************************************************************************
5
!
6
! Solve the Turing equation!
7
!
8
! ARGUMENTS:
9
!
10
! TYPE(Model_t) :: Model,
11
! INPUT: All model information (mesh, materials, BCs, etc...)
12
!
13
! TYPE(Solver_t) :: Solver
14
! INPUT: Linear & nonlinear equation solver options
15
!
16
! REAL(KIND=dp) :: dt,
17
! INPUT: Timestep size for time dependent simulations
18
!
19
! LOGICAL :: TransientSimulation
20
! INPUT: Steady state or transient simulation
21
!
22
!******************************************************************************
23
USE DefUtils
24
25
IMPLICIT NONE
26
!------------------------------------------------------------------------------
27
TYPE(Solver_t) :: Solver
28
TYPE(Model_t) :: Model
29
30
REAL(KIND=dp) :: dt
31
LOGICAL :: TransientSimulation
32
!------------------------------------------------------------------------------
33
! Local variables
34
!------------------------------------------------------------------------------
35
LOGICAL :: AllocationsDone = .FALSE., Found
36
TYPE(Element_t),POINTER :: Element
37
38
REAL(KIND=dp) :: Norm
39
INTEGER :: n, nb, nd, t, istat
40
41
TYPE(ValueList_t), POINTER :: BodyForce, Material
42
REAL(KIND=dp), ALLOCATABLE :: STIFF(:,:), LOAD(:), FORCE(:), MASS(:,:)
43
44
REAL(KIND=dp), ALLOCATABLE :: CoeffA(:), CoeffB(:), CoeffC(:), CoeffG(:), &
45
CoeffNu(:), DiffU(:), DiffV(:), Solution(:,:)
46
47
SAVE MASS, STIFF, LOAD, FORCE, AllocationsDone, CoeffA, CoeffB, CoeffC, CoeffG, &
48
CoeffNu, DiffU, DiffV, Solution
49
!------------------------------------------------------------------------------
50
51
!Allocate some permanent storage, this is done first time only:
52
!--------------------------------------------------------------
53
IF ( .NOT. AllocationsDone ) THEN
54
N = 2*Solver % Mesh % MaxElementDOFs ! just big enough for elemental arrays
55
ALLOCATE( FORCE(N), LOAD(N), STIFF(N,N), MASS(N,N), STAT=istat )
56
57
ALLOCATE( CoeffA(N), stat=istat )
58
ALLOCATE( CoeffB(N), stat=istat )
59
ALLOCATE( CoeffC(N), stat=istat )
60
ALLOCATE( CoeffG(N), stat=istat )
61
ALLOCATE( CoeffNu(N), stat=istat )
62
ALLOCATE( DiffU(N), stat=istat )
63
ALLOCATE( DiffV(N), stat=istat )
64
ALLOCATE( Solution(2,1:N), stat=istat )
65
66
IF ( istat /= 0 ) THEN
67
CALL Fatal( 'TuringSolve', 'Memory allocation error.' )
68
END IF
69
AllocationsDone = .TRUE.
70
END IF
71
72
!System assembly:
73
!----------------
74
CALL DefaultInitialize()
75
DO t=1,Solver % NumberOfActiveElements
76
Element => GetActiveElement(t)
77
n = GetElementNOFNodes()
78
nd = GetElementNOFDOFs()
79
80
CALL GetVectorLocalSolution( Solution )
81
82
Material => GetMaterial()
83
CoeffA(1:nd) = GetReal( Material, 'Alpha' )
84
CoeffB(1:nd) = GetReal( Material, 'Beta' )
85
CoeffC(1:nd) = GetReal( Material, 'C' )
86
CoeffG(1:nd) = GetReal( Material, 'Gamma' )
87
CoeffNu(1:nd) = GetReal( Material, 'nu' )
88
DiffU(1:nd) = GetReal( Material, 'du' )
89
DiffV(1:nd) = GetReal( Material, 'dv' )
90
91
! Get element local matrix and rhs vector:
92
! ----------------------------------------
93
CALL LocalMatrix( MASS, STIFF, FORCE, LOAD, Element, n, nd )
94
95
IF ( TransientSimulation ) CALL Default1stOrderTime( MASS, STIFF, FORCE )
96
CALL DefaultUpdateEquations( STIFF, FORCE )
97
END DO
98
CALL DefaultFinishAssembly()
99
CALL DefaultDirichletBCs()
100
101
102
! And finally, solve:
103
!--------------------
104
Norm = DefaultSolve()
105
106
CONTAINS
107
108
!------------------------------------------------------------------------------
109
SUBROUTINE LocalMatrix( MASS, STIFF, FORCE, LOAD, Element, n, nd )
110
!------------------------------------------------------------------------------
111
REAL(KIND=dp), TARGET :: MASS(:,:), STIFF(:,:), FORCE(:), LOAD(:)
112
INTEGER :: n, nd
113
TYPE(Element_t), POINTER :: Element
114
!------------------------------------------------------------------------------
115
REAL(KIND=dp) :: Basis(nd),dBasisdx(nd,3),DetJ,LoadAtIP
116
LOGICAL :: Stat
117
INTEGER :: i,j,t,p,q,dim
118
REAL(KIND=dp), POINTER :: M(:,:), A(:,:), F(:)
119
TYPE(GaussIntegrationPoints_t) :: IP
120
121
REAL(KIND=dp) :: du,dv,nu,alpha,beta,gamma,uprev,vprev,C,s, Base, Grad
122
123
TYPE(Nodes_t) :: Nodes
124
SAVE Nodes
125
!------------------------------------------------------------------------------
126
dim = CoordinateSystemDimension()
127
128
CALL GetElementNodes( Nodes )
129
MASS = 0.0d0
130
STIFF = 0.0d0
131
FORCE = 0.0d0
132
133
! Numerical integration:
134
! ----------------------
135
IP = GaussPoints( Element )
136
DO t=1,IP % n
137
! Basis function values & derivatives at the integration point:
138
!--------------------------------------------------------------
139
stat = ElementInfo( Element, Nodes, IP % U(t), IP % V(t), &
140
IP % W(t), detJ, Basis, dBasisdx )
141
142
s = IP % s(t) * DetJ
143
144
du = SUM( Basis(1:nd) * DiffU(1:nd) )
145
dv = SUM( Basis(1:nd) * DiffV(1:nd) )
146
nu = SUM( Basis(1:nd) * CoeffNu(1:nd) )
147
alpha = SUM( BAsis(1:nd) * CoeffA(1:nd) )
148
beta = SUM( Basis(1:nd) * CoeffB(1:nd) )
149
C = SUM( Basis(1:nd) * CoeffC(1:nd) )
150
gamma = SUM( Basis(1:nd) * CoeffG(1:nd) )
151
152
uprev = SUM( Basis(1:nd) * Solution( 1,1:nd ) )
153
vprev = SUM( Basis(1:nd) * Solution( 2,1:nd ) )
154
155
! Finally, the elemental matrix & vector:
156
!----------------------------------------
157
DO p=1,nd
158
DO q=1,nd
159
i = 2*(p-1)+1
160
j = 2*(q-1)+1
161
M => MASS(i:i+1, j:j+1)
162
A => STIFF(i:i+1, j:j+1)
163
164
Base = s * Basis(q) * Basis(p)
165
Grad = s * SUM( dBasisdx(q,:) * dBasisdx(p,:) )
166
167
M(1,1) = M(1,1) + Base
168
M(2,2) = M(2,2) + Base
169
A(1,1) = A(1,1) + du*Grad + nu*((vprev+C)*vprev-1) * Base
170
A(1,2) = A(1,2) + nu*((3*vprev+C)*uprev-alpha) * Base
171
A(2,1) = A(2,1) - nu*((vprev+C)*vprev+gamma) * Base
172
A(2,2) = A(2,2) + dv*Grad - nu*((3*vprev+C)*uprev+beta) * Base
173
END DO
174
i = 2*(p-1)+1
175
F => FORCE(i:i+1)
176
F(1) = F(1) + s * nu*(3*vprev+C)*uprev*vprev * Basis(p)
177
F(2) = F(2) - s * nu*(3*vprev+C)*uprev*vprev * Basis(p)
178
END DO
179
END DO
180
!------------------------------------------------------------------------------
181
END SUBROUTINE LocalMatrix
182
!------------------------------------------------------------------------------
183
184
!------------------------------------------------------------------------------
185
END SUBROUTINE TuringSolver
186
!------------------------------------------------------------------------------
187
188