Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/CostSolver_Adjoint.F90
3204 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer/Ice, a glaciological add-on to Elmer
4
! * http://elmerice.elmerfem.org
5
! *
6
! *
7
! * This program is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU General Public License
9
! * as published by the Free Software Foundation; either version 2
10
! * of the License, or (at your option) any later version.
11
! *
12
! * This program is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
! * GNU General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU General Public License
18
! * along with this program (in file fem/GPL-2); if not, write to the
19
! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
! * Boston, MA 02110-1301, USA.
21
! *
22
! *****************************************************************************/
23
! ******************************************************************************
24
! *
25
! * Authors: f. Gillet-Chaulet (LGGE, Grenoble,France)
26
! * Email: [email protected]
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date:
30
! *
31
! *****************************************************************************
32
!Compute the Cost function of the Adjoint inverse Problem
33
! as Integral_Surface Node_Cost ds
34
! with a regularization as Sum_bedrock 0.5 Lambda (dBeta/dx)^2
35
!
36
! Serial/Parallel 2D/3D
37
!
38
! Need :
39
! - Name of the Cost Variable
40
! - Lambda and Beta for regularization
41
! - define in the sif Name='surface' and Name='bed' in appropriate BC.
42
! - define in the sif in the surface BC:
43
! 'Adjoint Cost = Real ...' : The nodal value of the cost
44
! 'Adjoint Cost der 1 = Real ...' : The derivative of 'Adjoint Cost' w.r.t. u-velocity
45
! 'Adjoint Cost der 2 = Real ...' : The derivative of 'Adjoint Cost' w.r.t. v-velocity
46
! 'Adjoint Cost der 3 = Real ...' : The derivative of 'Adjoint Cost' w.r.t. w-velocity
47
!
48
! *****************************************************************************
49
SUBROUTINE CostSolver_Adjoint_init( Model,Solver,dt,TransientSimulation )
50
!------------------------------------------------------------------------------
51
USE DefUtils
52
53
IMPLICIT NONE
54
!------------------------------------------------------------------------------
55
TYPE(Solver_t), TARGET :: Solver
56
TYPE(Model_t) :: Model
57
REAL(KIND=dp) :: dt
58
LOGICAL :: TransientSimulation
59
!------------------------------------------------------------------------------
60
! Local variables
61
!------------------------------------------------------------------------------
62
INTEGER :: NormInd, LineInd, i
63
LOGICAL :: GotIt, MarkFailed, AvoidFailed
64
CHARACTER(LEN=MAX_NAME_LEN) :: Name
65
66
Name = ListGetString( Solver % Values, 'Equation',GotIt)
67
IF( .NOT. ListCheckPresent( Solver % Values,'Variable') ) THEN
68
CALL ListAddString( Solver % Values,'Variable',&
69
'-nooutput -global '//TRIM(Name)//'_var')
70
END IF
71
END
72
!******************************************************************************
73
SUBROUTINE CostSolver_Adjoint( Model,Solver,dt,TransientSimulation )
74
!------------------------------------------------------------------------------
75
!******************************************************************************
76
USE DefUtils
77
IMPLICIT NONE
78
!------------------------------------------------------------------------------
79
TYPE(Solver_t) :: Solver
80
TYPE(Model_t) :: Model
81
82
REAL(KIND=dp) :: dt
83
LOGICAL :: TransientSimulation
84
!
85
CHARACTER(LEN=MAX_NAME_LEN), PARAMETER :: DefaultCostFile = 'CostOfT.dat'
86
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName,CostFile
87
CHARACTER(LEN=MAX_NAME_LEN) :: BCName,CostSolName,VarSolName
88
TYPE(Element_t),POINTER :: Element
89
TYPE(Variable_t), POINTER :: TimeVar,CostVar,BetaSol
90
TYPE(Variable_t), POINTER :: VelocitybSol
91
TYPE(ValueList_t), POINTER :: BC,SolverParams
92
TYPE(Nodes_t) :: ElementNodes
93
TYPE(GaussIntegrationPoints_t) :: IntegStuff
94
REAL(KIND=dp), POINTER :: Beta(:)
95
REAL(KIND=dp), POINTER :: Vb(:)
96
INTEGER, POINTER :: NodeIndexes(:), BetaPerm(:)
97
INTEGER, POINTER :: VbPerm(:)
98
Logical :: Firsttime=.true.,Found,Parallel,stat,Gotit,UnFoundFatal=.TRUE.
99
integer :: i,j,k,l,t,n,NMAX,DIM,ierr,c
100
real(kind=dp) :: Cost,Cost_bed,Cost_surf,Cost_S,Cost_bed_S,Cost_surf_S,Lambda,Change
101
real(kind=dp),Save :: Oldf=0._dp
102
real(kind=dp) :: Bu,Bv,u,v,w,s,coeff,SqrtElementMetric,x
103
REAL(KIND=dp) :: NodeCost(Model % MaxElementNodes),Basis(Model % MaxElementNodes), dBasisdx(Model % MaxElementNodes,3)
104
REAL(KIND=dp) :: NodeCostb(Model % MaxElementNodes),NodeCost_der(3,Model %MaxElementNodes)
105
CHARACTER*10 :: date,temps
106
107
save Firsttime,Parallel
108
save SolverName,CostSolName,VarSolName,Lambda,CostFile
109
save ElementNodes
110
111
DIM = CoordinateSystemDimension()
112
113
If (Firsttime) then
114
115
WRITE(SolverName, '(A)') 'CostSolver_Adjoint'
116
117
CALL Info(SolverName,'***********************',level=0)
118
CALL Info(SolverName,' This solver has been replaced by:',level=0)
119
CALL Info(SolverName,' Adjoint_CostContSolver ',level=0)
120
CALL Info(SolverName,' Adjoint_CostRegSolver ',level=0)
121
CALL Info(SolverName,' See documentation under: ',level=0)
122
CALL Info(SolverName,' elmerice/Solvers/Documentation ',level=0)
123
CALL Info(SolverName,'***********************',level=0)
124
CALL FATAL(SolverName,' Use new solver !!')
125
126
!!!!!!! Check for parallel run
127
Parallel = (ParEnv % PEs > 1)
128
129
!!!!!!!!!!! get Solver Variables
130
SolverParams => GetSolverParams()
131
132
CostFile = ListGetString(Solver % Values,'Cost Filename',Found )
133
IF (.NOT. Found) CostFile = DefaultCostFile
134
CALL DATE_AND_TIME(date,temps)
135
If (Parallel) then
136
if (ParEnv % MyPe.EQ.0) then
137
OPEN (12, FILE=CostFile)
138
write(12,'(a1,a2,a1,a2,a1,a4,5x,a2,a1,a2,a1,a2)') '#',date(5:6),'/',date(7:8),'/',date(1:4), &
139
temps(1:2),':',temps(3:4),':',temps(5:6)
140
CLOSE(12)
141
End if
142
Else
143
OPEN (12, FILE=CostFile)
144
write(12,'(a1,a2,a1,a2,a1,a4,5x,a2,a1,a2,a1,a2)') '#',date(5:6),'/',date(7:8),'/',date(1:4), &
145
temps(1:2),':',temps(3:4),':',temps(5:6)
146
CLOSE(12)
147
End if
148
149
150
VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)
151
IF(.NOT.Found) THEN
152
CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')
153
CALL WARN(SolverName,'Taking default value >Beta<')
154
WRITE(VarSolName,'(A)') 'Beta'
155
END IF
156
157
CostSolName = GetString( SolverParams,'Cost Variable Name', Found)
158
IF(.NOT.Found) THEN
159
CALL WARN(SolverName,'Keyword >Cost Variable Name< not found in section >Solver<')
160
CALL WARN(SolverName,'Taking default value >CostValue<')
161
WRITE(CostSolName,'(A)') 'CostValue'
162
END IF
163
164
Lambda = GetConstReal( SolverParams,'Lambda', Found)
165
IF(.NOT.Found) THEN
166
CALL WARN(SolverName,'Keyword >Lambda< not found in section >Solver<')
167
CALL WARN(SolverName,'Taking default value Lambda=0.0')
168
Lambda = 0.0
169
End if
170
171
!!! End of First visit
172
Firsttime=.false.
173
Endif
174
175
BetaSol => VariableGet( Model % Mesh % Variables, VarSolName,UnFoundFatal=UnFoundFatal)
176
Beta => BetaSol % Values
177
BetaPerm => BetaSol % Perm
178
179
VelocitybSol => VariableGet( Model % Mesh % Variables, 'Velocityb',UnFoundFatal=UnFoundFatal)
180
Vb => VelocitybSol % Values
181
VbPerm => VelocitybSol % Perm
182
c=DIM + 1 ! size of the velocity variable
183
IF (VelocitybSol % DOFs.NE.c) then
184
WRITE(Message,'(A,I1,A,I1)') &
185
'Variable Velocityb has ',VelocitybSol % DOFs,' DOFs, should be',c
186
CALL FATAL(SolverName,Message)
187
End If
188
Vb=0.0_dp
189
190
191
Cost=0._dp
192
Cost_surf=0._dp
193
Cost_bed=0._dp
194
DO t=1,Model % Mesh % NumberOfBoundaryElements
195
196
Element => GetBoundaryElement(t)
197
198
BC => GetBC()
199
IF ( .NOT. ASSOCIATED(BC) ) CYCLE
200
201
BCName = ListGetString( BC,'Name', Found)
202
IF((BCName /= 'surface').AND.(BCName /= 'bed')) CYCLE
203
204
CALL GetElementNodes( ElementNodes )
205
n = GetElementNOFNodes()
206
NodeIndexes => Element % NodeIndexes
207
208
NodeCost=0.0_dp
209
IF (BCName == 'surface') THEN
210
NodeCost(1:n) = ListGetReal(BC, 'Adjoint Cost', n, NodeIndexes, GotIt,&
211
UnFoundFatal=UnFoundFatal)
212
NodeCost_der=0.0_dp
213
214
NodeCost_der(1,1:n)=ListGetReal(BC, 'Adjoint Cost der 1', n, NodeIndexes, GotIt)
215
NodeCost_der(2,1:n)=ListGetReal(BC, 'Adjoint Cost der 2', n, NodeIndexes, GotIt)
216
NodeCost_der(3,1:n)=ListGetReal(BC, 'Adjoint Cost der 3', n, NodeIndexes, GotIt)
217
218
Else IF (BCName == 'bed') Then
219
NodeCost(1:n)=Beta(BetaPerm(NodeIndexes(1:n)))
220
End if
221
222
!------------------------------------------------------------------------------
223
! Numerical integration
224
!------------------------------------------------------------------------------
225
IntegStuff = GaussPoints( Element )
226
227
228
NodeCostb=0.0_dp
229
230
DO i=1,IntegStuff % n
231
U = IntegStuff % u(i)
232
V = IntegStuff % v(i)
233
W = IntegStuff % w(i)
234
!------------------------------------------------------------------------------
235
! Basis function values & derivatives at the integration point
236
!------------------------------------------------------------------------------
237
stat = ElementInfo( Element,ElementNodes,U,V,W,SqrtElementMetric, &
238
Basis,dBasisdx )
239
240
x = SUM( ElementNodes % x(1:n) * Basis(1:n) )
241
s = 1.0d0
242
243
IF ( CurrentCoordinateSystem() /= Cartesian ) THEN
244
s = 2.0d0 * PI * x
245
END IF
246
s = s * SqrtElementMetric * IntegStuff % s(i)
247
248
IF (BCName == 'surface') Then
249
coeff = SUM(NodeCost(1:n) * Basis(1:n))
250
Cost_surf=Cost_surf+coeff*s
251
NodeCostb(1:n)=NodeCostb(1:n) + s*Basis(1:n)
252
else IF (BCName == 'bed') Then
253
coeff = SUM(NodeCost(1:n) * dBasisdx(1:n,1))
254
coeff = coeff * coeff
255
IF (DIM.eq.3) then
256
coeff=coeff+ &
257
SUM(NodeCost(1:n)*dBasisdx(1:n,2))*SUM(NodeCost(1:n) * dBasisdx(1:n,2))
258
END IF
259
Cost_bed=Cost_bed+coeff*s
260
else
261
coeff = 0.0
262
End if
263
264
End do
265
IF (BCName == 'surface') Then
266
c=DIM + 1 ! size of the velocity variable
267
Do j=1,n
268
Do i=1,DIM
269
k=(VbPerm(NodeIndexes(j))-1)*c+i
270
Vb(k)=Vb(k)+NodeCostb(j)*NodeCost_der(i,j)
271
End Do
272
End Do
273
END if
274
End do
275
276
Cost=Cost_surf+0.5*Lambda*Cost_bed
277
278
TimeVar => VariableGet( Model % Mesh % Variables, 'Time' )
279
280
IF (Parallel) THEN
281
CALL MPI_ALLREDUCE(Cost,Cost_S,1,&
282
MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)
283
CALL MPI_ALLREDUCE(Cost_surf,Cost_surf_S,1,&
284
MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)
285
CALL MPI_ALLREDUCE(Cost_bed,Cost_bed_S,1,&
286
MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)
287
CostVar => VariableGet( Model % Mesh % Variables, CostSolName )
288
IF (ASSOCIATED(CostVar)) THEN
289
CostVar % Values(1)=Cost_S
290
END IF
291
IF (ParEnv % MyPE == 0) then
292
OPEN (12, FILE=CostFile,POSITION='APPEND')
293
write(12,'(e13.5,2x,e15.8,2x,e15.8,2x,e15.8)') TimeVar % Values(1),Cost_S,Cost_surf_S,Cost_bed_S
294
CLOSE(12)
295
End if
296
ELSE
297
CostVar => VariableGet( Model % Mesh % Variables, CostSolName )
298
IF (ASSOCIATED(CostVar)) THEN
299
CostVar % Values(1)=Cost
300
END IF
301
OPEN (12, FILE=CostFile,POSITION='APPEND')
302
write(12,'(e13.5,2x,e15.8,2x,e15.8,2x,e15.8)') TimeVar % Values(1),Cost,Cost_surf,Cost_bed
303
close(12)
304
Cost_S=Cost
305
END IF
306
307
Solver % Variable % Values(1)=Cost_S
308
Solver % Variable % Norm = Cost_S
309
IF (SIZE(Solver%Variable % Values) == Solver%Variable % DOFs) THEN
310
!! MIMIC COMPUTE CHANGE STYLE
311
Change=2.*(Cost_S-Oldf)/(Cost_S+Oldf)
312
Change=abs(Change)
313
WRITE( Message, '(a,g15.8,g15.8,a)') &
314
'SS (ITER=1) (NRM,RELC): (',Cost_S, Change,&
315
' ) :: Cost'
316
CALL Info( 'ComputeChange', Message, Level=3 )
317
Oldf=Cost_S
318
ENDIF
319
320
Return
321
!------------------------------------------------------------------------------
322
END SUBROUTINE CostSolver_Adjoint
323
!------------------------------------------------------------------------------
324
! *****************************************************************************
325
326