planit 1.0.2__tar.gz → 1.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {planit-1.0.2 → planit-1.2.2}/PKG-INFO +7 -2
- {planit-1.0.2 → planit-1.2.2}/README.md +4 -1
- {planit-1.0.2 → planit-1.2.2}/planit/eos/aquatable.py +3 -1
- {planit-1.0.2 → planit-1.2.2}/planit/eos/eosfuncs.py +24 -4
- {planit-1.0.2 → planit-1.2.2}/planit/eos/eostab_extension.py +4 -2
- {planit-1.0.2 → planit-1.2.2}/planit/eos/rhoUtable.py +1 -0
- planit-1.2.2/planit/impacttools.py +459 -0
- {planit-1.0.2 → planit-1.2.2}/planit/main.py +4 -4
- {planit-1.0.2 → planit-1.2.2}/planit/makeplanet.py +13 -9
- planit-1.2.2/planit/plotting.py +298 -0
- planit-1.2.2/planit/snaptools/__init__.py +2 -0
- planit-1.2.2/planit/snaptools/io.py +786 -0
- planit-1.2.2/planit/snaptools/snaptools.py +555 -0
- {planit-1.0.2 → planit-1.2.2}/planit/utils.py +7 -0
- {planit-1.0.2 → planit-1.2.2}/planit.egg-info/PKG-INFO +7 -2
- {planit-1.0.2 → planit-1.2.2}/planit.egg-info/SOURCES.txt +7 -1
- {planit-1.0.2 → planit-1.2.2}/planit.egg-info/requires.txt +1 -0
- planit-1.2.2/pyproject.toml +37 -0
- {planit-1.0.2 → planit-1.2.2}/tests/test_eos.py +30 -3
- planit-1.2.2/tests/test_imp.py +38 -0
- planit-1.2.2/tests/test_io.py +102 -0
- planit-1.2.2/tests/test_make.py +74 -0
- planit-1.2.2/tests/test_plot.py +72 -0
- planit-1.2.2/tests/test_snap.py +122 -0
- planit-1.2.2/tests/test_utils.py +65 -0
- planit-1.0.2/planit/impacttools.py +0 -572
- planit-1.0.2/planit/snaptools.py +0 -933
- planit-1.0.2/pyproject.toml +0 -13
- planit-1.0.2/tests/test_make.py +0 -24
- planit-1.0.2/tests/test_snap.py +0 -14
- planit-1.0.2/tests/test_utils.py +0 -33
- {planit-1.0.2 → planit-1.2.2}/LICENSE +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit/__init__.py +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit/eos/__init__.py +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit/eos/aneostable.py +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit/eos/eos_table.py +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit/eos/tabinterp.py +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit/globaldefs.py +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit.egg-info/dependency_links.txt +0 -0
- {planit-1.0.2 → planit-1.2.2}/planit.egg-info/top_level.txt +0 -0
- {planit-1.0.2 → planit-1.2.2}/setup.cfg +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: planit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: The PLANetary Impact Toolkit provides tools for accessing, manipulating, and analysing smoothed particle hydrodynamcis (SPH) impact simulation data, and creating planets for SPH impact simulations.
|
|
5
5
|
Author-email: Philip Carter <p.carter@bristol.ac.uk>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
7
7
|
Project-URL: Homepage, https://github.com/PhilJCarter/planit
|
|
8
|
+
Requires-Python: >=3.10
|
|
8
9
|
Description-Content-Type: text/markdown
|
|
9
10
|
License-File: LICENSE
|
|
10
11
|
Requires-Dist: numpy
|
|
@@ -14,11 +15,15 @@ Requires-Dist: numba
|
|
|
14
15
|
Requires-Dist: h5py
|
|
15
16
|
Requires-Dist: seagen
|
|
16
17
|
Requires-Dist: cmasher
|
|
18
|
+
Requires-Dist: IPython
|
|
17
19
|
Dynamic: license-file
|
|
18
20
|
|
|
19
21
|
# planit
|
|
20
22
|
|
|
21
23
|
[](https://github.com/PhilJCarter/planit/actions/workflows/python-test.yml)
|
|
24
|
+
[](https://PhilJCarter.github.io/planit/cov_html/index.html)
|
|
25
|
+
[](https://github.com/PhilJCarter/planit/tree/main?tab=GPL-3.0-1-ov-file#GPL-3.0-1-ov-file)
|
|
26
|
+
|
|
22
27
|
|
|
23
28
|
The **Plan**etary **I**mpact **T**oolkit provides tools for accessing, manipulating, and
|
|
24
29
|
analysing smoothed particle hydrodynamcis (SPH) impact simulation data, and creating
|
|
@@ -29,7 +34,7 @@ Sarah T. Stewart (sstewa56@asu.edu)
|
|
|
29
34
|
|
|
30
35
|
## Overview
|
|
31
36
|
|
|
32
|
-
**planit** currently supports the SPH codes [Gadget2-planetary](https://github.com/PlanetSim/gadget2-planetary) and [SWIFT](http://www.swiftsim.com/).
|
|
37
|
+
**planit** currently supports the SPH codes [Gadget2-planetary](https://github.com/PlanetSim/gadget2-planetary), [pkdgrav3](https://bitbucket.org/dpotter/pkdgrav3/src/master/), and [SWIFT](http://www.swiftsim.com/).
|
|
33
38
|
|
|
34
39
|
`makeplanet` provides functions for generating adiabatic 1D planet structures and
|
|
35
40
|
converting these into (unequilibrated) SPH planets.\
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# planit
|
|
2
2
|
|
|
3
3
|
[](https://github.com/PhilJCarter/planit/actions/workflows/python-test.yml)
|
|
4
|
+
[](https://PhilJCarter.github.io/planit/cov_html/index.html)
|
|
5
|
+
[](https://github.com/PhilJCarter/planit/tree/main?tab=GPL-3.0-1-ov-file#GPL-3.0-1-ov-file)
|
|
6
|
+
|
|
4
7
|
|
|
5
8
|
The **Plan**etary **I**mpact **T**oolkit provides tools for accessing, manipulating, and
|
|
6
9
|
analysing smoothed particle hydrodynamcis (SPH) impact simulation data, and creating
|
|
@@ -11,7 +14,7 @@ Sarah T. Stewart (sstewa56@asu.edu)
|
|
|
11
14
|
|
|
12
15
|
## Overview
|
|
13
16
|
|
|
14
|
-
**planit** currently supports the SPH codes [Gadget2-planetary](https://github.com/PlanetSim/gadget2-planetary) and [SWIFT](http://www.swiftsim.com/).
|
|
17
|
+
**planit** currently supports the SPH codes [Gadget2-planetary](https://github.com/PlanetSim/gadget2-planetary), [pkdgrav3](https://bitbucket.org/dpotter/pkdgrav3/src/master/), and [SWIFT](http://www.swiftsim.com/).
|
|
15
18
|
|
|
16
19
|
`makeplanet` provides functions for generating adiabatic 1D planet structures and
|
|
17
20
|
converting these into (unequilibrated) SPH planets.\
|
|
@@ -17,9 +17,11 @@ def loadAQUAEOS(eos='Water-AQUA-v1.0', eostype='AQUA', debug = False):
|
|
|
17
17
|
|
|
18
18
|
if eos == 'Water-AQUA-v1.0':
|
|
19
19
|
eosdir = eospath + 'aqua-water/'
|
|
20
|
-
|
|
20
|
+
womaID = 304
|
|
21
|
+
|
|
21
22
|
NewEOS = EOStable() # FIRST make new empty EOS object
|
|
22
23
|
NewEOS.TYPE = eostype
|
|
24
|
+
NewEOS.womaID = womaID
|
|
23
25
|
NewEOS.VERSION = 1.0
|
|
24
26
|
|
|
25
27
|
NewEOS.loadaquatable(eosdir+'aqua_eos_rhot_v1_0.dat')
|
|
@@ -50,9 +50,9 @@ UserEOS4 = None
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
# Name lists for EoS
|
|
53
|
-
ironnames = ['Iron-ANEOS-SLVTv0.2G1', 'iron', 'ANEOSIron', 'Fe', 'Iron', 401]
|
|
54
|
-
alloynames = ['Fe85Si15-ANEOS-SLVTv0.2G1', 'alloy', 'ANEOSFeSiAlloy', 'FeSi', 'Alloy', 'IronAlloy', 'ironalloy', 402]
|
|
55
|
-
forsteritenames = ['Forsterite-ANEOS-SLVTv1.0G1', 'forsterite', 'ANEOSForsterite', 'Forsterite', 'Fo', 400]
|
|
53
|
+
ironnames = ['Iron-ANEOS-SLVTv0.2G1', 'iron', 'ANEOSIron', 'Fe', 'Iron', 401, 63]
|
|
54
|
+
alloynames = ['Fe85Si15-ANEOS-SLVTv0.2G1', 'alloy', 'ANEOSFeSiAlloy', 'FeSi', 'Alloy', 'IronAlloy', 'ironalloy', 402, 64]
|
|
55
|
+
forsteritenames = ['Forsterite-ANEOS-SLVTv1.0G1', 'forsterite', 'ANEOSForsterite', 'Forsterite', 'Fo', 400, 62]
|
|
56
56
|
pyrolitenames = ['Pyrolite_ANEOS_SLVTv0.2', 'pyrolite', 'Pyrolite', 'ANEOSPyrolite', 403]
|
|
57
57
|
aquawaternames = ['Water-AQUA-v1.0', 'AQUA', 'AQUAWater', 'aqua', 304]
|
|
58
58
|
fivephasewaternames = ['5PhaseEOSv8.3', '5PhaseWater', '5phasewater', 'SS08', 'SenftStewartWater', 'SenftStewart08', 303]
|
|
@@ -253,6 +253,26 @@ uconversion_U_inv = 1./uconversion_U
|
|
|
253
253
|
uconversion_S_inv = 1./uconversion_S
|
|
254
254
|
|
|
255
255
|
|
|
256
|
+
def pkdgrav3towoma(pkdmats):
|
|
257
|
+
"""Translate pkdgrav3/EOSLib material numbers to swift/woma IDs"""
|
|
258
|
+
swiftmats = pkdmats.copy()
|
|
259
|
+
swiftmats[pkdmats==63] = 401 # iron
|
|
260
|
+
swiftmats[pkdmats==62] = 400 # forsterite
|
|
261
|
+
swiftmats[pkdmats==64] = 402 # FeSi alloy
|
|
262
|
+
|
|
263
|
+
return swiftmats
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def womatopkdgrav3(swiftmats):
|
|
267
|
+
"""Translate swift/woma IDs to pkdgrav3/EOSLib material numbers"""
|
|
268
|
+
pkdmats = swiftmats.copy()
|
|
269
|
+
pkdmats[swiftmats==401] = 63 # iron
|
|
270
|
+
pkdmats[swiftmats==400] = 62 # forsterite
|
|
271
|
+
pkdmats[swiftmats==402] = 64 # FeSi alloy
|
|
272
|
+
|
|
273
|
+
return pkdmats
|
|
274
|
+
|
|
275
|
+
|
|
256
276
|
def calcprop(Qlab,Xlab,Ylab,X,Y,mats):
|
|
257
277
|
"""Calculate thermodynamic property
|
|
258
278
|
|
|
@@ -322,7 +342,7 @@ def _calc_prop(Qlab,Xlab,Ylab,X,Y,EOSlist):
|
|
|
322
342
|
Q = npy.zeros(len(X))
|
|
323
343
|
for i in numba.prange(len(X)):
|
|
324
344
|
|
|
325
|
-
if EOSlist[i].TYPE in ['ANEOS','SESAME','AQUA']:
|
|
345
|
+
if EOSlist[i].TYPE in ['ANEOS', 'SESAME', 'AQUA']:
|
|
326
346
|
if Ylab == 'S':
|
|
327
347
|
Q[i] = tabinterp.from_rhoS(Qlab, X[i], Y[i], EOSlist[i])
|
|
328
348
|
elif Ylab == 'U':
|
|
@@ -79,10 +79,12 @@ class EOStable(extEOStable):
|
|
|
79
79
|
passer.T = self.T
|
|
80
80
|
passer.P = self.P
|
|
81
81
|
passer.U = self.U
|
|
82
|
-
|
|
82
|
+
if len(self.A) > 0:
|
|
83
|
+
passer.A = self.A
|
|
83
84
|
passer.S = self.S
|
|
84
85
|
passer.cs = self.cs
|
|
85
|
-
|
|
86
|
+
if len(self.cv) > 0:
|
|
87
|
+
passer.cv = self.cv
|
|
86
88
|
# passer.KPA = self.KPA
|
|
87
89
|
# passer.MDQ = self.MDQ
|
|
88
90
|
passer.TYPE = self.TYPE
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"""
|
|
2
|
+
planit impact class and analysis tools
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .globaldefs import *
|
|
6
|
+
from .snaptools import Snapshot
|
|
7
|
+
from . import plotting
|
|
8
|
+
|
|
9
|
+
import numpy as npy
|
|
10
|
+
import scipy
|
|
11
|
+
import glob
|
|
12
|
+
import os
|
|
13
|
+
import matplotlib
|
|
14
|
+
import matplotlib.pyplot as plt
|
|
15
|
+
import cmasher
|
|
16
|
+
|
|
17
|
+
# for movie:
|
|
18
|
+
from IPython import display
|
|
19
|
+
import matplotlib.animation
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ImpSnapshot(Snapshot):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Impact:
|
|
27
|
+
"""
|
|
28
|
+
Gadget/Swift impact class
|
|
29
|
+
|
|
30
|
+
A wrapper for holding multiple snapshots
|
|
31
|
+
|
|
32
|
+
load()
|
|
33
|
+
plotseq()
|
|
34
|
+
attrmov()
|
|
35
|
+
"""
|
|
36
|
+
def __init__(self):
|
|
37
|
+
#self.targ = None
|
|
38
|
+
#self.proj = None
|
|
39
|
+
#self.v = None
|
|
40
|
+
#self.b = None
|
|
41
|
+
self.nsnaps = 0
|
|
42
|
+
self.snap = self.data = None
|
|
43
|
+
|
|
44
|
+
def load(self,loc,thermo=False,inter=1,compress=True,code='swift',ndigits=4,prefix='snapshot',sep='_',prefix2=None,flist=None):
|
|
45
|
+
Nf2 = Nf = 0
|
|
46
|
+
increment1 = increment2 = 1
|
|
47
|
+
flist2 = []
|
|
48
|
+
loc = str(loc)
|
|
49
|
+
if loc[-1] != '/':
|
|
50
|
+
loc = loc + '/'
|
|
51
|
+
files2 = npy.empty(0)
|
|
52
|
+
if flist:
|
|
53
|
+
files = files1 = flist
|
|
54
|
+
self.nsnaps = len(flist)
|
|
55
|
+
else:
|
|
56
|
+
if code=='swift':
|
|
57
|
+
flist = sorted(glob.glob(loc+prefix+sep+'[0-9]*.hdf5'))
|
|
58
|
+
if prefix2:
|
|
59
|
+
flist2 = sorted(glob.glob(loc+prefix2+sep+'[0-9]*.hdf5'))
|
|
60
|
+
else:
|
|
61
|
+
flist = sorted(glob.glob(loc+prefix+sep+'[0-9]*'))
|
|
62
|
+
if prefix2:
|
|
63
|
+
flist2 = sorted(glob.glob(loc+prefix2+sep+'[0-9]*'))
|
|
64
|
+
Nf1 = [(flist[x].split('/')[-1]).split(sep)[1].split('.')[0] for x in range(len(flist))]
|
|
65
|
+
if prefix2:
|
|
66
|
+
Nf2 = [(flist2[x].split('/')[-1]).split(sep)[1].split('.')[0] for x in range(len(flist2))]
|
|
67
|
+
if len(Nf1)>0:
|
|
68
|
+
Nf1 = sorted(npy.array(Nf1).astype(int))
|
|
69
|
+
increment1 = int(Nf1[1] - Nf1[0])
|
|
70
|
+
Nf = int(Nf1[-1])
|
|
71
|
+
else:
|
|
72
|
+
Nf = 0
|
|
73
|
+
if prefix2 and len(Nf2)>0:
|
|
74
|
+
Nf2 = sorted(npy.array(Nf2).astype(int))
|
|
75
|
+
increment2 = int(Nf2[1]-Nf2[0])
|
|
76
|
+
Nf2 = int(Nf2[-1])
|
|
77
|
+
else:
|
|
78
|
+
Nf2 = 0
|
|
79
|
+
print('Loading', int(Nf/increment1 + Nf2/increment2), 'files...')
|
|
80
|
+
self.nsnaps = len(flist)+len(flist2)
|
|
81
|
+
if self.nsnaps>2:
|
|
82
|
+
if Nf2>0:
|
|
83
|
+
files2 = npy.arange(0,Nf2+increment2,inter*increment2)
|
|
84
|
+
files1 = npy.arange(0,Nf+increment1,inter*increment1)
|
|
85
|
+
files = npy.append(files1,files2)
|
|
86
|
+
elif self.nsnaps>0:
|
|
87
|
+
files = npy.array([0,Nf])
|
|
88
|
+
else:
|
|
89
|
+
files = []
|
|
90
|
+
|
|
91
|
+
self.data = npy.ndarray((len(files),),dtype=object)
|
|
92
|
+
|
|
93
|
+
for i in range(len(self.data)):
|
|
94
|
+
honly = True
|
|
95
|
+
if i==0 or i==len(self.data)-1:
|
|
96
|
+
honly = False
|
|
97
|
+
self.data[i] = ImpSnapshot()
|
|
98
|
+
if code=='swift' or code=='Swift':
|
|
99
|
+
if i<len(files1):
|
|
100
|
+
self.data[i].load(loc+prefix+sep+'{:>0{width}d}.hdf5'.format(int(files[i]),width=ndigits),headonly=honly,thermo=thermo,compress=compress)
|
|
101
|
+
else:
|
|
102
|
+
self.data[i].load(loc+prefix2+sep+'{:>0{width}d}.hdf5'.format(int(files[i]),width=ndigits),headonly=honly,thermo=thermo,compress=compress)
|
|
103
|
+
else:
|
|
104
|
+
if i<len(files1):
|
|
105
|
+
self.data[i].load(loc+prefix+sep+'{:>0{width}d}'.format(int(files[i]),width=ndigits),headonly=honly,thermo=thermo,compress=compress)
|
|
106
|
+
else:
|
|
107
|
+
self.data[i].load(loc+prefix2+sep+'{:>0{width}d}'.format(int(files[i]),width=ndigits),headonly=honly,thermo=thermo,compress=compress)
|
|
108
|
+
|
|
109
|
+
self.snap = self.data
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def plotseq(self, n=4, ptype='materials', type=None, seq=None, times=None, scale='Mm', potmin=False, tcut = 3600., zoom=1., focus='potmin', cmap=None):
|
|
113
|
+
"""
|
|
114
|
+
tcut -- time cut for pre-contact treatment
|
|
115
|
+
"""
|
|
116
|
+
if seq is None: # and times is None:
|
|
117
|
+
if self.nsnaps>n:
|
|
118
|
+
seq = npy.logspace(0,npy.log10(len(self.data)-1),n).astype(int)
|
|
119
|
+
else:
|
|
120
|
+
seq = npy.arange(self.nsnaps)
|
|
121
|
+
elif seq is not None:
|
|
122
|
+
n = len(seq)
|
|
123
|
+
|
|
124
|
+
if type: # for backwards compatibility
|
|
125
|
+
ptype = type
|
|
126
|
+
|
|
127
|
+
scf = plotting.get_scale_fac(scale)
|
|
128
|
+
axlim = 4*int(npy.ceil((self.data[0].x.max()-self.data[0].x.min())/scf/8.))
|
|
129
|
+
zcut = axlim/200.*scf
|
|
130
|
+
|
|
131
|
+
# region to grid/plot
|
|
132
|
+
#zmin=-axlim/10.
|
|
133
|
+
#zmax=axlim/10.
|
|
134
|
+
|
|
135
|
+
axlim /= zoom
|
|
136
|
+
|
|
137
|
+
# number of cells for grid
|
|
138
|
+
Ng = 1601j
|
|
139
|
+
#Ngz = 21j
|
|
140
|
+
|
|
141
|
+
#zi=npy.linspace(zmin,zmax,int(Ngz.imag))
|
|
142
|
+
#X,Y,Z = npy.mgrid[-axlim:axlim:(Ng),-axlim:axlim:(Ng),zmin:zmax:(Ngz)]
|
|
143
|
+
X,Y = npy.mgrid[-axlim:axlim:(Ng),-axlim:axlim:(Ng)]
|
|
144
|
+
Z = npy.full_like(X, 0)
|
|
145
|
+
|
|
146
|
+
if potmin: # for backwards compatibility
|
|
147
|
+
focus='potmin'
|
|
148
|
+
|
|
149
|
+
if not cmap:
|
|
150
|
+
cmap = plotting.get_default_colormap(ptype)
|
|
151
|
+
if ptype in plotting.phase_type:
|
|
152
|
+
cmap = matplotlib.colors.ListedColormap(cmap.colors[[0,1,2,3,4,5],:])
|
|
153
|
+
#cmap = matplotlib.colors.ListedColormap(cmap.colors[0,1,2,3,4,5])
|
|
154
|
+
|
|
155
|
+
fig = plt.figure(figsize=(10,6))
|
|
156
|
+
|
|
157
|
+
for i in range(len(seq)):
|
|
158
|
+
j = seq[i]
|
|
159
|
+
plt.subplot(1,n,i+1,aspect='equal')
|
|
160
|
+
|
|
161
|
+
if ptype in plotting.materials_type:
|
|
162
|
+
im = plotting.plot_snapshot_scatter(self.data[j],cmap=cmap,plotQ=-(self.data[j].id/PROJ_ID_OFFSET).astype(int),ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,focus=focus)
|
|
163
|
+
elif ptype in plotting.density_type:
|
|
164
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
165
|
+
elif ptype in plotting.entropy_type:
|
|
166
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,plotQ=self.data[j].S/1e7,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
167
|
+
elif ptype in plotting.temperature_type:
|
|
168
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,plotQ=self.data[j].T,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
169
|
+
elif ptype in plotting.pressure_type:
|
|
170
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,plotQ=self.data[j].P/1e9,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
171
|
+
elif ptype in plotting.phase_type:
|
|
172
|
+
im = plotting.plot_snapshot_scatter(self.data[j],cmap=cmap,plotQ=self.data[j].phase,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,focus=focus)
|
|
173
|
+
|
|
174
|
+
if i>0:
|
|
175
|
+
plt.gca().set_yticklabels([])
|
|
176
|
+
plt.gca().set_ylabel('')
|
|
177
|
+
|
|
178
|
+
if i == len(seq)-1:
|
|
179
|
+
tlab = plt.gca().texts[0]
|
|
180
|
+
tlab.set_text(tlab.get_text()+' hrs')
|
|
181
|
+
|
|
182
|
+
if ptype not in plotting.materials_type:
|
|
183
|
+
if i == len(seq)-1:
|
|
184
|
+
pbox=plt.gca().get_position()
|
|
185
|
+
xw = 0.25
|
|
186
|
+
cbar_ax = fig.add_axes([pbox.x1-xw, pbox.y1*1.1, xw, 0.015])
|
|
187
|
+
cbar = fig.colorbar(im, cax=cbar_ax, orientation='horizontal')
|
|
188
|
+
plotting.format_colorbar_axis(cbar, ptype)
|
|
189
|
+
plt.subplots_adjust(wspace=0, hspace=0)
|
|
190
|
+
#plt.show(block=False)
|
|
191
|
+
return fig
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def attrmov(self, n=40, ptype='materials', seq=None, times=None, scale='Mm', focus='potmin', fps=12, zoom=1., cmap = None, dpi=400, bitrate=5000, tcut = 3600.):
|
|
195
|
+
if seq is None: #and times is None:
|
|
196
|
+
if self.nsnaps>n:
|
|
197
|
+
seq = npy.logspace(0,npy.log10(len(self.data)-1),n).astype(int)
|
|
198
|
+
else:
|
|
199
|
+
seq = npy.arange(self.nsnaps-1)
|
|
200
|
+
elif seq is not None:
|
|
201
|
+
n = len(seq)
|
|
202
|
+
|
|
203
|
+
if ptype not in [*plotting.materials_type,*plotting.density_type,*plotting.entropy_type,*plotting.phase_type,*plotting.pressure_type,*plotting.temperature_type]:
|
|
204
|
+
raise ValueError('Unknown plot type:',ptype)
|
|
205
|
+
|
|
206
|
+
scf = plotting.get_scale_fac(scale)
|
|
207
|
+
axlim = 1.5*int(npy.ceil((self.data[0].x.max()-self.data[0].x.min())/scf/8.))/zoom #4*
|
|
208
|
+
zcut = axlim/200.*scf
|
|
209
|
+
|
|
210
|
+
# number of cells for grid
|
|
211
|
+
Ng = 1201j
|
|
212
|
+
#Ngz = 21j
|
|
213
|
+
|
|
214
|
+
# region to grid/plot
|
|
215
|
+
#zmin=-axlim/10.
|
|
216
|
+
#zmax=axlim/10.
|
|
217
|
+
#zlim = zmax/5.*scf
|
|
218
|
+
|
|
219
|
+
#zi=npy.linspace(zmin,zmax,int(Ngz.imag))
|
|
220
|
+
#X,Y,Z = npy.mgrid[-axlim:axlim:(Ng),-axlim:axlim:(Ng),zmin:zmax:(Ngz)]
|
|
221
|
+
X,Y = npy.mgrid[-axlim:axlim:(Ng),-axlim:axlim:(Ng)]
|
|
222
|
+
Z = npy.full_like(X, 0)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
if not cmap:
|
|
226
|
+
cmap = plotting.get_default_colormap(ptype)
|
|
227
|
+
if ptype in plotting.phase_type:
|
|
228
|
+
cmap = matplotlib.colors.ListedColormap(cmap.colors[[0,1,2,3,4,5],:])
|
|
229
|
+
|
|
230
|
+
j = 0
|
|
231
|
+
def attrmovfunc(j):
|
|
232
|
+
plt.clf()
|
|
233
|
+
plt.minorticks_on()
|
|
234
|
+
|
|
235
|
+
if ptype in plotting.materials_type:
|
|
236
|
+
im = plotting.plot_snapshot_scatter(self.data[j],cmap=cmap,plotQ=-(self.data[j].id/PROJ_ID_OFFSET).astype(int),ax=plt.gca(),ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,focus=focus)
|
|
237
|
+
elif ptype in plotting.phase_type:
|
|
238
|
+
im = plotting.plot_snapshot_scatter(self.data[j],cmap=cmap,plotQ=self.data[j].phase,ax=plt.gca(),ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,focus=focus)
|
|
239
|
+
elif ptype in plotting.density_type:
|
|
240
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,plotQ=self.data[j].rho,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
241
|
+
elif ptype in plotting.entropy_type:
|
|
242
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,plotQ=self.data[j].S/1e7,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
243
|
+
elif ptype in plotting.temperature_type:
|
|
244
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,plotQ=self.data[j].T,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
245
|
+
elif ptype in plotting.pressure_type:
|
|
246
|
+
im = plotting.plot_snapshot_fluid(self.data[j],X,Y,Z,plotQ=self.data[j].P/1e9,ax=plt.gca(),cmap=cmap,ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=0.5*self.data[0].vel.min(),focus=focus)
|
|
247
|
+
|
|
248
|
+
if ptype not in plotting.materials_type:
|
|
249
|
+
pbox = plt.gca().get_position()
|
|
250
|
+
cbar_ax = fig.add_axes([pbox.x1*1.02, pbox.y0, 0.035, 1.0*(pbox.y1-pbox.y0)])
|
|
251
|
+
cbar = fig.colorbar(im, cax=cbar_ax, orientation='vertical')
|
|
252
|
+
plotting.format_colorbar_axis(cbar, ptype, y=True)
|
|
253
|
+
|
|
254
|
+
if n>30 and j!=0 and j!=len(self.data)-1:
|
|
255
|
+
self.data[j].freedata()
|
|
256
|
+
|
|
257
|
+
fig = plt.figure(figsize=(3.5,2.8))
|
|
258
|
+
|
|
259
|
+
if len(seq)==1:
|
|
260
|
+
attrmovfunc(seq[0])
|
|
261
|
+
plt.subplots_adjust(top=0.98,bottom=0.11,left=0.17,right=0.8)
|
|
262
|
+
plt.show(block=False)
|
|
263
|
+
return fig
|
|
264
|
+
else:
|
|
265
|
+
if matplotlib.animation.FFMpegWriter.isAvailable():
|
|
266
|
+
filetype = '.mp4'
|
|
267
|
+
else:
|
|
268
|
+
filetype = '.gif'
|
|
269
|
+
if ptype in plotting.materials_type:
|
|
270
|
+
movfile = os.path.dirname(self.data[0].file)+'/materials'+filetype
|
|
271
|
+
elif ptype in plotting.density_type:
|
|
272
|
+
movfile = os.path.dirname(self.data[0].file)+'/density'+filetype
|
|
273
|
+
elif ptype in plotting.entropy_type:
|
|
274
|
+
movfile = os.path.dirname(self.data[0].file)+'/entropy'+filetype
|
|
275
|
+
elif ptype in plotting.phase_type:
|
|
276
|
+
movfile = os.path.dirname(self.data[0].file)+'/phase'+filetype
|
|
277
|
+
elif ptype in plotting.pressure_type:
|
|
278
|
+
movfile = os.path.dirname(self.data[0].file)+'/pressure'+filetype
|
|
279
|
+
elif ptype in plotting.temperature_type:
|
|
280
|
+
movfile = os.path.dirname(self.data[0].file)+'/temperature'+filetype
|
|
281
|
+
else:
|
|
282
|
+
movfile = os.path.dirname(self.data[0].file)+'/attrmov'+filetype
|
|
283
|
+
anim=matplotlib.animation.FuncAnimation(fig,attrmovfunc,seq)
|
|
284
|
+
plt.subplots_adjust(top=0.975,bottom=0.105,left=0.17,right=0.8)
|
|
285
|
+
##anim.save(movfile,dpi=200,writer=matplotlib.animation.PillowWriter(fps=fps,bitrate=1000)) #writer='ffmpeg' # 800 # 9000 fps=fps,bitrate=1000
|
|
286
|
+
anim.save(movfile,dpi=dpi,fps=fps,bitrate=bitrate) #writer='ffmpeg' # 800 # 9000 fps=fps,bitrate=1000
|
|
287
|
+
plt.show()
|
|
288
|
+
plt.close()
|
|
289
|
+
|
|
290
|
+
html=display.Video(movfile,embed=True,width=500)
|
|
291
|
+
return html
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def multiplotseq(imps, n=4, types='materials', seqs=None, times=None, scale='Mm', potmin=False, zoom=1., uppercaselab=False, focus='potmin', tcut=3600.):
|
|
296
|
+
if (not isinstance(imps,list)) and (not isinstance(types,list)):
|
|
297
|
+
return imps.plotseq(n=n,ptype=types,seq=seqs,times=times,scale=scale,focus=focus,zoom=zoom)
|
|
298
|
+
elif not isinstance(imps,list):
|
|
299
|
+
imps=[imps,]
|
|
300
|
+
elif not isinstance(types,list):
|
|
301
|
+
types=[types,]
|
|
302
|
+
if seqs is None: # and times is None:
|
|
303
|
+
if imps[0].nsnaps>n:
|
|
304
|
+
seqs = npy.logspace(0,npy.log10(len(imps[0].data)-1),n).astype(int)
|
|
305
|
+
else:
|
|
306
|
+
seqs = npy.arange(imps[0].nsnaps)
|
|
307
|
+
elif not isinstance(seqs,list):
|
|
308
|
+
n = len(seqs)
|
|
309
|
+
seqs = [seqs,]
|
|
310
|
+
elif seqs:
|
|
311
|
+
n = [len(s) for s in seqs]
|
|
312
|
+
if not all(x==n[0] for x in n):
|
|
313
|
+
print('Warning: unequal sequences will produce ugly plots')
|
|
314
|
+
|
|
315
|
+
if not isinstance(zoom,list):
|
|
316
|
+
zoom=[zoom,]
|
|
317
|
+
|
|
318
|
+
scf = plotting.get_scale_fac(scale)
|
|
319
|
+
|
|
320
|
+
# number of cells for grid
|
|
321
|
+
Ng = 1201j
|
|
322
|
+
#Ngz = 15j
|
|
323
|
+
|
|
324
|
+
if potmin:
|
|
325
|
+
focus='potmin'
|
|
326
|
+
|
|
327
|
+
m = 1
|
|
328
|
+
k = 0
|
|
329
|
+
leftcol = None
|
|
330
|
+
toprow = None
|
|
331
|
+
|
|
332
|
+
fig = plt.figure()#figsize=(10,4))
|
|
333
|
+
fig.set_figwidth(8.)
|
|
334
|
+
fig.set_figheight(8./max(n)*(len(imps)*len(types)) + 1.*len(imps)**1.75)#-0.1
|
|
335
|
+
gs = fig.add_gridspec(ncols=max(n), nrows=len(imps)*len(types),wspace=0,hspace=0,right=0.98,top=0.96)
|
|
336
|
+
#print(max(n),len(imps)*len(types))
|
|
337
|
+
|
|
338
|
+
for imp, seq, zoomfac in zip(imps, seqs, zoom):#, types):
|
|
339
|
+
axlim = 2*int(npy.ceil((imp.data[0].x.max()-imp.data[0].x.min())/scf/8.)) #4
|
|
340
|
+
zcut = axlim/200.*scf #200
|
|
341
|
+
# region to grid/plot
|
|
342
|
+
#zmin = -axlim/10.
|
|
343
|
+
#zmax = axlim/10.
|
|
344
|
+
axlim /= zoomfac
|
|
345
|
+
|
|
346
|
+
#zlim = zmax/5.*scf
|
|
347
|
+
#zi = npy.linspace(zmin,zmax,int(Ngz.imag))
|
|
348
|
+
#X,Y,Z = npy.mgrid[-axlim:axlim:(Ng),-axlim:axlim:(Ng),zmin:zmax:(Ngz)]
|
|
349
|
+
X,Y = npy.mgrid[-axlim:axlim:(Ng),-axlim:axlim:(Ng)]
|
|
350
|
+
Z = npy.full_like(X, 0)
|
|
351
|
+
|
|
352
|
+
l = 0
|
|
353
|
+
|
|
354
|
+
for ptype in types:
|
|
355
|
+
n = len(seq)
|
|
356
|
+
# if l==0:
|
|
357
|
+
# cmap = plt.get_cmap('cmr.bubblegum').copy() #'plasma'
|
|
358
|
+
# cmapphase = plt.get_cmap('plasma', 6).copy()
|
|
359
|
+
# elif l==1 and len(types)>2:
|
|
360
|
+
# cmap = plt.get_cmap('cmr.bubblegum').copy()#cmocean.cm.haline #plt.get_cmap('magma')#.reversed()
|
|
361
|
+
# cmapphase = plt.get_cmap('cmr.bubblegum', 6).copy()
|
|
362
|
+
# elif l==2 or l==1:
|
|
363
|
+
# cmap = plt.get_cmap('cmr.eclipse').copy()
|
|
364
|
+
# cmapphase = plt.get_cmap('cmr.eclipse', 6).copy()
|
|
365
|
+
# else:
|
|
366
|
+
# cmap=plt.get_cmap('plasma').copy()
|
|
367
|
+
# cmapphase = plt.get_cmap('plasma', 6).copy()
|
|
368
|
+
cmap = plotting.get_default_colormap(ptype)
|
|
369
|
+
if ptype in plotting.phase_type:
|
|
370
|
+
cmap = matplotlib.colors.ListedColormap(cmap.colors[[0,1,2,3,4,5],:])
|
|
371
|
+
# if ptype in plotting.density_type:
|
|
372
|
+
# cmap.set_under('k')
|
|
373
|
+
# else:
|
|
374
|
+
# cmap.set_under('w')
|
|
375
|
+
|
|
376
|
+
for i in range(len(seq)):
|
|
377
|
+
j = seq[i]
|
|
378
|
+
#plt.subplot(len(imps),n,(m-1)*n + i+1,aspect='equal')
|
|
379
|
+
fig.add_subplot(gs[m-1,i],aspect='equal')
|
|
380
|
+
|
|
381
|
+
if imp.data[j].header.time < tcut:
|
|
382
|
+
vcut = 0.5*imp.data[0].vel.min()
|
|
383
|
+
|
|
384
|
+
if ptype in plotting.materials_type:
|
|
385
|
+
im = plotting.plot_snapshot_scatter(imp.data[j],cmap=cmap,plotQ=-(imp.data[j].id/PROJ_ID_OFFSET).astype(int),ax=plt.gca(),ptype=ptype,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,focus=focus)
|
|
386
|
+
elif ptype in plotting.density_type:
|
|
387
|
+
im = plotting.plot_snapshot_fluid(imp.data[j],X,Y,Z,ax=plt.gca(),cmap=cmap,ptype=ptype,plotQ=imp.data[j].rho,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=vcut,focus=focus)
|
|
388
|
+
elif ptype in plotting.pressure_type:
|
|
389
|
+
im = plotting.plot_snapshot_fluid(imp.data[j],X,Y,Z,ax=plt.gca(),cmap=cmap,ptype=ptype,plotQ=imp.data[j].P/1e9,axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,vcut=vcut,focus=focus)
|
|
390
|
+
elif ptype in plotting.entropy_type:
|
|
391
|
+
im = plotting.plot_snapshot_fluid(imp.data[j],X,Y,Z,ax=plt.gca(),cmap=cmap,ptype=ptype,plotQ=imp.data[j].S/1e7,axlim=axlim,scale=scale,zcut=zcut,focus=focus,tcut=tcut,vcut=vcut)
|
|
392
|
+
elif ptype in plotting.temperature_type:
|
|
393
|
+
im = plotting.plot_snapshot_fluid(imp.data[j],X,Y,Z,ax=plt.gca(),cmap=cmap,ptype=ptype,plotQ=imp.data[j].T,axlim=axlim,scale=scale,zcut=zcut,focus=focus,tcut=tcut,vcut=vcut)
|
|
394
|
+
elif ptype in plotting.phase_type:
|
|
395
|
+
im = plotting.plot_snapshot_scatter(imp.data[j],cmap=cmap,plotQ=imp.data[j].phase,ptype=ptype,ax=plt.gca(),axlim=axlim,scale=scale,zcut=zcut,tcut=tcut,focus=focus)
|
|
396
|
+
|
|
397
|
+
if i>0:
|
|
398
|
+
plt.gca().set_yticklabels([])
|
|
399
|
+
plt.gca().set_ylabel('')
|
|
400
|
+
if m != len(imps)*len(types):
|
|
401
|
+
plt.gca().set_xticklabels([])
|
|
402
|
+
plt.gca().set_xlabel('')
|
|
403
|
+
if i==0:
|
|
404
|
+
if ptype in [*plotting.density_type,*plotting.temperature_type]:
|
|
405
|
+
if uppercaselab:
|
|
406
|
+
plt.text(0.05,0.95,chr(64+m),ha='left',va='top',fontsize=9,fontweight='bold',color='w',transform=plt.gca().transAxes)
|
|
407
|
+
else:
|
|
408
|
+
plt.text(0.05,0.95,chr(96+m),ha='left',va='top',fontsize=9,fontweight='bold',color='w',transform=plt.gca().transAxes)
|
|
409
|
+
else:
|
|
410
|
+
if uppercaselab:
|
|
411
|
+
plt.text(0.05,0.95,chr(64+m),ha='left',va='top',fontsize=9,fontweight='bold',color='k',transform=plt.gca().transAxes)
|
|
412
|
+
else:
|
|
413
|
+
plt.text(0.05,0.95,chr(96+m),ha='left',va='top',fontsize=9,fontweight='bold',color='k',transform=plt.gca().transAxes)
|
|
414
|
+
|
|
415
|
+
ax = plt.gca()
|
|
416
|
+
if i>0:
|
|
417
|
+
colpos = ax.get_position()
|
|
418
|
+
gap = leftcol.x1-colpos.x0
|
|
419
|
+
ax.set_position([colpos.x0+gap,colpos.y0,colpos.width,colpos.height])
|
|
420
|
+
colpos = ax.get_position()
|
|
421
|
+
#else:
|
|
422
|
+
# pos = ax.get_position()
|
|
423
|
+
leftcol = ax.get_position()
|
|
424
|
+
if m>1:
|
|
425
|
+
rowpos = ax.get_position()
|
|
426
|
+
gap = toprow.y0-rowpos.y1
|
|
427
|
+
if k==1:
|
|
428
|
+
gap -= 0.04/max(1,len(imps)-1.1)#0.05
|
|
429
|
+
ax.set_position([rowpos.x0,rowpos.y0+gap,rowpos.width,rowpos.height])
|
|
430
|
+
#else:
|
|
431
|
+
# plt.subplots_adjust(wspace=0)
|
|
432
|
+
|
|
433
|
+
if m==1 and i==0:
|
|
434
|
+
firstplot = plt.gca()
|
|
435
|
+
|
|
436
|
+
if ptype not in plotting.materials_type:
|
|
437
|
+
if i == len(seq)-1 and (m==1 or m==len(imps)*len(types)):
|
|
438
|
+
pbox = ax.get_position()
|
|
439
|
+
xw = 0.33
|
|
440
|
+
if m==1:
|
|
441
|
+
cbar_ax = fig.add_axes([pbox.x1-xw, pbox.y1+0.26/max(1,2*len(imps)-1.9)*xw, xw, 0.02/max(1,2*len(imps)**0.8-1.8)])#0.27
|
|
442
|
+
#cbar_ax = fig.add_axes([pbox.x1-xw, pbox.y1+0.32*xw, xw, 0.015])
|
|
443
|
+
elif m==len(imps)*len(types):
|
|
444
|
+
pbox = firstplot.get_position()
|
|
445
|
+
#cbar_ax = fig.add_axes([pbox.x1-xw, pbox.y0-0.6/max(1,1.5*len(imps)-0.7)*xw, xw, 0.032/max(1,2*len(imps)-1.8)])#0.47
|
|
446
|
+
cbar_ax = fig.add_axes([pbox.x0, pbox.y1+0.26/max(1,2*len(imps)-1.9)*xw, xw, 0.02/max(1,2*len(imps)**0.8-1.8)])#0.47
|
|
447
|
+
cbar = fig.colorbar(im,cax=cbar_ax,orientation='horizontal')
|
|
448
|
+
plotting.format_colorbar_axis(cbar, ptype, y=False)
|
|
449
|
+
k=0
|
|
450
|
+
m+=1
|
|
451
|
+
l+=1
|
|
452
|
+
cbar_ax = None
|
|
453
|
+
toprow = ax.get_position()
|
|
454
|
+
k=1
|
|
455
|
+
|
|
456
|
+
#fig.set_figwidth(10)
|
|
457
|
+
#print(colpos.x0,colpos.y0,colpos.x1,colpos.y1)
|
|
458
|
+
#plt.show()
|
|
459
|
+
return fig
|
|
@@ -5,21 +5,21 @@ planit (PLANetary Impact Toolkit)
|
|
|
5
5
|
Classes and functions for setting-up, accessing, manipulating,
|
|
6
6
|
and analysing SPH impact simulation data.
|
|
7
7
|
|
|
8
|
-
Supported planetary impact codes: gadget-2-planetary, swift
|
|
8
|
+
Supported planetary impact codes: gadget-2-planetary, swift, pkdgrav3
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
Philip J. Carter (p.carter@bristol.ac.uk)
|
|
12
12
|
|
|
13
13
|
Sarah T. Stewart (sstewa56@asu.edu)
|
|
14
14
|
|
|
15
|
-
v1.
|
|
15
|
+
v1.2
|
|
16
16
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
from .globaldefs import *
|
|
20
20
|
from . import eos
|
|
21
21
|
from . import utils
|
|
22
|
-
from .snaptools import Snapshot
|
|
22
|
+
from .snaptools import Snapshot, io
|
|
23
23
|
from .impacttools import Impact
|
|
24
24
|
|
|
25
25
|
|
|
@@ -40,7 +40,7 @@ def loadimpact(loc,thermo=False,inter=1,compress=True,code='swift'):
|
|
|
40
40
|
|
|
41
41
|
def load_seagen(partplanet, thermo=False, init_h=100e5):
|
|
42
42
|
s = Snapshot()
|
|
43
|
-
|
|
43
|
+
io.load_seagen(s, partplanet, thermo=thermo, init_h=init_h)
|
|
44
44
|
return s
|
|
45
45
|
|
|
46
46
|
def combine(body1, body2, bidoffset=PROJ_ID_OFFSET, thermo=False, box=0.0):
|