Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/CostSolver_Robin.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:
26
! * Email:
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date:
30
! *
31
! *****************************************************************************
32
!Compute the Cost function of the Arhtern/Gudmundsson inverse Problem
33
! as Sum_Surface (vn-vd).(sigma_n-sigma_d).n
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
! - Solutions of Neumann and Dirchlet problem
41
! (Velocities Only, Stresses are computed here)
42
! - Lambda and Beta for regularization
43
! - define in the sif Name='surface' and Name='bed' in appropriate BC.
44
!
45
! *****************************************************************************
46
SUBROUTINE CostSolver_Robin_init( Model,Solver,dt,TransientSimulation )
47
!------------------------------------------------------------------------------
48
USE DefUtils
49
50
IMPLICIT NONE
51
!------------------------------------------------------------------------------
52
TYPE(Solver_t), TARGET :: Solver
53
TYPE(Model_t) :: Model
54
REAL(KIND=dp) :: dt
55
LOGICAL :: TransientSimulation
56
!------------------------------------------------------------------------------
57
! Local variables
58
!------------------------------------------------------------------------------
59
INTEGER :: NormInd, LineInd, i
60
LOGICAL :: GotIt, MarkFailed, AvoidFailed
61
CHARACTER(LEN=MAX_NAME_LEN) :: Name
62
63
Name = ListGetString( Solver % Values, 'Equation',GotIt)
64
IF( .NOT. ListCheckPresent( Solver % Values,'Variable') ) THEN
65
CALL ListAddString( Solver % Values,'Variable',&
66
'-nooutput -global '//TRIM(Name)//'_var')
67
END IF
68
END
69
! *****************************************************************************
70
SUBROUTINE CostSolver_Robin( Model,Solver,dt,TransientSimulation )
71
!------------------------------------------------------------------------------
72
!******************************************************************************
73
USE DefUtils
74
USE MaterialModels
75
IMPLICIT NONE
76
!------------------------------------------------------------------------------
77
TYPE(Solver_t) :: Solver
78
TYPE(Model_t) :: Model
79
80
REAL(KIND=dp) :: dt
81
LOGICAL :: TransientSimulation
82
!
83
CHARACTER(LEN=MAX_NAME_LEN), PARAMETER :: DefaultCostFile = 'CostOfT.dat'
84
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName,NeumannSolName,DirichletSolName,CostFile
85
CHARACTER(LEN=MAX_NAME_LEN) :: BCName
86
CHARACTER(LEN=MAX_NAME_LEN) :: CostSolName, VarSolName
87
TYPE(Solver_t), POINTER :: ParSolver
88
TYPE(Element_t),POINTER :: Element,Parent
89
TYPE(Variable_t), POINTER :: TimeVar,CostVar
90
TYPE(ValueList_t), POINTER :: BC,SolverParams
91
TYPE(Nodes_t) :: ElementNodes,ParentNodes
92
TYPE(GaussIntegrationPoints_t) :: IntegStuff
93
INTEGER, POINTER :: NodeIndexes(:)
94
95
Logical :: Firsttime=.true.,Found,Parallel,stat
96
integer :: i,j,k,l,t,n,np,NMAX,DIM,ierr
97
98
real(kind=dp) :: Cost,Cost_surf,Cost_bed,Cost_S,Cost_surf_S,Cost_bed_S,Change
99
real(kind=dp),SAVE :: Oldf=0._dp
100
real(kind=dp) :: coeff,sTimesN
101
real(kind=dp) :: Viscosity,Viscosityn,Viscosityd
102
real(kind=dp) :: pressuren,pressured
103
real(kind=dp),dimension(3) :: Normal,vn,vd
104
real(kind=dp),dimension(3,3) :: LGradn,LGradd,SRn,SRd,Sn,Sd
105
real(kind=dp) :: Lambda
106
real(kind=dp) :: u,v,w,s,SqrtElementMetric,PSqrtElementMetric,x,y,z
107
REAL(KIND=dp),allocatable :: NodalBeta(:),NodalViscosity(:)
108
REAL(KIND=dp),allocatable :: Nodalvn(:,:),Nodalvd(:,:),Nodalvelon(:,:),Nodalvelod(:,:)
109
REAL(KIND=dp),allocatable :: Basis(:), PBasis(:),dBasisdx(:,:),PdBasisdx(:,:)
110
111
CHARACTER*10 :: date,temps
112
113
save Firsttime,Parallel,CostFile,DIM,ElementNodes,ParentNodes
114
save SolverName,NeumannSolName,DirichletSolName,VarSolname,CostSolName
115
save Lambda
116
save NodalBeta,NodalViscosity,Nodalvn,Nodalvd,Nodalvelon,Nodalvelod
117
save Basis,PBasis,dBasisdx,PdBasisdx
118
119
120
If (Firsttime) then
121
DIM = CoordinateSystemDimension()
122
WRITE(SolverName, '(A)') 'CostSolver_Robin'
123
124
!!!!!!! Check for parallel run
125
Parallel = (ParEnv % PEs > 1 )
126
127
NMAX= Model % MaxElementNodes
128
allocate(NodalBeta(NMAX),NodalViscosity(NMAX), &
129
Nodalvn(DIM+1,NMAX),Nodalvd(DIM+1,NMAX), Nodalvelon(3,NMAX),Nodalvelod(3,NMAX), &
130
Basis(NMAX),PBasis(NMAX),&
131
dBasisdx(NMAX,3),PdBasisdx(NMAX,3))
132
133
!!!!!!!!!!! get Solver Variables
134
SolverParams => GetSolverParams()
135
136
CostFile = ListGetString(Solver % Values,'Cost Filename',Found )
137
IF (.NOT. Found) CostFile = DefaultCostFile
138
CALL DATE_AND_TIME(date,temps)
139
If (Parallel) then
140
if (ParEnv % MyPe.EQ.0) then
141
OPEN (12, FILE=CostFile)
142
write(12,'(a1,a2,a1,a2,a1,a4,5x,a2,a1,a2,a1,a2)') '#',date(5:6),'/',date(7:8),'/',date(1:4), &
143
temps(1:2),':',temps(3:4),':',temps(5:6)
144
CLOSE(12)
145
End if
146
Else
147
OPEN (12, FILE=CostFile)
148
write(12,'(a1,a2,a1,a2,a1,a4,5x,a2,a1,a2,a1,a2)') '#',date(5:6),'/',date(7:8),'/',date(1:4), &
149
temps(1:2),':',temps(3:4),':',temps(5:6)
150
CLOSE(12)
151
End if
152
153
154
NeumannSolName = GetString( SolverParams,'Neumann Solution Name', Found)
155
IF(.NOT.Found) THEN
156
CALL WARN(SolverName,'Keyword >Neumann Solution Name< not found in section >Equation<')
157
CALL WARN(SolverName,'Taking default value >Flow Solution<')
158
WRITE(NeumannSolName,'(A)') 'Flow Solution'
159
END IF
160
161
DirichletSolName = GetString( SolverParams,'Dirichlet Solution Name', Found)
162
IF(.NOT.Found) THEN
163
CALL WARN(SolverName,'Keyword >Dirichlet Solution Name< not found in section >Equation<')
164
CALL WARN(SolverName,'Taking default value >Flow Solution<')
165
WRITE(NeumannSolName,'(A)') 'Flow Solution'
166
End if
167
168
Lambda = GetConstReal( SolverParams,'Lambda', Found)
169
IF(.NOT.Found) THEN
170
CALL WARN(SolverName,'Keyword >Lambda< not found in section >Equation<')
171
CALL WARN(SolverName,'Taking default value Lambda=0.0')
172
Lambda = 0.0
173
End if
174
CostSolName = GetString( SolverParams,'Cost Variable Name', Found)
175
IF(.NOT.Found) THEN
176
CALL WARN(SolverName,'Keyword >Cost Variable Name< not found in section >Solver<')
177
CALL WARN(SolverName,'Taking default value >CostValue<')
178
WRITE(CostSolName,'(A)') 'CostValue'
179
END IF
180
VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)
181
IF(.NOT.Found) THEN
182
CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')
183
CALL WARN(SolverName,'Taking default value >Beta<')
184
WRITE(VarSolName,'(A)') 'Beta'
185
END IF
186
187
188
189
!!! End of First visit
190
Firsttime=.false.
191
Endif
192
193
194
Cost=0._dp
195
Cost_surf=0.0_dp
196
Cost_bed=0.0_dp
197
198
DO t=1,Solver % Mesh % NumberOfBoundaryElements
199
Element => GetBoundaryElement(t)
200
201
BC => GetBC()
202
IF ( .NOT. ASSOCIATED(BC) ) CYCLE
203
204
BCName = ListGetString( BC,'Name', Found)
205
IF((BCName /= 'surface').AND.(BCName /= 'bed')) CYCLE
206
207
208
CALL GetElementNodes( ElementNodes )
209
n = GetElementNOFNodes()
210
NodeIndexes => Element % NodeIndexes
211
212
213
IF (BCName == 'surface') THEN
214
Parent => Element % BoundaryInfo % Left
215
IF ( .NOT. ASSOCIATED(Parent) ) &
216
Parent => Element % BoundaryInfo % Right
217
218
np = GetElementNOFDOFs(Parent)
219
CALL GetElementNodes( ParentNodes, Parent )
220
221
NodalViscosity(1:np) = GetReal( GetMaterial(Parent),'Viscosity',UElement=Parent )
222
CALL GetVectorLocalSolution(Nodalvn,NeumannSolName,UElement=Parent )
223
CALL GetVectorLocalSolution(Nodalvd,DirichletSolName,UElement=Parent )
224
NodalVelon=0._dp
225
NodalVelod=0._dp
226
Do k=1,DIM
227
NodalVelon(k,1:np)=Nodalvn(k,1:np)
228
NodalVelod(k,1:np)=Nodalvd(k,1:np)
229
End do
230
231
ELSE IF (BCName == 'bed') Then
232
CALL GetScalarLocalSolution(NodalBeta,VarSolName,Element)
233
END IF
234
235
!------------------------------------------------------------------------------
236
! Numerical integration
237
!------------------------------------------------------------------------------
238
IntegStuff = GaussPoints( Element )
239
240
DO i=1,IntegStuff % n
241
U = IntegStuff % u(i)
242
V = IntegStuff % v(i)
243
W = IntegStuff % w(i)
244
!------------------------------------------------------------------------------
245
! Basis function values & derivatives at the integration point
246
!------------------------------------------------------------------------------
247
stat = ElementInfo( Element,ElementNodes,U,V,W,SqrtElementMetric, &
248
Basis,dBasisdx )
249
250
s = SqrtElementMetric * IntegStuff % s(i)
251
IF ( CurrentCoordinateSystem() /= Cartesian ) THEN
252
x = SUM( ElementNodes % x(1:n)*Basis(1:n) )
253
y = SUM( ElementNodes % y(1:n)*Basis(1:n) )
254
z = SUM( ElementNodes % z(1:n)*Basis(1:n) )
255
s = s * CoordinateSqrtMetric(x,y,z)
256
END IF
257
258
IF (BCName == 'surface') THEN
259
Normal = NormalVector( Element, ElementNodes, U, V, .TRUE. )
260
261
CALL GetParentUVW( Element,n,Parent,np,U,V,W,Basis )
262
stat = ElementInfo( Parent,ParentNodes,U,V,W,PSqrtElementMetric, &
263
PBasis,PdBasisdx )
264
265
Viscosity = SUM( NodalViscosity(1:np)*PBasis(1:np) )
266
267
Do k=1,3
268
vn(k)=SUM( Nodalvelon(k,1:np)*PBasis(1:np) )
269
vd(k)=SUM( Nodalvelod(k,1:np)*PBasis(1:np) )
270
End do
271
272
Viscosityn = EffectiveViscosity( Viscosity, 1.0_dp, NodalVelon(1,1:np), Nodalvelon(2,1:np), Nodalvelon(3,1:np), &
273
Parent, ParentNodes, np, np, u, v, w, LocalIP=t )
274
LGradn = MATMUL( NodalVelon(:,1:np), PdBasisdx(1:np,:) )
275
SRn = 0.5 * ( LGradn + TRANSPOSE(LGradn) )
276
Pressuren = SUM( Nodalvn(DIM+1,1:np)*PBasis(1:np) )
277
sn=2.0*Viscosityn*SRn
278
Do k=1,3
279
sn(k,k)=sn(k,k)-Pressuren
280
End do
281
282
283
Viscosityd = EffectiveViscosity( Viscosity, 1.0_dp, Nodalvelod(1,1:np), Nodalvelod(2,1:np), Nodalvelod(3,1:np), &
284
Parent, ParentNodes, np, np, u, v, w, LocalIP=i )
285
LGradd = MATMUL( NodalVelod(:,1:np), PdBasisdx(1:np,:) )
286
SRd = 0.5 * ( LGradd + TRANSPOSE(LGradd) )
287
Pressured = SUM( Nodalvd(DIM+1,1:np)*PBasis(1:np) )
288
sd=2.0*Viscosityd*SRd
289
Do k=1,3
290
sd(k,k)=sd(k,k)-Pressured
291
End do
292
293
coeff=0._dp
294
Do k=1,3
295
sTimesN=0.0_dp
296
Do l=1,3
297
sTimesN=sTimesN+(sn(k,l)-sd(k,l))*Normal(l)
298
End do
299
coeff=coeff+(Vn(k)-Vd(k))*sTimesN
300
End do
301
302
Cost_surf=Cost_surf+coeff*s
303
304
ELSE IF (BCName == 'bed') THEN
305
coeff=SUM(NodalBeta(1:n) * dBasisdx(1:n,1))
306
coeff=coeff*coeff
307
IF (DIM.eq.3) then
308
coeff=coeff+ &
309
SUM(NodalBeta(1:n)*dBasisdx(1:n,2))*SUM(NodalBeta(1:n) * dBasisdx(1:n,2))
310
END IF
311
Cost_bed=Cost_bed+coeff*s
312
313
END IF
314
315
End do
316
End do
317
318
Cost=Cost_surf+0.5*Lambda*Cost_bed
319
320
TimeVar => VariableGet( Solver % Mesh % Variables, 'Time' )
321
322
323
IF (Parallel) THEN
324
CALL MPI_ALLREDUCE(Cost,Cost_S,1,&
325
MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)
326
CALL MPI_ALLREDUCE(Cost_surf,Cost_surf_S,1,&
327
MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)
328
CALL MPI_ALLREDUCE(Cost_bed,Cost_bed_S,1,&
329
MPI_DOUBLE_PRECISION,MPI_SUM,ELMER_COMM_WORLD,ierr)
330
CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )
331
IF (ASSOCIATED(CostVar)) THEN
332
CostVar % Values(1)=Cost_S
333
END IF
334
IF (ParEnv % MyPE == 0) then
335
OPEN (12, FILE=CostFile,POSITION='APPEND')
336
write(12,'(e13.5,2x,e15.8,2x,e15.8,2x,e15.8)') TimeVar % Values(1),Cost_S,Cost_surf_S,Cost_bed_S
337
CLOSE(12)
338
End if
339
ELSE
340
CostVar => VariableGet( Solver % Mesh % Variables, CostSolName )
341
IF (ASSOCIATED(CostVar)) THEN
342
CostVar % Values(1)=Cost
343
END IF
344
Cost_S=Cost
345
OPEN (10, FILE=CostFile,POSITION='APPEND')
346
write(10,'(e13.5,2x,e15.8,2x,e15.8,2x,e15.8)') TimeVar % Values(1),Cost,Cost_surf,Cost_bed
347
close(10)
348
END IF
349
350
Solver % Variable % Values(1)=Cost_S
351
Solver % Variable % Norm = Cost_S
352
IF (SIZE(Solver%Variable % Values) == Solver%Variable % DOFs) THEN
353
!! MIMIC COMPUTE CHANGE STYLE
354
Change=2.*(Cost_S-Oldf)/(Cost_S+Oldf)
355
Change=abs(Change)
356
WRITE( Message, '(a,g15.8,g15.8,a)') &
357
'SS (ITER=1) (NRM,RELC): (',Cost_S, Change,&
358
' ) :: Cost'
359
CALL Info( 'ComputeChange', Message, Level=3 )
360
Oldf=Cost_S
361
ENDIF
362
363
364
Return
365
366
367
!------------------------------------------------------------------------------
368
END SUBROUTINE CostSolver_Robin
369
!------------------------------------------------------------------------------
370
! *****************************************************************************
371
372