Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def add(self, particle=None, **kwargs):
"""
Adds a particle to REBOUND. Accepts one of the following:
1) A single Particle structure.
2) The particle's mass and a set of cartesian coordinates: m,x,y,z,vx,vy,vz.
3) The primary as a Particle structure, the particle's mass and a set of orbital elements: primary,m,a,anom,e,omega,inv,Omega,MEAN (see :class:`.Orbit` for the definition of orbital elements).
4) A name of an object (uses NASA Horizons to look up coordinates)
5) A list of particles or names.
"""
if particle is not None:
if isinstance(particle, Particle):
if (self.gravity == "tree" or self.collision == "tree") and self.root_size <=0.:
raise ValueError("The tree code for gravity and/or collision detection has been selected. However, the simulation box has not been configured yet. You cannot add particles until the the simulation box has a finite size.")
clibrebound.reb_add(byref(self), particle)
elif isinstance(particle, list):
for p in particle:
self.add(p, **kwargs)
elif isinstance(particle,str):
if self.python_unit_l == 0 or self.python_unit_m == 0 or self.python_unit_t == 0:
self.units = ('AU', 'yr2pi', 'Msun')
self.add(horizons.getParticle(particle, **kwargs), hash=particle)
units_convert_particle(self.particles[-1], 'km', 's', 'kg', hash_to_unit(self.python_unit_l), hash_to_unit(self.python_unit_t), hash_to_unit(self.python_unit_m))
else:
raise ValueError("Argument passed to add() not supported.")
else:
self.add(Particle(simulation=self, **kwargs))
if hasattr(self, '_widgets'):
self._display_heartbeat(pointer(self))
orbits : bool, optional
The default value for this is True and the widget will draw the instantaneous
orbits of the particles. For simulations in which particles are not on
Keplerian orbits, the orbits shown will not be accurate.
overlay : string, optional
Change the default text overlay. Set to None to hide all text.
"""
self.screenshotcountall = 0
self.width, self.height = size
self.t, self.N = simulation.t, simulation.N
self.orientation = orientation
self.autorefresh = autorefresh
self.orbits = orbits
self.useroverlay = overlay
self.simp = pointer(simulation)
clibrebound.reb_display_copy_data.restype = c_int
if scale is None:
self.scale = simulation.display_data.contents.scale
else:
self.scale = scale
self.count += 1
super(Widget, self).__init__()
--------
>>> sim = rebound.Simulation()
>>> sim.add(m=1, x=0)
>>> sim.add(m=1, x=1)
>>> com = sim.calculate_com()
>>> com.x
0.5
"""
if last is not None:
last = min(last, self.N_real-1)
clibrebound.reb_get_jacobi_com.restype = Particle
com = clibrebound.reb_get_jacobi_com(byref(self.particles[last]))
return com
else:
clibrebound.reb_get_com.restype = Particle
com = clibrebound.reb_get_com(byref(self))
return com
self.r = 0.
else:
self.r = r
self.lastcollision = 0.
self.c = None
self.ap = None
if notNone([e,inc,omega,pomega,Omega,M,f,theta,T]) and notNone(pal):
raise ValueError("You cannot mix Pal coordinates (h,k,ix,iy) with the following orbital elements: e,inc,Omega,omega,pomega,f,M,theta,T. If a longitude/anomaly is needed in Pal coordinates, use l.")
if notNone(cart) and notNone(orbi):
raise ValueError("You cannot pass cartesian coordinates and orbital elements (and/or primary) at the same time.")
if notNone(orbi):
if simulation is None:
raise ValueError("Need to specify simulation when initializing particle with orbital elements.")
if primary is None:
clibrebound.reb_get_com.restype = Particle
primary = clibrebound.reb_get_com(byref(simulation)) # this corresponds to adding in Jacobi coordinates
if jacobi_masses is True:
interior_mass = 0
for p in simulation.particles:
interior_mass += p.m
# orbit conversion uses mu=G*(p.m+primary.m) so set prim.m=Mjac-m so mu=G*Mjac
primary.m = simulation.particles[0].m*(self.m + interior_mass)/interior_mass - self.m
if a is None and P is None:
raise ValueError("You need to pass either a semimajor axis or orbital period to initialize the particle using orbital elements.")
if a is not None and P is not None:
raise ValueError("You can pass either the semimajor axis or orbital period, but not both.")
if a is None:
a = (P**2*simulation.G*(primary.m + self.m)/(4.*math.pi**2))**(1./3.)
if notNone(pal):
# Pal orbital parameters
if h is None:
def __init__(self):
clibrebound.reb_init_simulation(byref(self))
else:
variation_order = 1
# Shortcuts for variable names
if variation == "l":
variation = "lambda"
if variation2 == "l":
variation2 = "lambda"
if variation == "i":
variation = "inc"
if variation2 == "i":
variation2 = "inc"
variationtypes = ["m","a","e","inc","omega","Omega","f","k","h","lambda","ix","iy"]
if variation_order==1:
if variation in variationtypes:
method = getattr(clibrebound, 'reb_derivatives_'+variation)
method.restype = Particle
p = method(c_double(simulation.G), primary, particle)
else:
raise ValueError("Variational particles can only be initializes using the derivatives with respect to one of the following: %s."%", ".join(variationtypes))
elif variation_order==2:
if variation in variationtypes and variation2 in variationtypes:
# Swap variations if needed
vi1 = variationtypes.index(variation)
vi2 = variationtypes.index(variation2)
if vi2 < vi1:
variation, variation2 = variation2, variation
method = getattr(clibrebound, 'reb_derivatives_'+variation+'_'+variation2)
method.restype = Particle
p = method(c_double(simulation.G), primary, particle)
else:
def refresh(self, simp=None, isauto=0):
"""
Manually refreshes a widget.
Note that this function can also be called using the wrapper function of
the Simulation object: sim.refreshWidgets().
"""
if simp==None:
simp = self.simp
if self.autorefresh==0 and isauto==1:
return
sim = simp.contents
size_changed = clibrebound.reb_display_copy_data(simp)
clibrebound.reb_display_prepare_data(simp,c_int(self.orbits))
if sim.N>0:
self.particle_data = (c_char * (4*7*sim.N)).from_address(sim.display_data.contents.particle_data).raw
if self.orbits:
self.orbit_data = (c_char * (4*9*(sim.N-1))).from_address(sim.display_data.contents.orbit_data).raw
if size_changed:
#TODO: Implement better GPU size change
pass
if self.useroverlay==True:
self.overlay = "REBOUND (%s), N=%d, t=%g"%(sim.integrator,sim.N,sim.t)
elif self.useroverlay==None or self.useroverlay==False:
self.overlay = ""
else:
self.overlay = self.useroverlay + ", N=%d, t=%g"%(sim.N,sim.t)
self.N = sim.N
self.t = sim.t
if notNone(pal):
# Pal orbital parameters
if h is None:
h = 0.
if k is None:
k = 0.
if l is None:
l = 0.
if ix is None:
ix = 0.
if iy is None:
iy = 0.
if((ix*ix + iy*iy) > 4.0):
raise ValueError("Passed (ix, iy) coordinates are not valid, squared sum exceeds 4.")
clibrebound.reb_tools_pal_to_particle.restype = Particle
p = clibrebound.reb_tools_pal_to_particle(c_double(simulation.G), primary, c_double(self.m), c_double(a), c_double(l), c_double(k), c_double(h), c_double(ix), c_double(iy))
else:
# Normal orbital parameters
if e is None:
e = 0.
if inc is None:
inc = 0.
if Omega is None: # we require that Omega be passed if you want to specify longitude of node
Omega = 0.
pericenters = [omega, pomega] # Need omega for C function. Can specify it either directly or through pomega indirectly.
numNones = pericenters.count(None)
if numNones == 0:
raise ValueError("Can't pass both omega and pomega")
if numNones == 2: # Neither passed. Default to 0.
omega = 0.
def hash(key):
hash_types = c_uint32, c_uint, c_ulong
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str,
int_types = int,
else:
string_types = basestring,
int_types = int, long,
if isinstance(key, int_types):
return c_uint32(key)
elif isinstance(key, hash_types):
return key
elif isinstance(key, string_types):
clibrebound.reb_hash.restype = c_uint32
return c_uint32(clibrebound.reb_hash(c_char_p(key.encode('ascii'))))
else:
raise AttributeError("Need to pash hash an integer or string.")