Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/CalvingHydroInterp.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: Samuel Cook
26
! * Email: [email protected]
27
! * Web: http://www.csc.fi/elmer
28
! * Address: CSC - Scientific Computing Ltd.
29
! * Keilaranta 14
30
! * 02101 Espoo, Finland
31
! *
32
! * Original Date: 18 January 2018
33
! *
34
! *****************************************************************************/
35
!> Interpolates ice variables necessary for hydrology from ice mesh to hydro
36
!> mesh as part of combined calving-hydrology simulations.
37
SUBROUTINE IceToHydroInterp( Model,Solver,Timestep,TransientSimulation )
38
!******************************************************************************
39
!
40
! ARGUMENTS:
41
!
42
! TYPE(Model_t) :: Model,
43
! INPUT: All model information (mesh,materials,BCs,etc...)
44
!
45
! TYPE(Solver_t) :: Solver
46
! INPUT: Linear equation solver options
47
!
48
! REAL(KIND=dp) :: Timestep
49
! INPUT: Timestep size for time dependent simulations
50
!
51
!******************************************************************************
52
USE Differentials
53
USE MaterialModels
54
USE DefUtils
55
USE InterpVarToVar
56
!------------------------------------------------------------------------------
57
IMPLICIT NONE
58
!------------------------------------------------------------------------------
59
!------------------------------------------------------------------------------
60
! External variables
61
!------------------------------------------------------------------------------
62
TYPE(Model_t) :: Model
63
TYPE(Solver_t), TARGET :: Solver
64
LOGICAL :: TransientSimulation
65
REAL(KIND=dp) :: Timestep
66
!------------------------------------------------------------------------------
67
! Local variables
68
!------------------------------------------------------------------------------
69
TYPE(Mesh_t), POINTER :: IceMesh, HydroMesh
70
TYPE(Solver_t), POINTER :: HydroSolver, TempSolver
71
TYPE(Variable_t), POINTER :: HydroVar=>NULL(),WorkVar=>NULL(),&
72
InterpVar1=>NULL(),InterpVar2=>NULL(),&
73
InterpVar3=>NULL(),InterpVar4=>NULL(),&
74
InterpVar5=>NULL(),WorkVar2=>NULL()
75
TYPE(Variable_t), TARGET :: InterpVar1Copy, InterpVar2Copy,&
76
InterpVar3Copy, InterpVar4Copy, InterpVar5Copy
77
TYPE(ValueList_t), POINTER :: Params, BC
78
TYPE(Element_t), POINTER :: Element=>NULL()
79
CHARACTER(MAX_NAME_LEN) :: Variable1, Variable2, Variable3, Variable4,&
80
Variable5, VarName, iString
81
LOGICAL :: Found=.FALSE., FirstTime=.TRUE., LoadReaders, Hit=.FALSE.
82
LOGICAL, POINTER :: BasalLogical(:)
83
INTEGER, POINTER :: InterpDim(:), IceMeshBasePerm(:)=>NULL(),&
84
NPP(:)=>NULL(), RefNode(:)=>NULL(), NewPerm1(:),&
85
ReaderPerm1(:), NewPerm2(:), NewPerm3(:),&
86
NewPerm4(:), NewPerm5(:), ReaderPerm2(:),&
87
ReaderPerm3(:), ReaderPerm4(:), ReaderPerm5(:),&
88
ReaderPerm6(:), ReaderPerm7(:), ReaderPerm8(:),&
89
ReaderPerm9(:), ReaderPerm10(:)
90
INTEGER, ALLOCATABLE, TARGET :: DefaultPerm(:), ZeroNodes(:)
91
INTEGER :: i, j, k, HPSolver, Reader1, Reader2, Reader3,&
92
Reader4, Reader5, Reader, NumVar, DummyInt, ierr,&
93
ElementBC, BasalBC, n, NearestNode, SideBC1, SideBC2, HitCount,&
94
ZeroCounter, TSolver
95
REAL(KIND=dp), POINTER :: NVP(:)=>NULL(), NewValues1(:), NewValues2(:),&
96
NewValues3(:), NewValues4(:), NewValues5(:),&
97
ReaderValues1(:), ReaderValues2(:),&
98
ReaderValues3(:), ReaderValues4(:),&
99
ReaderValues5(:), ReaderValues6(:),&
100
ReaderValues7(:), ReaderValues8(:),&
101
ReaderValues9(:), ReaderValues10(:)
102
REAL(KIND=dp) :: IceTempResSum, HydroTempResSum, ScaleFactor,&
103
ElementTempResSum, Dist, Threshold, MinDist, x, y,&
104
NewNS, MeanNS
105
REAL(KIND=dp), ALLOCATABLE :: NSValues(:)
106
REAL(KIND=dp), ALLOCATABLE, TARGET :: ParITRS(:), ParHTRS(:), NewValues6(:)
107
SAVE HydroMesh, FirstTime, HPSolver, TSolver
108
!NewPerm1,&
109
!NewValues1,NewValues2, NewValues3, NewValues4, NewValues5, DefaultPerm
110
!------------------------------------------------------------------------------
111
Params => GetSolverParams()
112
113
!For loading variables that remain constant and are read in from files
114
!E.g. Zb or surface melting
115
!Various keywords need to be specified in solver section of SIF
116
IF(FirstTime) THEN
117
DO i=1,Model % NumberOfSolvers
118
IF(Model % Solvers(i) % Variable % Name == 'hydraulic potential') THEN
119
HPSolver = i
120
HydroSolver => Model % Solvers(HPSolver)
121
EXIT
122
END IF
123
END DO
124
DO i=1,Model % NumberOfSolvers
125
IF(Model % Solvers(i) % Variable % Name == 'temp') THEN
126
TSolver = i
127
TempSolver => Model % Solvers(TSolver)
128
EXIT
129
END IF
130
END DO
131
132
LoadReaders = GetLogical(Params,'Load Reader Variables',Found)
133
IF(.NOT. Found) LoadReaders = .FALSE.
134
IF(LoadReaders) THEN
135
NumVar = GetInteger(Params, 'Number Of Variables To Read',Found)
136
IF(.NOT. Found) CALL Fatal('Ice2Hydro', 'Number of variables to read &
137
not specified')
138
IF(NumVar > 10) CALL Info('Ice2Hydro', 'Not set up for more than 10&
139
reader variables - increase maximum limit in source code', Level=1)
140
141
!A default perm in case the variables to be loaded don't have a perm
142
!associated. Assumes node 1 = value 1
143
ALLOCATE(DefaultPerm(HydroSolver % Mesh % NumberOfNodes))
144
DO i=1, HydroSolver % Mesh % NumberOfNodes
145
DefaultPerm(i) = i
146
END DO
147
148
DO i=1, NumVar
149
iString = STR(i)
150
Reader = GetInteger(Params, 'Reader Solver '//iString, Found)
151
IF(Found) THEN
152
VarName = GetString(Params, 'Reader V'//iString, Found)
153
IF(.NOT. Found) PRINT *, 'No reader '//iString//' variable specified'
154
!For the case if you're restarting from a mesh where this variable
155
!has already been added
156
WorkVar => VariableGet(HydroSolver % Mesh % Variables,&
157
VarName, ThisOnly=.TRUE.)
158
IF(ASSOCIATED(WorkVar)) CYCLE
159
160
WorkVar => VariableGet(Model % Solvers(Reader) % Mesh % Variables,&
161
VarName, ThisOnly=.TRUE.)
162
163
!Allocate the variable perm to default value if not associated
164
IF(.NOT. ASSOCIATED(WorkVar % Perm)) THEN
165
ALLOCATE(WorkVar % Perm(HydroSolver % Mesh % NumberOfNodes))
166
WorkVar % Perm(1:SIZE(WorkVar % Perm)) = DefaultPerm(1:SIZE(WorkVar % Perm))
167
END IF
168
169
!There has to be a better way to do this, but you can't use indices
170
!in variable names, so I can't see a way of allocating the arrays in
171
!the loop, such that each variable gets its own perm and values
172
IF(i==1) ALLOCATE(ReaderPerm1(SIZE(WorkVar % Perm)), ReaderValues1(SIZE(WorkVar % Values)))
173
IF(i==2) ALLOCATE(ReaderPerm2(SIZE(WorkVar % Perm)), ReaderValues2(SIZE(WorkVar % Values)))
174
IF(i==3) ALLOCATE(ReaderPerm3(SIZE(WorkVar % Perm)), ReaderValues3(SIZE(WorkVar % Values)))
175
IF(i==4) ALLOCATE(ReaderPerm4(SIZE(WorkVar % Perm)), ReaderValues4(SIZE(WorkVar % Values)))
176
IF(i==5) ALLOCATE(ReaderPerm5(SIZE(WorkVar % Perm)), ReaderValues5(SIZE(WorkVar % Values)))
177
IF(i==6) ALLOCATE(ReaderPerm6(SIZE(WorkVar % Perm)), ReaderValues6(SIZE(WorkVar % Values)))
178
IF(i==7) ALLOCATE(ReaderPerm7(SIZE(WorkVar % Perm)), ReaderValues7(SIZE(WorkVar % Values)))
179
IF(i==8) ALLOCATE(ReaderPerm8(SIZE(WorkVar % Perm)), ReaderValues8(SIZE(WorkVar % Values)))
180
IF(i==9) ALLOCATE(ReaderPerm9(SIZE(WorkVar % Perm)), ReaderValues9(SIZE(WorkVar % Values)))
181
IF(i==10) ALLOCATE(ReaderPerm10(SIZE(WorkVar % Perm)), ReaderValues10(SIZE(WorkVar % Values)))
182
IF(i==1) THEN
183
ReaderPerm1 = WorkVar % Perm
184
ReaderValues1 = WorkVar % Values
185
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
186
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues1, &
187
ReaderPerm1)
188
ELSEIF(i==2) THEN
189
ReaderPerm2 = WorkVar % Perm
190
ReaderValues2 = WorkVar % Values
191
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
192
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues2, &
193
ReaderPerm2)
194
ELSEIF(i==3) THEN
195
ReaderPerm3 = WorkVar % Perm
196
ReaderValues3 = WorkVar % Values
197
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
198
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues3, &
199
ReaderPerm3)
200
ELSEIF(i==4) THEN
201
ReaderPerm4 = WorkVar % Perm
202
ReaderValues4 = WorkVar % Values
203
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
204
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues4, &
205
ReaderPerm4)
206
ELSEIF(i==5) THEN
207
ReaderPerm5 = WorkVar % Perm
208
ReaderValues5 = WorkVar % Values
209
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
210
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues5, &
211
ReaderPerm5)
212
ELSEIF(i==6) THEN
213
ReaderPerm6 = WorkVar % Perm
214
ReaderValues6 = WorkVar % Values
215
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
216
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues6, &
217
ReaderPerm6)
218
ELSEIF(i==7) THEN
219
ReaderPerm7 = WorkVar % Perm
220
ReaderValues7 = WorkVar % Values
221
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
222
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues7, &
223
ReaderPerm7)
224
ELSEIF(i==8) THEN
225
ReaderPerm8 = WorkVar % Perm
226
ReaderValues8 = WorkVar % Values
227
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
228
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues8, &
229
ReaderPerm8)
230
ELSEIF(i==9) THEN
231
ReaderPerm9 = WorkVar % Perm
232
ReaderValues9 = WorkVar % Values
233
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
234
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues9, &
235
ReaderPerm9)
236
ELSEIF(i==10) THEN
237
ReaderPerm10 = WorkVar % Perm
238
ReaderValues10 = WorkVar % Values
239
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
240
Mesh, Model % Solvers(HPSolver), VarName, 1, ReaderValues10, &
241
ReaderPerm10)
242
END IF
243
244
END IF
245
END DO
246
247
NULLIFY(WorkVar)
248
249
END IF!LoadReaders
250
END IF!FirstTime
251
252
!To update reader variables each time called. Perhaps not always necessary
253
!but better safe than sorry
254
LoadReaders = GetLogical(Params,'Load Reader Variables',Found)
255
IF(LoadReaders .AND. .NOT. FirstTime) THEN
256
NumVar = GetInteger(Params, 'Number Of Variables To Read',Found)
257
IF(.NOT. Found) CALL Fatal('Ice2Hydro', 'Number of variables to read &
258
not specified')
259
IF(NumVar > 10) CALL Info('Ice2Hydro', 'Not set up for more than 10&
260
reader variables - increase maximum limit in source code', Level=1)
261
DO i=1, NumVar
262
iString = STR(i)
263
Reader = GetInteger(Params, 'Reader Solver '//iString, Found)
264
IF(Found) THEN
265
VarName = GetString(Params, 'Reader V'//iString, Found)
266
IF(.NOT. Found) PRINT *, 'No reader '//iString//' variable specified'
267
WorkVar => VariableGet(Model % Solvers(Reader) % Mesh % Variables,&
268
VarName, ThisOnly=.TRUE.)
269
WorkVar2 => VariableGet(Model % Solvers(HPSolver) % Mesh % Variables,&
270
VarName, ThisOnly=.TRUE.)
271
WorkVar2 % Values = WorkVar % Values
272
END IF
273
END DO
274
275
END IF
276
277
!Time to interpolate variables that are solved on ice mesh
278
HydroSolver => Model % Solvers(HPSolver)
279
TempSolver => Model % Solvers(TSolver)
280
ALLOCATE(InterpDim(1)); InterpDim = (/3/)
281
ALLOCATE(BasalLogical(Model % Mesh % NumberOfNodes))
282
ALLOCATE(IceMeshBasePerm(Model % Mesh % NumberOfNodes))
283
284
CALL MakePermUsingMask(Model, Solver, Model % Mesh, "Bottom Surface Mask",&
285
.FALSE., IceMeshBasePerm, DummyInt)
286
287
!True nodes ignored by InterpolateVarToVarReduced
288
DO i=1, Model % Mesh % NumberOfNodes
289
BasalLogical(i) = (IceMeshBasePerm(i) <=0)
290
END DO
291
292
!Set up list of variables needed by GlaDS that have to be interpolated
293
InterpVar1 => VariableGet(Model % Mesh % Variables, "normalstress", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
294
InterpVar2 => VariableGet(Model % Mesh % Variables, "velocity 1", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
295
InterpVar3 => VariableGet(Model % Mesh % Variables, "velocity 2", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
296
InterpVar4 => VariableGet(Model % Mesh % Variables, "groundedmask", ThisOnly=.TRUE., UnfoundFatal=.FALSE.)
297
InterpVar5 => VariableGet(Model % Mesh % Variables, "gmcheck", ThisOnly=.TRUE., UnfoundFatal=.FALSE.)
298
299
!Make copies of the relevant variables to save messing around with the mesh
300
!variable list - only need perms and values
301
ALLOCATE(InterpVar1Copy % Values(SIZE(InterpVar1 % Values)), InterpVar1Copy % Perm(SIZE(InterpVar1 % Perm)))
302
InterpVar1Copy % Values = InterpVar1 % Values
303
InterpVar1Copy % Perm = InterpVar1 % Perm
304
InterpVar1Copy % Next => InterpVar2Copy
305
InterpVar1Copy % Name = InterpVar1 % Name
306
307
ALLOCATE(InterpVar2Copy % Values(SIZE(InterpVar2 % Values)), InterpVar2Copy % Perm(SIZE(InterpVar2 % Perm)))
308
InterpVar2Copy % Values = InterpVar2 % Values
309
InterpVar2Copy % Perm = InterpVar2 % Perm
310
InterpVar2Copy % Next => InterpVar3Copy
311
InterpVar2Copy % Name = InterpVar2 % Name
312
313
ALLOCATE(InterpVar3Copy % Values(SIZE(InterpVar3 % Values)), InterpVar3Copy % Perm(SIZE(InterpVar3 % Perm)))
314
InterpVar3Copy % Values = InterpVar3 % Values
315
InterpVar3Copy % Perm = InterpVar3 % Perm
316
IF(ASSOCIATED(InterpVar4)) THEN
317
InterpVar3Copy % Next => InterpVar4Copy
318
ELSE
319
InterpVar3Copy % Next => NULL()
320
END IF
321
InterpVar3Copy % Name = InterpVar3 % Name
322
323
IF(ASSOCIATED(InterpVar4)) THEN
324
ALLOCATE(InterpVar4Copy % Values(SIZE(InterpVar4 % Values)), InterpVar4Copy % Perm(SIZE(InterpVar4 % Perm)))
325
InterpVar4Copy % Values = InterpVar4 % Values
326
InterpVar4Copy % Perm = InterpVar4 % Perm
327
IF(ASSOCIATED(InterpVar5)) THEN
328
InterpVar4Copy % Next => InterpVar5Copy
329
ELSE
330
InterpVar4Copy % Next => NULL()
331
END IF
332
InterpVar4Copy % Name = InterpVar4 % Name
333
END IF
334
335
IF(ASSOCIATED(InterpVar5)) THEN
336
ALLOCATE(InterpVar5Copy % Values(SIZE(InterpVar5 % Values)), InterpVar5Copy % Perm(SIZE(InterpVar5 % Perm)))
337
InterpVar5Copy % Values = InterpVar5 % Values
338
InterpVar5Copy % Perm = InterpVar5 % Perm
339
InterpVar5Copy % Next => NULL()
340
InterpVar5Copy % Name = InterpVar5 % Name
341
END IF
342
343
InterpVar1 => InterpVar1Copy
344
InterpVar2 => InterpVar2Copy
345
InterpVar3 => InterpVar3Copy
346
IF(ASSOCIATED(InterpVar4)) InterpVar4 => InterpVar4Copy
347
IF(ASSOCIATED(InterpVar5)) InterpVar5 => InterpVar5Copy
348
IF(FirstTime) THEN
349
FirstTime=.FALSE.
350
WorkVar => VariableGet(HydroSolver % Mesh % Variables,&
351
'hydraulic potential', ThisOnly=.TRUE.)
352
ALLOCATE(NewPerm1(SIZE(WorkVar % Perm)),NewValues1(SIZE(WorkVar % Values)))
353
ALLOCATE(NewPerm2(SIZE(WorkVar % Perm)),NewValues2(SIZE(WorkVar % Values)))
354
ALLOCATE(NewPerm3(SIZE(WorkVar % Perm)),NewValues3(SIZE(WorkVar % Values)))
355
ALLOCATE(NewPerm4(SIZE(WorkVar % Perm)),NewValues4(SIZE(WorkVar % Values)))
356
ALLOCATE(NewPerm5(SIZE(WorkVar % Perm)),NewValues5(SIZE(WorkVar % Values)))
357
NewPerm1 = WorkVar % Perm
358
NewPerm2 = WorkVar % Perm
359
NewPerm3 = WorkVar % Perm
360
NewPerm4 = WorkVar % Perm
361
NewPerm5 = WorkVar % Perm
362
!NPP => NewPerm1
363
NewValues1 = 0.0_dp
364
NewValues2 = 0.0_dp
365
NewValues3 = 0.0_dp
366
NewValues4 = 0.0_dp
367
NewValues5 = 0.0_dp
368
!NVP => NewValues1
369
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
370
Mesh, HydroSolver, InterpVar1 % Name, 1,&
371
NewValues1, NewPerm1)
372
!NVP => NewValues2
373
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
374
Mesh, HydroSolver, InterpVar2 % Name, 1,&
375
NewValues2, NewPerm2)
376
!NVP => NewValues3
377
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
378
Mesh, HydroSolver, InterpVar3 % Name, 1,&
379
NewValues3, NewPerm3)
380
IF(ASSOCIATED(InterpVar4)) THEN
381
!NVP => NewValues4
382
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
383
Mesh, HydroSolver, InterpVar4 % Name, 1,&
384
NewValues4, NewPerm4)
385
END IF
386
IF(ASSOCIATED(InterpVar5)) THEN
387
!NVP => NewValues5
388
CALL VariableAdd(HydroSolver % Mesh % Variables, HydroSolver % &
389
Mesh, HydroSolver, InterpVar5 % Name, 1,&
390
NewValues5, NewPerm5)
391
END IF
392
END IF
393
394
!Have to divide temp residual by ice boundary weights before interpolating.
395
!I initially did this by creating a new variable and interpolating that, but
396
!it did some very odd things, such as randomly crashing the plume solver, so
397
!this just alters the values of temp residual in place, interpolates them,
398
!and then restores the old values.
399
WorkVar => VariableGet(Model % Mesh % Variables, 'temp residual', ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
400
ALLOCATE(NewValues6(SIZE(WorkVar % Values)))
401
NewValues6 = 0.0_dp
402
NewValues6 = WorkVar % Values
403
!CALL CalculateNodalWeights(TempSolver, .TRUE., WorkVar % Perm, 'IceWeights')
404
WorkVar2 => VariableGet(Model % Mesh % Variables, 'IceWeights', ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
405
!IF(ParEnv % PEs > 1) CALL ParallelSumVector(TempSolver % Matrix, WorkVar2 % Values)
406
!DO i=1, Model % Mesh % NumberOfBoundaryElements!SIZE(WorkVar % Perm)
407
!Element => Model % Mesh % Elements(Model % Mesh % NumberOfBulkElements+i)
408
!n = GetElementNOFNodes(Element)
409
!DO j=1, n
410
!IF(WorkVar2 % Values(WorkVar2 % Perm(Element % NodeIndexes(j)))==0) CYCLE
411
!WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(j))) =&
412
!WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(j)))/&
413
!WorkVar2 % Values(WorkVar2 % Perm(Element % NodeIndexes(j)))
414
!END DO
415
!END DO
416
DO i=1, SIZE(WorkVar % Perm)
417
IF(WorkVar2 % Values(WorkVar2 % Perm(i)) .NE. 0.0) THEN
418
WorkVar % Values(WorkVar % Perm(i)) = WorkVar % Values(WorkVar % Perm(i))/WorkVar2 % Values(WorkVar2 % Perm(i))
419
ELSE
420
WorkVar % Values(WorkVar % Perm(i)) = 0.0
421
END IF
422
END DO
423
424
CALL ParallelActive(.TRUE.)
425
CALL InterpolateVarToVarReduced(Model % Mesh, HydroSolver % Mesh, 'temp residual',&
426
InterpDim, OldNodeMask=BasalLogical, Variables=InterpVar1)
427
CALL MPI_BARRIER(ELMER_COMM_WORLD, ierr)
428
429
!To restore temp residual values on ice mesh
430
WorkVar % Values = NewValues6
431
DEALLOCATE(NewValues6)
432
433
!Interpolating GroundedMask will inevitably create values that aren't -1, 0
434
!or 1, so need to round them to the nearest integer
435
!Also, enforce grounded on upstream areas to deal with boundary
436
!interpolation artefacts
437
IF(ASSOCIATED(InterpVar5)) THEN
438
WorkVar => VariableGet(HydroSolver % Mesh % Variables, "gmcheck", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
439
DO i=1, SIZE(WorkVar % Values)
440
WorkVar % Values(i) = ANINT(WorkVar % Values(i))
441
END DO
442
END IF
443
IF(ASSOCIATED(InterpVar4)) THEN
444
WorkVar => VariableGet(HydroSolver % Mesh % Variables, "groundedmask", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
445
DO i=1, SIZE(WorkVar % Values)
446
WorkVar % Values(i) = ANINT(WorkVar % Values(i))
447
END DO
448
449
RefNode => ListGetIntegerArray(Params, 'Reference Node', Found)
450
IF(Found) THEN
451
Threshold = GetConstReal(Params, 'Threshold Distance', Found)
452
IF(.NOT. Found) Threshold = 10000.0
453
454
DO i=1, SIZE(WorkVar % Perm)
455
Dist = (HydroSolver % Mesh % Nodes % x(WorkVar % Perm(i)) -&
456
RefNode(1))**2
457
Dist = Dist + (HydroSolver % Mesh % Nodes % y(WorkVar % Perm(i)) -&
458
RefNode(2))**2
459
Dist = SQRT(Dist)
460
IF(Dist > Threshold) WorkVar % Values(WorkVar % Perm(i)) = 1.0
461
END DO
462
END IF
463
464
Hit = .FALSE.
465
SideBC1 = 0
466
SideBC2 = 0
467
HitCount = 0
468
DO i=1, Model % NumberOfBCs
469
BC => Model % BCs(i) % Values
470
Hit = ListGetLogical(BC, "Side", Found)
471
IF(Hit) THEN
472
IF(HitCount == 0) THEN
473
SideBC1 = i
474
ELSEIF(HitCount == 1) THEN
475
SideBC2 = i
476
ELSE
477
CALL Info('CalvingHydroInterp', 'You appear to have more than two&
478
lateral boundaries. Are you sure about this?')
479
END IF
480
Hit = .FALSE.
481
HitCount = HitCount+1
482
IF(HitCount == 2) EXIT
483
END IF
484
END DO
485
486
DO i=1, HydroSolver % Mesh % NumberOfBoundaryElements
487
Element => GetBoundaryElement(i, HydroSolver)
488
ElementBC = GetBCId(Element)
489
IF(ElementBC == SideBC1 .OR. ElementBC == SideBC2) THEN
490
n = GetElementNOFNodes(Element)
491
DO j=1,n
492
IF(WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(j))) == -1.0) THEN
493
WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(j))) = 1.0
494
END IF
495
END DO
496
END IF
497
END DO
498
END IF
499
500
!This is to remove boundary artefacts in normalstress, which, otherwise,
501
!really mess the hydrology up. Artefacts do exist in velocity and temp
502
!residual, but have much less impact
503
!Routine will search for nearest node that has a non-zero value of
504
!normalstress and substitute that value for the erroneous zero value.
505
!Ideally, should interpolate from nearest non-zero nodes, but not worth the
506
!extra faff for a minimal gain
507
508
!This first section is due to SolveLinearSystem invalidating the
509
!Force2Stress variable (i.e. normalstress) on the hydro mesh. Not really
510
!sure why it does this, but this fix seems to work without any knock-on
511
!effects.
512
WorkVar2 => HydroSolver % Mesh % Variables
513
DO WHILE (ASSOCIATED(WorkVar2))
514
IF (TRIM(WorkVar2 % Name) == 'normalstress') THEN
515
IF (.NOT. WorkVar2 % Valid) THEN
516
WorkVar2 % Valid = .TRUE.
517
WorkVar2 % PrimaryMesh => HydroSolver % Mesh
518
END IF
519
EXIT
520
END IF
521
WorkVar2 => WorkVar2 % Next
522
END DO
523
524
WorkVar2 => VariableGet(HydroSolver % Mesh % Variables, "normalstress", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
525
MeanNS = 0.0_dp
526
!ZeroCounter = 0
527
528
!DO i=1, HydroSolver % Mesh % NumberOfBoundaryElements
529
! Element => GetBoundaryElement(i, HydroSolver)
530
! n = GetElementNOFNodes(Element)
531
! IF(ANY(WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(1:n))) == -1.0)) CYCLE
532
! DO j=1,n
533
! MeanNS = MeanNS+WorkVar2 % Values(WorkVar2 % Perm(Element %&
534
! NodeIndexes(j)))
535
! IF(WorkVar2 % Values(WorkVar2 % Perm(Element % NodeIndexes(j)))==0.0)&
536
! THEN
537
! ZeroCounter = ZeroCounter + 1
538
! END IF
539
! END DO
540
!END DO
541
!MeanNS = MeanNS/(HydroSolver % Mesh % NumberOfBoundaryElements-ZeroCounter)
542
543
DO i=1, HydroSolver % Mesh % NumberOfBoundaryElements
544
Element => GetBoundaryElement(i, HydroSolver)
545
n = GetElementNOFNodes(Element)
546
IF(ANY(WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(1:n))) == -1.0)) CYCLE
547
ALLOCATE(NSValues(n))
548
DO j=1,n
549
NSValues(j) = WorkVar2 % Values(WorkVar2 % Perm(Element % NodeIndexes(j)))
550
END DO
551
ZeroCounter = 0
552
DO j=1,n
553
IF(NSValues(j) .NE. 0.0) CYCLE
554
ZeroCounter = ZeroCounter + 1
555
END DO
556
!This will currently only work for elements with 2 or 3 nodes
557
SELECT CASE (n-ZeroCounter)
558
CASE (0)
559
CALL Info('CalvingHydroInterp', 'No non-0 values of NormalStress. &
560
Making a guess')
561
NewNS = (SUM(WorkVar2 % Values)/SIZE(WorkVar2 % Values))+3.0_dp !MeanNS
562
CASE (1)
563
NewNS = SUM(NSValues)
564
CASE (2)
565
NewNS = SUM(NSValues)/2
566
CASE DEFAULT
567
CALL Info('CalvingHydroInterp', 'No NormalStress correction possible')
568
PRINT *, 'Diagnostics: ',n,ZeroCounter,Element % NodeIndexes
569
END SELECT
570
DO j=1,n
571
IF(NSValues(j) .NE. 0.0) CYCLE
572
WorkVar2 % Values(WorkVar2 % Perm(Element % NodeIndexes(j))) = NewNS
573
END DO
574
DEALLOCATE(NSValues)
575
END DO
576
577
!Finally, the area of the hydromesh beyond the calving front has to be
578
!forced to be ungrounded, so interpolation artefacts there have to be
579
!cleared away. The main job is done by InterpVarToVar, but there are always
580
!a few places where it messes up, which are corrected here.
581
DO i=1, HydroSolver % Mesh % NumberOfBulkElements
582
Element => HydroSolver % Mesh % Elements(i)
583
n = GetElementNOFNodes(Element)
584
DO j=1, n
585
IF(WorkVar2 % Values(WorkVar2 % Perm(Element % NodeIndexes(j))) == 0.0) THEN
586
WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(j))) = -1.0
587
END IF
588
589
END DO
590
END DO
591
592
!Temp residual needs to be conserved. Here, just integrate across all
593
!elements and compare totals, then scale values on hydromesh uniformly to
594
!bring in line with ice mesh
595
WorkVar => VariableGet(Model % Mesh % Variables, "temp residual", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
596
597
IceTempResSum = 0.0_dp
598
IceTempResSum = SUM(WorkVar % Values)
599
600
!WorkVar => VariableGet(HydroSolver % Mesh % Variables, "hydraulic potential", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
601
WorkVar => VariableGet(HydroSolver % Mesh % Variables, "temp residual", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
602
!WorkVar => VariableGet(HydroSolver % Mesh % Variables, "WeightedTR", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
603
!CALL CalculateNodalWeights(HydroSolver, .FALSE., WorkVar % Perm, 'HydroWeights')
604
!WorkVar => VariableGet(HydroSolver % Mesh % Variables, "temp residual", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
605
WorkVar2 => VariableGet(HydroSolver % Mesh % Variables, "HydroWeights", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
606
!IF(ParEnv % PEs > 1) CALL ParallelSumVector(HydroSolver % Matrix, WorkVar2 % Values)
607
DO i=1,SIZE(WorkVar % Perm)
608
!Element => HydroSolver % Mesh % Elements(i)
609
!n = GetElementNOFNodes(Element)
610
!DO j=1, n
611
!WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(j))) =&
612
!WorkVar % Values(WorkVar % Perm(Element % NodeIndexes(j)))*&
613
!WorkVar2 % Values(WorkVar2 % Perm(Element % NodeIndexes(j)))
614
!END DO
615
WorkVar % Values(WorkVar % Perm(i)) =&
616
WorkVar % Values(WorkVar % Perm(i))*WorkVar2 % Values(WorkVar2 % Perm(i))
617
END DO
618
HydroTempResSum = 0.0_dp
619
HydroTempResSum = SUM(WorkVar % Values)
620
621
ALLOCATE(ParITRS(ParEnv % PEs), ParHTRS(ParEnv % PEs))
622
ParITRS = 0.0_dp
623
ParHTRS = 0.0_dp
624
625
IF(ParEnv % PEs > 1) THEN
626
CALL MPI_BARRIER(ELMER_COMM_WORLD, ierr)
627
CALL MPI_Gather(IceTempResSum, 1, MPI_DOUBLE_PRECISION, ParITRS, 1, MPI_DOUBLE_PRECISION, 0, ELMER_COMM_WORLD, ierr)
628
CALL MPI_Gather(HydroTempResSum, 1, MPI_DOUBLE_PRECISION, ParHTRS, 1, MPI_DOUBLE_PRECISION, 0, ELMER_COMM_WORLD, ierr)
629
IF(ParEnv % myPE == 0) THEN
630
IF(ANINT(SUM(ParITRS)) .NE. ANINT(SUM(ParHTRS))) THEN
631
ScaleFactor = SUM(ParITRS)/SUM(ParHTRS)
632
END IF
633
END IF
634
CALL MPI_BARRIER(ELMER_COMM_WORLD, ierr)
635
CALL MPI_Bcast(ScaleFactor, 1, MPI_DOUBLE_PRECISION, 0, ELMER_COMM_WORLD, ierr)
636
DO i=1, SIZE(WorkVar % Values)
637
WorkVar % Values(i) = WorkVar % Values(i)*ScaleFactor
638
END DO
639
ELSE
640
IF(ANINT(IceTempResSum) .NE. ANINT(HydroTempResSum)) THEN
641
ScaleFactor = IceTempResSum/HydroTempResSum
642
DO i=1, SIZE(WorkVar % Values)
643
WorkVar % Values(i) = WorkVar % Values(i)*ScaleFactor
644
END DO
645
END IF
646
END IF
647
648
DEALLOCATE(InterpDim, BasalLogical, IceMeshBasePerm, ParITRS, ParHTRS)
649
DEALLOCATE(InterpVar1Copy % Values, InterpVar2Copy % Values, InterpVar3Copy % Values)
650
DEALLOCATE(InterpVar1Copy % Perm, InterpVar2Copy % Perm, InterpVar3Copy % Perm)
651
IF(ASSOCIATED(InterpVar4)) DEALLOCATE(InterpVar4Copy % Values, InterpVar4Copy % Perm)
652
IF(ASSOCIATED(InterpVar5)) DEALLOCATE(InterpVar5Copy % Values, InterpVar5Copy % Perm)
653
NULLIFY(InterpVar1, InterpVar2, InterpVar3, InterpVar4, InterpVar5,&
654
WorkVar, HydroSolver, NVP, NPP, BC, Element, RefNode, WorkVar2,&
655
TempSolver)
656
!-------------------------------------------------------------------------------
657
CONTAINS
658
!-------------------------------------------------------------------------------
659
CHARACTER(len=20) FUNCTION STR(k)
660
!Converts and integer to a string
661
INTEGER, INTENT(IN) :: k
662
WRITE (STR, *) k
663
STR = adjustl(STR)
664
END FUNCTION STR
665
!-------------------------------------------------------------------------------
666
END SUBROUTINE
667
668
! *****************************************************************************/
669
!> Interpolates hydrology variables necessary for calving from hydro mesh to ice
670
!> mesh as part of combined calving-hydrology simulations.
671
SUBROUTINE HydroToIceInterp( Model,Solver,Timestep,TransientSimulation )
672
!******************************************************************************
673
!
674
! ARGUMENTS:
675
!
676
! TYPE(Model_t) :: Model,
677
! INPUT: All model information (mesh,materials,BCs,etc...)
678
!
679
! TYPE(Solver_t) :: Solver
680
! INPUT: Linear equation solver options
681
!
682
! REAL(KIND=dp) :: Timestep
683
! INPUT: Timestep size for time dependent simulations
684
!
685
!******************************************************************************
686
USE Differentials
687
USE MaterialModels
688
USE DefUtils
689
USE InterpVarToVar
690
!------------------------------------------------------------------------------
691
IMPLICIT NONE
692
!------------------------------------------------------------------------------
693
!------------------------------------------------------------------------------
694
! External variables
695
!------------------------------------------------------------------------------
696
TYPE(Model_t) :: Model
697
TYPE(Solver_t), TARGET :: Solver
698
LOGICAL :: TransientSimulation
699
REAL(KIND=dp) :: Timestep
700
!------------------------------------------------------------------------------
701
! Local variables
702
!------------------------------------------------------------------------------
703
TYPE(Mesh_t), POINTER :: IceMesh, HydroMesh
704
TYPE(Solver_t), POINTER :: HydroSolver
705
TYPE(Variable_t), POINTER :: WorkVar=>NULL(), InterpVar1=>NULL(),&
706
InterpVar2=>NULL(), InterpVar3=>NULL()
707
TYPE(Variable_t), TARGET :: InterpVar1Copy, InterpVar2Copy, InterpVar3Copy
708
TYPE(ValueList_t), POINTER :: Params
709
LOGICAL :: FirstTime=.TRUE.
710
LOGICAL, POINTER :: BasalLogical(:)
711
INTEGER, POINTER :: InterpDim(:), IceMeshBasePerm(:)=>NULL(),&
712
NPP(:)=>NULL(), NewPerm1(:)
713
INTEGER, ALLOCATABLE, TARGET :: NewPerm2(:), NewPerm3(:)
714
INTEGER :: i, HPSolver, DummyInt, ierr
715
REAL(KIND=dp), POINTER :: NVP(:)=>NULL(), NewValues1(:)
716
REAL(KIND=dp), ALLOCATABLE, TARGET :: NewValues2(:),&
717
NewValues3(:)
718
SAVE HydroMesh, FirstTime, HPSolver! NewPerm1,&
719
!NewValues1, NewPerm2, NewValues2, NewPerm3, NewValues3
720
721
!------------------------------------------------------------------------------
722
723
Params => GetSolverParams()
724
725
!For finding main hydrology solver so know where to interpolate from.
726
IF(FirstTime) THEN
727
DO i=1,Model % NumberOfSolvers
728
IF(Model % Solvers(i) % Variable % Name == 'hydraulic potential') THEN
729
HPSolver = i
730
EXIT
731
END IF
732
END DO
733
END IF!FirstTime
734
735
!Time to interpolate variables that are solved on ice mesh
736
HydroSolver => Model % Solvers(HPSolver)
737
ALLOCATE(InterpDim(1)); InterpDim = (/3/)
738
ALLOCATE(BasalLogical(Model % Mesh % NumberOfNodes))
739
ALLOCATE(IceMeshBasePerm(Model % Mesh % NumberOfNodes))
740
741
CALL MakePermUsingMask(Model, Solver, Model % Mesh, "Bottom Surface Mask",&
742
.FALSE., IceMeshBasePerm, DummyInt)
743
744
!True nodes ignored by InterpolateVarToVarReduced
745
DO i=1, Model % Mesh % NumberOfNodes
746
BasalLogical(i) = (IceMeshBasePerm(i) <=0)
747
END DO
748
749
!Set up list of variables needed by GlaDS that have to be interpolated
750
InterpVar1 => VariableGet(HydroSolver % Mesh % Variables, "water pressure", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
751
!InterpVar2 => VariableGet(HydroSolver % Mesh % Variables, "sheet discharge 1", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
752
!InterpVar3 => VariableGet(HydroSolver % Mesh % Variables, "sheet discharge 2", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
753
754
!Make copies of the relevant variables to save messing around with the mesh
755
!variable list - only need perms and values
756
ALLOCATE(InterpVar1Copy % Values(SIZE(InterpVar1 % Values)), InterpVar1Copy % Perm(SIZE(InterpVar1 % Perm)))
757
InterpVar1Copy % Values = InterpVar1 % Values
758
InterpVar1Copy % Perm = InterpVar1 % Perm
759
InterpVar1Copy % Next => NULL() !InterpVar2Copy
760
InterpVar1Copy % Name = InterpVar1 % Name
761
762
!ALLOCATE(InterpVar2Copy % Values(SIZE(InterpVar2 % Values)), InterpVar2Copy % Perm(SIZE(InterpVar2 % Perm)))
763
!InterpVar2Copy % Values = InterpVar2 % Values
764
!InterpVar2Copy % Perm = InterpVar2 % Perm
765
!InterpVar2Copy % Next => InterpVar3Copy
766
!InterpVar2Copy % Name = InterpVar2 % Name
767
768
!ALLOCATE(InterpVar3Copy % Values(SIZE(InterpVar3 % Values)), InterpVar3Copy % Perm(SIZE(InterpVar3 % Perm)))
769
!InterpVar3Copy % Values = InterpVar3 % Values
770
!InterpVar3Copy % Perm = InterpVar3 % Perm
771
!InterpVar3Copy % Next => NULL()
772
!InterpVar3Copy % Name = InterpVar3 % Name
773
774
InterpVar1 => InterpVar1Copy
775
!InterpVar2 => InterpVar2Copy
776
!InterpVar3 => InterpVar3Copy
777
778
!Variables need to be added to mesh before interpolated as list
779
IF(FirstTime) THEN
780
FirstTime = .FALSE.
781
WorkVar => VariableGet(Model % Mesh % Variables,&
782
'velocity 1', ThisOnly=.TRUE.)
783
ALLOCATE(NewPerm1(SIZE(WorkVar % Perm)),NewValues1(SIZE(WorkVar % Values)))
784
!ALLOCATE(NewPerm2(SIZE(WorkVar % Perm)),NewValues2(SIZE(WorkVar % Values)))
785
!ALLOCATE(NewPerm3(SIZE(WorkVar % Perm)),NewValues3(SIZE(WorkVar % Values)))
786
NewPerm1 = WorkVar % Perm
787
!NewPerm2 = NewPerm1
788
!NewPerm3 = NewPerm1
789
!NPP => NewPerm1
790
NewValues1 = 0.0_dp
791
!NewValues2 = 0.0_dp
792
!NewValues3 = 0.0_dp
793
!NVP => NewValues1
794
CALL VariableAdd(Model % Mesh % Variables, Model % &
795
Mesh, CurrentModel % Solver, InterpVar1 % Name, 1,&
796
NewValues1, NewPerm1)
797
!NPP => NewPerm2
798
!NVP => NewValues2
799
!CALL VariableAdd(Model % Mesh % Variables, Model % &
800
! Mesh, CurrentModel % Solver, InterpVar2 % Name, 1,&
801
! NVP, NPP)
802
!NPP => NewPerm3
803
!NVP => NewValues3
804
!CALL VariableAdd(Model % Mesh % Variables, Model % &
805
! Mesh, CurrentModel % Solver, InterpVar3 % Name, 1,&
806
! NVP, NPP)
807
END IF
808
809
CALL ParallelActive(.TRUE.)
810
CALL InterpolateVarToVarReduced(HydroSolver % Mesh, Model % Mesh,&
811
'effective pressure', InterpDim, NewNodeMask=BasalLogical,&
812
Variables=InterpVar1)
813
CALL MPI_BARRIER(ELMER_COMM_WORLD, ierr)
814
CALL ParallelActive(.FALSE.)
815
816
DEALLOCATE(InterpDim, BasalLogical, IceMeshBasePerm, InterpVar1Copy % Perm,&
817
InterpVar1Copy % Values)!, InterpVar2Copy % Perm,&
818
!InterpVar2Copy % Values, InterpVar3Copy % Perm,&
819
!InterpVar3Copy % Values)
820
NULLIFY(HydroSolver, WorkVar, NVP, NPP, InterpVar1)!, InterpVar2, InterpVar3)
821
822
END SUBROUTINE
823
! *****************************************************************************/
824
!> Works out weights on hydro mesh at beginning of simulation
825
SUBROUTINE HydroWeightsSolver( Model,Solver,Timestep,TransientSimulation )
826
!******************************************************************************
827
!
828
! ARGUMENTS:
829
!
830
! TYPE(Model_t) :: Model,
831
! INPUT: All model information (mesh,materials,BCs,etc...)
832
!
833
! TYPE(Solver_t) :: Solver
834
! INPUT: Linear equation solver options
835
!
836
! REAL(KIND=dp) :: Timestep
837
! INPUT: Timestep size for time dependent simulations
838
!
839
!******************************************************************************
840
USE Differentials
841
USE MaterialModels
842
USE DefUtils
843
USE InterpVarToVar
844
!------------------------------------------------------------------------------
845
IMPLICIT NONE
846
!------------------------------------------------------------------------------
847
!------------------------------------------------------------------------------
848
! External variables
849
!------------------------------------------------------------------------------
850
TYPE(Model_t) :: Model
851
TYPE(Solver_t), TARGET :: Solver
852
LOGICAL :: TransientSimulation
853
REAL(KIND=dp) :: Timestep
854
!------------------------------------------------------------------------------
855
! Local variables
856
!------------------------------------------------------------------------------
857
TYPE(Variable_t), POINTER :: WorkVar
858
!------------------------------------------------------------------------------
859
CALL CalculateNodalWeights(Solver, .FALSE.,VarName='HydroWeights')
860
WorkVar => VariableGet(Solver % Mesh % Variables, "HydroWeights", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
861
IF(ParEnv % PEs > 1) CALL ParallelSumVector(Solver % Matrix, WorkVar % Values)
862
NULLIFY(WorkVar)
863
END SUBROUTINE
864
! *****************************************************************************/
865
!> Works out weights on ice mesh
866
SUBROUTINE IceWeightsSolver( Model,Solver,Timestep,TransientSimulation )
867
!******************************************************************************
868
!
869
! ARGUMENTS:
870
!
871
! TYPE(Model_t) :: Model,
872
! INPUT: All model information (mesh,materials,BCs,etc...)
873
!
874
! TYPE(Solver_t) :: Solver
875
! INPUT: Linear equation solver options
876
!
877
! REAL(KIND=dp) :: Timestep
878
! INPUT: Timestep size for time dependent simulations
879
!
880
!******************************************************************************
881
USE Differentials
882
USE MaterialModels
883
USE DefUtils
884
USE InterpVarToVar
885
!------------------------------------------------------------------------------
886
IMPLICIT NONE
887
!------------------------------------------------------------------------------
888
!------------------------------------------------------------------------------
889
! External variables
890
!------------------------------------------------------------------------------
891
TYPE(Model_t) :: Model
892
TYPE(Solver_t), TARGET :: Solver
893
LOGICAL :: TransientSimulation
894
REAL(KIND=dp) :: Timestep
895
!------------------------------------------------------------------------------
896
! Local variables
897
!------------------------------------------------------------------------------
898
TYPE(Variable_t), POINTER :: WorkVar
899
!------------------------------------------------------------------------------
900
CALL CalculateNodalWeights(Solver, .TRUE.,VarName='IceWeights')
901
WorkVar => VariableGet(Solver % Mesh % Variables, "IceWeights", ThisOnly=.TRUE., UnfoundFatal=.TRUE.)
902
IF(ParEnv % PEs > 1) CALL ParallelSumVector(Solver % Matrix, WorkVar % Values)
903
NULLIFY(WorkVar)
904
END SUBROUTINE
905
906