def get_orbit_of_the_star(self, particle_set): # Function that integrates the orbit of the star. # input: particle_set -> defined in an inertial system # steps: # 1. The Galaxy model is created # 2. A copy of particle_set is created in the rotating frame # where the stellar motion is computed # 3. The Galaxy and the particles in the rotating frame are coupled through the rotating Bridge # 4. The evolution of the system is made # 5. The positions and velocities in particle_set are updated by transforming the # phase-space coordinates back to the inertial frame. X = [] Y = [] MW = self.galaxy() particles_in_rotating_coordinates = self.creation_particles_noinertial( particle_set) gravless = drift_without_gravity(particles_in_rotating_coordinates) system = Rotating_Bridge(self.omega, timestep=self.dt_bridge, verbose=False, method=self.method) system.add_system(gravless, (MW, ), False) system.add_system(MW, (), False) while (self.time < self.t_end - self.dt_bridge / 2): X.append(particle_set[0].x.value_in(units.kpc)) Y.append(particle_set[0].y.value_in(units.kpc)) self.time += self.dt_bridge system.evolve_model(self.time) self.noinertial_to_inertial(particles_in_rotating_coordinates, particle_set) return X, Y
def test2(self): p0=Particles(1) p0.position = [0.0, 1.0, 0.0] | units.m p0.velocity = [1.0, 0.0, 0.0] | units.m/units.s pos1=p0.position.copy() vel1=p0.velocity.copy() omega=1. | units.s**-1 N=0.25 dt=0.01 method = SPLIT_6TH_SS_M13 tend=N*2*numpy.pi/omega dt=dt*2*numpy.pi/omega pr=inertial_to_rotating(0*dt,omega, p0) drift=drift_without_gravity(pr, time=0 | units.s) sys=Rotating_Bridge(omega, timestep=dt, method=method) sys.add_system(drift) sys.evolve_model(tend) pi=rotating_to_inertial(tend, omega,pr) pos2=pi.position.copy() self.assertAlmostEqual(sys.model_time,tend) self.assertAlmostEqual(pos1+vel1*tend,pos2,12) pi.velocity=-pi.velocity pr=inertial_to_rotating(0*dt,-omega,pi) drift=drift_without_gravity(pr,time=0| units.s) sys=Rotating_Bridge(-omega, timestep=dt,method=method) sys.add_system(drift) sys.evolve_model(tend) pi=rotating_to_inertial(tend,-omega,pr) pos3=pi.position.copy() self.assertAlmostEqual(pos1,pos3,12)
def get_orbit_of_the_star(self, particle_set): # Function that integrates the orbit of the star. # input: particle_set -> defined in an inertial system # steps: # 1. The Galaxy model is created # 2. A copy of particle_set is created in the rotating frame # where the stellar motion is computed # 3. The Galaxy and the particles in the rotating frame are coupled through the rotating Bridge # 4. The evolution of the system is made # 5. The positions and velocities in particle_set are updated by transforming the # phase-space coordinates back to the inertial frame. X = [] Y = [] MW = self.galaxy() particles_in_rotating_coordinates = self.creation_particles_noinertial(particle_set) gravless = drift_without_gravity(particles_in_rotating_coordinates) system = Rotating_Bridge(self.omega, timestep=self.dt_bridge, verbose=False, method=self.method) system.add_system(gravless, (MW,), False) system.add_system(MW, (), False) while self.time < self.t_end - self.dt_bridge / 2: X.append(particle_set[0].x.value_in(units.kpc)) Y.append(particle_set[0].y.value_in(units.kpc)) self.time += self.dt_bridge system.evolve_model(self.time) self.noinertial_to_inertial(particles_in_rotating_coordinates, particle_set) return X, Y
def get_pos_vel_and_orbit(self, particle_set, pos): particle_set.velocity = (-1) * particle_set.velocity MW = self.galaxy() print("OMEGA:", self.omega.as_quantity_in(1 / units.Gyr)) particle_rot = self.creation_particles_noinertial(particle_set) gravless = drift_without_gravity(particle_rot) system = Rotating_Bridge(self.omega, timestep=self.dt_bridge, verbose=False, method=self.method) system.add_system(gravless, (MW, ), False) system.add_system(MW, (), False) # This is to update time inside the interface Ei = system.potential_energy + system.kinetic_energy + system.jacobi_potential_energy energy = [] #self.testing_potential_and_force(MW, -1.5|units.kpc, 3|units.kpc, -0.8 |units.kpc) # pos = particle_set[0].position dmin = pos.length() tmin = 0 | units.Myr d = [] | units.kpc t = [] | units.Myr d.append((pos - particle_set.position).length()) t.append(self.time) while (self.time < self.t_end - self.dt_bridge / 2): self.time += self.dt_bridge system.evolve_model(self.time) self.noinertial_to_inertial(particle_rot, particle_set) Ef = system.potential_energy + system.kinetic_energy + system.jacobi_potential_energy dje = (Ef - Ei) / Ei energy.append(dje) d.append((pos - particle_set.position).length()) t.append(self.time) if d[-1] < dmin: dmin = d[-1] tmin = self.time x = particle_set.x y = particle_set.y print("minimum", tmin.in_(units.Myr), dmin.in_(units.parsec)) bar_angle = self.bar_phase + (self.omega_bar * self.time) spiral_angle = self.spiral_phase + (self.omega_spiral * self.time) return self.time, particle_set[0].x.value_in(units.kpc), particle_set[0].y.value_in(units.kpc),\ particle_set[0].z.value_in(units.kpc), particle_set[0].vx.value_in(units.kms), \ particle_set[0].vy.value_in(units.kms), particle_set[0].vz.value_in(units.kms), \ bar_angle , spiral_angle, t, d
def evolution_of_the_cluster(self, cluster): ''' Function that makes de cluster evolution. input: cluster -> defined in an inertial frame (centered at the Galactic center) steps in this function: 1. From cluster, another cluster is defined in a rotating frame 2. The gravity code is initialized 3. The stellar evolution is initialized 4. the Galaxy model is constructed 5. The Galaxy and the cluster in the rotating frame are coupled via the Rotating Bridge 6. The evolution of the system is made 7. the cluster properties are transformed back to the inertial frame ''' cluster_in_rotating_frame = self.creation_cluster_in_rotating_frame( cluster) # N body code epsilon = self.softening(cluster) convert_nbody = nbody_system.nbody_to_si(cluster.mass.sum(), cluster.virial_radius()) gravity = Huayno(convert_nbody) gravity.parameters.timestep = self.dt_bridge / 3. gravity.particles.add_particles(cluster_in_rotating_frame) gravity.parameters.epsilon_squared = epsilon**2 channel_from_gravity_to_rotating_cluster = gravity.particles.new_channel_to( cluster_in_rotating_frame) channel_from_rotating_cluster_to_gravity = cluster_in_rotating_frame.new_channel_to( gravity.particles) #stellar evolution code se = SeBa() se.particles.add_particles(cluster_in_rotating_frame) channel_from_rotating_cluster_to_se = cluster_in_rotating_frame.new_channel_to( se.particles) channel_from_se_to_rotating_cluster = se.particles.new_channel_to( cluster_in_rotating_frame) # Galaxy model and Rotating bridge MW = self.galactic_model() system = Rotating_Bridge(self.omega_system, timestep=self.dt_bridge, verbose=False, method=self.method) system.add_system(gravity, (MW, ), False) system.add_system(MW, (), False) X = [] Y = [] T = [] #Cluster evolution while (self.time <= self.t_end - self.dt_bridge / 2): self.time += self.dt_bridge system.evolve_model(self.time) se.evolve_model(self.time) channel_from_gravity_to_rotating_cluster.copy_attributes( ['x', 'y', 'z', 'vx', 'vy', 'vz']) channel_from_se_to_rotating_cluster.copy_attributes([ 'mass', 'radius', 'luminosity', 'age', 'temperature', 'stellar_type' ]) channel_from_rotating_cluster_to_gravity.copy_attributes(['mass']) self.from_noinertial_to_cluster_in_inertial_frame( cluster_in_rotating_frame, cluster) time = self.time.value_in(units.Myr) cm = cluster.center_of_mass() # write data if ((time == 2) or (time == 50) or (time == 100) or (time == 150)): X.append((cluster.x - cm[0]).value_in(units.kpc)) Y.append((cluster.y - cm[1]).value_in(units.kpc)) T.append(time) gravity.stop() se.stop() return T, X, Y
def evolution_of_the_cluster(self, cluster): ''' Function that makes de cluster evolution. input: cluster -> defined in an inertial frame (centered at the Galactic center) steps in this function: 1. From cluster, another cluster is defined in a rotating frame 2. The gravity code is initialized 3. The stellar evolution is initialized 4. the Galaxy model is constructed 5. The Galaxy and the cluster in the rotating frame are coupled via the Rotating Bridge 6. The evolution of the system is made 7. the cluster properties are transformed back to the inertial frame ''' cluster_in_rotating_frame = self.creation_cluster_in_rotating_frame( cluster) # N body code epsilon = self.softening(cluster) convert_nbody = nbody_system.nbody_to_si( cluster.mass.sum(), cluster.virial_radius()) gravity = Huayno(convert_nbody) gravity.parameters.timestep = self.dt_bridge/3. gravity.particles.add_particles(cluster_in_rotating_frame) gravity.parameters.epsilon_squared = epsilon**2 channel_from_gravity_to_rotating_cluster = \ gravity.particles.new_channel_to( cluster_in_rotating_frame) channel_from_rotating_cluster_to_gravity = \ cluster_in_rotating_frame.new_channel_to(gravity.particles) # stellar evolution code se = SeBa() se.particles.add_particles(cluster_in_rotating_frame) channel_from_rotating_cluster_to_se = \ cluster_in_rotating_frame.new_channel_to(se.particles) channel_from_se_to_rotating_cluster = se.particles.new_channel_to( cluster_in_rotating_frame) # Galaxy model and Rotating bridge MW = self.galactic_model() system = Rotating_Bridge( self.omega_system, timestep=self.dt_bridge, verbose=False, method=self.method) system.add_system(gravity, (MW,), False) system.add_system(MW, (), False) X = [] Y = [] T = [] # Cluster evolution while (self.time <= self.t_end-self.dt_bridge/2): self.time += self.dt_bridge system.evolve_model(self.time) se.evolve_model(self.time) channel_from_gravity_to_rotating_cluster.copy_attributes( ['x', 'y', 'z', 'vx', 'vy', 'vz']) channel_from_se_to_rotating_cluster.copy_attributes( [ 'mass', 'radius', 'luminosity', 'age', 'temperature', 'stellar_type' ] ) channel_from_rotating_cluster_to_gravity.copy_attributes(['mass']) self.from_noinertial_to_cluster_in_inertial_frame( cluster_in_rotating_frame, cluster) time = self.time.value_in(units.Myr) cm = cluster.center_of_mass() # write data if ((time == 2) or (time == 50) or (time == 100) or (time == 150)): X.append((cluster.x-cm[0]).value_in(units.kpc)) Y.append((cluster.y-cm[1]).value_in(units.kpc)) T.append(time) gravity.stop() se.stop() return T, X, Y
def test2(self): p0 = Particles(1) p0.position = [0.0, 1.0, 0.0] | units.m p0.velocity = [1.0, 0.0, 0.0] | units.m / units.s pos1 = p0.position.copy() vel1 = p0.velocity.copy() omega = 1. | units.s**-1 N = 0.25 dt = 0.01 method = SPLIT_6TH_SS_M13 tend = N * 2 * numpy.pi / omega dt = dt * 2 * numpy.pi / omega pr = inertial_to_rotating(0 * dt, omega, p0) drift = drift_without_gravity(pr, time=0 | units.s) sys = Rotating_Bridge(omega, timestep=dt, method=method) sys.add_system(drift) sys.evolve_model(tend) pi = rotating_to_inertial(tend, omega, pr) pos2 = pi.position.copy() self.assertAlmostEqual(sys.model_time, tend) self.assertAlmostEqual(pos1 + vel1 * tend, pos2, 12) pi.velocity = -pi.velocity pr = inertial_to_rotating(0 * dt, -omega, pi) drift = drift_without_gravity(pr, time=0 | units.s) sys = Rotating_Bridge(-omega, timestep=dt, method=method) sys.add_system(drift) sys.evolve_model(tend) pi = rotating_to_inertial(tend, -omega, pr) pos3 = pi.position.copy() self.assertAlmostEqual(pos1, pos3, 12)