Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/examples/InverseMethods_OLD/src/GradientValidation.F90
3206 views
1
! Compare the total derivative of the cost function computed as:
2
! (1) dJ=P.G where P is a perturbation vector of the variable of interest
3
! G is the gradient of the cost function computed by an inverse method
4
! (2) [J(V+hP)-J(V)]/h : forward finite difference computation of the derivative
5
! V is the variable of interest
6
! h is the step size
7
!
8
!
9
! Compute (1) from at the first iteration and update V=Vini+hP, h=1
10
! Compute (2) for all the other iteration with h^i+1=h^i/2
11
!
12
! Serial/parallel 2D/3D
13
!
14
! Keyword in Solver section of the .sif:
15
! Cost Variable Name
16
! Optimized Variable Name
17
! Perturbed Variable Name
18
! Gradient Variable Name
19
! Result File
20
!
21
! Output: in result File: h , abs((1)-(2))/(1) , (1), (2)
22
!
23
!
24
! *****************************************************************************
25
SUBROUTINE GradientValidation ( Model,Solver,dt,TransientSimulation )
26
!------------------------------------------------------------------------------
27
!******************************************************************************
28
USE DefUtils
29
IMPLICIT NONE
30
!------------------------------------------------------------------------------
31
TYPE(Solver_t) :: Solver
32
TYPE(Model_t) :: Model
33
34
REAL(KIND=dp) :: dt
35
LOGICAL :: TransientSimulation
36
!
37
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName
38
TYPE(Element_t),POINTER :: Element
39
TYPE(ValueList_t), POINTER :: SolverParams
40
TYPE(Variable_t), POINTER :: Var,PVar,CostVar,GradVar
41
REAL(KIND=dp), POINTER :: Values(:),PValues(:),CostValues(:),GradValues(:)
42
INTEGER, POINTER :: Perm(:),PPerm(:),GradPerm(:)
43
INTEGER, POINTER :: NodeIndexes(:)
44
45
REAL(KIND=dp),allocatable :: x(:),xp(:),g(:)
46
REAL(KIND=dp) :: J,J0,h,dJ,dJd
47
48
integer :: i,t,n,NMAX,NActiveNodes
49
integer :: ierr
50
integer,allocatable :: ActiveNodes(:)
51
integer,allocatable :: NewNode(:)
52
integer,parameter :: io=20
53
integer :: MyPe=-1
54
55
Logical :: FirstVisit=.true.,Found
56
Logical :: Parallel
57
logical,allocatable :: VisitedNode(:)
58
59
CHARACTER(LEN=MAX_NAME_LEN) :: CostSolName,VarSolName,GradSolName,PSolName,ResultFile
60
CHARACTER*10 :: date,temps
61
62
!
63
save FirstVisit
64
save SolverName
65
save CostSolName,VarSolName,GradSolName,ResultFile
66
save ActiveNodes,NActiveNodes
67
save x,xp
68
save J0,h,dJ
69
save MyPe
70
save Parallel
71
72
73
! Read Constant from sif solver section
74
IF(FirstVisit) Then
75
76
WRITE(SolverName, '(A)') 'GradientValidation'
77
78
! Check we have a parallel run
79
Parallel = .FALSE.
80
IF(ASSOCIATED(Solver % Matrix % ParMatrix)) Then
81
IF ( Solver % Matrix % ParMatrix % ParEnv % PEs > 1 ) Parallel =.True.
82
MyPe=ParEnv % MyPe
83
End if
84
85
86
SolverParams => GetSolverParams()
87
88
!!!!!!!!!!!!find active nodes
89
NMAX=Solver % Mesh % NumberOfNodes
90
allocate(VisitedNode(NMAX),NewNode(NMAX))
91
VisitedNode=.false.
92
NewNode=-1
93
94
NActiveNodes=0
95
DO t=1,Solver % NumberOfActiveElements
96
Element => GetActiveElement(t)
97
n = GetElementNOFNodes()
98
NodeIndexes => Element % NodeIndexes
99
Do i=1,n
100
if (VisitedNode(NodeIndexes(i))) then
101
cycle
102
else
103
VisitedNode(NodeIndexes(i))=.true.
104
NActiveNodes=NActiveNodes+1
105
NewNode(NActiveNodes)=NodeIndexes(i)
106
endif
107
End do
108
End do
109
110
if (NActiveNodes.eq.0) THEN
111
WRITE(Message,'(A)') 'NActiveNodes = 0 !!!'
112
CALL FATAL(SolverName,Message)
113
End if
114
115
allocate(ActiveNodes(NActiveNodes),x(NActiveNodes),xp(NActiveNodes),g(NActiveNodes))
116
ActiveNodes(1:NActiveNodes)=NewNode(1:NActiveNodes)
117
118
deallocate(VisitedNode,NewNode)
119
120
!!!!!!! Solver Params
121
122
CostSolName = GetString( SolverParams,'Cost Variable Name', Found)
123
IF(.NOT.Found) THEN
124
CALL WARN(SolverName,'Keyword >Cost Variable Name< not found in section >Solver<')
125
CALL WARN(SolverName,'Taking default value >CostValue<')
126
WRITE(CostSolName,'(A)') 'CostValue'
127
END IF
128
VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)
129
IF(.NOT.Found) THEN
130
CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')
131
CALL WARN(SolverName,'Taking default value >Beta<')
132
WRITE(VarSolName,'(A)') 'Beta'
133
END IF
134
PSolName = GetString( SolverParams,'Perturbed Variable Name', Found)
135
IF(.NOT.Found) THEN
136
CALL WARN(SolverName,'Keyword >Perturbed Variable Name< not found in section >Solver<')
137
CALL WARN(SolverName,'Taking default value >BetaP<')
138
WRITE(VarSolName,'(A)') 'BetaP'
139
END IF
140
GradSolName = GetString( SolverParams,'Gradient Variable Name', Found)
141
IF(.NOT.Found) THEN
142
CALL WARN(SolverName,'Keyword >Gradient Variable Name< not found in section >Solver<')
143
CALL WARN(SolverName,'Taking default value >DJDB<')
144
WRITE(GradSolName,'(A)') 'DJDB'
145
END IF
146
ResultFile=GetString( SolverParams,'Result File',Found)
147
IF(Found) Then
148
IF ((Parallel.AND.(MyPe.EQ.0)).OR.(.NOT.Parallel)) Then
149
open(io,file=trim(ResultFile))
150
CALL DATE_AND_TIME(date,temps)
151
write(io,'(a1,a2,a1,a2,a1,a4,5x,a2,a1,a2,a1,a2)')'#',date(5:6),'/',date(7:8),'/',date(1:4), &
152
temps(1:2),':',temps(3:4),':',temps(5:6)
153
write(io,'(A)') '# step size, relative error, Adjoint total der., FD total der.'
154
close(io)
155
ENDIF
156
ELSE
157
CALL FATAL(SolverName,'Keyword <Result File> Not Found')
158
ENDIF
159
160
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
161
CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )
162
IF (ASSOCIATED(CostVar)) THEN
163
CostValues => CostVar % Values
164
ELSE
165
WRITE(Message,'(A,A,A)') 'No variable >',CostSolName,'< found'
166
CALL FATAL(SolverName,Message)
167
ENDIF
168
Var => VariableGet( Solver % Mesh % Variables, VarSolName )
169
IF (ASSOCIATED(Var)) THEN
170
Values => Var % Values
171
Perm => Var % Perm
172
ELSE
173
WRITE(Message,'(A,A,A)') 'No variable >',VarSolName,'< found'
174
CALL FATAL(SolverName,Message)
175
ENDIF
176
PVar => VariableGet( Solver % Mesh % Variables, PSolName )
177
IF (ASSOCIATED(PVar)) THEN
178
PValues => PVar % Values
179
PPerm => PVar % Perm
180
ELSE
181
WRITE(Message,'(A,A,A)') 'No variable >',PSolName,'< found'
182
CALL FATAL(SolverName,Message)
183
ENDIF
184
GradVar => VariableGet( Solver % Mesh % Variables, GradSolName)
185
IF (ASSOCIATED(GradVar)) THEN
186
GradValues => GradVar % Values
187
GradPerm => GradVar % Perm
188
ELSE
189
WRITE(Message,'(A,A,A)') 'No variable >',GradSolName,'< found'
190
CALL FATAL(SolverName,Message)
191
END IF
192
193
x(1:NActiveNodes)=Values(Perm(ActiveNodes(1:NActiveNodes)))
194
g(1:NActiveNodes)=GradValues(GradPerm(ActiveNodes(1:NActiveNodes)))
195
xp(1:NActiveNodes)=PValues(PPerm(ActiveNodes(1:NActiveNodes)))
196
197
!!!!!! On calcul la dervivee totale à partir de la valeur du
198
!gradient
199
dJ=0._dp
200
Do i=1,NActiveNodes
201
dJ=dJ+xp(i)*g(i)
202
End do
203
deallocate(g)
204
205
IF (Parallel) THEN
206
CALL MPI_ALLREDUCE(dJ,dJ,1,&
207
MPI_DOUBLE_PRECISION,MPI_SUM,MPI_COMM_WORLD,ierr)
208
ENDIF
209
210
211
!!!!! On sauve la valeur de J0 pour le calcul diffrence fini.
212
J0=CostValues(1)
213
214
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
215
h=1.0_dp
216
Do i=1,NActiveNodes
217
Values(Perm(ActiveNodes(i)))=x(i)+h*xp(i)
218
End do
219
220
221
FirstVisit=.FALSE.
222
Return
223
End if
224
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
225
226
CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )
227
IF (ASSOCIATED(CostVar)) THEN
228
CostValues => CostVar % Values
229
ELSE
230
WRITE(Message,'(A,A,A)') 'No variable >',CostSolName,'< found'
231
CALL FATAL(SolverName,Message)
232
ENDIF
233
Var => VariableGet( Solver % Mesh % Variables, VarSolName )
234
IF (ASSOCIATED(Var)) THEN
235
Values => Var % Values
236
Perm => Var % Perm
237
ELSE
238
WRITE(Message,'(A,A,A)') 'No variable >',VarSolName,'< found'
239
CALL FATAL(SolverName,Message)
240
ENDIF
241
242
243
J=CostValues(1)
244
245
dJd=(J-J0)/h
246
247
IF (Parallel) MyPe=ParEnv % MyPe
248
IF ((Parallel.AND.(MyPe.EQ.0)).OR.(.NOT.Parallel)) Then
249
open(io,file=trim(ResultFile),position='append')
250
write(io,'(4(e15.8,2x))') h,abs(dJ-dJd)/abs(dJ),dJ,dJd
251
close(io)
252
ENDIF
253
254
h=h/2.0_dp
255
Do i=1,NActiveNodes
256
Values(Perm(ActiveNodes(i)))=x(i)+h*xp(i)
257
End Do
258
259
Return
260
!------------------------------------------------------------------------------
261
END SUBROUTINE GradientValidation
262
!------------------------------------------------------------------------------
263
264
265
266