Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/AdjointSolver.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 adjoint state of the Stokes equations.
33
!>
34
SUBROUTINE AdjointSolver( Model,Solver,dt,TransientSimulation )
35
!------------------------------------------------------------------------------
36
!******************************************************************************
37
!
38
!
39
! ARGUMENTS:
40
!
41
! TYPE(Model_t) :: Model,
42
! INPUT: All model information (mesh, materials, BCs, etc...)
43
!
44
! TYPE(Solver_t) :: Solver
45
! INPUT: Linear & nonlinear equation solver options
46
!
47
! REAL(KIND=dp) :: dt,
48
! INPUT: Timestep size for time dependent simulations
49
!
50
! LOGICAL :: TransientSimulation
51
! INPUT: Steady state or transient simulation
52
!
53
!******************************************************************************
54
USE DefUtils
55
USE NavierStokes
56
57
IMPLICIT NONE
58
!------------------------------------------------------------------------------
59
TYPE(Solver_t) :: Solver
60
TYPE(Model_t) :: Model
61
62
63
REAL(KIND=dp) :: dt
64
LOGICAL :: TransientSimulation
65
!------------------------------------------------------------------------------
66
! Local variables
67
!------------------------------------------------------------------------------
68
TYPE(Solver_t),Pointer :: NSSolver
69
TYPE(Matrix_t),POINTER :: InitMat,TransMat,StiffMatrix
70
TYPE(ValueList_t),POINTER :: BC,SolverParams
71
TYPE(Nodes_t) :: ElementNodes
72
TYPE(Element_t),POINTER :: Element
73
TYPE(Variable_t), POINTER :: Sol
74
TYPE(Variable_t), POINTER :: VelocitybSol
75
REAL(KIND=dp), POINTER :: Vb(:)
76
INTEGER, POINTER :: VbPerm(:)
77
REAL(KIND=dp),POINTER :: ForceVector(:)
78
integer :: t,n,NSDOFs,NVals,SolverInd
79
REAL(KIND=dp),ALLOCATABLE :: STIFF(:,:),FORCE(:),ExtPressure(:),LoadVector(:,:),Alpha(:),Beta(:),SlipCoeff(:,:),w(:)
80
Logical :: Gotit,GotForceBC,NormalTangential,Firsttime=.true.,UnFoundFatal=.TRUE.
81
INTEGER, POINTER :: NodeIndexes(:),Perm(:)
82
integer :: p,q,dim,c
83
84
integer :: i,iii,jjj,k
85
Real(KIND=dp) :: Unorm
86
REAL(KIND=dp), allocatable :: FullMat(:,:)
87
character(len=50) :: fo1
88
character(LEN=MAX_NAME_LEN) :: SolName
89
character(LEN=MAX_NAME_LEN) :: SolverName="Adjoint Solver"
90
91
92
save SolverName,Firsttime,SolverInd,STIFF,FORCE,ExtPressure,LoadVector,Alpha,Beta,SlipCoeff,w
93
94
CALL Info(SolverName,'***********************',level=0)
95
CALL Info(SolverName,' This solver has been replaced by:',level=0)
96
CALL Info(SolverName,' Adjoint_LinearSolver ',level=0)
97
CALL Info(SolverName,' See documentation under: ',level=0)
98
CALL Info(SolverName,' elmerice/Solvers/Documentation ',level=0)
99
CALL Info(SolverName,'***********************',level=0)
100
CALL FATAL(SolverName,' Use new solver !!')
101
102
DIM = CoordinateSystemDimension()
103
104
StiffMatrix => Solver % Matrix
105
ForceVector => StiffMatrix % RHS
106
107
Sol => Solver % Variable
108
NSDOFs = Sol % DOFs
109
Perm => Sol % Perm
110
111
! CALL InitializeToZero( StiffMatrix, ForceVector )
112
CALL DefaultInitialize()
113
114
if (Firsttime) then
115
Firsttime=.False.
116
N = Solver % Mesh % MaxElementDOFs
117
allocate(FORCE( 2*NSDOFs*N ),STIFF( 2*NSDOFs*N,2*NSDOFs*N ),ExtPressure(N), &
118
SlipCoeff(3,N),LoadVector(4,N),Alpha(N),Beta(N),w(N))
119
120
SolverParams => GetSolverParams()
121
SolName = GetString( SolverParams,'Flow Solution Equation Name',Gotit)
122
IF (.NOT.Gotit) Then
123
CALL WARN(SolverName,'Keyword >Flow Solution Equation Name< not found in SolverParams')
124
CALL WARN(SolverName,'Taking default value >Flow Solution<')
125
WRITE(SolName,'(A)') 'Flow Solution'
126
Endif
127
128
DO i=1,Model % NumberOfSolvers
129
if (TRIM(SolName) == ListGetString(Model % Solvers(i) % Values, 'Equation')) exit
130
End do
131
if (i.eq.(Model % NumberOfSolvers+1)) CALL FATAL(SolverName,'Could not find Flow Solver Equation Name')
132
SolverInd=i
133
end if
134
135
136
137
NSSolver => Model % Solvers(SolverInd)
138
IF(.NOT.ASSOCIATED(NSSolver % Matrix % BulkValues)) CALL FATAL(SolverName,'Flow Solver BulkValues not associated. &
139
Add >Calculate Loads = Logical true< In the flow solver section')
140
141
InitMat => AllocateMatrix()
142
InitMat % NumberOfRows = NSSolver % Matrix % NumberOfRows
143
InitMat % Values => NSSolver % Matrix % BulkValues
144
InitMat % Rows => NSSolver % Matrix % Rows
145
InitMat % Cols => NSSolver % Matrix % Cols
146
InitMat % Diag => NSSolver % Matrix % Diag
147
148
149
VelocitybSol => VariableGet( Solver % Mesh % Variables, 'Velocityb',UnFoundFatal=UnFoundFatal )
150
Vb => VelocitybSol % Values
151
VbPerm => VelocitybSol % Perm
152
153
IF (VelocitybSol % DOFs.NE.(dim+1)) then
154
WRITE(Message,'(A,I1,A,I1)') &
155
'Variable Velocityb has ',VelocitybSol % DOFs,' DOFs, should be',dim+1
156
CALL FATAL(SolverName,Message)
157
End If
158
159
TransMat => NULL()
160
TransMat => CRS_Transpose(InitMat)
161
162
NULLIFY( InitMat % Rows, InitMat % Cols, InitMat % Diag, InitMat % Values )
163
CALL FreeMatrix( InitMat )
164
165
CALL CRS_SortMatrix( TransMat , .true. )
166
167
IF ( SIZE(StiffMatrix % Values) .NE. SIZE(TransMat % Values) ) THEN
168
CALL WARN(SolverName,'StiffMatrix different size to TransMat. Is this the correct the body?')
169
END IF
170
171
StiffMatrix % Values = TransMat % Values
172
StiffMatrix % Rows = TransMat % Rows
173
StiffMatrix % Cols = TransMat % Cols
174
IF(ASSOCIATED(TransMat % Diag)) StiffMatrix % Diag = TransMat % Diag
175
ForceVector = 0.0
176
Perm = NSSolver % Variable % Perm
177
178
deallocate( TransMat % Rows, TransMat % Cols , TransMat % Values)
179
IF(ASSOCIATED(TransMat % Diag)) DEALLOCATE(TransMat % Diag)
180
nullify(TransMat)
181
182
DO t = 1,Solver % Mesh % NumberOfBoundaryElements
183
184
Element => GetBoundaryElement(t)
185
IF ( .NOT. ActiveBoundaryElement() ) CYCLE
186
187
n = GetElementNOFNodes()
188
!
189
! The element type 101 (point element) can only be used
190
! to set Dirichlet BCs, so skip ´em at this stage.
191
!
192
IF ( GetElementFamily() == 1 ) CYCLE
193
194
CALL GetElementNodes( ElementNodes )
195
NodeIndexes => Element % NodeIndexes
196
197
BC => GetBC()
198
IF ( .NOT. ASSOCIATED(BC) ) CYCLE
199
200
GotForceBC = GetLogical( BC, 'Adjoint Force BC',gotIt )
201
202
IF (GotForceBC) Then
203
LoadVector=0.0d0
204
Alpha=0.0d0
205
Beta=0.0d0
206
STIFF=0.0
207
FORCE=0.0
208
ExtPressure=0.0
209
SlipCoeff = 0.0d0
210
211
! I only see 1 case where we have to impose Neumann condition to the
212
! Adjoint system; the slip BC
213
NormalTangential = GetLogical( BC, &
214
'Normal-Tangential Adjoint', GotIt )
215
216
SlipCoeff(1,1:n) = GetReal( BC, 'Slip Coefficient 1',GotIt )
217
SlipCoeff(2,1:n) = GetReal( BC, 'Slip Coefficient 2',GotIt )
218
SlipCoeff(3,1:n) = GetReal( BC, 'Slip Coefficient 3',GotIt )
219
220
CALL NavierStokesBoundary( STIFF, FORCE, &
221
LoadVector, Alpha, Beta, ExtPressure, SlipCoeff, NormalTangential, &
222
Element, n, ElementNodes )
223
224
CALL DefaultUpdateEquations( STIFF, FORCE )
225
end if
226
227
END DO
228
229
!forcing of the adjoint system comes from the Velocityb variable computed
230
!with the cost function
231
c = dim + 1
232
Do t=1,Solver%Mesh%NumberOfNodes
233
Do i=1,c
234
p=(Perm(t)-1)*c+i
235
q=(VbPerm(t)-1)*c+i
236
ForceVector(p)=Vb(q)
237
End Do
238
EndDo
239
240
CALL FinishAssembly( Solver, ForceVector )
241
242
CALL DefaultDirichletBCs()
243
244
Unorm = DefaultSolve()
245
246
Return
247
!------------------------------------------------------------------------------
248
END SUBROUTINE AdjointSolver
249
!------------------------------------------------------------------------------
250
251
252