def timefractal(N=1000, fd=1.6, tend=0.25 | nbody_system.time, inttype=Huayno.inttypes.HOLD_DKD, seed=12345678): stars = new_fractal_cluster_model(N=N, fractal_dimension=fd, random_seed=seed, virial_ratio=0.5, do_scale=True, verbose=False) code = Huayno() code.parameters.inttype_parameter = inttype code.parameters.timestep_parameter = 0.01 code.particles.add_particles(stars) E0 = code.kinetic_energy + code.potential_energy p0 = code.particles.total_momentum() t1 = time() code.evolve_model(tend) t2 = time() E = code.kinetic_energy + code.potential_energy p = code.particles.total_momentum() code.stop() return t2 - t1, abs(E0 - E) / E0, p0 - p
def test4(self): print "Test with masses" target_number_of_particles = 100 masses = (range(1, 11) | units.MSun) * 1.0 convert_nbody = nbody_system.nbody_to_si(1000 | units.MSun, 1 | units.parsec) particles = new_fractal_cluster_model(masses=masses, convert_nbody=convert_nbody, do_scale=True) ek = particles.kinetic_energy() ep = particles.potential_energy() self.assertEquals(len(particles), 10) self.assertAlmostEqual( particles.total_mass(), 1000 | units.MSun) # Note: total_mass == converter's mass unit! self.assertAlmostEqual( masses.sum(), 55 | units.MSun) # Note: total_mass != masses.sum() self.assertAlmostEqual(particles.center_of_mass(), [0, 0, 0] | units.parsec) self.assertAlmostEqual(particles.center_of_mass_velocity(), [0, 0, 0] | units.km / units.s) self.assertAlmostEqual(ek / ep, -0.5, 12) self.assertAlmostRelativeEqual( ek, (0.25 * constants.G * (1000 | units.MSun)**2 / (1.0 | units.parsec)).as_quantity_in(ek.unit), 12)
def testcc(): N = 200 parts = new_fractal_cluster_model(N=N, fractal_dimension=2.0, random_seed=1234532) # parts = new_plummer_model(N) f = pyplot.figure(figsize=(8, 8)) pyplot.plot(parts.x.number, parts.y.number, 'r.') pyplot.xlim(-1, 1) pyplot.ylim(-1, 1) pyplot.savefig("fractal.png") def distfunc(p, q): return timestep(p, q, _G=nbody_system.G) graph, cc = connected_components(parts, treshold=1. / 512 | nbody_system.time, distfunc=distfunc) f = pyplot.figure(figsize=(8, 8)) for i, parts in enumerate(cc): for p in parts: pyplot.plot(p.x.number, p.y.number, colors[i % len(colors)] + '.') alledges = graph.all_edges() for e in alledges: pyplot.plot([e[2].x.number, e[1].x.number], [e[2].y.number, e[1].y.number], 'b') pyplot.xlim(-1, 1) pyplot.ylim(-1, 1) pyplot.savefig("cc.png")
def test2(self): print "test 2: test energy." target_number_of_particles = 100 parts = new_fractal_cluster_model(N=target_number_of_particles) ek = parts.kinetic_energy() ep = parts.potential_energy(G=nbody_system.G) self.assertAlmostEqual(ek / abs(ep), 0.5, 12) self.assertAlmostRelativeEqual(ep, -0.5 | nbody_system.energy, 12)
def new_cluster(D=2.6, Q=0.5, number_of_stars = 10): masses = new_broken_power_law_mass_distribution(number_of_stars, mass_boundaries=[0.08, 0.1, 0.5, 50.0] | units.MSun, alphas=[-0.3, -1.3, -2.3]) convert_nbody = nbody_system.nbody_to_si(masses.sum(), 1.0 | units.parsec) particles = new_fractal_cluster_model(convert_nbody=convert_nbody, masses = masses, fractal_dimension = D, virial_ratio = Q, do_scale=True) particles.move_to_center() return particles
def test6(self): print "Test fractal dimension." number_of_particles = 1000 for target_fractal_dimension in [1.6, 2.0, 2.5, 3.0]: particles = new_fractal_cluster_model( N=number_of_particles, fractal_dimension=target_fractal_dimension, do_scale=False, random_seed=1234321 ) self.assertAlmostRelativeEquals(particles.box_counting_dimension(), target_fractal_dimension, 1) self.assertAlmostRelativeEquals(particles.correlation_dimension(), target_fractal_dimension, 1)
def test3(self): print "test 3: test energy physical units." target_number_of_particles = 100 convert_nbody = nbody_system.nbody_to_si(1000 | units.MSun, 1 | units.parsec) parts = new_fractal_cluster_model(N=target_number_of_particles, convert_nbody=convert_nbody) ek = parts.kinetic_energy() ep = parts.potential_energy() self.assertAlmostEqual(ek / abs(ep), 0.5, 12) self.assertAlmostRelativeEqual(ep, -0.5 * constants.G * (1000 | units.MSun) ** 2 / (1.0 | units.parsec), 12)
def test6(self): print "Test fractal dimension." number_of_particles = 1000 for target_fractal_dimension in [1.6, 2.0, 2.5, 3.0]: particles = new_fractal_cluster_model( N=number_of_particles, fractal_dimension=target_fractal_dimension, do_scale=False, random_seed=1234321) self.assertAlmostRelativeEquals(particles.box_counting_dimension(), target_fractal_dimension, 1) self.assertAlmostRelativeEquals(particles.correlation_dimension(), target_fractal_dimension, 1)
def test3(self): print "test 3: test energy physical units." target_number_of_particles = 100 convert_nbody = nbody_system.nbody_to_si(1000 | units.MSun, 1 | units.parsec) parts = new_fractal_cluster_model(N=target_number_of_particles, convert_nbody=convert_nbody) ek = parts.kinetic_energy() ep = parts.potential_energy() self.assertAlmostEqual(ek / abs(ep), 0.5, 12) self.assertAlmostRelativeEqual( ep, -0.5 * constants.G * (1000 | units.MSun)**2 / (1.0 | units.parsec), 12)
def test5(self): print "Test with masses, with correct mass unit in converter" target_number_of_particles = 100 masses = (range(1, 11) | units.MSun) * 1.0 convert_nbody = nbody_system.nbody_to_si(masses.sum(), 1 | units.parsec) particles = new_fractal_cluster_model(masses=masses, convert_nbody=convert_nbody, do_scale=True) ek = particles.kinetic_energy() ep = particles.potential_energy() self.assertEquals(len(particles), 10) self.assertAlmostEqual(particles.total_mass(), 55 | units.MSun) # Note: total_mass == converter's mass unit! self.assertAlmostEqual(particles.center_of_mass(), [0, 0, 0] | units.parsec) self.assertAlmostEqual(particles.center_of_mass_velocity(), [0, 0, 0] | units.km / units.s) self.assertAlmostEqual(ek / ep, -0.5, 12) self.assertAlmostRelativeEqual( ek, (0.25 * constants.G * (55 | units.MSun) ** 2 / (1.0 | units.parsec)).as_quantity_in(ek.unit), 12 )
def generate_initial_conditions( number_of_stars = 10000, number_of_gas_particles = 2*10**6, star_formation_efficiency = 0.1, virial_radius = 0.33 | units.parsec, virial_ratio = 1.0, use_fractal = False): numpy.random.seed(12345678) seed_fractal = 312357271 masses = new_kroupa_mass_distribution(number_of_stars) total_stellar_mass = masses.sum() total_mass = total_stellar_mass / star_formation_efficiency converter = nbody_system.nbody_to_si(total_mass, virial_radius) if use_fractal: stars = new_fractal_cluster_model(number_of_stars, convert_nbody=converter, do_scale=False, fractal_dimension=1.6, random_seed=seed_fractal) else: stars = new_plummer_model(number_of_stars, convert_nbody=converter, do_scale=False) stars.mass = masses stars.move_to_center() print "scaling positions to match virial_radius" stars.position *= virial_radius / stars.virial_radius() print "scaling velocities to match virial_ratio" stars.velocity *= numpy.sqrt(virial_ratio * converter.to_si(0.5|nbody_system.energy) * star_formation_efficiency / stars.kinetic_energy()) print "new_gas_plummer_distribution" gas = new_gas_plummer_distribution( number_of_gas_particles, total_mass = (total_mass - total_stellar_mass), virial_radius = virial_radius, type = "fcc") gas.h_smooth = 0.0 | units.parsec filename = "YSC_{0}_stars{1}_gas{2}k_".format("fractal" if use_fractal else "plummer", number_of_stars, number_of_gas_particles/1000) print "Writing initial conditions to", filename, "+ stars/gas.amuse" write_set_to_file(stars, filename+"stars.amuse", "amuse", append_to_file=False) write_set_to_file(gas, filename+"gas.amuse", "amuse", append_to_file=False) with open(filename+"info.pkl", "wb") as outfile: cPickle.dump([converter], outfile) return stars, gas, filename
def test1(self): print "First test: making a fractal cluster." target_number_of_particles = 100 parts = new_fractal_cluster_model(N=target_number_of_particles) self.assertEquals(len(parts), 100)
few_dynamical_timescales.as_string_in(units.day)) n_steps = 100 if self.debug: monitor = dict(time=[]|units.day, kinetic=[]|units.J, potential=[]|units.J, thermal=[]|units.J) #~ velocity_damp_factor = (1.0 - 2 * (few_dynamical_timescales / n_steps) / self.dynamical_timescale) velocity_damp_factor = 0.8 for i_step, time in enumerate(few_dynamical_timescales * numpy.linspace(1.0/n_steps, 1.0, n_steps)): hydro.evolve_model(time) channel_from_hydro.copy_attributes(["mass","x","y","z","vx","vy","vz","u"]) gas_particles.position -= gas_particles.center_of_mass() #~ gas_particles.velocity = (gas_particles.velocity - gas_particles.center_of_mass_velocity()) * (i_step * 1.0 / n_steps) gas_particles.velocity = velocity_damp_factor * (gas_particles.velocity - gas_particles.center_of_mass_velocity()) channel_to_hydro.copy_attributes(["mass","x","y","z","vx","vy","vz","u"]) if self.debug: monitor["time"].append(time) monitor["kinetic"].append(hydro.kinetic_energy) monitor["potential"].append(hydro.potential_energy) monitor["thermal"].append(hydro.thermal_energy) hydro.stop() if self.debug: energy_evolution_plot(monitor["time"], monitor["kinetic"], monitor["potential"], monitor["thermal"]) return gas_particles if __name__ == "__main__": stars = new_fractal_cluster_model(N=1000, )
def new_star_cluster( stellar_mass=False, initial_mass_function="salpeter", upper_mass_limit=125. | units.MSun, lower_mass_limit=0.1 | units.MSun, number_of_stars=1024, effective_radius=3.0 | units.parsec, star_distribution="plummer", star_distribution_w0=7.0, star_distribution_fd=2.0, star_metallicity=0.01, # initial_binary_fraction=0, **kwargs): """ Create stars. When using an IMF, either the stellar mass is fixed (within stochastic error) or the number of stars is fixed. When using equal-mass stars, both are fixed. """ imf_name = initial_mass_function.lower() if imf_name == "salpeter": from amuse.ic.salpeter import new_salpeter_mass_distribution initial_mass_function = new_salpeter_mass_distribution elif imf_name == "kroupa": from amuse.ic.brokenimf import new_kroupa_mass_distribution initial_mass_function = new_kroupa_mass_distribution elif imf_name == "flat": from amuse.ic.flatimf import new_flat_mass_distribution initial_mass_function = new_flat_mass_distribution elif imf_name == "fixed": from amuse.ic.flatimf import new_flat_mass_distribution def new_fixed_mass_distribution(number_of_particles, *list_arguments, **keyword_arguments): return new_flat_mass_distribution( number_of_particles, mass_min=stellar_mass / number_of_stars, mass_max=stellar_mass / number_of_stars, ) initial_mass_function = new_fixed_mass_distribution if stellar_mass: # Add stars to cluster, until mass limit reached (inclusive!) mass = initial_mass_function( 0, mass_min=lower_mass_limit, mass_max=upper_mass_limit, ) while mass.sum() < stellar_mass: mass.append( initial_mass_function( 1, mass_min=lower_mass_limit, mass_max=upper_mass_limit, )[0]) total_mass = mass.sum() number_of_stars = len(mass) else: # Give stars their mass mass = initial_mass_function( number_of_stars, mass_min=lower_mass_limit, mass_max=upper_mass_limit, ) total_mass = mass.sum() converter = generic_unit_converter.ConvertBetweenGenericAndSiUnits( total_mass, 1. | units.kms, effective_radius, ) # Give stars a position and velocity, based on the distribution model. if star_distribution == "plummer": stars = new_plummer_sphere( number_of_stars, convert_nbody=converter, ) elif star_distribution == "king": stars = new_king_model( number_of_stars, star_distribution_w0, convert_nbody=converter, ) elif star_distribution == "fractal": stars = new_fractal_cluster_model( number_of_stars, fractal_dimension=star_distribution_fd, convert_nbody=converter, ) else: return -1, "No stellar distribution" # set the stellar mass. stars.mass = mass # set other stellar parameters. stars.metallicity = star_metallicity # Virialize the star cluster if > 1 star if len(stars) > 1: stars.move_to_center() stars.scale_to_standard( convert_nbody=converter, # virial_ratio=virial_ratio, # smoothing_length_squared= ..., ) # Record the cluster's initial parameters to the particle distribution stars.collection_attributes.initial_mass_function = imf_name stars.collection_attributes.upper_mass_limit = upper_mass_limit stars.collection_attributes.lower_mass_limit = lower_mass_limit stars.collection_attributes.number_of_stars = number_of_stars stars.collection_attributes.effective_radius = effective_radius stars.collection_attributes.star_distribution = star_distribution stars.collection_attributes.star_distribution_w0 = star_distribution_w0 stars.collection_attributes.star_distribution_fd = star_distribution_fd stars.collection_attributes.star_metallicity = star_metallicity # Derived/legacy values stars.collection_attributes.converter_mass = \ converter.to_si(1 | nbody_system.mass) stars.collection_attributes.converter_length =\ converter.to_si(1 | nbody_system.length) stars.collection_attributes.converter_speed =\ converter.to_si(1 | nbody_system.speed) return stars
def testhuayno(N=100, fd=1.6, seed=1234567): parts = new_fractal_cluster_model(N=N, fractal_dimension=fd, random_seed=seed) # parts.z*=0 # parts.vz*=0 def distfunc(p, q): return timestep(p, q, _G=nbody_system.G) f = pyplot.figure(figsize=(8, 8)) pyplot.plot(parts.x.number, parts.y.number, 'r.') pyplot.xlim(-1, 1) pyplot.ylim(-1, 1) pyplot.savefig("fractal-%3.1f.png" % fd) i = 0 cc = [] newparts = parts while len(cc) < len(parts): tcurrent = 1. / 2**i | nbody_system.time # lcurrent=1./2**i | nbody_system.length parts = newparts graph, cc = connected_components(parts, treshold=tcurrent, distfunc=distfunc) # graph,cc=connected_components(parts,treshold=lcurrent) print i, tcurrent, len(cc), len(parts) if len(cc) > 1: f = pyplot.figure(figsize=(8, 8)) alledges = graph.all_edges() for e in alledges: pyplot.plot([e[2].x.number, e[1].x.number], [e[2].y.number, e[1].y.number], 'grey', linewidth=0.5) for ip, iparts in enumerate(cc): for p in iparts: pyplot.plot(p.x.number, p.y.number, 'k.', markersize=8., mew=.5) pyplot.xlim(-1.2, 1.2) pyplot.ylim(-1.2, 1.2) single = 0 for s in cc: if len(s) == 1: single += 1 binary = 0 for s in cc: if len(s) == 2: binary += 1 pyplot.text(0.6, -.85, "level: %2i" % i, fontsize=16) pyplot.text(0.6, -.95, "#cc: %i" % len(cc), fontsize=16) pyplot.text(0.6, -1.05, "#s,b: %i,%i" % (single, binary), fontsize=16) pyplot.text(0.6, -1.15, "#parts: %i" % len(parts), fontsize=16) pyplot.savefig("cc-%3.1f-%3.3i.png" % (fd, i)) newparts = Particles() for s in cc: if len(s) > 2: for p in s: newparts.add_particle(p) i += 1 print len(cc), len(parts)