Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/DJDmu_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:
26
! * Email:
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date:
30
! *
31
! *****************************************************************************
32
! Compute the nodal gradient of the Cost function with respect to the ice
33
! viscosity for the control inverse method
34
! (cf Morlighem, M., Ice sheet properties inferred by combining numerical
35
! modeling and remote sensing data)
36
!
37
! Serial/Parallel and 2D/3D
38
!
39
!
40
! .sif parameters:
41
! In the Solver section:
42
! - Flow Solution Name = String ; name of the variable for the direct problem ("Flow Solution" default)
43
! - Adjoint Solution Name = String ; name of the variable for the Adjoint system ("Adjoint" default)
44
! - Optimized Variable Name = String ; ("Mu" default)
45
! - Gradient Variable Name = String ; t ("DJDMu" default)
46
! - SquareFormulation = Logical ; True if the viscosity ios defined as alpha^2
47
! and optimisation on alpha to ensure Mu> 0
48
!
49
!
50
! In the Material Section:
51
! if SquareFormulation = False:
52
! Viscosity = Equals mu
53
! If SquareFormulation = True:
54
! Viscosity = Variable mu
55
! Real MATC "tx*tx"
56
!
57
!
58
! Execute this solver in the main ice body in conjunction with :
59
! -CostSolver_Adjoint.f90: To compute the cost function;
60
! !!ATTENTION!! : No regularistaion yet put Lamda=Real 0.0 for the computation of the cost function
61
! -Optimise_m1qn3[Serial/Parallel].f90: for the optimization
62
!
63
! *****************************************************************************
64
SUBROUTINE DJDMu_Adjoint( Model,Solver,dt,TransientSimulation )
65
!------------------------------------------------------------------------------
66
!******************************************************************************
67
USE DefUtils
68
USE MaterialModels
69
IMPLICIT NONE
70
!------------------------------------------------------------------------------
71
TYPE(Solver_t) :: Solver
72
TYPE(Model_t) :: Model
73
74
REAL(KIND=dp) :: dt
75
LOGICAL :: TransientSimulation
76
!
77
!!!! Variables utiles pour les elements et les fonctions de base
78
TYPE(Element_t),POINTER :: Element
79
TYPE(Nodes_t) :: ElementNodes
80
TYPE(GaussIntegrationPoints_t) :: IntegStuff
81
TYPE(ValueList_t), POINTER :: SolverParams,Material
82
real(kind=dp),allocatable :: Basis(:),dBasisdx(:,:)
83
real(kind=dp) :: u,v,w,SqrtElementMetric
84
INTEGER, POINTER :: NodeIndexes(:)
85
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName
86
87
!!!!! variables Elmer
88
TYPE(Variable_t), POINTER :: GradVariable, Variable, VeloSolN,VeloSolD
89
REAL(KIND=dp), POINTER :: GradValues(:),VelocityN(:),VelocityD(:),Values(:)
90
INTEGER, POINTER :: GradPerm(:), VeloNPerm(:),VeloDPerm(:),Perm(:)
91
CHARACTER(LEN=MAX_NAME_LEN) ::GradSolName,NeumannSolName,DirichletSolName,VarSolName
92
93
!! autres variables
94
real(kind=dp),allocatable :: VisitedNode(:),db(:)
95
real(kind=dp),allocatable,dimension(:) :: Ux,Uy,Uz
96
real(kind=dp) :: Velo(3),dVelodx(3,3)
97
real(kind=dp) :: s,ss,c2,c3
98
real(kind=dp) :: mub,Viscosityb
99
real(kind=dp),allocatable,dimension(:) :: c2n,c3n
100
real(kind=dp),allocatable,dimension(:) :: NodalViscosityb
101
102
103
integer :: i,j,t,n,NMAX,NpN,NActiveNodes,DIM,e,p,q
104
105
CHARACTER(LEN=MAX_NAME_LEN) :: ViscosityFlag
106
107
logical :: SquareFormulation
108
Logical :: Firsttime=.true.,Found,stat,gotit,UnFoundFatal=.TRUE.
109
110
111
save Firsttime,DIM
112
save ElementNodes
113
save SolverName
114
save NeumannSolName,DirichletSolName,VarSolName,GradSolName
115
save SquareFormulation
116
save VisitedNode,db,Basis,dBasisdx
117
save Ux,Uy,Uz
118
save c2n,c3n
119
save NodalViscosityb
120
121
!!!! Firsttime Do some allocation and initialisation
122
If (Firsttime) then
123
124
DIM = CoordinateSystemDimension()
125
WRITE(SolverName, '(A)') 'DJDMu_Adjoint'
126
127
NMAX=Solver % Mesh % NumberOfNodes
128
NpN=Model % MaxElementNodes
129
130
allocate(VisitedNode(NMAX),db(NMAX), &
131
Basis(NpN), &
132
dBasisdx(NpN,3), &
133
Ux(NpN),Uy(NpN),Uz(NpN),&
134
c2n(NpN),c3n(NpN),&
135
NodalViscosityb(NpN))
136
137
!!!!!!!!!!! get Solver Variables
138
SolverParams => GetSolverParams()
139
140
NeumannSolName = GetString( SolverParams,'Flow Solution Name', Found)
141
IF(.NOT.Found) THEN
142
CALL WARN(SolverName,'Keyword >Flow Solution Name< not found in section >Solver<')
143
CALL WARN(SolverName,'Taking default value >Flow Solution<')
144
WRITE(NeumannSolName,'(A)') 'Flow Solution'
145
END IF
146
DirichletSolName = GetString( SolverParams,'Adjoint Solution Name', Found)
147
IF(.NOT.Found) THEN
148
CALL WARN(SolverName,'Keyword >Adjoint Solution Name< not found in section >Solver<')
149
CALL WARN(SolverName,'Taking default value >VeloD<')
150
WRITE(DirichletSolName,'(A)') 'VeloD'
151
END IF
152
VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)
153
IF(.NOT.Found) THEN
154
CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')
155
CALL WARN(SolverName,'Taking default value >Mu<')
156
WRITE(VarSolName,'(A)') 'Mu'
157
END IF
158
GradSolName = GetString( SolverParams,'Gradient Variable Name', Found)
159
IF(.NOT.Found) THEN
160
CALL WARN(SolverName,'Keyword >Gradient Variable Name< not found in section >Solver<')
161
CALL WARN(SolverName,'Taking default value >DJDMu<')
162
WRITE(GradSolName,'(A)') 'DJDmu'
163
END IF
164
SquareFormulation=GetLogical( SolverParams, 'SquareFormulation', Found)
165
IF(.NOT.Found) THEN
166
CALL WARN(SolverName,'Logical Keyword >SquareFormulation< not found in section >Solver<')
167
CALL WARN(SolverName,'Taking default value >FALSE<')
168
SquareFormulation=.FALSE.
169
END IF
170
171
!!! End of First visit
172
Firsttime=.false.
173
Endif
174
175
! Get variables needed by the Solver
176
177
GradVariable => VariableGet( Solver % Mesh % Variables, GradSolName,UnFoundFatal=UnFoundFatal)
178
GradValues => GradVariable % Values
179
GradPerm => GradVariable % Perm
180
GradValues=0._dp
181
182
Variable => VariableGet( Solver % Mesh % Variables, VarSolName,UnFoundFatal=UnFoundFatal)
183
Values => Variable % Values
184
Perm => Variable % Perm
185
186
VeloSolN => VariableGet( Solver % Mesh % Variables, NeumannSolName,UnFoundFatal=UnFoundFatal)
187
VelocityN => VeloSolN % Values
188
VeloNPerm => VeloSolN % Perm
189
190
VeloSolD => VariableGet( Solver % Mesh % Variables, DirichletSolName,UnFoundFatal=UnFoundFatal)
191
VelocityD => VeloSolD % Values
192
VeloDPerm => VeloSolD % Perm
193
194
195
VisitedNode=0.0_dp
196
db=0.0_dp
197
198
DO e=1,Solver % NumberOfActiveElements
199
200
Element => GetActiveElement(e)
201
Material => GetMaterial()
202
CALL GetElementNodes( ElementNodes )
203
n = GetElementNOFNodes()
204
NodeIndexes => Element % NodeIndexes
205
206
VisitedNode(NodeIndexes(1:n))=VisitedNode(NodeIndexes(1:n))+1.0_dp
207
208
Ux=0.0_dp
209
Uy=0.0_dp
210
Uz=0.0_dp
211
Ux(1:n)=VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(1:n))-1)+1)
212
Uy(1:n)=VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(1:n))-1)+2)
213
If (DIM.eq.3) Uz(1:n)=VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(1:n))-1)+3)
214
215
!!!!
216
nodalViscosityb=0.0_dp
217
218
IntegStuff = GaussPoints( Element )
219
220
DO t=1,IntegStuff%n
221
222
u = IntegStuff % u(t)
223
v = IntegStuff % v(t)
224
w =IntegStuff % w(t)
225
226
stat = ElementInfo( Element, ElementNodes, u, v, w,SqrtElementMetric, &
227
Basis, dBasisdx) !removed bubbles
228
229
s = SqrtElementMetric * IntegStuff % s(t)
230
231
mub=0.0_dp
232
Do p=1,n
233
Do q=1,n
234
Do i=1,DIM
235
Do j=1,DIM
236
mub=mub+ s * dBasisdx(q,j) * dBasisdx(p,j) * &
237
(- VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(q))-1)+i) * &
238
VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(p))-1)+i))
239
240
mub=mub+ s * dBasisdx(q,i) * dBasisdx(p,j) * &
241
(- VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(q))-1)+j) * &
242
& VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(p))-1)+i))
243
End Do !j
244
End Do !i
245
End Do !q
246
End Do !p
247
248
ViscosityFlag = ListGetString( Material,'Viscosity Model', GotIt,UnFoundFatal)
249
250
SELECT CASE( ViscosityFlag )
251
CASE('power law')
252
DO j=1,3
253
dVelodx(1,j) = SUM( Ux(1:n)*dBasisdx(1:n,j) )
254
dVelodx(2,j) = SUM( Uy(1:n)*dBasisdx(1:n,j) )
255
dVelodx(3,j) = SUM( Uz(1:n)*dBasisdx(1:n,j) )
256
END DO
257
258
Velo(1) = SUM( Basis(1:n) * Ux(1:n) )
259
Velo(2) = SUM( Basis(1:n) * Uy(1:n) )
260
Velo(3) = SUM( Basis(1:n) * Uz(1:n) )
261
262
ss = SecondInvariant(Velo,dVelodx)/2
263
264
c2n = ListGetReal( Material, 'Viscosity Exponent', n, NodeIndexes )
265
c2 = SUM( Basis(1:n) * c2n(1:n) )
266
267
s = ss
268
269
c3n = ListGetReal( Material, 'Critical Shear Rate',n, NodeIndexes ,gotIt )
270
IF (GotIt) THEN
271
c3 = SUM( Basis(1:n) * c3n(1:n) )
272
IF(s < c3**2) THEN
273
s = c3**2
274
END IF
275
END IF
276
277
Viscosityb=mub*s**((c2-1)/2)
278
279
CASE default
280
CALL FATAL(SolverName,'Viscosity Model has to be power Law')
281
END SELECT
282
283
nodalViscosityb(1:n)=nodalViscosityb(1:n)+Viscosityb*Basis(1:n)
284
End Do !on IPs
285
286
IF (SquareFormulation) then
287
nodalViscosityb(1:n)=nodalViscosityb(1:n)*2.0_dp*Values(Perm(NodeIndexes(1:n)))
288
END IF
289
290
db(NodeIndexes(1:n)) = db(NodeIndexes(1:n)) + nodalViscosityb(1:n)
291
End Do ! on elements
292
293
Do t=1,Solver % Mesh % NumberOfNodes
294
if (VisitedNode(t).lt.1.0_dp) cycle
295
GradValues(GradPerm(t))=db(t)
296
End do
297
298
Return
299
300
!------------------------------------------------------------------------------
301
END SUBROUTINE DJDMu_Adjoint
302
!------------------------------------------------------------------------------
303
304
305
306