Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/UserFunctions/USF_SourceCalcCalving.F90
3196 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://elmerice.elmerfem.org
28
! *
29
! * Original Date:
30
! * 2018/05/30. Samuel Cook
31
! *****************************************************************************
32
!------------------------------------------------------------------------------
33
!> Works out a total source (meltwater input) term for GlaDS calculations.
34
!> Uses surface runoff (from RACMO, etc.) and temp residual values from Elmer.
35
!> Additional keywords needed in Body Force section of SIF:
36
!>
37
!> Surface Melt = Logical True or False
38
!> If True, will look for a surface melt variable to add to source
39
!>
40
!> Internal Melt = Logical True or False
41
!> If True, will calculate melt due to friction heating using residuals
42
!> from the TemperateIceSolver
43
!>
44
!> Surface Melt Variable Name = String "[name of variable]"
45
!> If Surface Melt = Logical True, the name of the relevant variable to
46
!> search for surface melt values in needs to be provided. Make sure this
47
!> variable is defined throughout the vertical extent of the mesh, not
48
!> just on the surface, or it won't be found
49
!>
50
!> Internal Melt Variable Name = String "[name of variable]"
51
!> The name of the variable in which the residual temperature values are
52
!> stored, if Internal Melt = Logical True
53
!>
54
!------------------------------------------------------------------------------
55
FUNCTION SourceCalc (Model, NodeNumber, SomeVariable) RESULT(Source)
56
!------------------------------------------------------------------------------
57
USE DefUtils
58
IMPLICIT NONE
59
60
TYPE(Model_t) :: Model
61
INTEGER :: NodeNumber
62
REAL(KIND=dp) :: SomeVariable
63
64
!----------------------------------------------------------
65
TYPE(Element_t), POINTER :: CurrentElement
66
TYPE(Variable_t), POINTER :: IMVar, SMVar, Weights
67
TYPE(ValueList_t), POINTER :: BodyForce
68
INTEGER :: i, HPSolver
69
REAL(KIND=dp) :: Source, InternalMelt, SurfaceMelt
70
LOGICAL :: Found, SMLogical, IMLogical, FirstTime=.TRUE., Calving
71
CHARACTER(LEN=20) :: IMVarName, SMVarName
72
73
SAVE FirstTime, HPSolver, Calving
74
!------------------------------------------------------------------------
75
Found = .FALSE.
76
SMLogical = .FALSE.
77
IMLogical = .FALSE.
78
79
CurrentElement => Model % CurrentElement
80
BodyForce => GetBodyForce(CurrentElement)
81
82
!Construct table of element areas and get some mesh parameters.
83
!Only needed first time function called; subsequently saved
84
IF (FirstTime) THEN
85
Calving = GetLogical(Model % Simulation, 'Calving', Found)
86
IF(.NOT. Found) Calving = .FALSE.
87
DO i=1, Model % NumberOfSolvers
88
IF(Model % Solvers(i) % Variable % Name == 'hydraulic potential') THEN
89
HPSolver = i
90
EXIT
91
END IF
92
END DO
93
94
!Calculate nodal weights for scaling purposes
95
CALL CalculateNodalWeights(Model % Solvers(HPSolver), .FALSE., VarName='Weights')
96
FirstTime = .FALSE.
97
END IF !FirstTime
98
99
!Get internal melt variable - in Elmer, will be the temperature residual
100
!Name and logical defined in Body Force section of sif
101
IMLogical = GetLogical(BodyForce,'Internal Melt',Found)
102
IF(.NOT. Found) CALL Fatal('SourceCalc', "You've not specified if you want internal melt, silly")
103
IF (IMLogical) THEN
104
IMVarName = GetString(BodyForce,'Internal Melt Variable Name',Found)
105
IF(Calving) THEN
106
IMVar => VariableGet(Model % Solvers(HPSolver) % Mesh % Variables,&
107
IMVarName, ThisOnly = .TRUE., UnfoundFatal = .TRUE.)
108
Weights => VariableGet(Model % Solvers(HPSolver) % Mesh % Variables,&
109
'Weights', ThisOnly = .TRUE., UnfoundFatal = .TRUE.)
110
ELSE
111
IMVar => VariableGet(Model % Variables, IMVarName, ThisOnly = .TRUE., UnfoundFatal = .TRUE.)
112
Weights => VariableGet(Model % Variables, 'Weights', ThisOnly = .TRUE., UnfoundFatal = .TRUE.)
113
END IF
114
Found = .FALSE.
115
END IF
116
117
!Get Surface Melt - Logical and name set in Body Force in sif
118
!Needs to be surface runoff values in m/year
119
!Make sure is defined on basal nodes/throughout glacier, rather than just
120
!surface
121
SMVarName = GetString(BodyForce,'Surface Melt Variable Name',Found)
122
SMLogical = GetLogical(BodyForce,'Surface Melt',Found)
123
IF(.NOT. Found) CALL Fatal('SourceCalc', "You've not defined surface melt, you muppet")
124
IF (SMLogical) THEN
125
IF(Calving) THEN
126
SMVar => VariableGet(Model % Solvers(HPSolver) % Mesh % Variables,&
127
SMVarName, ThisOnly = .TRUE., UnfoundFatal = .TRUE.)
128
ELSE
129
SMVar => VariableGet(Model % Variables, SMVarName, ThisOnly = .TRUE., UnfoundFatal = .TRUE.)
130
END IF
131
Found = .FALSE.
132
END IF
133
134
IF(IMLogical) THEN
135
!If Temp Residual overall positive, no internal melting
136
!Temp Res is essentially difference between temperature and upper or lower
137
!limit
138
!If temp exceeded upper limit, then is negative; if below lower limit,
139
!is positive
140
!Here, should therefore all be negative, unless glacier dropped below
141
!absolute zero....
142
IF(IMVar % Values(IMVar % Perm(NodeNumber))>=0.0) THEN
143
InternalMelt = 0.0
144
ELSE
145
!Latent heat of fusion of water is 333.55 J/g, so dividing by that gives
146
! g of ice melted.
147
!TempRes in MJ, though (probably), so dividing by 333.55 gives Mg of ice
148
! melted
149
!1 Mg is 1 t, which is 1000 kg, so 1000 l, so 1 m3 (all per year), so
150
!that's it
151
!Also need to divide by element area to get m
152
InternalMelt = (ABS(IMVar % Values(IMVar % Perm(NodeNumber)))/Weights % Values(Weights % Perm(NodeNumber)))/333.55
153
END IF
154
ELSE
155
InternalMelt = 0.0
156
END IF
157
158
IF(SMLogical) THEN
159
IF(Calving) THEN
160
IF(SMVar % Values(SMVar % Perm(NodeNumber))>0.0) THEN
161
SurfaceMelt = SMVar % Values(SMVar % Perm(NodeNumber))
162
ELSE
163
SurfaceMelt = 0.0
164
END IF
165
ELSE
166
IF(SMVar % Values(SMVar % Perm(NodeNumber))>0.0) THEN
167
SurfaceMelt = SMVar % Values(SMVar % Perm(NodeNumber))
168
ELSE
169
SurfaceMelt = 0.0
170
END IF
171
END IF
172
ELSE
173
SurfaceMelt = 0.0
174
END IF
175
176
!Work out total
177
Source = InternalMelt + SurfaceMelt
178
179
!------------------------------------------------------------------------------
180
END FUNCTION SourceCalc
181
!------------------------------------------------------------------------------
182
183