Skip to content

Commit f694824

Browse files
author
dflemin3
committed
added means to compute disk orbital elements at each radius
1 parent daaa32e commit f694824

File tree

7 files changed

+157
-13
lines changed

7 files changed

+157
-13
lines changed

AddBinary.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,7 @@ def calcLongOfAscNode(x1=1, x2=0, v1=1, v2=0, flag=True):
441441
magN = np.linalg.norm(n, axis=ax)
442442

443443
# Ensure no divide by zero errors?
444-
if np.fabs(magN) < SMALL:
445-
magN = 1.0
444+
magN[magN < SMALL] = 1.0
446445

447446
# Compute LoAN
448447
inc = calcInc(x1, x2, v1, v2)
@@ -452,7 +451,7 @@ def calcLongOfAscNode(x1=1, x2=0, v1=1, v2=0, flag=True):
452451
Omega[inc < SMALL] = 0.0
453452

454453
# Fix phase due to arccos return range
455-
Omega[dotProduct(n, j) < 0] = 2.0 * np.pi - Omega
454+
Omega[dotProduct(n, j) < 0] = 2.0 * np.pi - Omega[dotProduct(n, j) < 0]
456455

457456
# Convert to degrees, return
458457
return Omega * RAD2DEG
@@ -490,10 +489,10 @@ def calcEccVector(x1=1, x2=0, v1=1, v2=0, m1=1, m2=1, flag=True):
490489

491490
# Relative position vector in cgs
492491
r = (x1 - x2)
493-
magR = np.linalg.norm(r, axis=ax)
492+
magR = np.linalg.norm(r, axis=ax).reshape(len(r),1)
494493

495494
# Compute standard gravitational parameter in cgs
496-
mu = BigG * (m1 + m2)
495+
mu = (BigG * (m1 + m2)).reshape(len(r),1)
497496

498497
# Compute relative velocity vector in cgs with appropriate scale
499498
v = (v1 - v2)
@@ -560,8 +559,7 @@ def calcArgPeri(x1=1, x2=0, v1=1, v2=0, m1=1, m2=1, flag=True):
560559
magN = np.linalg.norm(n, axis=ax)
561560

562561
# Ensure no divide by zero errors?
563-
if np.fabs(magN) < SMALL:
564-
magN = 1.0
562+
magN[magN < SMALL] = 1.0
565563

566564
# Compute argument of periapsis
567565
inc = calcInc(x1, x2, v1, v2)
@@ -618,7 +616,7 @@ def calcTrueAnomaly(x1=1, x2=0, v1=1, v2=0, m1=1, m2=1, flag=True):
618616
if dotProduct(r, v) < 0.0:
619617
nu = 2.0 * np.pi - nu
620618
else:
621-
nu[dotProduct(r, v) < 0.0] = 2.0 * np.pi - nu
619+
nu[dotProduct(r, v) < 0.0] = 2.0 * np.pi - nu[dotProduct(r, v) < 0.0]
622620

623621
# Convert to degrees, return
624622
return nu * RAD2DEG

IC.p

1.7 MB
Binary file not shown.

IC_settings.p

-54 Bytes
Binary file not shown.

binary.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def __init__(self, X, m1, m2, state):
103103

104104
def __repr__(self):
105105
"""
106-
When invoked, return the orbital elements.
106+
Return the orbital elements and the masses of the primary and secondary.
107107
"""
108108
return "(%s,%s,%s,%s,%s,%s), mass: (%s,%s)" % (self.e,
109109
self.a,
@@ -130,7 +130,6 @@ def assignOrbElems(self, X):
130130
Output:
131131
None
132132
"""
133-
# Only assign data if it doesn't exist
134133
self.e = float(X[0])
135134
self.a = float(X[1])
136135
self.i = float(X[2])

binaryUtils.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ def calcDiskRadialBins(s,r_in=0,r_out=0,bins=50):
267267
#Bin gas particles by radius
268268
pg = pynbody.analysis.profile.Profile(s.gas,max=r_out,nbins=bins)
269269
r = isaac.strip_units(pg['rbins']) #Radius from origin in xy plane
270-
mask = (r > r.min()) & (r < r_out) #Ensure you're not right on binary or too far out. Redundant, but whatever
270+
mask = (r > r_in) & (r < r_out) #Ensure you're not right on binary or too far out. Redundant, but whatever
271271
r = r[mask]
272272

273273
#Make nice, evenly spaced radial bins vector
@@ -550,6 +550,9 @@ def calcEccVsRadius(s,rBinEdges):
550550
551551
Outputs:
552552
ecc: Vector of len = len(r) containing disk eccentricity.
553+
554+
NOTE: 99% sure this is completely wrong --dflemin3 07/23/15
555+
553556
"""
554557
ecc = np.zeros(len(rBinEdges)-1)
555558

@@ -687,4 +690,59 @@ def calcStableSigma(r,rd,Mstar,Mdisk,Q):
687690
sigma_0 *= np.power(r/rd,3.0)
688691
sigma_0 *= np.sqrt(1.0 + 4.0*Q*Q*(np.power(rd/r,3.0) - np.power(rd/r,1.5)))
689692

690-
return sigma_0
693+
return sigma_0
694+
695+
def orbElemsVsRadius(s,rBinEdges,average=False):
696+
"""
697+
Computes the orbital elements for disk particles about a binary system in given radial bins.
698+
Assumes center of mass has v ~ 0
699+
700+
Parameters
701+
----------
702+
703+
s: Tipsy snapshot
704+
rBinEdges: numpy array
705+
Radial bin edges [AU] preferably calculated using binaryUtils.calcDiskRadialBins
706+
average: bool
707+
True -> average over all particles in bin, false -> randomly select 1 particle in bin
708+
709+
Returns
710+
-------
711+
orbElems: numpy array
712+
6 x len(rBinEdges) - 1 containing orbital elements at each radial bin
713+
as e, a, i, Omega, w, nu
714+
"""
715+
716+
#Read snapshot and pull out values of interest
717+
stars = s.stars
718+
gas = s.gas
719+
M = np.sum(stars['mass'])
720+
zero = np.zeros(3).reshape((1, 3))
721+
orbElems = np.zeros((6,len(rBinEdges)-1))
722+
723+
#Gas orbiting about system center of mass
724+
com = computeCOM(stars,gas)
725+
726+
#Loop over radial bins calculating orbital elements
727+
for i in range(0,len(rBinEdges)-1):
728+
if average: #Average over all gas particles in subsection
729+
rMask = np.logical_and(isaac.strip_units(gas['rxy']) > rBinEdges[i], isaac.strip_units(gas['rxy']) < rBinEdges[i+1])
730+
if i > 0:
731+
mass = M + np.sum(gas[gas['rxy'] < rBinEdges[i]]['mass'])
732+
else:
733+
mass = M
734+
N = len(gas[rMask])
735+
g = gas[rMask]
736+
orbElems[:,i] = np.sum(AddBinary.calcOrbitalElements(g['pos'],com,g['vel'],zero,mass,g['mass']),axis=-1)/N
737+
else: #Randomly select 1 particle in subsection for calculations
738+
rMask = np.logical_and(isaac.strip_units(gas['rxy']) > rBinEdges[i], isaac.strip_units(gas['rxy']) < rBinEdges[i+1])
739+
if i > 0:
740+
mass = M + np.sum(gas[gas['rxy'] < rBinEdges[i]]['mass'])
741+
else:
742+
mass = M
743+
g = gas[rMask]
744+
index = np.random.randint(0,len(g))
745+
particle = g[index]
746+
orbElems[:,i] = AddBinary.calcOrbitalElements(com,particle['pos'],zero,particle['vel'],mass,particle['mass'])
747+
748+
return orbElems

kepler38.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
m2 = IC.settings.physical.M - m1
2525

2626
#Scale the mass of the disk to be some fraction of the star mass
27-
IC.settings.snapshot.mScale = 0.05
27+
IC.settings.snapshot.mScale = 0.1
2828

2929
#Define whether the star is a single star or binary
3030
IC.settings.physical.starMode = 'binary'

test.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""
2+
@author: dflemin3
3+
Script for generating disk ICs about a stellar system
4+
using ibackus's ICgen routines.
5+
See https://github.com/ibackus/ICgen
6+
"""
7+
import ICgen
8+
import pynbody
9+
import binary
10+
11+
SimArray = pynbody.array.SimArray
12+
13+
# Initialize a blank initial conditions (IC) object:
14+
IC = ICgen.IC()
15+
16+
# Let's set the star mass and gas mass assuming H2 = 2 (m_h = 1) and some metals added
17+
IC.settings.physical.M = SimArray(1.198, 'Msol') #Total stellar mass in solar masses
18+
IC.settings.physical.m = SimArray(2.35, 'm_p') #mean molecular mass
19+
20+
#Define masses of primary, secondary as pynbody SimArrays
21+
#Note, m1 + m2 == IC.settings.physical.M
22+
#Only need to set if you're considernig a circumbinary system
23+
m1 = SimArray(0.949,'Msol')
24+
m2 = IC.settings.physical.M - m1
25+
26+
#Scale the mass of the disk to be some fraction of the star mass
27+
IC.settings.snapshot.mScale = 4.0
28+
29+
#Define whether the star is a single star or binary
30+
IC.settings.physical.starMode = 'binary'
31+
32+
#Set binary system parameters. If single star, comment this out
33+
#Define list of orbital elements of the following form:
34+
#X = [e, a [AU], i, Omega, w, nu] where all angles are in degrees
35+
X = [0.1032, 0.1469, 0.0, 0.0, 0.0, 0.0]
36+
IC.settings.physical.binsys = binary.Binary(X,m1,m2,'kepler')
37+
38+
# Lets generate a disk with powerlaw from [Rin,Rd] au followed by a cutoff
39+
# Set up the surface density profile settings. Notice that right now the
40+
# Lets use a simple powerlaw with cut-offs at the interior and edge of the
41+
# disk
42+
# The important parameters to set are:
43+
# Rd : Disk radius, should be a pynbody SimArray
44+
# Qmin : Minimum estimated Toomre Q in the disk
45+
# n_points : number of radial points to calculate sigma at
46+
# power: sigma ~ r^(power)
47+
IC.settings.sigma.kind = 'powerlaw'
48+
IC.settings.sigma.power = -1
49+
IC.settings.sigma.Qmin = 1.0
50+
IC.settings.sigma.n_points = 500
51+
52+
IC.settings.sigma.Rd = SimArray(2.0,'au') #Outer edge of powerlaw part of disk
53+
IC.settings.sigma.rmax = 2.0 #Set rmax
54+
IC.settings.sigma.rin = 0.25 #Set inner disk radius
55+
IC.settings.cutlength = 0.01 #Set exp cutoff length scale
56+
IC.settings.pos_gen.method = 'random' #Instead of grid sampling, use random
57+
58+
#This will save the ICs to
59+
# IC.p in the current directory
60+
IC.save()
61+
62+
# Change the settings used for numerically calculating the gas density
63+
IC.settings.rho_calc.nr = 500 # Number of radial points to calculate on
64+
IC.settings.rho_calc.nz = 100 # Number of vertical points to calculate on
65+
66+
# Set the number of gas particles
67+
IC.settings.pos_gen.nParticles = 100000
68+
69+
# Set up the temperature profile to use. Available kinds are 'powerlaw'
70+
# and 'MQWS'
71+
# We'll use something of the form T = T0(r/r0)^Tpower
72+
IC.settings.physical.kind = 'powerlaw'
73+
IC.settings.physical.Tpower = -0.5 # exponent
74+
IC.settings.physical.T0 = SimArray(300.0, 'K') # temperature at r0
75+
IC.settings.physical.Tmin = SimArray(50.0, 'K') # Minimum temperature
76+
IC.settings.physical.r0 = SimArray(1.0, 'au')
77+
78+
# Lets have changa run on the local preset
79+
IC.settings.changa_run.preset = 'local'
80+
81+
# Save our work to IC.p
82+
IC.save()
83+
IC.settings()
84+
85+
#Actually generate snapshot
86+
IC.generate()
87+
IC.save()
88+
# This will run through the whole procedure and save a tipsy snapshot
89+
# to snapshot.std with a basic .param file saved to snapshot.param

0 commit comments

Comments
 (0)