Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/ElmerIceUtils.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: Mondher Chekki
26
! * Email:
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date: 15/12/2018
30
!
31
! ****************************************************************************/
32
! -----------------------------------------------------------------------
33
34
MODULE ElmerIceUtils
35
36
USE DefUtils
37
38
CONTAINS
39
40
SUBROUTINE ComputeWeight(Model, Solver, VarName, WeightIn)
41
42
!------------------------------------------------------------------------------
43
!******************************************************************************
44
!
45
! Compute weight at Boundaries (if Weight is not associated)
46
! and Sum over all Partitions
47
!
48
! ARGUMENTS:
49
!
50
! TYPE(Model_t) :: Model,
51
! INPUT: All model information (mesh,materials,BCs,etc...)
52
!
53
! TYPE(Solver_t) :: Solver
54
! INPUT: Linear equation solver options
55
!
56
! CHARACTER(LEN=MAX_NAME_LEN) :: VarName
57
! INPUT: Name of the variable
58
!
59
! TYPE(Variable_t) :: WeightIn
60
! INPUT/OUTPUT : Variable Associated Weight
61
!
62
!******************************************************************************
63
IMPLICIT NONE
64
65
TYPE(Model_t) :: Model
66
TYPE(Solver_t), TARGET :: Solver
67
CHARACTER(LEN=MAX_NAME_LEN) :: VarName
68
TYPE(Variable_t), POINTER :: WeightIn
69
70
!------------------------------------------------------------------------------
71
! Local variables
72
!------------------------------------------------------------------------------
73
CHARACTER(LEN=MAX_NAME_LEN) :: FunctionName
74
75
LOGICAL :: UnFoundFatal=.TRUE.
76
INTEGER :: nlen
77
REAL(KIND=dp) :: at, at0
78
79
FunctionName='ComputeWeight'
80
81
!------------------------------------------------------------------------------
82
! Compute Boundary Weights
83
!------------------------------------------------------------------------------
84
nlen = LEN_TRIM(VarName)
85
86
NULLIFY( WeightIn )
87
88
CALL CalculateNodalWeights(Model % Solver,.TRUE.)
89
WeightIn => VariableGet( Solver % Mesh % Variables, &
90
VarName(1:nlen)//' Boundary Weights' ,UnFoundFatal=UnFoundFatal)
91
IF( .NOT. ASSOCIATED( WeightIn ) ) THEN
92
CALL Fatal('ComputeWeight','Weight variable not present?')
93
END IF
94
95
CALL INFO(FunctionName, 'All Done', level=3)
96
97
END SUBROUTINE ComputeWeight
98
99
SUBROUTINE UpdatePartitionWeight(Model, Solver, VarName, Force, Force_tmp)
100
101
!------------------------------------------------------------------------------
102
!******************************************************************************
103
!
104
! Compute weight at Boundaries (if Weight is not associated)
105
! and Sum over all Partitions
106
!
107
! ARGUMENTS:
108
!
109
! TYPE(Model_t) :: Model,
110
! INPUT: All model information (mesh,materials,BCs,etc...)
111
!
112
! TYPE(Solver_t) :: Solver
113
! INPUT: Linear equation solver options
114
!
115
! CHARACTER(LEN=MAX_NAME_LEN) :: VarName
116
! INPUT: Name of the variable
117
!
118
! TYPE(Variable_t) :: WeightIn
119
! INPUT/OUTPUT : Variable Associated Weight
120
!
121
!******************************************************************************
122
IMPLICIT NONE
123
124
TYPE(Model_t) :: Model
125
TYPE(Solver_t), TARGET :: Solver
126
CHARACTER(LEN=MAX_NAME_LEN) :: VarName
127
TYPE(Variable_t), POINTER :: Force
128
REAL(KIND=dp) :: Force_tmp(:)
129
130
131
INTEGER, POINTER :: WeightPerm(:), ForcePerm(:)
132
INTEGER :: i, nlen, istat
133
REAL(KIND=dp), POINTER :: WeightValues(:), ForceValues(:)
134
REAL(KIND=dp) , ALLOCATABLE :: WeightValues_tmp(:)
135
TYPE(Variable_t), POINTER :: WeightIn
136
137
!------------------------------------------------------------------------------
138
! Local variables
139
!------------------------------------------------------------------------------
140
CHARACTER(LEN=MAX_NAME_LEN) :: FunctionName
141
142
LOGICAL :: UnFoundFatal=.TRUE.
143
REAL(KIND=dp) :: at, at0
144
145
FunctionName='UpdatePartitionWeight'
146
147
CALL ComputeWeight(Model, Solver, VarName, WeightIn)
148
149
WeightPerm => WeightIn % Perm
150
WeightValues => WeightIn % Values
151
152
ForcePerm => Force % Perm
153
ForceValues => Force % Values
154
155
!----- -------------------------------------------------------------------------
156
! Allocate temporary storage
157
!----- -------------------------------------------------------------------------
158
159
ALLOCATE(WeightValues_tmp(SIZE(WeightValues)),STAT=istat)
160
IF ( istat /= 0 ) THEN
161
CALL Fatal( FunctionName, 'Memory allocation error.' )
162
END IF
163
164
WeightValues_tmp(:) = WeightValues(:)
165
Force_tmp(:) = ForceValues(:)
166
167
IF ( ParEnv % PEs >1 ) THEN
168
CALL ParallelSumVector( Solver % Matrix, WeightValues)
169
DO i=1, Model % Mesh % NumberOfNodes
170
IF (WeightPerm(i)>0) THEN
171
Force_tmp(ForcePerm(i)) = Force_tmp(ForcePerm(i)) * &
172
(WeightValues_tmp(WeightPerm(i))/WeightValues(WeightPerm(i)))
173
END IF
174
END DO
175
END IF
176
177
CALL INFO(FunctionName, 'All Done', level=3)
178
179
END SUBROUTINE UpdatePartitionWeight
180
181
182
SUBROUTINE UpdatePeriodicNodes(Model, Solver, VarName, WeightIn, ThisDim)
183
184
!------------------------------------------------------------------------------
185
!******************************************************************************
186
!
187
! Update values at Periodic nodes
188
!
189
! ARGUMENTS:
190
!
191
! TYPE(Model_t) :: Model,
192
! INPUT: All model information (mesh,materials,BCs,etc...)
193
!
194
! TYPE(Solver_t) :: Solver
195
! INPUT: Linear equation solver options
196
!
197
! CHARACTER(LEN=MAX_NAME_LEN) :: VarName
198
! INPUT: Name of the variable
199
!
200
! TYPE(Variable_t) :: WeightIn
201
! INPUT/OUTPUT : Variable Associated Weight
202
!
203
! INTEGER :: ThisDim
204
! INPUT : Variable Component X/Y/Z
205
!
206
!******************************************************************************
207
208
209
IMPLICIT NONE
210
211
TYPE(Model_t) :: Model
212
TYPE(Solver_t), TARGET :: Solver
213
CHARACTER(LEN=MAX_NAME_LEN) :: VarName
214
TYPE(Variable_t), POINTER :: WeightIn
215
INTEGER :: ThisDim
216
217
!------------------------------------------------------------------------------
218
! Local variables
219
!------------------------------------------------------------------------------
220
TYPE(Variable_t), POINTER :: Weight
221
REAL(KIND=dp), POINTER :: WeightValues(:)
222
INTEGER, POINTER :: WeightPerm(:)
223
CHARACTER(LEN=MAX_NAME_LEN) :: FunctionName
224
225
TYPE(Matrix_t), POINTER :: Projector
226
LOGICAL, ALLOCATABLE :: ActivePart(:)
227
228
INTEGER :: iBC, ii, jj, i ,j , k, nlen, l
229
INTEGER :: PeriodicNode1, PeriodicNode2
230
INTEGER :: LocalPeriodicNode1, LocalPeriodicNode2
231
INTEGER :: VarDim
232
REAL(KIND=dp) :: isPeriodic, tmpValue
233
234
LOGICAL :: UnFoundFatal=.TRUE., GotIt
235
REAL(KIND=dp) :: at, at0
236
237
FunctionName='UpdatePeriodicNodes'
238
239
240
NULLIFY( Weight )
241
242
Weight => WeightIn
243
244
WeightPerm => Weight % Perm
245
WeightValues => Weight % Values
246
247
nlen = LEN_TRIM(VarName)
248
VarDim = Weight % DOFs
249
250
CALL INFO("Update Periodic Nodes for: "//VarName(1:nlen), 'Start', level=3)
251
!---------------------------------------------------------------------------
252
! date Values at Periodic Nodes using a Projector
253
!---------------------------------------------------------------------------
254
ALLOCATE(ActivePart(MAX( Model % NumberOfBodyForces,Model % NumberOfBCs)))
255
256
ActivePart = .FALSE.
257
258
DO iBC=1,Model % NumberOfBCs
259
IF ( ListGetLogical( Model % BCs(iBC) % Values, &
260
'Periodic BC ' // VarName(1:nlen), GotIt ) ) ActivePart(iBC) = .TRUE.
261
IF ( ListGetLogical( Model % BCs(iBC) % Values, &
262
'Anti Periodic BC ' // VarName(1:nlen), GotIt ) ) ActivePart(iBC) = .TRUE.
263
IF ( ListCheckPresent( Model % BCs(iBC) % Values, &
264
'Periodic BC Scale ' // VarName(1:nlen) ) ) ActivePart(iBC) = .TRUE.
265
END DO
266
267
DO iBC=1,Model % NumberOfBCs
268
IF (ActivePart(iBC)) THEN
269
Projector => Model % BCs(iBC) % PMatrix
270
IF ( ASSOCIATED( Projector ) ) THEN
271
DO i=1,Projector % NumberOfRows
272
DO l = Projector % Rows(i), Projector % Rows(i+1)-1
273
274
PeriodicNode1 = Projector % InvPerm(i)
275
PeriodicNode2 = Projector % Cols(l)
276
isPeriodic = Projector % Values(l)
277
278
IF ( PeriodicNode1 <= 0 .OR. PeriodicNode2 <= 0 ) CYCLE
279
280
LocalPeriodicNode1 = WeightPerm(PeriodicNode1)
281
LocalPeriodicNode2 = WeightPerm(PeriodicNode2)
282
283
IF ( LocalPeriodicNode1>0 .and. LocalPeriodicNode2>0 ) THEN
284
285
LocalPeriodicNode1=VarDim*(LocalPeriodicNode1-1)+ThisDim
286
LocalPeriodicNode2=VarDim*(LocalPeriodicNode2-1)+ThisDim
287
288
tmpValue=WeightValues(LocalPeriodicNode1)
289
290
WeightValues(LocalPeriodicNode1) = tmpValue + isPeriodic*WeightValues(LocalPeriodicNode2)
291
WeightValues(LocalPeriodicNode2) = WeightValues(LocalPeriodicNode2) + isPeriodic*tmpValue
292
293
ENDIF !LocalPeriodicNode >0
294
END DO !l
295
END DO !i
296
END IF !Projector
297
END IF !ActivePart
298
299
END DO !iBC
300
301
CALL INFO(FunctionName, 'All Done', level=3)
302
303
END SUBROUTINE UpdatePeriodicNodes
304
305
SUBROUTINE SetZeroAtPeriodicNodes(Model, Solver, VarName, WeightValues, WeightPerm, TargetPerm)
306
307
!------------------------------------------------------------------------------
308
!******************************************************************************
309
!
310
! Set 0 values at Periodic nodes
311
!
312
! ARGUMENTS:
313
!
314
! TYPE(Model_t) :: Model,
315
! INPUT: All model information (mesh,materials,BCs,etc...)
316
!
317
! TYPE(Solver_t) :: Solver
318
! INPUT: Linear equation solver options
319
!
320
! CHARACTER(LEN=MAX_NAME_LEN) :: VarName
321
! INPUT: Name of the variable
322
!
323
!******************************************************************************
324
325
326
IMPLICIT NONE
327
328
TYPE(Model_t) :: Model
329
TYPE(Solver_t), TARGET :: Solver
330
CHARACTER(LEN=MAX_NAME_LEN) :: VarName
331
REAL(KIND=dp) :: WeightValues(:)
332
INTEGER :: WeightPerm(:)
333
INTEGER :: TargetPerm(:)
334
335
!------------------------------------------------------------------------------
336
! Local variables
337
!------------------------------------------------------------------------------
338
TYPE(Variable_t), POINTER :: Weight
339
CHARACTER(LEN=MAX_NAME_LEN) :: FunctionName
340
341
TYPE(Matrix_t), POINTER :: Projector
342
LOGICAL, ALLOCATABLE :: ActivePart(:)
343
344
INTEGER :: iBC, ii, jj, i ,j , k, nlen, l
345
INTEGER :: PeriodicNode1
346
INTEGER :: LocalPeriodicNode1
347
REAL(KIND=dp) :: isPeriodic
348
349
LOGICAL :: GotIt
350
REAL(KIND=dp) :: at, at0
351
352
FunctionName='SetZeroAtPeriodicNodes'
353
354
nlen = LEN_TRIM(VarName)
355
!---------------------------------------------------------------------------
356
! date Values at Periodic Nodes using a Projector
357
!---------------------------------------------------------------------------
358
ALLOCATE(ActivePart(MAX( Model % NumberOfBodyForces,Model % NumberOfBCs)))
359
360
ActivePart = .FALSE.
361
362
DO iBC=1,Model % NumberOfBCs
363
IF ( ListGetLogical( Model % BCs(iBC) % Values, &
364
'Periodic BC ' // VarName(1:nlen), GotIt ) ) ActivePart(iBC) = .TRUE.
365
IF ( ListGetLogical( Model % BCs(iBC) % Values, &
366
'Anti Periodic BC ' // VarName(1:nlen), GotIt ) ) ActivePart(iBC) = .TRUE.
367
IF ( ListCheckPresent( Model % BCs(iBC) % Values, &
368
'Periodic BC Scale ' // VarName(1:nlen) ) ) ActivePart(iBC) = .TRUE.
369
END DO
370
371
DO iBC=1,Model % NumberOfBCs
372
IF (ActivePart(iBC)) THEN
373
Projector => Model % BCs(iBC) % PMatrix
374
IF ( ASSOCIATED( Projector ) ) THEN
375
DO i=1,Projector % NumberOfRows
376
DO l = Projector % Rows(i), Projector % Rows(i+1)-1
377
378
PeriodicNode1 = Projector % InvPerm(i)
379
380
isPeriodic = Projector % Values(l)
381
382
IF ( PeriodicNode1 <= 0 ) CYCLE
383
384
LocalPeriodicNode1 = TargetPerm(PeriodicNode1)
385
386
IF ( WeightPerm(PeriodicNode1) > 0 ) WeightValues(LocalPeriodicNode1) = 0.0D0
387
388
END DO !l
389
END DO !i
390
END IF !Projector
391
END IF !ActivePart
392
393
END DO !iBC
394
395
CALL INFO(FunctionName, 'All Done', level=3)
396
397
END SUBROUTINE SetZeroAtPeriodicNodes
398
399
END MODULE ElmerIceUtils
400
401