Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/DJDBeta_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 integrated gradient of the Cost function for the
33
! Arthern/Gudmindsson Inverse Problem
34
!
35
! Serial/Parallel and 2D/3D
36
!
37
! Need:
38
! - Dirichlet and Neumann Problems Solutions
39
! - Name of Beta variable and Grad Variable
40
! - Power formulation if 'Slip Coef'=10^Beta and optimization on Beta
41
! - Beta2 formulation if 'Slip Coef'=Beta^2 and optimization on Beta
42
! - Lambda : the regularization coefficient (Jr=0.5 Lambda (dBeta/dx)^2)
43
!
44
! *****************************************************************************
45
SUBROUTINE DJDBeta_Robin( Model,Solver,dt,TransientSimulation )
46
!------------------------------------------------------------------------------
47
!******************************************************************************
48
USE DefUtils
49
IMPLICIT NONE
50
!------------------------------------------------------------------------------
51
TYPE(Solver_t) :: Solver
52
TYPE(Model_t) :: Model
53
54
REAL(KIND=dp) :: dt
55
LOGICAL :: TransientSimulation
56
!
57
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName,NeumannSolName,DirichletSolName
58
CHARACTER(LEN=MAX_NAME_LEN) :: VarSolName,GradSolName
59
TYPE(Element_t),POINTER :: Element
60
TYPE(Variable_t), POINTER :: PointerToVariable, BetaVariable, VeloSolN,VeloSolD,TimeVar
61
TYPE(ValueList_t), POINTER :: SolverParams
62
TYPE(Nodes_t) :: ElementNodes
63
TYPE(GaussIntegrationPoints_t) :: IntegStuff
64
REAL(KIND=dp), POINTER :: VariableValues(:),VelocityN(:),VelocityD(:),BetaValues(:)
65
INTEGER, POINTER :: Permutation(:), VeloNPerm(:),VeloDPerm(:),BetaPerm(:),NodeIndexes(:)
66
Logical :: Firsttime=.true.,Found,stat,UnFoundFatal=.TRUE.
67
integer :: i,j,t,n,NMAX,NActiveNodes,DIM
68
real(kind=dp),allocatable :: VisitedNode(:),db(:),Basis(:),dBasisdx(:,:)
69
real(kind=dp),allocatable :: NodeDJ(:)
70
real(kind=dp) :: vn(3),vd(3)
71
real(kind=dp) :: u,v,w,SqrtElementMetric
72
real(kind=dp) :: Lambda,IPGrad
73
logical :: PowerFormulation,Beta2Formulation
74
75
76
save Firsttime,DIM
77
save ElementNodes
78
save SolverName
79
save NeumannSolName,DirichletSolName,VarSolName,GradSolName
80
save Lambda
81
save PowerFormulation,Beta2Formulation
82
83
save VisitedNode,db,NodeDJ,Basis,dBasisdx
84
85
If (Firsttime) then
86
87
DIM = CoordinateSystemDimension()
88
WRITE(SolverName, '(A)') 'DJDBeta_Robin'
89
90
NMAX=Solver % Mesh % NumberOfNodes
91
allocate(VisitedNode(NMAX),db(NMAX), NodeDJ(Model % MaxElementNodes), &
92
Basis(Model % MaxElementNodes), &
93
dBasisdx(Model % MaxElementNodes,3))
94
95
!!!!!!!!!!! get Solver Variables
96
SolverParams => GetSolverParams()
97
98
NeumannSolName = GetString( SolverParams,'Neumann Solution Name', Found)
99
IF(.NOT.Found) THEN
100
CALL WARN(SolverName,'Keyword >Neumann Solution Name< not found in section >Equation<')
101
CALL WARN(SolverName,'Taking default value >Flow Solution<')
102
WRITE(NeumannSolName,'(A)') 'Flow Solution'
103
END IF
104
DirichletSolName = GetString( SolverParams,'Dirichlet Solution Name', Found)
105
IF(.NOT.Found) THEN
106
CALL WARN(SolverName,'Keyword >Dirichlet Solution Name< not found in section >Equation<')
107
CALL WARN(SolverName,'Taking default value >VeloD<')
108
WRITE(DirichletSolName,'(A)') 'VeloD'
109
END IF
110
111
VarSolName = GetString( SolverParams,'Optimized Variable Name', Found)
112
IF(.NOT.Found) THEN
113
CALL WARN(SolverName,'Keyword >Optimized Variable Name< not found in section >Solver<')
114
CALL WARN(SolverName,'Taking default value >Beta<')
115
WRITE(VarSolName,'(A)') 'Beta'
116
END IF
117
GradSolName = GetString( SolverParams,'Gradient Variable Name', Found)
118
IF(.NOT.Found) THEN
119
CALL WARN(SolverName,'Keyword >Gradient Variable Name< not found in section >Solver<')
120
CALL WARN(SolverName,'Taking default value >DJDB<')
121
WRITE(GradSolName,'(A)') 'DJDB'
122
END IF
123
124
Lambda = GetConstReal( SolverParams,'Lambda', Found)
125
IF(.NOT.Found) THEN
126
CALL WARN(SolverName,'Keyword >Lambda< not found in section >Equation<')
127
CALL WARN(SolverName,'Taking default value Lambda=0.0')
128
Lambda = 0.0
129
End if
130
131
PowerFormulation=GetLogical( SolverParams, 'PowerFormulation', Found)
132
IF(.NOT.Found) THEN
133
CALL WARN(SolverName,'Keyword >PowerFormulation< not found in section >Equation<')
134
CALL WARN(SolverName,'Taking default value >FALSE<')
135
PowerFormulation=.FALSE.
136
END IF
137
Beta2Formulation=GetLogical( SolverParams, 'Beta2Formulation', Found)
138
IF(.NOT.Found) THEN
139
CALL WARN(SolverName,'Keyword >Beta2Formulation< not found in section >Equation<')
140
CALL WARN(SolverName,'Taking default value >FALSE<')
141
Beta2Formulation=.FALSE.
142
END IF
143
IF (PowerFormulation.and.Beta2Formulation) then
144
WRITE(Message,'(A)') 'Can t be PowerFormulation and Beta2Formulation in the same time'
145
CALL FATAL(SolverName,Message)
146
End if
147
148
!!! End of First visit
149
Firsttime=.false.
150
Endif
151
152
! Get variables needed by the Solver
153
154
PointerToVariable => VariableGet( Solver % Mesh % Variables, GradSolName,UnFoundFatal=UnFoundFatal)
155
VariableValues => PointerToVariable % Values
156
Permutation => PointerToVariable % Perm
157
VariableValues=0._dp
158
159
BetaVariable => VariableGet( Solver % Mesh % Variables, VarSolName,UnFoundFatal=UnFoundFatal)
160
BetaValues => BetaVariable % Values
161
BetaPerm => BetaVariable % Perm
162
163
VeloSolN => VariableGet( Solver % Mesh % Variables, NeumannSolName,UnFoundFatal=UnFoundFatal)
164
VelocityN => VeloSolN % Values
165
VeloNPerm => VeloSolN % Perm
166
167
VeloSolD => VariableGet( Solver % Mesh % Variables, DirichletSolName,UnFoundFatal=UnFoundFatal)
168
VelocityD => VeloSolD % Values
169
VeloDPerm => VeloSolD % Perm
170
171
172
VisitedNode=0.0_dp
173
db=0.0_dp
174
175
DO t=1,Solver % NumberOfActiveElements
176
177
Element => GetActiveElement(t)
178
CALL GetElementNodes( ElementNodes )
179
n = GetElementNOFNodes()
180
NodeIndexes => Element % NodeIndexes
181
182
! Compute Nodal Value of DJDBeta
183
Do i=1,n
184
VisitedNode(NodeIndexes(i))=VisitedNode(NodeIndexes(i))+1.0_dp
185
186
vn=0.0
187
vd=0.0
188
vn(1) = VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(i))-1)+1)
189
vn(2) = VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(i))-1)+2)
190
vd(1) = VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(i))-1)+1)
191
vd(2) = VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(i))-1)+2)
192
if (DIM.eq.3) then
193
vn(3)=VelocityN((DIM+1)*(VeloNPerm(NodeIndexes(i))-1)+3)
194
vd(3)=VelocityD((DIM+1)*(VeloDPerm(NodeIndexes(i))-1)+3)
195
endif
196
197
NodeDJ(i)=(calcNorm(vD)-calcNorm(vN))
198
IF (PowerFormulation) then
199
NodeDJ(i)=NodeDJ(i)*(10**(BetaValues(BetaPerm(NodeIndexes(i)))))*log(10.0)
200
END IF
201
IF (Beta2Formulation) then
202
NodeDJ(i)=NodeDJ(i)*2.0_dp*BetaValues(BetaPerm(NodeIndexes(i)))
203
ENDIF
204
End do
205
206
! Compute Integrated Nodal Value of DJDBeta
207
IntegStuff = GaussPoints( Element )
208
DO j=1,IntegStuff % n
209
U = IntegStuff % u(j)
210
V = IntegStuff % v(j)
211
W = IntegStuff % w(j)
212
stat = ElementInfo(Element,ElementNodes,U,V,W,SqrtElementMetric, &
213
Basis,dBasisdx )
214
Do i=1,n
215
IPGrad=NodeDJ(i)*Basis(i)
216
If (Lambda /= 0.0) then
217
IPGrad=IPGrad+Lambda*(SUM(dBasisdx(1:n,1)*BetaValues(BetaPerm(NodeIndexes(1:n))))*dBasisdx(i,1))
218
IF (DIM.eq.3) then
219
IPGrad=IPGrad+Lambda*(SUM(dBasisdx(1:n,2)*BetaValues(BetaPerm(NodeIndexes(1:n))))*dBasisdx(i,2))
220
End if
221
End if
222
db(NodeIndexes(i)) = db(NodeIndexes(i)) + &
223
SqrtElementMetric*IntegStuff % s(j)*IPGrad
224
End do
225
End Do
226
End do
227
228
Do t=1,Solver % Mesh % NumberOfNodes
229
if (VisitedNode(t).lt.1.0_dp) cycle
230
VariableValues(Permutation(t))=db(t)
231
End do
232
233
Return
234
235
CONTAINS
236
237
function calcNorm(v) result(v2)
238
implicit none
239
real(kind=dp) :: v(3),v2
240
241
v2=v(1)*v(1)+v(2)*v(2)+v(3)*v(3)
242
end function calcNorm
243
!------------------------------------------------------------------------------
244
END SUBROUTINE DJDBeta_Robin
245
!------------------------------------------------------------------------------
246
247
248
249