Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/AdjointStokes/AdjointStokes_GradientMu.F90
3206 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
! .sif parameters:
40
! In the Solver section:
41
! - Flow Solution Name = String ; name of the variable for the direct problem ("Flow Solution" default)
42
! - Adjoint Solution Name = String ; name of the variable for the Adjoint system ("Adjoint" default)
43
! - Optimized Variable Name = String ; ("Mu" default)
44
! - Gradient Variable Name = String ; t ("DJDMu" default)
45
!
46
! Sometimes a modified function of viscosity is used such that viscosity != optvar and instead
47
! viscosity = f(optvar) where optvar is the variable to be optimised. In this case the 'Viscosity
48
! derivative' must be set in the material section. The USF_CoV functions can be used for this.
49
! For example, for the case viscosity = optvar^2, viscosity can be set like this in the material section:
50
! viscosity = variable optvar
51
! REAL procedure "ElmerIceUSF" "Asquare"
52
! And the partial derivative can be set like this:
53
! Viscosity derivative = Variable optvar
54
! REAL procedure "ElmerIceUSF" "Asquare_d"
55
!
56
! Execute this solver in the main ice body in conjunction with :
57
! -CostSolver_Adjoint.f90: To compute the cost function;
58
! !!ATTENTION!! : No regularistaion yet put Lamda=Real 0.0 for the computation of the cost function
59
! -Optimise_m1qn3[Serial/Parallel].f90: for the optimization
60
!
61
! *****************************************************************************
62
SUBROUTINE AdjointStokes_GradientMuSolver( Model,Solver,dt,TransientSimulation )
63
!------------------------------------------------------------------------------
64
!******************************************************************************
65
USE DefUtils
66
USE MaterialModels
67
IMPLICIT NONE
68
!------------------------------------------------------------------------------
69
TYPE(Solver_t) :: Solver
70
TYPE(Model_t) :: Model
71
72
REAL(KIND=dp) :: dt
73
LOGICAL :: TransientSimulation
74
!
75
!!!! Variables utiles pour les elements et les fonctions de base
76
TYPE(Element_t),POINTER :: Element
77
TYPE(Nodes_t) :: ElementNodes
78
TYPE(GaussIntegrationPoints_t) :: IntegStuff
79
TYPE(ValueList_t), POINTER :: SolverParams,Material
80
TYPE(ValueList_t), POINTER :: BC
81
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(:)
90
INTEGER, POINTER :: GradPerm(:), VeloNPerm(:),VeloDPerm(:)
91
CHARACTER(LEN=MAX_NAME_LEN) ::GradSolName,NeumannSolName,DirichletSolName
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
REAL(kind=dp),allocatable,SAVE :: NodalDer(:)
102
LOGICAL :: HaveDer
103
104
integer :: i,j,t,n,NMAX,NpN,DIM,e,p,q
105
106
CHARACTER(LEN=MAX_NAME_LEN) :: ViscosityFlag
107
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,GradSolName
115
save VisitedNode,db,Basis,dBasisdx
116
save Ux,Uy,Uz
117
save c2n,c3n
118
save NodalViscosityb
119
120
!!!! Firsttime Do some allocation and initialisation
121
If (Firsttime) then
122
123
DIM = CoordinateSystemDimension()
124
WRITE(SolverName, '(A)') 'DJDMu_Adjoint'
125
126
NMAX=Solver % Mesh % NumberOfNodes
127
NpN=Model % MaxElementNodes
128
129
allocate(VisitedNode(NMAX),db(NMAX), &
130
Basis(NpN), &
131
dBasisdx(NpN,3), &
132
Ux(NpN),Uy(NpN),Uz(NpN),&
133
c2n(NpN),c3n(NpN),&
134
NodalViscosityb(NpN))
135
136
allocate(NodalDer(NMAX))
137
138
!!!!!!!!!!! get Solver Variables
139
SolverParams => GetSolverParams()
140
141
NeumannSolName = GetString( SolverParams,'Flow Solution Name', Found)
142
IF(.NOT.Found) THEN
143
CALL WARN(SolverName,'Keyword >Flow Solution Name< not found in section >Solver<')
144
CALL WARN(SolverName,'Taking default value >Flow Solution<')
145
WRITE(NeumannSolName,'(A)') 'Flow Solution'
146
END IF
147
DirichletSolName = GetString( SolverParams,'Adjoint Solution Name', Found)
148
IF(.NOT.Found) THEN
149
CALL WARN(SolverName,'Keyword >Adjoint Solution Name< not found in section >Solver<')
150
CALL WARN(SolverName,'Taking default value >VeloD<')
151
WRITE(DirichletSolName,'(A)') 'VeloD'
152
END IF
153
GradSolName = GetString( SolverParams,'Gradient Variable Name', Found)
154
IF(.NOT.Found) THEN
155
CALL WARN(SolverName,'Keyword >Gradient Variable Name< not found in section >Solver<')
156
CALL WARN(SolverName,'Taking default value >DJDMu<')
157
WRITE(GradSolName,'(A)') 'DJDmu'
158
END IF
159
160
!!! End of First visit
161
Firsttime=.false.
162
Endif
163
164
! Get variables needed by the Solver
165
166
GradVariable => VariableGet( Solver % Mesh % Variables, GradSolName,UnFoundFatal=UnFoundFatal)
167
GradValues => GradVariable % Values
168
GradPerm => GradVariable % Perm
169
GradValues=0._dp
170
171
VeloSolN => VariableGet( Solver % Mesh % Variables, NeumannSolName,UnFoundFatal=UnFoundFatal)
172
VelocityN => VeloSolN % Values
173
VeloNPerm => VeloSolN % Perm
174
175
VeloSolD => VariableGet( Solver % Mesh % Variables, DirichletSolName,UnFoundFatal=UnFoundFatal)
176
VelocityD => VeloSolD % Values
177
VeloDPerm => VeloSolD % Perm
178
179
VisitedNode=0.0_dp
180
db=0.0_dp
181
182
Elements: DO e=1,Solver % NumberOfActiveElements
183
184
Element => GetActiveElement(e)
185
Material => GetMaterial()
186
CALL GetElementNodes( ElementNodes )
187
n = GetElementNOFNodes()
188
NodeIndexes => Element % NodeIndexes
189
190
NodalDer(1:n) = ListGetReal(Material,'Viscosity derivative',n,NodeIndexes,Found=HaveDer)
191
192
VisitedNode(NodeIndexes(1:n))=VisitedNode(NodeIndexes(1:n))+1.0_dp
193
194
Ux=0.0_dp
195
Uy=0.0_dp
196
Uz=0.0_dp
197
Ux(1:n)=VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(1:n))-1)+1)
198
Uy(1:n)=VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(1:n))-1)+2)
199
If (DIM.eq.3) Uz(1:n)=VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(1:n))-1)+3)
200
201
!!!!
202
nodalViscosityb=0.0_dp
203
204
IntegStuff = GaussPoints( Element )
205
206
IPs: DO t=1,IntegStuff%n
207
208
u = IntegStuff % u(t)
209
v = IntegStuff % v(t)
210
w =IntegStuff % w(t)
211
212
stat = ElementInfo( Element, ElementNodes, u, v, w,SqrtElementMetric, &
213
Basis, dBasisdx) !removed bubbles
214
215
s = SqrtElementMetric * IntegStuff % s(t)
216
217
mub=0.0_dp
218
p_loop: DO p=1,n
219
q_loop: DO q=1,n
220
i_loop: DO i=1,DIM
221
j_loop: DO j=1,DIM
222
mub=mub+ s * dBasisdx(q,j) * dBasisdx(p,j) * &
223
(- VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(q))-1)+i) * &
224
VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(p))-1)+i))
225
226
mub=mub+ s * dBasisdx(q,i) * dBasisdx(p,j) * &
227
(- VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(q))-1)+j) * &
228
& VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(p))-1)+i))
229
END DO j_loop
230
END DO i_loop
231
END DO q_loop
232
END DO p_loop
233
234
ViscosityFlag = ListGetString( Material,'Viscosity Model', GotIt,UnFoundFatal)
235
236
SELECT CASE( ViscosityFlag )
237
CASE('power law')
238
DO j=1,3
239
dVelodx(1,j) = SUM( Ux(1:n)*dBasisdx(1:n,j) )
240
dVelodx(2,j) = SUM( Uy(1:n)*dBasisdx(1:n,j) )
241
dVelodx(3,j) = SUM( Uz(1:n)*dBasisdx(1:n,j) )
242
END DO
243
244
Velo(1) = SUM( Basis(1:n) * Ux(1:n) )
245
Velo(2) = SUM( Basis(1:n) * Uy(1:n) )
246
Velo(3) = SUM( Basis(1:n) * Uz(1:n) )
247
248
ss = SecondInvariant(Velo,dVelodx)/2
249
250
c2n = ListGetReal( Material, 'Viscosity Exponent', n, NodeIndexes )
251
c2 = SUM( Basis(1:n) * c2n(1:n) )
252
253
s = ss
254
255
c3n = ListGetReal( Material, 'Critical Shear Rate',n, NodeIndexes ,gotIt )
256
IF (GotIt) THEN
257
c3 = SUM( Basis(1:n) * c3n(1:n) )
258
IF(s < c3**2) THEN
259
s = c3**2
260
END IF
261
END IF
262
263
Viscosityb=mub*s**((c2-1)/2)
264
265
CASE default
266
CALL FATAL(SolverName,'Viscosity Model has to be power Law')
267
END SELECT
268
269
nodalViscosityb(1:n)=nodalViscosityb(1:n)+Viscosityb*Basis(1:n)
270
END DO IPs
271
272
IF (HaveDer) THEN
273
nodalViscosityb(1:n)=nodalViscosityb(1:n)*NodalDer(1:n)
274
END IF
275
276
db(NodeIndexes(1:n)) = db(NodeIndexes(1:n)) + nodalViscosityb(1:n)
277
END DO Elements
278
279
DO t=1,Solver % Mesh % NumberOfNodes
280
IF (VisitedNode(t).LT.1.0_dp) CYCLE
281
GradValues(GradPerm(t))=db(t)
282
END DO
283
284
RETURN
285
286
!------------------------------------------------------------------------------
287
END SUBROUTINE AdjointStokes_GradientMuSolver
288
!------------------------------------------------------------------------------
289
290
291
292