Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/tests/1dtests_MeshLevels/Poisson.f90
5255 views
1
SUBROUTINE PoissonSolver( Model,Solver,dt,TransientSimulation )
2
!------------------------------------------------------------------------------
3
!******************************************************************************
4
!
5
! Solve the Poisson equation!
6
!
7
! ARGUMENTS:
8
!
9
! TYPE(Model_t) :: Model,
10
! INPUT: All model information (mesh, materials, BCs, etc...)
11
!
12
! TYPE(Solver_t) :: Solver
13
! INPUT: Linear & nonlinear equation solver options
14
!
15
! REAL(KIND=dp) :: dt,
16
! INPUT: Timestep size for time dependent simulations
17
!
18
! LOGICAL :: TransientSimulation
19
! INPUT: Steady state or transient simulation
20
!
21
!******************************************************************************
22
USE DefUtils
23
24
IMPLICIT NONE
25
!------------------------------------------------------------------------------
26
TYPE(Solver_t) :: Solver
27
TYPE(Model_t) :: Model
28
29
REAL(KIND=dp) :: dt
30
LOGICAL :: TransientSimulation
31
!------------------------------------------------------------------------------
32
! Local variables
33
!------------------------------------------------------------------------------
34
TYPE(Element_t),POINTER :: Element
35
36
LOGICAL :: AllocationsDone = .FALSE., Found
37
38
INTEGER :: n, t, istat, active
39
REAL(KIND=dp) :: Norm
40
41
TYPE(ValueList_t), POINTER :: BodyForce
42
TYPE(Mesh_t), POINTER :: Mesh
43
REAL(KIND=dp), ALLOCATABLE :: STIFF(:,:), LOAD(:), FORCE(:)
44
45
SAVE STIFF, LOAD, FORCE, AllocationsDone
46
!------------------------------------------------------------------------------
47
48
Mesh => GetMesh()
49
50
!Allocate some permanent storage, this is done first time only:
51
!--------------------------------------------------------------
52
IF ( .NOT. AllocationsDone ) THEN
53
N = Mesh % MaxElementNodes ! just big enough for elemental arrays
54
ALLOCATE( FORCE(N), LOAD(N), STIFF(N,N), STAT=istat )
55
IF ( istat /= 0 ) THEN
56
CALL Fatal( 'PoissonSolve', 'Memory allocation error.' )
57
END IF
58
AllocationsDone = .TRUE.
59
END IF
60
61
!Initialize the system and do the assembly:
62
!------------------------------------------
63
CALL DefaultInitialize()
64
65
active = GetNOFActive()
66
DO t=1,active
67
Element => GetActiveElement(t)
68
n = GetElementNOFNodes()
69
70
LOAD = 0.0d0
71
BodyForce => GetBodyForce()
72
IF ( ASSOCIATED(BodyForce) ) &
73
Load(1:n) = GetReal( BodyForce, 'Source', Found )
74
75
!Get element local matrix and rhs vector:
76
!----------------------------------------
77
CALL LocalMatrix( STIFF, FORCE, LOAD, Element, n )
78
79
!Update global matrix and rhs vector from local matrix & vector:
80
!---------------------------------------------------------------
81
CALL DefaultUpdateEquations( STIFF, FORCE )
82
END DO
83
84
CALL DefaultFinishAssembly()
85
CALL DefaultDirichletBCs()
86
Norm = DefaultSolve()
87
88
CONTAINS
89
90
!------------------------------------------------------------------------------
91
SUBROUTINE LocalMatrix( STIFF, FORCE, LOAD, Element, n )
92
!------------------------------------------------------------------------------
93
REAL(KIND=dp) :: STIFF(:,:), FORCE(:), LOAD(:)
94
INTEGER :: n
95
TYPE(Element_t), POINTER :: Element
96
!------------------------------------------------------------------------------
97
REAL(KIND=dp) :: Basis(n),dBasisdx(n,3),DetJ,LoadAtIP
98
LOGICAL :: Stat
99
INTEGER :: t
100
TYPE(GaussIntegrationPoints_t) :: IP
101
102
TYPE(Nodes_t) :: Nodes
103
SAVE Nodes
104
!------------------------------------------------------------------------------
105
CALL GetElementNodes( Nodes )
106
STIFF = 0.0d0
107
FORCE = 0.0d0
108
109
!Numerical integration:
110
!----------------------
111
IP = GaussPoints( Element )
112
DO t=1,IP % n
113
! Basis function values & derivatives at the integration point:
114
!--------------------------------------------------------------
115
stat = ElementInfo( Element, Nodes, IP % U(t), IP % V(t), &
116
IP % W(t), detJ, Basis, dBasisdx )
117
118
! The source term at the integration point:
119
!------------------------------------------
120
LoadAtIP = SUM( Basis(1:n) * LOAD(1:n) )
121
122
! Finally, the elemental matrix & vector:
123
!----------------------------------------
124
STIFF(1:n,1:n) = STIFF(1:n,1:n) + IP % s(t) * DetJ * &
125
MATMUL( dBasisdx, TRANSPOSE( dBasisdx ) )
126
FORCE(1:n) = FORCE(1:n) + IP % s(t) * DetJ * LoadAtIP * Basis(1:n)
127
END DO
128
!------------------------------------------------------------------------------
129
END SUBROUTINE LocalMatrix
130
!------------------------------------------------------------------------------
131
END SUBROUTINE PoissonSolver
132
!------------------------------------------------------------------------------
133
134