-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCGOpSub.f90
60 lines (51 loc) · 1.99 KB
/
CGOpSub.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
59
60
Subroutine CGOpSub(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
!%Deta = %F == residual k == V1(eta) + [T - Q(k-1)]eta - d(k-1) = Error in Water Volume
b = a ! Initial guess
!Ab == (P(k,l-1) + T - Q(k-1,l-1)).eta(k,l)
Call MatOp(HydroParam%eta,Ab,dt,HydroParam,MeshParam)
! b - Ab = V1(eta) + [T - Q(k-1)]eta - d(k-1) + P(k,l-1).eta(k,l-1)
r = b - Ab + HydroParam%P*HydroParam%eta
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 CGOpSub