-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCGOp.f90
58 lines (49 loc) · 1.77 KB
/
CGOp.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Subroutine CGOp(a,b,dt,HydroParam,MeshParam)
! Matrix Free Conjugate Gradient Method
! Input:
! a -> Input Matrix
! Output:
! b -> Solution
! List of Modifications:
! -> 10.03.2014: Routine Implementation (Rafael Cavalcanti)
! -> 10.03.2014: Fortran Sintax (Rafael Cavalcanti)
! Programmer: Michael Dumbser
Use MeshVars !, Only: nElem, Edge, Neighbor, EdgeLength, Cirdistance
Use Hydrodynamic
!Use SimulationModel, Only: dt,NearZero
Implicit None
Real:: alpha, tol, lambda, alphanew
Integer:: k, N
Integer:: iElem, iEdge, Pij, Face
Real:: Soma, Coef
Real:: NearZero = 1e-10
Real:: dt
type(MeshGridParam) :: MeshParam
type(HydrodynamicParam) :: HydroParam
Real, intent(in) :: a(MeshParam%nElem)
Real, intent(out) :: b(MeshParam%nElem)
Real:: r(MeshParam%nElem), Ab(MeshParam%nElem), pCG(MeshParam%nElem), v(MeshParam%nElem)
N = MeshParam%nElem
b = a ! Initial guess
Call MatOp(b,Ab,dt,HydroParam,MeshParam)
! b - Ab = %Deta - (P+T).eta(k,0)
r = b - Ab
pCG = r ! Steepest Descent Direction
alpha = Dot_Product(r,r) ! Square of the norm of r
tol = 1e-14 ! Tolerance
Do k = 1,1000*N
If ( sqrt(alpha) < tol ) Then
! System has been solved
!Print*, 'The system has been solved with: ',k, 'CGOp iterations'
Return
EndIf
Call MatOp(pCG,v,dt,HydroParam,MeshParam)
lambda = alpha/Dot_Product(pCG,v)
b = b + lambda*pCG
r = r - lambda*v
alphanew = Dot_Product(r,r)
pCG = r + alphanew/alpha*pCG
alpha = alphanew
EndDo
Return
End Subroutine CGOp