-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathSPHHydros.py
More file actions
159 lines (140 loc) · 5.81 KB
/
SPHHydros.py
File metadata and controls
159 lines (140 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
from SpheralCompiledPackages import *
from spheralDimensions import spheralDimensions
dims = spheralDimensions()
#-------------------------------------------------------------------------------
# The generic SPHHydro pattern.
#-------------------------------------------------------------------------------
def SPH(W,
WPi = None,
WGrad = None,
dataBase = None,
Q = None,
filter = None,
cfl = 0.25,
useVelocityMagnitudeForDt = False,
compatibleEnergyEvolution = True,
evolveTotalEnergy = False,
gradhCorrection = True,
XSPH = True,
correctVelocityGradient = True,
sumMassDensityOverAllNodeLists = True,
densityUpdate = RigorousSumDensity,
HUpdate = IdealH,
epsTensile = 0.0,
nTensile = 4.0,
damageRelieveRubble = False,
strengthInDamage = False,
xmin = (-1e100, -1e100, -1e100),
xmax = ( 1e100, 1e100, 1e100),
etaMinAxis = 0.1,
ASPH = False,
smoothingScaleMethod = None):
# Check if we're running solid or fluid hydro
nfluid = dataBase.numFluidNodeLists
nsolid = dataBase.numSolidNodeLists
if nsolid > 0 and nsolid != nfluid:
print("SPH Error: you have provided both solid and fluid NodeLists, which is currently not supported.")
print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,")
print(" which will result in fluid behaviour for those nodes.")
raise RuntimeError("Cannot mix solid and fluid NodeLists.")
# Check for deprecated arguments
if not filter is None:
print("SPH DEPRECATION WARNING: filter is no longer used -- ignoring")
# Pick the appropriate C++ constructor from dimensionality and coordinates
ndim = dataBase.nDim
if GeometryRegistrar.coords() == CoordinateType.Spherical:
assert ndim == 1
if nsolid > 0:
constructor = SolidSphericalSPH
else:
constructor = SphericalSPH
# Build the spherical kernels
print("Constructing Spherical kernels...")
W3S1 = SphericalKernel(W)
W = W3S1
if WPi:
WPi3S1 = SphericalKernel(WPi)
WPi = WPi3S1
if WGrad:
WGrad3S1 = SphericalKernel(WGrad)
WGrad = WGrad3S1
elif GeometryRegistrar.coords() == CoordinateType.RZ:
assert ndim == 2
if nsolid > 0:
constructor = SolidSPHRZ
else:
constructor = SPHRZ
else:
if nsolid > 0:
constructor = eval("SolidSPH%id" % ndim)
else:
constructor = eval("SPH%id" % ndim)
# Fill out the set of kernels
if WPi is None:
WPi = W
if WGrad is None:
WGrad = W
# Artificial viscosity.
if not Q:
Cl = 2.0*(dataBase.maxKernelExtent/2.0)
Cq = 2.0*(dataBase.maxKernelExtent/2.0)**2
if GeometryRegistrar.coords() == CoordinateType.Spherical:
Q = eval("LimitedMonaghanGingoldViscosity%id(Clinear=%g, Cquadratic=%g, kernel=WPi.baseKernel1d)" % (ndim, Cl, Cq))
else:
Q = eval("LimitedMonaghanGingoldViscosity%id(Clinear=%g, Cquadratic=%g, kernel=WPi)" % (ndim, Cl, Cq))
# Build the constructor arguments
xmin = (ndim,) + xmin
xmax = (ndim,) + xmax
kwargs = {"dataBase" : dataBase,
"Q" : Q,
"W" : W,
"WPi" : WPi,
"cfl" : cfl,
"useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt,
"compatibleEnergyEvolution" : compatibleEnergyEvolution,
"evolveTotalEnergy" : evolveTotalEnergy,
"gradhCorrection" : gradhCorrection,
"XSPH" : XSPH,
"correctVelocityGradient" : correctVelocityGradient,
"sumMassDensityOverAllNodeLists" : sumMassDensityOverAllNodeLists,
"densityUpdate" : densityUpdate,
"epsTensile" : epsTensile,
"nTensile" : nTensile,
"xmin" : eval("Vector%id(%g, %g, %g)" % xmin),
"xmax" : eval("Vector%id(%g, %g, %g)" % xmax)}
if nsolid > 0:
kwargs.update({"WGrad" : WGrad,
"damageRelieveRubble" : damageRelieveRubble,
"strengthInDamage" : strengthInDamage})
# Build the SPH hydro
result = constructor(**kwargs)
# Add the Q as a sub-package (to run before the hydro)
result.Q = Q
result.prependSubPackage(Q)
# Smoothing scale update
if smoothingScaleMethod is None:
WH = W.baseKernel1d if GeometryRegistrar.coords() == CoordinateType.Spherical else W
if ASPH:
if isinstance(ASPH, str) and ASPH.upper() == "CLASSIC":
smoothingScaleMethod = eval(f"ASPHClassicSmoothingScale{ndim}d(HUpdate, WH)")
else:
smoothingScaleMethod = eval(f"ASPHSmoothingScale{ndim}d(HUpdate, WH)")
else:
smoothingScaleMethod = eval(f"SPHSmoothingScale{ndim}d(HUpdate, WH)")
result._smoothingScaleMethod = smoothingScaleMethod
result.appendSubPackage(smoothingScaleMethod)
# In spherical coordatinates, preserve our locally constructed spherical kernels
if GeometryRegistrar.coords() == CoordinateType.Spherical:
result._W3S1 = W
result._WPi3S1 = WPi
result._WGrad3S1 = WGrad
# If we're using area-weighted RZ, store etaMinAxis
if GeometryRegistrar.coords() == CoordinateType.RZ:
result.etaMinAxis = etaMinAxis
return result
#-------------------------------------------------------------------------------
# Provide shorthand names for ASPH
#-------------------------------------------------------------------------------
def ASPH(*args, **kwargs):
kwargs.update({"ASPH" : True})
return SPH(*args, **kwargs)