Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/DJDmu_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 nodal gradient of the Cost function with respect to the ice viscosity
33
! for the Robin inverse method (Arthern & Gudmundsson, J. Glaciol., 2010)
34
!
35
! Serial/Parallel and 2D/3D
36
!
37
!
38
! .sif parameters:
39
! In the Solver section:
40
! - Neumann Solution Name = String ; name of the variable for the neumann problem ("Flow Solution" default)
41
! - Dirichlet Solution Name = String ; name of the variable for the Dirichlet problem ("VeloD" default)
42
! - Optimized Variable Name = String ; ("Mu" default)
43
! - Gradient Variable Name = String ; t ("DJDMu" default)
44
! - SquareFormulation = Logical ; True if the viscosity ios defined as alpha^2
45
! and optimisation on alpha to ensure Mu> 0
46
!
47
!
48
! In the Material Section:
49
! if SquareFormulation = False:
50
! Viscosity = Equals mu
51
! If SquareFormulation = True:
52
! Viscosity = Variable mu
53
! Real MATC "tx*tx"
54
!
55
!
56
! Execute this solver in the main ice body in conjunction with :
57
! -CostSolver_Robin.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 DJDMu_Robin( Model,Solver,dt,TransientSimulation )
63
!------------------------------------------------------------------------------
64
!******************************************************************************
65
USE DefUtils
66
IMPLICIT NONE
67
!------------------------------------------------------------------------------
68
TYPE(Solver_t) :: Solver
69
TYPE(Model_t) :: Model
70
71
REAL(KIND=dp) :: dt
72
LOGICAL :: TransientSimulation
73
!
74
!!!! Variables utiles pour les elements et les fonctions de base
75
TYPE(Element_t),POINTER :: Element
76
TYPE(Nodes_t) :: ElementNodes
77
TYPE(GaussIntegrationPoints_t) :: IntegStuff
78
TYPE(ValueList_t), POINTER :: SolverParams, Material
79
real(kind=dp),allocatable :: Basis(:),dBasisdx(:,:)
80
real(kind=dp) :: u,v,w,SqrtElementMetric
81
INTEGER, POINTER :: NodeIndexes(:)
82
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName
83
84
!!!!! variables Elmer
85
TYPE(Variable_t), POINTER :: Variable, GradVariable,VeloSolN,VeloSolD
86
REAL(KIND=dp), POINTER :: Values(:),GradValues(:),VelocityN(:),VelocityD(:)
87
INTEGER, POINTER :: Perm(:),GradPerm(:),VeloNPerm(:),VeloDPerm(:)
88
CHARACTER(LEN=MAX_NAME_LEN) :: VarSolName,GradSolName,NeumannSolName,DirichletSolName
89
90
!! autres variables
91
real(kind=dp),allocatable :: VisitedNode(:),db(:)
92
real(kind=dp),allocatable :: NodeDJ(:),NodalVeloN(:,:),NodalVeloD(:,:)
93
real(kind=dp),allocatable :: m(:),cs(:)
94
real(kind=dp) :: vn(3),vd(3),LGradN(3,3),LGradD(3,3),SRD(3,3),SRN(3,3)
95
real(kind=dp) :: IPGrad,SecInv
96
97
integer :: i,j,t,n,NMAX,NActiveNodes,DIM
98
99
Logical :: Firsttime=.true.,Found,stat,UnFoundFatal=.TRUE.
100
logical :: SquareFormulation
101
102
103
save Firsttime,DIM
104
save ElementNodes
105
save SolverName
106
save NeumannSolName,DirichletSolName,VarSolName,GradSolName
107
save SquareFormulation
108
save VisitedNode,db,NodeDJ,Basis,dBasisdx,NodalVeloN,NodalVeloD
109
save m,cs
110
111
If (Firsttime) then
112
113
DIM = CoordinateSystemDimension()
114
WRITE(SolverName, '(A)') 'DJDMu_Robin'
115
116
NMAX=Solver % Mesh % NumberOfNodes
117
allocate(VisitedNode(NMAX),db(NMAX), NodeDJ(Model % MaxElementNodes), &
118
Basis(Model % MaxElementNodes), &
119
dBasisdx(Model % MaxElementNodes,3), &
120
NodalVeloN(3,Model % MaxElementNodes),NodalVeloD(3,Model % MaxElementNodes), &
121
m(Model % MaxElementNodes),cs(Model % MaxElementNodes))
122
123
!!!!!!!!!!! get Solver Variables
124
SolverParams => GetSolverParams()
125
126
NeumannSolName = GetString( SolverParams,'Neumann Solution Name', Found)
127
IF(.NOT.Found) THEN
128
CALL WARN(SolverName,'Keyword >Neumann Solution Name< not found in section >Solver<')
129
CALL WARN(SolverName,'Taking default value >Flow Solution<')
130
WRITE(NeumannSolName,'(A)') 'Flow Solution'
131
END IF
132
DirichletSolName = GetString( SolverParams,'Dirichlet Solution Name', Found)
133
IF(.NOT.Found) THEN
134
CALL WARN(SolverName,'Keyword >Dirichlet Solution Name< not found in section >Solver<')
135
CALL WARN(SolverName,'Taking default value >VeloD<')
136
WRITE(DirichletSolName,'(A)') 'VeloD'
137
END IF
138
139
VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)
140
IF(.NOT.Found) THEN
141
CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')
142
CALL WARN(SolverName,'Taking default value >Mu<')
143
WRITE(VarSolName,'(A)') 'Mu'
144
END IF
145
GradSolName = GetString( SolverParams,'Gradient Variable Name', Found)
146
IF(.NOT.Found) THEN
147
CALL WARN(SolverName,'Keyword >Gradient Variable Name< not found in section >Solver<')
148
CALL WARN(SolverName,'Taking default value >DJDMu<')
149
WRITE(GradSolName,'(A)') 'DJDmu'
150
END IF
151
SquareFormulation=GetLogical( SolverParams, 'SquareFormulation', Found)
152
IF(.NOT.Found) THEN
153
CALL WARN(SolverName,'Keyword >SquareFormulation< not found in section >Solver<')
154
CALL WARN(SolverName,'Taking default value >FALSE<')
155
SquareFormulation=.FALSE.
156
END IF
157
158
!!! End of First visit
159
Firsttime=.false.
160
Endif
161
162
! Get variables needed by the Solver
163
164
GradVariable => VariableGet( Solver % Mesh % Variables, GradSolName,UnFoundFatal=UnFoundFatal)
165
GradValues => GradVariable % Values
166
GradPerm => GradVariable % Perm
167
168
Variable => VariableGet( Solver % Mesh % Variables, VarSolName,UnFoundFatal=UnFoundFatal)
169
Values => Variable % Values
170
Perm => Variable % Perm
171
172
VeloSolN => VariableGet( Solver % Mesh % Variables, NeumannSolName,UnFoundFatal=UnFoundFatal)
173
VelocityN => VeloSolN % Values
174
VeloNPerm => VeloSolN % Perm
175
176
VeloSolD => VariableGet( Solver % Mesh % Variables, DirichletSolName,UnFoundFatal=UnFoundFatal)
177
VelocityD => VeloSolD % Values
178
VeloDPerm => VeloSolD % Perm
179
180
181
VisitedNode=0.0_dp
182
db=0.0_dp
183
184
DO t=1,Solver % NumberOfActiveElements
185
186
Element => GetActiveElement(t)
187
Material => GetMaterial()
188
CALL GetElementNodes( ElementNodes )
189
n = GetElementNOFNodes()
190
NodeIndexes => Element % NodeIndexes
191
192
NodalVeloN = 0.0d0
193
NodalVeloD = 0.0d0
194
DO i=1, dim
195
NodalVeloN(i,1:n) = VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(1:n))-1)+i)
196
NodalVeloD(i,1:n) = VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(1:n))-1)+i)
197
END DO
198
199
!! exposant nodal
200
m=ListGetReal(Material, 'Viscosity Exponent', n, NodeIndexes)
201
cs=ListGetReal(Material, 'Critical Shear Rate', n, NodeIndexes)
202
203
! Compute Nodal Value of DJDmu
204
Do i=1,n
205
VisitedNode(NodeIndexes(i))=VisitedNode(NodeIndexes(i))+1.0_dp
206
207
u=Element % Type % NodeU(i)
208
v=Element % Type % NodeV(i)
209
w=Element % Type % NodeW(i)
210
211
stat=ElementInfo(Element,ElementNodes,u,v,w, &
212
SqrtElementMetric,Basis,dBasisdx)
213
214
LGradN=0.0_dp
215
LGradD=0.0_dp
216
LGradN = MATMUL( NodalVeloN(:,1:n), dBasisdx(1:n,:) )
217
SRN = 0.5 * ( LGradN + TRANSPOSE(LGradN) )
218
LGradD = MATMUL( NodalVeloD(:,1:n), dBasisdx(1:n,:) )
219
SRD = 0.5 * ( LGradD + TRANSPOSE(LGradD) )
220
221
NodeDJ(i)=2._dp*(calcNorm2(SRD)-calcNorm2(SRN))
222
if (m(i).ne.1.0_dp) then
223
SecInv=2.0_dp*calcNorm2(SRN) ! le carre du Second invariant de D
224
If (SecInv.lt.cs(i)*cs(i)) SecInv=cs(i)*cs(i)
225
NodeDJ(i)=NodeDJ(i)*SecInv**(0.5_dp*(m(i)-1._dp))
226
end if
227
228
if (SquareFormulation) then
229
NodeDJ(i)=NodeDJ(i)*2.0_dp*Values(Perm(NodeIndexes(i)))
230
End if
231
End do
232
233
! Compute Integrated Nodal Value of DJDmu
234
IntegStuff = GaussPoints( Element )
235
DO j=1,IntegStuff % n
236
U = IntegStuff % u(j)
237
V = IntegStuff % v(j)
238
W = IntegStuff % w(j)
239
stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &
240
Basis,dBasisdx )
241
Do i=1,n
242
IPGrad=NodeDJ(i)*Basis(i)
243
244
db(NodeIndexes(i)) = db(NodeIndexes(i)) + &
245
SqrtElementMetric*IntegStuff % s(j)*IPGrad
246
End do
247
End Do
248
End do
249
250
Do t=1,Solver % Mesh % NumberOfNodes
251
if (VisitedNode(t).lt.1.0_dp) cycle
252
GradValues(GradPerm(t))=db(t)
253
End do
254
255
Return
256
257
CONTAINS
258
259
function calcNorm(v) result(v2)
260
implicit none
261
real(kind=dp) :: v(3),v2
262
263
v2=v(1)*v(1)+v(2)*v(2)+v(3)*v(3)
264
end function calcNorm
265
266
function calcNorm2(v) result(v2)
267
implicit none
268
real(kind=dp) :: v(3,3),v2
269
integer :: i,j
270
271
v2=0._dp
272
Do i=1,3
273
Do j=1,3
274
v2=v2+v(i,j)*v(j,i)
275
End do
276
End do
277
278
end function calcNorm2
279
!------------------------------------------------------------------------------
280
END SUBROUTINE DJDMu_Robin
281
!------------------------------------------------------------------------------
282
283
284
285