示例#1
0
def run_ph4(infile = None, number_of_stars = 40,
             end_time = 10 | nbody_system.time,
             delta_t = 1 | nbody_system.time,
             n_workers = 1, use_gpu = 1, gpu_worker = 1,
             accuracy_parameter = 0.1,
             softening_length = -1 | nbody_system.length,
             manage_encounters = 1, random_seed = 1234):

    if random_seed <= 0:
        numpy.random.seed()
        random_seed = numpy.random.randint(1, pow(2,31)-1)
    numpy.random.seed(random_seed)
    print "random seed =", random_seed

    if infile != None: print "input file =", infile
    print "end_time =", end_time.number
    print "delta_t =", delta_t.number
    print "n_workers =", n_workers
    print "use_gpu =", use_gpu
    print "manage_encounters =", manage_encounters
    print "\ninitializing the gravity module"
    sys.stdout.flush()

    # Note that there are actually three GPU options to test:
    #
    #	1. use the GPU code and allow GPU use (default)
    #	2. use the GPU code but disable GPU use (-g)
    #	3. use the non-GPU code (-G)

    if gpu_worker == 1:
        try:
            gravity = grav(number_of_workers = n_workers,
                           redirection = "none", mode = "gpu")
        except Exception as ex:
            gravity = grav(number_of_workers = n_workers, redirection = "none")
    else:
        gravity = grav(number_of_workers = n_workers, redirection = "none")

    gravity.initialize_code()
    gravity.parameters.set_defaults()

    #-----------------------------------------------------------------

    if infile == None:

        print "making a Plummer model"
        stars = new_plummer_model(number_of_stars)

        id = numpy.arange(number_of_stars)
        stars.id = id+1

        print "setting particle masses and radii"
	#stars.mass = (1.0 / number_of_stars) | nbody_system.mass
        scaled_mass = new_salpeter_mass_distribution_nbody(number_of_stars) 
        stars.mass = scaled_mass
        stars.radius = 0.02 | nbody_system.length

        print "centering stars"
        stars.move_to_center()
        print "scaling stars to virial equilibrium"
        stars.scale_to_standard(smoothing_length_squared
                                    = gravity.parameters.epsilon_squared)

        time = 0.0 | nbody_system.time
        sys.stdout.flush()

    else:

        # Read the input data.  Units are dynamical.

        print "reading file", infile

        id = []
        mass = []
        pos = []
        vel = []

        f = open(infile, 'r')
        count = 0
        for line in f:
            if len(line) > 0:
                count += 1
                cols = line.split()
                if count == 1: snap = int(cols[0])
                elif count == 2: number_of_stars = int(cols[0])
                elif count == 3: time = float(cols[0]) | nbody_system.time
                else:
                    if len(cols) >= 8:
                        id.append(int(cols[0]))
                        mass.append(float(cols[1]))
                        pos.append((float(cols[2]),
                                    float(cols[3]), float(cols[4])))
                        vel.append((float(cols[5]),
                                    float(cols[6]), float(cols[7])))
        f.close()

        stars = datamodel.Particles(number_of_stars)
        stars.id = id
        stars.mass = mass | nbody_system.mass
        stars.position = pos | nbody_system.length
        stars.velocity = vel | nbody_system.speed
        stars.radius = 0. | nbody_system.length

    # print "IDs:", stars.id.number
    sys.stdout.flush()

    #-----------------------------------------------------------------

    if softening_length == -1 | nbody_system.length:
        eps2 = 0.25*(float(number_of_stars))**(-0.666667) \
			| nbody_system.length**2
    else:
        eps2 = softening_length*softening_length

    gravity.parameters.timestep_parameter = accuracy_parameter
    gravity.parameters.epsilon_squared = eps2
    gravity.parameters.use_gpu = use_gpu
    # gravity.parameters.manage_encounters = manage_encounters

    print "adding particles"
    # print stars
    sys.stdout.flush()
    gravity.particles.add_particles(stars)
    gravity.commit_particles()

    print ''
    print "number_of_stars =", number_of_stars
    print "evolving to time =", end_time.number, \
          "in steps of", delta_t.number
    sys.stdout.flush()

    E0 = print_log(time, gravity)
    
    # Channel to copy values from the code to the set in memory.
    channel = gravity.particles.new_channel_to(stars)

    stopping_condition = gravity.stopping_conditions.collision_detection
    stopping_condition.enable()

    kep = Kepler(redirection = "none")
    kep.initialize_code()
    multiples_code = multiples.Multiples(gravity, new_smalln, kep)
    

    while time < end_time:
        time += delta_t
        multiples_code.evolve_model(time)

        # Copy values from the module to the set in memory.

        channel.copy()
    
        # Copy the index (ID) as used in the module to the id field in
        # memory.  The index is not copied by default, as different
        # codes may have different indices for the same particle and
        # we don't want to overwrite silently.

        channel.copy_attribute("index_in_code", "id")

        print_log(time, gravity, E0)
        sys.stdout.flush()

    print ''
    gravity.stop()
示例#2
0
def manage_encounter(star1, star2, stars, gravity_stars):

    # Manage an encounter between star1 and star2.  stars is the
    # python memory data set.  gravity_stars points to the gravity
    # module data.  Return value is the energy correction due to
    # multiples.

    # Establish child flags for use during the encounter calculation.

    stars.is_a_child = 0 | units.none
    parents = stars.select(is_a_parent, ["child1", "child2"])
    for s in stars:
        for p in parents:
            if p.child1 == s or p.child2 == s:
                s.is_a_child = 1 | units.none

    # Currently we don't include neighbors in the integration and the
    # size limitation on any final multiple is poorly implemented.

    print '\nin manage_encounter'
    sys.stdout.flush()

    # 1. Star1 and star2 reflect the data in the gravity module.  Find
    #    the corresponding particles in the local particle set.

    star1_in_memory = star1.as_particle_in_set(stars)  # pointers
    star2_in_memory = star2.as_particle_in_set(stars)

    # 1a. Copy the current position and velocity to mememory (need to
    #     create a better call for this, for example:
    #     star1.copy_to(star1_in_memory)

    star1_in_memory.position = star1.position
    star1_in_memory.velocity = star1.velocity
    star2_in_memory.position = star2.position
    star2_in_memory.velocity = star2.velocity

    # Basic diagnostics:

    print_pair_of_stars('**encounter**', star1_in_memory, star2_in_memory)

    print ''
    find_nnn(star1_in_memory, star2_in_memory, stars)
    find_nnn(star2_in_memory, star1_in_memory, stars)

    # 1b. Calculate the potential of [star1, star2] relative to the
    #     other top-level objects in the stars list (later: just use
    #     neighbors TODO).  Start the correction of dEmult by removing
    #     the initial top-level energy of the interacting particles
    #     from it.  (Add in the final energy later, on return from
    #     scale_top_level_list.)

    slist = [star1_in_memory, star2_in_memory]
    etot = total_energy(slist)
    print 'initial etot =', etot
    dEmult = -etot
    klist = [star1_in_memory, star2_in_memory]
    phi_external_init = relative_potential(slist, klist, stars)
    print 'phi_external_init =', phi_external_init

    # 2. Create a particle set to perform the close encounter
    #    calculation.

    particles_in_encounter = datamodel.Particles(0)

    # 3. Add stars to the encounter set, add in components when we
    #    encounter a binary.

    if not star1_in_memory.child1 is None:
        openup_tree(star1_in_memory, stars, particles_in_encounter)
    else:
        particles_in_encounter.add_particle(star1_in_memory)

    if not star2_in_memory.child1 is None:
        openup_tree(star2_in_memory, stars, particles_in_encounter)
    else:
        particles_in_encounter.add_particle(star2_in_memory)

    # particles_in_encounter.id = -1 | units.none  # need to make this -1 to
    # ensure smallN will set the
    # IDs, or else smallN seems
    # to fail... TODO

    # *** Desirable to propagate the IDs into smallN, for internal
    # *** diagnostic purposes...

    # print 'particles in smallN encounter:'
    # print particles_in_encounter.to_string(['x','y','z',
    #                                         'vx','vy','vz','mass','id'])

    print '\nparticles in encounter (flat tree):'
    for p in particles_in_encounter:
        print_multiple(p)

    initial_scale \
        = math.sqrt(((star1.position
                      -star2.position).number**2).sum())|nbody_system.length
    print 'initial_scale =', initial_scale.number
    sys.stdout.flush()

    # 4. Run the small-N encounter in the center of mass frame.

    # Probably desirable to make this a true scattering experiment by
    # separating star1 and star2 to a larger distance before starting
    # smallN.  TODO

    total_mass = star1.mass + star2.mass
    cmpos = (star1.mass * star1.position +
             star2.mass * star2.position) / total_mass
    cmvel = (star1.mass * star1.velocity +
             star2.mass * star2.velocity) / total_mass
    print 'CM KE =', 0.5 * total_mass.number * ((cmvel.number)**2).sum()
    for p in particles_in_encounter:
        p.position -= cmpos
        p.velocity -= cmvel

    run_smallN(particles_in_encounter)

    for p in particles_in_encounter:
        p.position += cmpos
        p.velocity += cmvel

    # print 'after smallN:'
    # print particles_in_encounter.to_string(['x','y','z',
    #                                         'vx','vy','vz',
    #                                         'mass', 'id'])
    # sys.stdout.flush()

    # 5. Carry out bookkeeping after the encounter and update the
    #    gravity module with the new data.

    # 5a. Remove star1 and star2 from the gravity module.

    gravity_stars.remove_particle(star1)
    gravity_stars.remove_particle(star2)

    # 5b. Create an object to handle the new binary information.

    binaries = trees.BinaryTreesOnAParticleSet(particles_in_encounter,
                                               "child1", "child2")

    # 5bb. Compress the top-level nodes before adding them to the
    #      gravity code.  Also recompute the external potential and
    #      absorb the tidal error into the top-level nodes of the
    #      encounter list.  Fially, add the change in top-level energy
    #      of the interacting subset into dEmult, so E(hacs64) + dEmult
    #      should be conserved.

    dEmult += scale_top_level_list(binaries, initial_scale, stars, klist,
                                   phi_external_init)

    # 5c. Update the positions and velocities of the stars (leaves) in
    #     the encounter; copy the position and velocity attributes of
    #     all stars updated during the encounter to the stars particle
    #     set in memory.  Do not copy child or any other attributes.

    tmp_channel = particles_in_encounter.new_channel_to(stars)
    tmp_channel.copy_attributes(['x', 'y', 'z', 'vx', 'vy', 'vz'])

    # 5d. Add stars not in a binary to the gravity code.

    stars_not_in_a_multiple = binaries.particles_not_in_a_multiple()
    stars_not_in_a_multiple_in_stars = \
        stars_not_in_a_multiple.get_intersecting_subset_in(stars)
    if len(stars_not_in_a_multiple_in_stars) > 0:
        gravity_stars.add_particles(stars_not_in_a_multiple_in_stars)

    # 5e. Add the inner (CM) nodes (root plus subnodes) to the stars
    #     in memory (the descendant nodes are already part of the
    #     set).

    for root in binaries.iter_roots():
        stars_in_a_multiple = root.get_descendants_subset()
        # print 'root.get_inner_nodes_subset():'
        # print root.get_inner_nodes_subset(); sys.stdout.flush()
        stars.add_particles(root.get_inner_nodes_subset())

    # 5f. Add roots of the binaries tree to the gravity code.

    # Must set radii to reflect multiple structure.  TODO

    for root in binaries.iter_roots():
        root_in_stars = root.particle.as_particle_in_set(stars)
        root_in_stars.id = new_root_index()
        # print 'root_in_stars:'
        # print root_in_stars; sys.stdout.flush(); sys.stdout.flush()
        gravity_stars.add_particle(root_in_stars)

    # 5g. Store the original position and velocity of the root so that
    #     the subparticle position can be updated later.

    for root in binaries.iter_roots():
        root_in_stars = root.particle.as_particle_in_set(stars)

        # Save root position and velocity so we can update the
        # position and velocity of the components when we open up the
        # binary tree.

        root_in_stars.original_x = root_in_stars.x
        root_in_stars.original_y = root_in_stars.y
        root_in_stars.original_z = root_in_stars.z
        root_in_stars.original_vx = root_in_stars.vx
        root_in_stars.original_vy = root_in_stars.vy
        root_in_stars.original_vz = root_in_stars.vz

    return dEmult
示例#3
0
def run_multiples(infile=None,
                  number_of_stars=64,
                  nmax=2048,
                  end_time=0.1 | nbody_system.time,
                  delta_t=0.125 | nbody_system.time,
                  dt_max=0.0625 | nbody_system.time,
                  n_ngb=16,
                  eta_irr=0.6,
                  eta_reg=0.1,
                  softening_length=0.0 | nbody_system.length,
                  random_seed=1234):

    if infile != None: print "input file =", infile
    print "end_time =", end_time.number
    print "nstars= ", number_of_stars,
    print "nmax= ", nmax,
    print "delta_t= ", delta_t.number
    print "dt_max= ", dt_max.number
    print "n_ngb= ", n_ngb,
    print "eta_irr= ", eta_irr
    print "eta_reg= ", eta_reg
    print "eps2=    ", softening_length.number**2
    print "\ninitializing the gravity module"
    sys.stdout.flush()

    if random_seed <= 0:
        numpy.random.seed()
        random_seed = numpy.random.randint(1, pow(2, 31) - 1)
    numpy.random.seed(random_seed)
    print "random seed =", random_seed

    # Note that there are actually three GPU options to test:
    #
    #	1. use the GPU code and allow GPU use (default)
    #	2. use the GPU code but disable GPU use (-g)
    #	3. use the non-GPU code (-G)

    gravity = grav(number_of_workers=1, debugger="none", redirection="none")
    gravity.initialize_code()

    #-----------------------------------------------------------------

    if infile == None:

        print "making a Plummer model"
        stars = new_plummer_model(number_of_stars)

        id = numpy.arange(number_of_stars)
        stars.id = id + 1

        print "setting particle masses and radii"
        #stars.mass = (1.0 / number_of_stars) | nbody_system.mass
        scaled_mass = new_salpeter_mass_distribution_nbody(number_of_stars)
        stars.mass = scaled_mass
        stars.radius = 0.0 | nbody_system.length

        print "centering stars"
        stars.move_to_center()
        print "scaling stars to virial equilibrium"
        stars.scale_to_standard(smoothing_length_squared=0
                                | nbody_system.length**2)

        time = 0.0 | nbody_system.time
        sys.stdout.flush()

    else:

        # Read the input data.  Units are dynamical.

        print "reading file", infile
        sys.stdout.flush()

        id = []
        mass = []
        pos = []
        vel = []

        f = open(infile, 'r')
        count = 0
        for line in f:
            if len(line) > 0:
                count += 1
                cols = line.split()
                if count == 1: snap = int(cols[0])
                elif count == 2: number_of_stars = int(cols[0])
                elif count == 3: time = float(cols[0]) | nbody_system.time
                else:
                    if len(cols) >= 8:
                        #        id.append(int(cols[0]))
                        id.append(count)
                        mass.append(float(cols[1]))
                        pos.append(
                            (float(cols[2]), float(cols[3]), float(cols[4])))
                        vel.append(
                            (float(cols[5]), float(cols[6]), float(cols[7])))
        f.close()

        stars = datamodel.Particles(number_of_stars)
        stars.id = id
        stars.mass = mass | nbody_system.mass
        stars.position = pos | nbody_system.length
        stars.velocity = vel | nbody_system.speed
        stars.radius = 0. | nbody_system.length
        nmax = 2 * len(mass)

    # print "IDs:", stars.id.number
    sys.stdout.flush()

    global root_index
    root_index = len(stars) + 10000
    #-----------------------------------------------------------------

    gravity.parameters.nmax = nmax
    gravity.parameters.dtmax = dt_max
    #    gravity.parameters.n_ngb   = n_ngb;
    gravity.parameters.eta_irr = eta_irr
    gravity.parameters.eta_reg = eta_reg
    gravity.parameters.eps2 = softening_length**2
    gravity.commit_parameters()

    print "adding particles"
    # print stars
    sys.stdout.flush()
    gravity.particles.add_particles(stars)
    gravity.commit_particles()

    print ''
    print "number_of_stars =", number_of_stars
    print "evolving to time =", end_time.number, \
          "in steps of", delta_t.number
    sys.stdout.flush()

    E0 = print_log('hacs64', gravity)
    dEmult = 0.0

    # Channel to copy values from the code to the set in memory.
    channel = gravity.particles.new_channel_to(stars)

    stopping_condition = gravity.stopping_conditions.collision_detection
    #stopping_condition.enable()

    # Tree structure on the stars dataset:

    stars.child1 = 0 | units.object_key
    stars.child2 = 0 | units.object_key

    while time < end_time:
        time += delta_t

        while gravity.get_time() < time:
            gravity.evolve_model(time)
            if stopping_condition.is_set():
                star1 = stopping_condition.particles(0)[0]
                star2 = stopping_condition.particles(1)[0]
                print '\n--------------------------------------------------'
                print 'stopping condition set at time', \
                    gravity.get_time().number

                E = print_log('hacs64', gravity, E0)
                print 'dEmult =', dEmult, 'dE =', (E - E0).number - dEmult
                # channel.copy()	# need other stars to be current in memory
                # print_energies(stars)

                # Synchronize everything for now.  Later we will just
                # synchronize neighbors if gravity supports that.  TODO
                gravity.synchronize_model()
                gravity.particles.synchronize_to(stars)

                dEmult += manage_encounter(star1, star2, stars,
                                           gravity.particles)

                # Recommit reinitializes all particles (and redundant
                # here, since done automatically).  Later we will just
                # recommit and reinitialize a list if gravity supports
                # it. TODO
                gravity.recommit_particles()

                E = print_log('hacs64', gravity, E0)
                print 'dEmult =', dEmult, 'dE =', (E - E0).number - dEmult
                print '\n--------------------------------------------------'

        ls = len(stars)

        # Copy values from the module to the set in memory.
        channel.copy()

        # Copy the index (ID) as used in the module to the id field in
        # memory.  The index is not copied by default, as different
        # codes may have different indices for the same particle and
        # we don't want to overwrite silently.

        channel.copy_attribute("index_in_code", "id")

        if len(stars) != ls:
            if 0:
                print "stars:"
                for s in stars:
                    print " ", s.id.number, s.mass.number, \
          s.x.number, s.y.number, s.z.number
            else:
                print "number of stars =", len(stars)
            sys.stdout.flush()

        E = print_log('hacs64', gravity, E0)
        print 'dEmult =', dEmult, 'dE =', (E - E0).number - dEmult

    print ''
    gravity.stop()
示例#4
0
def run_hacs(infile=None,
             number_of_stars=128,
             nmax=2048,
             end_time=0.1 | nbody_system.time,
             delta_t=0.125 | nbody_system.time,
             dt_max=0.0625 | nbody_system.time,
             n_ngb=16,
             eta_irr=0.6,
             eta_reg=0.1,
             softening_length=0.0 | nbody_system.length):

    if infile != None: print("input file =", infile)
    print("end_time =", end_time.number)
    print("nstars= ", number_of_stars, end=' ')
    print("nmax= ", nmax, end=' ')
    print("delta_t= ", delta_t.number)
    print("dt_max= ", dt_max.number)
    print("n_ngb= ", n_ngb, end=' ')
    print("eta_irr= ", eta_irr)
    print("eta_reg= ", eta_reg)
    print("eps2=    ", softening_length.number**2)
    print("\ninitializing the gravity module")
    sys.stdout.flush()

    #    gravity = grav(number_of_workers = 1, redirection = "none", mode='cpu')
    gravity = grav(number_of_workers=1, redirection="none", mode='cpu')
    gravity.initialize_code()

    #-----------------------------------------------------------------

    if infile == None:

        print("making a Plummer model")
        stars = new_plummer_model(number_of_stars)

        id = numpy.arange(number_of_stars)
        stars.id = id + 1

        print("setting particle masses and radii")
        #stars.mass = (1.0 / number_of_stars) | nbody_system.mass
        scaled_mass = new_salpeter_mass_distribution_nbody(number_of_stars)
        stars.mass = scaled_mass
        stars.radius = 0.0 | nbody_system.length

        print("centering stars")
        stars.move_to_center()
        print("scaling stars to virial equilibrium")
        stars.scale_to_standard(
            smoothing_length_squared=gravity.parameters.eps2)

        time = 0.0 | nbody_system.time
        sys.stdout.flush()

    else:

        # Read the input data.  Units are dynamical.

        print("reading file", infile)

        id = []
        mass = []
        pos = []
        vel = []

        f = open(infile, 'r')
        count = 0
        for line in f:
            if len(line) > 0:
                count += 1
                cols = line.split()
                if count == 1: snap = int(cols[0])
                elif count == 2: number_of_stars = int(cols[0])
                elif count == 3: time = float(cols[0]) | nbody_system.time
                else:
                    if len(cols) >= 8:
                        id.append(int(cols[0]))
                        mass.append(float(cols[1]))
                        pos.append(
                            (float(cols[2]), float(cols[3]), float(cols[4])))
                        vel.append(
                            (float(cols[5]), float(cols[6]), float(cols[7])))
        f.close()

        stars = datamodel.Particles(number_of_stars)
        stars.id = id
        print(len(mass), len(pos), len(vel), len(id))
        stars.mass = mass | nbody_system.mass
        stars.position = pos | nbody_system.length
        stars.velocity = vel | nbody_system.speed
        stars.radius = 0. | nbody_system.length
        nmax = 2 * len(mass)

    # print "IDs:", stars.id.number
    sys.stdout.flush()

    #-----------------------------------------------------------------

    gravity.parameters.nmax = nmax
    gravity.parameters.dtmax = dt_max
    #    gravity.parameters.n_ngb   = n_ngb;
    gravity.parameters.eta_irr = eta_irr
    gravity.parameters.eta_reg = eta_reg
    gravity.parameters.eps2 = softening_length**2
    gravity.commit_parameters()

    print("adding particles")
    # print stars
    sys.stdout.flush()
    gravity.particles.add_particles(stars)
    gravity.commit_particles()

    print('')
    print("number_of_stars =", number_of_stars)
    print("evolving to time =", end_time.number, \
          "in steps of", delta_t.number)
    sys.stdout.flush()

    E0 = print_log(time, gravity)

    # Channel to copy values from the code to the set in memory.
    channel = gravity.particles.new_channel_to(stars)

    stopping_condition = gravity.stopping_conditions.collision_detection
    stopping_condition.enable()

    #    stopping_condition.disable()

    while time < end_time:
        if (gravity.get_time() >= time):
            time += delta_t

        gravity.evolve_model(time)

        # Ensure that the stars list is consistent with the internal
        # data in the module.

        ls = len(stars)

        # Update the bookkeeping: synchronize stars with the module data.

        # this breaks the code ...
        channel.copy()

        # Copy values from the module to the set in memory.

        channel.copy_attribute("index_in_code", "id")

        # Copy the index (ID) as used in the module to the id field in
        # memory.  The index is not copied by default, as different
        # codes may have different indices for the same particle and
        # we don't want to overwrite silently.

        if stopping_condition.is_set():
            star1 = stopping_condition.particles(0)[0]
            star2 = stopping_condition.particles(1)[0]
            gravity.synchronize_model()
            print('\nstopping condition set at time', \
                gravity.get_time().number,'for:\n')
            print(star1)
            print('')
            print(star2)
            print('')
            gravity.particles.remove_particle(star1)
            gravity.particles.remove_particle(star2)

            gravity.recommit_particles()

            print('ls=', len(stars))

            gravity.update_particle_set()
            gravity.particles.synchronize_to(stars)

            print('ls=', len(stars))

        if len(stars) != ls:
            if 0:
                print("stars:")
                for s in stars:
                    print(" ", s.id.number, s.mass.number, s.x.number,
                          s.y.number, s.z.number)
            else:
                print("number of stars =", len(stars))
            sys.stdout.flush()

        print_log(gravity.get_time(), gravity, E0)
        sys.stdout.flush()

    print('')
    print_log(gravity.get_time(), gravity, E0)
    sys.stdout.flush()
    gravity.stop()
示例#5
0
def run_ph4(infile=None,
            outfile=None,
            number_of_stars=100,
            number_of_binaries=0,
            end_time=10 | nbody_system.time,
            delta_t=1 | nbody_system.time,
            n_workers=1,
            use_gpu=1,
            gpu_worker=1,
            salpeter=0,
            accuracy_parameter=0.1,
            softening_length=0.0 | nbody_system.length,
            manage_encounters=1,
            random_seed=1234):

    if random_seed <= 0:
        numpy.random.seed()
        random_seed = numpy.random.randint(1, pow(2, 31) - 1)
    numpy.random.seed(random_seed)
    print "random seed =", random_seed

    if infile != None: print "input file =", infile
    print "end_time =", end_time.number
    print "delta_t =", delta_t.number
    print "n_workers =", n_workers
    print "use_gpu =", use_gpu
    print "manage_encounters =", manage_encounters
    print "\ninitializing the gravity module"
    sys.stdout.flush()

    init_smalln()

    # Note that there are actually three GPU options:
    #
    #	1. use the GPU code and allow GPU use (default)
    #	2. use the GPU code but disable GPU use (-g)
    #	3. use the non-GPU code (-G)

    if gpu_worker == 1:
        try:
            gravity = grav(number_of_workers=n_workers,
                           redirection="none",
                           mode="gpu")
        except Exception as ex:
            gravity = grav(number_of_workers=n_workers, redirection="none")
    else:
        gravity = grav(number_of_workers=n_workers, redirection="none")

    gravity.initialize_code()
    gravity.parameters.set_defaults()

    #-----------------------------------------------------------------

    if infile == None:

        print "making a Plummer model"
        stars = new_plummer_model(number_of_stars)

        id = numpy.arange(number_of_stars)
        stars.id = id + 1

        print "setting particle masses and radii"
        if salpeter == 0:
            print 'equal masses'
            total_mass = 1.0 | nbody_system.mass
            scaled_mass = total_mass / number_of_stars
        else:
            print 'salpeter mass function'
            scaled_mass = new_salpeter_mass_distribution_nbody(number_of_stars)
        stars.mass = scaled_mass

        print "centering stars"
        stars.move_to_center()
        print "scaling stars to virial equilibrium"
        stars.scale_to_standard(
            smoothing_length_squared=gravity.parameters.epsilon_squared)

    else:

        # Read the input data.  Units are dynamical (sorry).
        # Format:  id  mass  pos[3]  vel[3]

        print "reading file", infile

        id = []
        mass = []
        pos = []
        vel = []

        f = open(infile, 'r')
        count = 0
        for line in f:
            if len(line) > 0:
                count += 1
                cols = line.split()
                if count == 1: snap = int(cols[0])
                elif count == 2: number_of_stars = int(cols[0])
                elif count == 3: time = float(cols[0]) | nbody_system.time
                else:
                    if len(cols) >= 8:
                        id.append(int(cols[0]))
                        mass.append(float(cols[1]))
                        pos.append(
                            (float(cols[2]), float(cols[3]), float(cols[4])))
                        vel.append(
                            (float(cols[5]), float(cols[6]), float(cols[7])))
        f.close()

        stars = datamodel.Particles(number_of_stars)
        stars.id = id
        stars.mass = mass | nbody_system.mass
        stars.position = pos | nbody_system.length
        stars.velocity = vel | nbody_system.speed
        #stars.radius = 0. | nbody_system.length

    total_mass = stars.mass.sum()
    ke = pa.kinetic_energy(stars)
    kT = ke / (1.5 * number_of_stars)

    if number_of_binaries > 0:

        # Turn selected stars into binary components.
        # Only tested for equal-mass case.

        kep = Kepler(redirection="none")
        kep.initialize_code()

        added_mass = 0.0 | nbody_system.mass

        # Work with energies rather than semimajor axes.

        Emin = 10 * kT
        Emax = 20 * kT
        ecc = 0.1

        id_count = number_of_stars
        nbin = 0
        for i in range(0, number_of_stars,
                       number_of_stars / number_of_binaries):

            # Star i is CM, becomes component, add other star at end.

            nbin += 1

            mass = stars[i].mass
            new_mass = numpy.random.uniform() * mass  # uniform q?
            mbin = mass + new_mass
            fac = new_mass / mbin
            E = Emin + numpy.random.uniform() * (Emax - Emin)
            a = 0.5 * nbody_system.G * mass * new_mass / E

            kep.initialize_from_elements(mbin, a, ecc)
            dr = quantities.AdaptingVectorQuantity()
            dr.extend(kep.get_separation_vector())
            dv = quantities.AdaptingVectorQuantity()
            dv.extend(kep.get_velocity_vector())

            newstar = datamodel.Particles(1)
            newstar.mass = new_mass
            newstar.position = stars[i].position + (1 - fac) * dr
            newstar.velocity = stars[i].velocity + (1 - fac) * dv
            # stars[i].mass = mass
            stars[i].position = stars[i].position - fac * dr
            stars[i].velocity = stars[i].velocity - fac * dv

            id_count += 1
            newstar.id = id_count
            stars.add_particles(newstar)
            added_mass += new_mass

            if nbin >= number_of_binaries: break

        kep.stop()

        print 'created', nbin, 'binaries'
        sys.stdout.flush()

        stars.mass = stars.mass * total_mass / (total_mass + added_mass)
        number_of_stars += nbin

    # Set dynamical radii (assuming virial equilibrium and standard
    # units).  Note that this choice should be refined, and updated
    # as the system evolves.  Probably the choice of radius should be
    # made entirely in the multiples module.  TODO.  In these units,
    # M = 1 and <v^2> = 0.5, so the mean 90-degree turnaround impact
    # parameter is
    #
    #		b_90 = G (m_1+m_2) / vrel^2
    #		     = 2 <m> / 2<v^2>
    #		     = 2 / N			for equal masses
    #
    # Taking r_i = m_i / 2<v^2> = m_i in virial equilibrium means
    # that, approximately, "contact" means a 90-degree deflection (r_1
    # + r_2 = b_90).  A more conservative choice with r_i less than
    # this value will isolates encounters better, but also place more
    # load on the large-N dynamical module.

    stars.radius = stars.mass.number | nbody_system.length

    time = 0.0 | nbody_system.time
    # print "IDs:", stars.id.number

    print "recentering stars"
    stars.move_to_center()
    sys.stdout.flush()

    #-----------------------------------------------------------------

    if softening_length < 0.0 | nbody_system.length:

        # Use ~interparticle spacing.  Assuming standard units here.  TODO

        eps2 = 0.25*(float(number_of_stars))**(-0.666667) \
   | nbody_system.length**2
    else:
        eps2 = softening_length * softening_length
    print 'softening length =', eps2.sqrt()

    gravity.parameters.timestep_parameter = accuracy_parameter
    gravity.parameters.epsilon_squared = eps2
    gravity.parameters.use_gpu = use_gpu
    # gravity.parameters.manage_encounters = manage_encounters

    print ''
    print "adding particles"
    # print stars
    sys.stdout.flush()
    gravity.particles.add_particles(stars)
    gravity.commit_particles()

    print ''
    print "number_of_stars =", number_of_stars
    print "evolving to time =", end_time.number, \
          "in steps of", delta_t.number
    sys.stdout.flush()

    # Channel to copy values from the code to the set in memory.
    channel = gravity.particles.new_channel_to(stars)

    stopping_condition = gravity.stopping_conditions.collision_detection
    stopping_condition.enable()

    # Debugging: prevent the multiples code from being called.
    if 0:
        stopping_condition.disable()
        print 'stopping condition disabled'
        sys.stdout.flush()

    # -----------------------------------------------------------------
    # Create the coupled code and integrate the system to the desired
    # time, managing interactions internally.

    kep = init_kepler(stars[0], stars[1])
    multiples_code = multiples.Multiples(gravity, new_smalln, kep)

    multiples_code.neighbor_perturbation_limit = 0.1
    #multiples_code.neighbor_distance_factor = 1.0
    #multiples_code.neighbor_veto = False
    #multiples_code.neighbor_distance_factor = 2.0
    multiples_code.neighbor_veto = True

    print ''
    print 'multiples_code.initial_scale_factor =', \
        multiples_code.initial_scale_factor
    print 'multiples_code.neighbor_perturbation_limit =', \
        multiples_code.neighbor_perturbation_limit
    print 'multiples_code.neighbor_veto =', \
        multiples_code.neighbor_veto
    print 'multiples_code.final_scale_factor =', \
        multiples_code.final_scale_factor
    print 'multiples_code.initial_scatter_factor =', \
        multiples_code.initial_scatter_factor
    print 'multiples_code.final_scatter_factor =', \
        multiples_code.final_scatter_factor
    print 'multiples_code.retain_binary_apocenter =', \
        multiples_code.retain_binary_apocenter
    print 'multiples_code.wide_perturbation_limit =', \
        multiples_code.wide_perturbation_limit

    pre = "%%% "
    E0, cpu0 = print_log(pre, time, multiples_code)

    while time < end_time:

        time += delta_t
        multiples_code.evolve_model(time)

        # Copy values from the module to the set in memory.

        channel.copy()

        # Copy the index (ID) as used in the module to the id field in
        # memory.  The index is not copied by default, as different
        # codes may have different indices for the same particle and
        # we don't want to overwrite silently.

        channel.copy_attribute("index_in_code", "id")

        print_log(pre, time, multiples_code, E0, cpu0)
        sys.stdout.flush()

    #-----------------------------------------------------------------

    if not outfile == None:

        # Write data to a file.

        f = open(outfile, 'w')

        #--------------------------------------------------
        # Need to save top-level stellar data and parameters.
        # Need to save multiple data and parameters.

        f.write('%.15g\n' % (time.number))
        for s in multiples_code.stars:
            write_star(s, f)

        #--------------------------------------------------

        f.close()
        print 'wrote file', outfile

    print ''
    gravity.stop()
示例#6
0
    def test8(self):
        code = Hermite()
        particles_in_binary = self.new_binary(0.1 | nbody_system.mass,
                                              0.1 | nbody_system.mass,
                                              0.01 | nbody_system.length,
                                              keyoffset=1)
        particles_in_binary.radius = 0.001 | nbody_system.length
        binary = datamodel.Particle(key=3)
        binary.child1 = particles_in_binary[0]
        binary.child2 = particles_in_binary[1]
        binary.radius = 0.5 | nbody_system.length
        binary.mass = 0.2 | nbody_system.mass
        binary.position = [0.0, 0.0, 0.0] | nbody_system.length
        binary.velocity = [0.0, 0.0, 0.0] | nbody_system.speed
        encounter_code = encounters.HandleEncounter(
            kepler_code=self.new_kepler(),
            resolve_collision_code=self.new_smalln(),
            interaction_over_code=None)
        encounter_code.parameters.hard_binary_factor = 1
        encounter_code.small_scale_factor = 1
        multiples_code = encounters.Multiples(
            gravity_code=code, handle_encounter_code=encounter_code)
        multiples_code.singles_in_binaries.add_particles(particles_in_binary)
        multiples_code.binaries.add_particle(binary)
        multiples_code.must_handle_one_encounter_per_stopping_condition = False

        field_particle = datamodel.Particle(key=4)
        field_particle.mass = 0.5 | nbody_system.mass
        field_particle.radius = 0.1 | nbody_system.length
        field_particle.position = [0.0, 0.2, 0.0] | nbody_system.length
        field_particle.velocity = [0.0, 0.0, 0.0] | nbody_system.speed

        multiples_code.singles.add_particle(field_particle)

        self.assertEquals(len(multiples_code.singles_in_binaries), 2)
        self.assertEquals(id(multiples_code.binaries[0].child1.particles_set),
                          id(multiples_code.singles_in_binaries))

        multiples_code.commit_particles()
        multiples_code.multiples.radius = 0.5 | nbody_system.length
        initial_energy = multiples_code.get_total_energy()

        self.assertEquals(len(multiples_code.multiples), 1)
        self.assertEquals(len(multiples_code.components_of_multiples), 2)
        self.assertEquals(len(multiples_code.particles), 2)

        stopping_condition = multiples_code.stopping_conditions.encounter_detection
        stopping_condition.enable()

        singles = datamodel.Particles()
        singles.add_particles(particles_in_binary)
        singles.add_particle(field_particle)

        singles_energy = singles.kinetic_energy() + singles.potential_energy(
            G=nbody_system.G)
        self.assertAlmostRelativeEquals(initial_energy, singles_energy, 3)

        multiples_code.evolve_model(2 | nbody_system.time)

        final_energy = multiples_code.get_total_energy()
        self.assertTrue(stopping_condition.is_set())
        self.assertAlmostRelativeEquals(initial_energy, final_energy, 7)
示例#7
0
    def test10(self):
        code = Hermite()

        particles_in_binary = self.new_binary(0.1 | nbody_system.mass,
                                              0.1 | nbody_system.mass,
                                              0.01 | nbody_system.length,
                                              keyoffset=1)
        particles_in_binary.radius = 0.001 | nbody_system.length

        encounter_code = encounters.HandleEncounter(
            kepler_code=self.new_kepler(),
            resolve_collision_code=self.new_smalln(),
        )

        encounter_code.parameters.hard_binary_factor = 1
        encounter_code.small_scale_factor = 1

        others = datamodel.Particles(key=[4, 5, 6])
        for i in range(3):
            others[i].position = [i, 0, 0] | nbody_system.length
            others[i].velocity = [0, 0, i] | nbody_system.speed
            others[i].mass = 1 | nbody_system.mass
            others[i].radius = 0.05 | nbody_system.length

        multiples_code = encounters.Multiples(
            gravity_code=code, handle_encounter_code=encounter_code)
        multiples_code.must_handle_one_encounter_per_stopping_condition = False
        multiples_code.singles.add_particles(particles_in_binary)
        multiples_code.singles.add_particles(others)

        multiples_code.commit_particles()
        multiples_code.evolve_model(1 | nbody_system.time)

        self.assertEquals(len(multiples_code.multiples), 1)
        self.assertEquals(len(multiples_code.components_of_multiples), 2)
        self.assertEquals(len(multiples_code.singles), 3)
        self.assertEquals(len(multiples_code.particles), 4)
        self.assertEquals(len(code.particles), 4)

        self.assertEquals(id(multiples_code.singles_in_binaries),
                          id(multiples_code.binaries[0].child1.particles_set))
        self.assertEquals(
            id(multiples_code.components_of_multiples),
            id(multiples_code.multiples[0].components[0].particles_set))
        #multiples_code.singles_in_binaries[0].mass = 0.2 | nbody_system.mass
        print multiples_code.particles.mass
        self.assertAlmostRelativeEquals(multiples_code.particles[-1].mass,
                                        1.1 | nbody_system.mass)
        self.assertAlmostRelativeEquals(multiples_code.particles.mass.sum(),
                                        0.1 + 0.1 + 3.0 | nbody_system.mass)
        multiples_code.update_model()

        self.assertAlmostRelativeEquals(multiples_code.particles[-1].mass,
                                        1.1 | nbody_system.mass)

        index = -1
        if not code.particles[index].mass > 1.0 | nbody_system.mass:
            index = -2
        self.assertAlmostRelativeEquals(code.particles[index].mass,
                                        1.1 | nbody_system.mass)

        multiples_code.singles_in_binaries[0].mass += 0.2 | nbody_system.mass

        multiples_code.update_model()

        self.assertAlmostRelativeEquals(multiples_code.particles[-1].mass,
                                        1.3 | nbody_system.mass)
        self.assertAlmostRelativeEquals(code.particles[index].mass,
                                        1.3 | nbody_system.mass)
示例#8
0
 def new_particle(self, mass):
     particles = datamodel.Particles(len(mass))
     particles.mass = mass
     self.my_particles.add_particles(particles)
     return list(
         range(len(self.my_particles) - len(mass), len(self.my_particles)))
示例#9
0
def merge_clusters_with_gas(sfeff=[0.3, 0.3],
                            Nstar=[1000, 1000],
                            totalNgas=40000,
                            t_end=30. | units.Myr,
                            dt_plot=0.05 | units.Myr,
                            Rscale=units.parsec([0.25, 0.25]),
                            tmerge=2.5 | units.Myr,
                            eps_star=0.001 | units.parsec,
                            runid="runtest",
                            feedback_efficiency=0.01,
                            subvirialfac=1.):

    try:
        os.mkdir(runid)
    except:
        pass
    print "Nstar, Ngas:", Nstar, totalNgas

    eps = 0.05 * Rscale.mean()

    IMF = SalpeterIMF(mass_max=100. | units.MSun)

    mean_star_mass = IMF.mass_mean()

    approx_gas_mass = 0. * mean_star_mass
    for e, N in zip(sfeff, Nstar):
        approx_gas_mass += (1 - e) * N * mean_star_mass / e
    mgas = approx_gas_mass / totalNgas

    print "gas particle mass:", mgas.in_(units.MSun)

    stars = []
    gas = []
    total_mass = 0. | units.MSun
    total_gas_mass = 0. | units.MSun
    total_star_mass = 0. | units.MSun
    for e, Ns, r in zip(sfeff, Nstar, Rscale):
        s, g = generate_cluster_with_gas(IMF,
                                         e,
                                         Ns,
                                         r,
                                         mgas,
                                         subvirialfac=subvirialfac,
                                         t_end=t_end)
        stars.append(s)
        gas.append(g)
        total_mass += s.mass.sum() + g.mass.sum()
        total_star_mass += s.mass.sum()
        total_gas_mass += g.mass.sum()

    print "total mass:", total_mass.in_(units.MSun)
    print "total star mass:", total_star_mass.in_(units.MSun)
    print "total gas mass:", total_gas_mass.in_(units.MSun)

    print "t_end:", t_end

    Rsep = (constants.G * total_mass * tmerge**2)**(1. / 3)

    stars[0].x = stars[0].x - Rsep / 2
    stars[1].x = stars[1].x + Rsep / 2
    gas[0].x = gas[0].x - Rsep / 2
    gas[1].x = gas[1].x + Rsep / 2

    conv = nbody_system.nbody_to_si(total_mass, Rsep)

    print "tmerge:", tmerge
    print "Rsep:", Rsep.in_(units.parsec)

    allgas = datamodel.Particles(0)
    allstars = datamodel.Particles(0)
    allgas.add_particles(gas[0])
    allgas.add_particles(gas[1])
    allstars.add_particles(stars[0])
    allstars.add_particles(stars[1])
    allgas.h_smooth = 0. | units.parsec
    allstars.radius = eps_star

    mu = 1.4 | units.amu
    gamma1 = 1.6667 - 1
    #  print 'min Temp:', (gamma1*min(allgas.u)*(1.4*units.amu)/constants.kB).in_(units.K)
    print 'min Temp:', (gamma1 * min(allgas.u) * mu / constants.kB).in_(
        units.K)

    print max(allgas.u)**0.5

    dt = smaller_nbody_power_of_two(dt_plot, conv)
    dt_star = smaller_nbody_power_of_two(0.001 | units.Myr, conv)  #0.001
    dt_sph = dt_star
    dt_fast = dt_star  # 8
    dt_feedback = dt_fast * 4  # 2

    if not dt_star <= dt_fast <= dt_feedback:
        raise Exception

    print 'dt_plot:', conv.to_nbody(dt_plot), dt_plot.in_(units.Myr)
    print 'dt:', conv.to_nbody(dt), dt.in_(units.Myr)
    print 'dt_feedback:', conv.to_nbody(dt_feedback), dt_feedback.in_(
        units.Myr)
    print 'dt_fast:', conv.to_nbody(dt_fast), dt_fast.in_(units.Myr)
    print 'dt_star:', conv.to_nbody(dt_star), dt_star.in_(units.Myr)
    print 'dt_sph:', conv.to_nbody(dt_sph), dt_sph.in_(units.Myr)

    sys = grav_gas_sse(
        PhiGRAPE,
        Gadget2,
        SSEplus,
        Octgrav,
        conv,
        mgas,
        allstars,
        allgas,
        dt_feedback,
        dt_fast,
        grav_parameters=(["epsilon_squared",
                          eps_star**2], ["timestep_parameter", 0.001]),
        #                                ["timestep", dt_star]),
        gas_parameters=(
            ["time_max", 32. | units.Myr],
            #                               ["courant", 0.15 | units.none],
            ["n_smooth", 64 | units.none],
            #                               ["artificial_viscosity_alpha",1.| units.none],
            ["n_smooth_tol", 0.005 | units.none],
            ## NB
            #                               ["max_size_timestep",7500. | units.yr],
            ## NB
            ["time_limit_cpu", 3600000 | units.s]),
        couple_parameters=(["epsilon_squared", eps**2], ["opening_angle",
                                                         0.5]),
        feedback_efficiency=feedback_efficiency,
        feedback_radius=0.025 * Rscale)

    nsnap = 0
    sys.synchronize_model()
    t = sys.model_time
    tout = t.value_in(units.Myr)
    ek = sys.kinetic_energy.value_in(1.e51 * units.erg)
    ep = sys.potential_energy.value_in(1.e51 * units.erg)
    eth = sys.thermal_energy.value_in(1.e51 * units.erg)
    ef = sys.feedback_energy.value_in(1.e51 * units.erg)
    print 't Ek Ep Eth Ef:', tout, ek, ep, eth, ef, ek + ep + eth - ef
    sys.dump_system_state(runid + "/dump-%6.6i" % nsnap)

    print 'max smooth:', max(sys.sph.gas_particles.radius).in_(units.parsec)
    print 'mean smooth:', sys.sph.gas_particles.radius.mean().in_(units.parsec)
    print 'min smooth:', min(sys.sph.gas_particles.radius).in_(units.parsec)
    print 'eps:', eps.in_(units.parsec)
    print 'feedback radius:', (0.01 * Rscale).in_(units.parsec)

    while (t < t_end - dt / 2):
        sys.evolve_model(t + dt)
        sys.synchronize_model()
        t = sys.model_time
        tout = t.value_in(units.Myr)
        ek = sys.kinetic_energy.value_in(1.e51 * units.erg)
        ep = sys.potential_energy.value_in(1.e51 * units.erg)
        eth = sys.thermal_energy.value_in(1.e51 * units.erg)
        ef = sys.feedback_energy.value_in(1.e51 * units.erg)
        print 't Ek Ep Eth Ef:', tout, ek, ep, eth, ef, ek + ep + eth - ef
        nsnap += 1
        sys.dump_system_state(runid + "/dump-%6.6i" % nsnap)
示例#10
0
    def _run_collision_with_integrator(self, inttype_parameter):
        particles = datamodel.Particles(7)
        particles.mass = 0.001 | nbody_system.mass
        particles.radius = 0.01 | nbody_system.length
        particles.x = [-101.0, -100.0, -0.5, 0.5, 100.0, 101.0, 104.0
                       ] | nbody_system.length
        particles.y = 0 | nbody_system.length
        particles.z = 0 | nbody_system.length
        particles.velocity = [[2, 0, 0], [-2, 0, 0]
                              ] * 3 + [[-4, 0, 0]] | nbody_system.speed

        instance = Huayno()
        instance.parameters.inttype_parameter = inttype_parameter
        instance.particles.add_particles(particles)
        collisions = instance.stopping_conditions.collision_detection
        collisions.enable()
        instance.evolve_model(1.0 | nbody_system.time)

        self.assertTrue(collisions.is_set())
        self.assertTrue(instance.model_time < 0.5 | nbody_system.time)
        self.assertEquals(len(collisions.particles(0)), 3)
        self.assertEquals(len(collisions.particles(1)), 3)
        self.assertEquals(
            len(particles - collisions.particles(0) - collisions.particles(1)),
            1)
        self.assertEquals(
            abs(collisions.particles(0).x - collisions.particles(1).x) <=
            (collisions.particles(0).radius + collisions.particles(1).radius),
            [True, True, True])

        sticky_merged = datamodel.Particles(len(collisions.particles(0)))
        sticky_merged.mass = collisions.particles(
            0).mass + collisions.particles(1).mass
        sticky_merged.radius = collisions.particles(0).radius
        for p1, p2, merged in zip(collisions.particles(0),
                                  collisions.particles(1), sticky_merged):
            merged.position = (p1 + p2).center_of_mass()
            merged.velocity = (p1 + p2).center_of_mass_velocity()

        print instance.model_time
        print instance.particles
        instance.particles.remove_particles(
            collisions.particles(0) + collisions.particles(1))
        instance.particles.add_particles(sticky_merged)

        instance.evolve_model(1.0 | nbody_system.time)
        print
        print instance.model_time
        print instance.particles
        self.assertTrue(collisions.is_set())
        self.assertTrue(instance.model_time < 1.0 | nbody_system.time)
        self.assertEquals(len(collisions.particles(0)), 1)
        self.assertEquals(len(collisions.particles(1)), 1)
        self.assertEquals(
            len(instance.particles - collisions.particles(0) -
                collisions.particles(1)), 2)
        self.assertEquals(
            abs(collisions.particles(0).x - collisions.particles(1).x) <=
            (collisions.particles(0).radius + collisions.particles(1).radius),
            [True])
        instance.stop()
示例#11
0
def add_planets(stars, number_of_planets, converter, cluster_name, Neptune=True, Double=False, write_file=True):
    """
    This is a function created to add planets to a set of stars in a cluster.
    The Function Returns: Nothing. It appends the planets to provided dataset.
    """
    # Creates the empty AMUSE Particle Set for the Planets
    planets = datamodel.Particles(number_of_planets)
    
    # Creates the List of Star Indices that will Host Plantes
    number_of_stars = len(stars)
    select_stars_indices = random.sample(xrange(0, number_of_stars), number_of_planets)
    i = 0
    
    # Creates One Jupiter-Like Planet Around the Each Star in the Subset
    if Neptune:
        for planet  in planets:
            j = select_stars_indices[i]
            planet.id = 5000000 + i + 1
            planet.host_star = stars[j].id
            planet.mass = converter.to_nbody(0.05 | units.MJupiter)
            planet.radius = planet.mass.number | nbody_system.length
            initial_orbit_radius = converter.to_nbody(30 | units.AU)
            planet.x = stars[j].x + initial_orbit_radius
            planet.y = stars[j].y
            planet.z = stars[j].z
            initial_orbit_speed = np.sqrt(stars[j].mass*nbody_system.G/initial_orbit_radius)
            planet.vx = stars[j].vx
            planet.vy = stars[j].vy + initial_orbit_speed
            planet.vz = stars[j].vz
            eulerAngle(planet, stars[j])
            i+=1
        stars.add_particles(planets)
        
    # Creates two Jupiters on Opposite Sides of Each Star in the Subset
    if Double:
        for planet in planets[:number_of_planets/2]:
            j = select_stars_indices[i]
            planet.id = 5000000 + i + 1
            planet.host_star = stars[j].id
            planet.mass = converter.to_nbody(1.0 | units.MJupiter)
            planet.radius = planet.mass.number | nbody_system.length
            initial_orbit_radius = converter.to_nbody(2 | units.AU)
            planet.x = stars[j].x + initial_orbit_radius
            planet.y = stars[j].y
            planet.z = stars[j].z
            initial_orbit_speed = np.sqrt(stars[j].mass*nbody_system.G/initial_orbit_radius)
            planet.vx = stars[j].vx
            planet.vy = stars[j].vy + initial_orbit_speed
            planet.vz = stars[j].vz
            i+=1
        i = 0
        for planet in planets[number_of_planets/2:]:
            j = select_stars_indices[i]
            planet.id = 5000000 + number_of_planets/2+i + 1
            planet.host_star = stars[j].id
            planet.mass = converter.to_nbody(0.053953 | units.MJupiter)
            planet.radius = planet.mass.number | nbody_system.length
            initial_orbit_radius = converter.to_nbody(30 |  units.AU)
            planet.x = stars[j].x - initial_orbit_radius
            planet.y = stars[j].y
            planet.z = stars[j].z
            initial_orbit_speed = np.sqrt(stars[j].mass*nbody_system.G/initial_orbit_radius)
            planet.vx = stars[j].vx
            planet.vy = stars[j].vy - initial_orbit_speed
            planet.vz = stars[j].vz
            i+=1
        stars.add_particles(planets)
    print planets
示例#12
0
    def test17(self):
        print "Testing BHTree collision_detection"
        particles = datamodel.Particles(7)
        particles.mass = 0.001 | nbody_system.mass
        particles.radius = 0.01 | nbody_system.length
        particles.x = [-101.0, -100.0, -0.5, 0.5, 100.0, 101.0, 104.0
                       ] | nbody_system.length
        particles.y = 0 | nbody_system.length
        particles.z = 0 | nbody_system.length
        particles.velocity = [[2, 0, 0], [-2, 0, 0]
                              ] * 3 + [[-4, 0, 0]] | nbody_system.speed

        instance = BHTree(redirection='none')
        instance.initialize_code()
        instance.parameters.set_defaults()

        # Uncommenting any of the following two lines will suppress collision detection
        #~        instance.parameters.use_self_gravity = 0
        #~        instance.parameters.epsilon_squared = 0.0 | nbody_system.length**2

        instance.parameters.opening_angle = 0.1
        instance.particles.add_particles(particles)
        collisions = instance.stopping_conditions.collision_detection
        collisions.enable()
        instance.evolve_model(1.0 | nbody_system.time)

        self.assertTrue(collisions.is_set())
        self.assertTrue(instance.model_time < 0.5 | nbody_system.time)
        self.assertEquals(len(collisions.particles(0)), 3)
        self.assertEquals(len(collisions.particles(1)), 3)
        self.assertEquals(
            len(particles - collisions.particles(0) - collisions.particles(1)),
            1)
        self.assertEquals(
            abs(collisions.particles(0).x - collisions.particles(1).x) <
            (collisions.particles(0).radius + collisions.particles(1).radius),
            [True, True, True])

        sticky_merged = datamodel.Particles(len(collisions.particles(0)))
        sticky_merged.mass = collisions.particles(
            0).mass + collisions.particles(1).mass
        sticky_merged.radius = collisions.particles(0).radius
        for p1, p2, merged in zip(collisions.particles(0),
                                  collisions.particles(1), sticky_merged):
            merged.position = (p1 + p2).center_of_mass()
            merged.velocity = (p1 + p2).center_of_mass_velocity()

        print instance.model_time
        print instance.particles
        instance.particles.remove_particles(
            collisions.particles(0) + collisions.particles(1))
        instance.particles.add_particles(sticky_merged)

        instance.evolve_model(1.0 | nbody_system.time)
        print
        print instance.model_time
        print instance.particles
        self.assertTrue(collisions.is_set())
        self.assertTrue(instance.model_time < 1.0 | nbody_system.time)
        self.assertEquals(len(collisions.particles(0)), 1)
        self.assertEquals(len(collisions.particles(1)), 1)
        self.assertEquals(
            len(instance.particles - collisions.particles(0) -
                collisions.particles(1)), 2)
        self.assertEquals(
            abs(collisions.particles(0).x - collisions.particles(1).x) <
            (collisions.particles(0).radius + collisions.particles(1).radius),
            [True])
        instance.stop()
示例#13
0
def scatter32(init, kep, gravity, treecheck,
              gamma = 1.e-6,
              delta_t = 0 | nbody_system.time,
              t_end = 1.e4 | nbody_system.time):

    # Kepler manages the two-body dynamics.
    # Gravity manages the N-body integration.
    # Treecheck determines the structure of the 3-body system.
    # Treecheck = gravity is OK.

    t1 = clock()		# <----------------- t1 -----------------

    # Create the 3-body system; time = 0 at outer peri.

    #time, id, mass, pos, vel = make_triple(init, kep, gamma)
    time, id, mass, pos, vel = make_triple2(init, kep, gamma)
    
    stars = datamodel.Particles(3)
    stars.id = id
    stars.mass = mass
    stars.position = pos
    stars.velocity = vel
    stars.radius = 0. | nbody_system.length

    #print stars

    print("adding particles")
    sys.stdout.flush()
    gravity.set_time(time)
    gravity.particles.add_particles(stars)
    #print "committing particles"
    #gravity.commit_particles()
    sys.stdout.flush()

    # Channel to copy values from the codes to the set in memory.

    channel = gravity.particles.new_channel_to(stars)
    if treecheck != gravity:
        channel2 = treecheck.particles.new_channel_to(stars)
    else:
        channel2 = channel

    # Don't have a proper unperturbed termination criterion in smallN.
    # For now, insist that the final time exceed minus the initial
    # time (recall that outer peri is at t = 0).

    t_crit = -time
    if delta_t.number <= 0.0: delta_t = 2*t_crit	# for efficiency

    print("evolving triple to completion in steps of", delta_t.number)
    sys.stdout.flush()

    t2 = clock()		# <----------------- t2 -----------------

    dt_init = t2 - t1
    dt_evolve = 0.0
    dt_over = 0.0
    dt_tree = 0.0
    dt_clean = 0.0

    final = Final_state()
    over = 0

    while time < t_end and over == 0:

        tt3 = clock()		# <----------------- tt3 ----------------

        time += delta_t
        gravity.evolve_model(time)

        energy = gravity.get_kinetic_energy()+gravity.get_potential_energy()
        print("time =", time.number, "energy =", energy.number)

        tt4 = clock()		# <----------------- tt4 ----------------

        if time > t_crit:

            # Check to see if the interaction is over.
            # Update the local stars data from the module.
            # Should still be a flat tree, even for SmallN.

            ttt5 = clock()	# <---------------- ttt5 ----------------

            if treecheck != gravity:

                channel.copy()
                channel.copy_attribute("index_in_code", "id")

                # Send the data to the treecheck module and test if the
                # interaction is over.

                treecheck.particles.add_particles(stars)
                treecheck.commit_particles()

            over = treecheck.is_over()

            ttt6 = clock()	# <---------------- ttt6 ----------------

            if over:
                #print '\nscatter32: interaction is over'

	        # The rest of the work is done by treecheck.  Note
                # that we are assuming that the outcomes of gravity
                # and treecheck are qualitatively similar...
                
                treecheck.update_particle_tree()  # builds an internal tree
						  # in the SmallN case
                treecheck.update_particle_set()	  # updates local bookkeeping
                treecheck.particles.synchronize_to(stars)
                channel2.copy()
                channel2.copy_attribute("index_in_code", "id")

		# Determine the final state.

                final = get_final_state(stars, kep)
                final.time = time.number

            ttt7 = clock()	# <---------------- ttt7 ----------------

	    # Clean up treecheck for the next use.

            #treecheck.particles.remove_particles(treecheck.particles)
            treecheck.reset()

            ttt8 = clock()	# <---------------- ttt8 ----------------
    
            dt_over += ttt6 - ttt5
            dt_tree += ttt7 - ttt6
            dt_clean += ttt8 - ttt7

        dt_evolve += tt4 - tt3
 
    if not over:
        #print '\nscatter32: interaction is not over'
        final.is_over = 0
        final.mbinary = -1.0
        final.semimajoraxis = -1.0
        final.eccentricity = -1.0
        final.escaper = -1
        final.mescaper = -1.0
        final.separation = -1.0
        final.v_rel = -1.0

    # Clean up internal data for recycling.
    # Reset children so that the garbage collection can do its work.
    stars.child1 = None
    stars.child2 = None
    gravity.reset()

    return final,numpy.array([dt_init, dt_evolve, dt_over, dt_tree, dt_clean])
示例#14
0
    def new_sets_from_arrays(self):
        offset = 0
        ids_per_set = []
        for x in self.header_struct.Npart:
            ids_per_set.append(self.ids[offset:offset + x])
            offset += x

        if self.ids_are_keys:
            sets = [datamodel.Particles(len(x), keys=x) for x in ids_per_set]
        else:
            sets = [datamodel.Particles(len(x)) for x in ids_per_set]
            for set, x in zip(sets, ids_per_set):
                if len(set) > 0:
                    set.id = x

        offset = 0
        for x in sets:
            length = len(x)
            if length == 0:
                continue

            x.position = nbody_system.length.new_quantity(
                self.positions[offset:offset + length])
            x.velocity = nbody_system.speed.new_quantity(
                self.velocities[offset:offset + length])
            if self.convert_gadget_w_to_velocity:
                x.velocity *= numpy.sqrt(1.0 + self.header_struct.Redshift)
            if not self.pot is None:
                x.potential_energy = nbody_system.energy.new_quantity(
                    self.pot[offset:offset + length])
            if not self.acc is None:
                x.acceleration = nbody_system.acceleration.new_quantity(
                    self.acc[offset:offset + length])
            if not self.dt is None:
                x.timestep = nbody_system.time.new_quantity(
                    self.dt[offset:offset + length])
            offset += length

        offset = 0
        for x, mass in zip(sets, self.header_struct.Massarr):
            length = len(x)
            if length == 0:
                continue
            if mass == 0.0:
                x.mass = nbody_system.mass.new_quantity(
                    self.masses[offset:offset + length])
                offset += length
            else:
                x.mass = nbody_system.mass.new_quantity(mass)

        if self.number_of_gas_particles > 0:
            gas_set = sets[self.GAS]
            unit = (nbody_system.length / nbody_system.time)**2
            gas_set.u = unit.new_quantity(self.u)
            unit = nbody_system.mass / nbody_system.length**3
            if not self.density is None:
                gas_set.rho = unit.new_quantity(self.density)
            if not self.hsml is None:
                gas_set.h_smooth = nbody_system.length.new_quantity(self.hsml)

        return sets
示例#15
0
def scatter3(init,
             kep,
             gravity,
             gamma=1.e-6,
             delta_t=0 | nbody_system.time,
             t_end=1.e4 | nbody_system.time):

    t1 = clock()  # <----------------- t1 -----------------

    # Create the 3-body system; time = 0 at outer periastron.

    #time, id, mass, pos, vel = make_triple(init, kep, gamma)
    time, id, mass, pos, vel = make_triple2(init, kep, gamma)

    stars = datamodel.Particles(3)
    stars.id = id
    stars.mass = mass
    stars.position = pos
    stars.velocity = vel
    stars.radius = 0. | nbody_system.length

    #print stars

    print("adding particles")
    sys.stdout.flush()
    gravity.set_time(time)
    gravity.particles.add_particles(stars)
    #print "committing particles"
    #gravity.commit_particles()
    sys.stdout.flush()

    # Channel to copy values from the code to the set in memory.
    channel = gravity.particles.new_channel_to(stars)

    # Don't have a proper unperturbed termination criterion in smallN.
    # For now, insist that the final time exceed minus the initial
    # time (recall that outer peri is at t = 0).

    t_crit = -time
    if delta_t.number <= 0.0: delta_t = 2 * t_crit  # for efficiency

    print("evolving triple to completion in steps of", delta_t.number)
    sys.stdout.flush()

    t2 = clock()  # <----------------- t2 -----------------

    dt_init = t2 - t1
    dt_evolve = 0.0
    dt_over = 0.0
    dt_tree = 0.0

    final = Final_state()
    over = 0

    while time < t_end and over == 0:

        tt3 = clock()  # <----------------- tt3 ----------------

        time += delta_t
        gravity.evolve_model(time)

        energy = gravity.get_kinetic_energy() + gravity.get_potential_energy()
        print("time =", time.number, "energy =", energy.number)

        tt4 = clock()  # <----------------- tt4 ----------------

        if time > t_crit:

            ttt5 = clock()  # <---------------- ttt5 ----------------

            over = gravity.is_over()

            ttt6 = clock()  # <---------------- ttt6 ----------------

            if over:
                #print '\nscatter3: interaction is over'

                gravity.update_particle_tree()
                gravity.update_particle_set()
                gravity.particles.synchronize_to(stars)
                channel.copy()
                channel.copy_attribute("index_in_code", "id")

                # Determine the final state.

                final = get_final_state(stars, kep)
                final.time = time.number

            ttt7 = clock()  # <---------------- ttt7 ----------------

            dt_over += ttt6 - ttt5
            dt_tree += ttt7 - ttt6

        dt_evolve += tt4 - tt3

    if not over:
        #print '\nscatter3: interaction is not over'
        final.is_over = 0
        final.mbinary = -1.0
        final.semimajoraxis = -1.0
        final.eccentricity = -1.0
        final.escaper = -1
        final.mescaper = -1.0
        final.separation = -1.0
        final.v_rel = -1.0

    # Clean up internal data for recycling.
    # Reset children so that the garbage collection can do its work.
    stars.child1 = None
    stars.child2 = None
    gravity.reset()

    return final, numpy.array([dt_init, dt_evolve, dt_over, dt_tree])
示例#16
0
from amuse.units import units
from amuse.units import nbody_system
from amuse.units.quantities import VectorQuantity
from amuse.plot import (plot, native_plot)


def simulate_massloss(time):
    return units.MSun(0.5 * (1.0 + 1.0 / (1.0 + numpy.exp(
        (time.value_in(time.unit) - 70.0) / 15.))))


if __name__ == "__main__":

    convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU)

    particles = datamodel.Particles(2)
    sun = particles[0]
    sun.mass = 1.0 | units.MSun
    sun.position = [0.0, 0.0, 0.0] | units.AU
    sun.velocity = [0.0, 0.0, 0.0] | units.AU / units.yr
    sun.radius = 1.0 | units.RSun

    earth = particles[1]
    earth.mass = 5.9736e24 | units.kg
    earth.radius = 6371.0 | units.km
    earth.position = [0.0, 1.0, 0.0] | units.AU
    earth.velocity = [2.0 * numpy.pi, -0.0001, 0.0] | units.AU / units.yr

    instance = Hermite(convert_nbody)
    instance.particles.add_particles(particles)
示例#17
0
    def test7(self):
        converter = nbody_system.nbody_to_si(units.MSun, units.parsec)

        code = Hermite(converter)
        stars = datamodel.Particles(keys=(1, 2))
        stars.mass = converter.to_si(1 | nbody_system.mass)
        stars.position = converter.to_si([
            [0, 0, 0],
            [1.1, 0, 0],
        ] | nbody_system.length)
        stars.velocity = converter.to_si([
            [0, 0, 0],
            [-0.5, 1.5, 0],
        ] | nbody_system.speed)
        stars.radius = converter.to_si(0.55 | nbody_system.length)

        encounter_code = encounters.HandleEncounter(
            kepler_code=self.new_kepler_si(),
            resolve_collision_code=self.new_smalln_si(),
            interaction_over_code=None,
            G=constants.G)
        encounter_code.small_scale_factor = 1.0
        encounter_code.parameters.hard_binary_factor = 1
        multiples_code = encounters.Multiples(
            gravity_code=code,
            handle_encounter_code=encounter_code,
            G=constants.G)
        multiples_code.must_handle_one_encounter_per_stopping_condition = False
        multiples_code.singles.add_particles(stars)
        multiples_code.commit_particles()

        stopping_condition = multiples_code.stopping_conditions.encounter_detection
        stopping_condition.enable()

        end_time = converter.to_si(3.0 | nbody_system.time)
        print end_time.as_quantity_in(units.Myr)
        multiples_code.evolve_model(end_time)
        self.assertTrue(stopping_condition.is_set())
        print multiples_code.model_time.as_quantity_in(units.Myr)
        #self.assertAlmostRelativeEquals(multiples_code.model_time , 5.96955 | units.Myr, 4)
        self.assertEquals(len(stopping_condition.particles(0)), 1)
        model = stopping_condition.particles(0)[0]

        self.assertEquals(len(model.particles_before_encounter), 2)
        self.assertEquals(len(model.particles_after_encounter), 2)

        before = model.particles_before_encounter
        after = model.particles_after_encounter

        self.assertAlmostRelativeEquals(before.center_of_mass(),
                                        after.center_of_mass(), 7)
        self.assertAlmostRelativeEquals(before.center_of_mass_velocity(),
                                        after.center_of_mass_velocity(), 7)

        total_energy_before = before.kinetic_energy(
        ) + before.potential_energy(G=constants.G)
        total_energy_after = after.kinetic_energy() + after.potential_energy(
            G=constants.G)

        self.assertAlmostRelativeEquals(total_energy_before,
                                        total_energy_after, 7)
示例#18
0
 def test9(self):
     x = datamodel.Particles(2)
     x.mass = [1.0, 2.0] | units.kg
     self.assertRaises(AmuseException, io.write_set_to_file, x, "test_unit.bogus", "bogus", 
         expected_message = "You tried to load or save a file with fileformat 'bogus'"
             ", but this format is not in the supported formats list")
示例#19
0
    def test9(self):
        code = Hermite()

        particles_in_binary = self.new_binary(0.1 | nbody_system.mass,
                                              0.1 | nbody_system.mass,
                                              0.01 | nbody_system.length,
                                              keyoffset=1)
        particles_in_binary.radius = 0.001 | nbody_system.length

        binary = datamodel.Particle(key=3)
        binary.child1 = particles_in_binary[0]
        binary.child2 = particles_in_binary[1]
        binary.radius = 0.5 | nbody_system.length
        binary.mass = 0.2 | nbody_system.mass
        encounter_code = encounters.HandleEncounter(
            kepler_code=self.new_kepler(),
            resolve_collision_code=self.new_smalln(),
        )

        others = datamodel.Particles(key=[4, 5, 6])
        for i in range(3):
            others[i].position = [i, 0, 0] | nbody_system.length
            others[i].velocity = [0, 0, i] | nbody_system.speed
            others[i].mass = 1 | nbody_system.mass
            others[i].radius = 0 | nbody_system.length

        multiples_code = encounters.Multiples(
            gravity_code=code, handle_encounter_code=encounter_code)
        multiples_code.singles_in_binaries.add_particles(particles_in_binary)
        multiples_code.binaries.add_particle(binary)

        multiples_code.singles.add_particles(others)

        multiples_code.commit_particles()

        self.assertEquals(len(multiples_code.multiples), 1)
        self.assertEquals(len(multiples_code.components_of_multiples), 2)
        self.assertEquals(len(multiples_code.singles), 3)
        self.assertEquals(len(multiples_code.particles), 4)
        self.assertEquals(len(code.particles), 4)

        self.assertAlmostRelativeEquals(multiples_code.particles[-1].mass,
                                        0.2 | nbody_system.mass)
        self.assertAlmostRelativeEquals(code.particles[-1].mass,
                                        0.2 | nbody_system.mass)
        self.assertAlmostRelativeEquals(code.particles[-1].position,
                                        [0, 0, 0] | nbody_system.length, 6)
        self.assertAlmostRelativeEquals(code.particles[-1].velocity,
                                        [0, 0, 0] | nbody_system.speed, 6)

        multiples_code.update_model()
        self.assertAlmostRelativeEquals(multiples_code.particles[-1].mass,
                                        0.2 | nbody_system.mass)
        self.assertAlmostRelativeEquals(code.particles[-1].mass,
                                        0.2 | nbody_system.mass)
        self.assertAlmostRelativeEquals(code.particles[-1].position,
                                        [0, 0, 0] | nbody_system.length, 6)
        self.assertAlmostRelativeEquals(code.particles[-1].velocity,
                                        [0, 0, 0] | nbody_system.speed, 6)

        multiples_code.singles_in_binaries[0].mass = 0.2 | nbody_system.mass

        multiples_code.update_model()

        print code.particles.mass
        self.assertAlmostRelativeEquals(multiples_code.particles[-1].mass,
                                        0.3 | nbody_system.mass)
        self.assertAlmostRelativeEquals(code.particles[-1].mass,
                                        0.3 | nbody_system.mass)
        print code.particles[-1].position
        print code.particles[-1].velocity
        self.assertAlmostRelativeEquals(code.particles[-1].position,
                                        [0.00166666666667, 0, 0]
                                        | nbody_system.length, 6)
        self.assertAlmostRelativeEquals(code.particles[-1].velocity,
                                        [0, 0.7453559925, 0]
                                        | nbody_system.speed, 6)
示例#20
0
 def new_set(self, number_of_items, keys=[]):
     if len(keys) > 0:
         return datamodel.Particles(number_of_items, keys=keys)
     else:
         return datamodel.Particles(number_of_items)
示例#21
0
    def test16(self):
        code = Hermite()

        n = 10
        singles = datamodel.Particles(keys=range(1, n + 1))
        singles.mass = 1 | nbody_system.mass
        for x in range(n):
            singles[x].position = [x * x, 0, 0] | nbody_system.length
        singles.velocity = [0, 0, 0] | nbody_system.speed

        singles.radius = 0.5 | nbody_system.length

        multiples_code = encounters.Multiples(
            gravity_code=code,
            handle_encounter_code=encounters.StickyHandleEncounter())
        multiples_code.singles.add_particles(singles)
        multiples_code.commit_particles()

        multiples_code.evolve_model(1 | nbody_system.time)
        print len(multiples_code.multiples)
        self.assertEquals(len(multiples_code.multiples), 1)
        self.assertEquals(len(multiples_code.particles), 9)
        self.assertEquals(len(multiples_code.singles), 8)
        self.assertEquals(len(multiples_code.binaries), 1)
        self.assertEquals(len(multiples_code.singles_in_binaries), 2)
        self.assertEquals(
            id(multiples_code.components_of_multiples),
            id(multiples_code.multiples[0].components[0].particles_set))
        print multiples_code.multiples[0].components
        io.write_set_to_file(
            (multiples_code.singles, multiples_code.singles_in_binaries,
             multiples_code.binaries, multiples_code.components_of_multiples,
             multiples_code.multiples),
            "multiples.hdf5",
            "hdf5",
            version="2.0",
            names=("singles", "singles_in_binaries", "binaries",
                   "components_of_multiples", "multiples"))

        multiples_code_loaded = encounters.Multiples(
            gravity_code=Hermite(),
            handle_encounter_code=encounters.StickyHandleEncounter())

        (singles, singles_in_binaries, binaries, components_of_multiples,
         multiples) = io.read_set_from_file(
             "multiples.hdf5",
             "hdf5",
             version="2.0",
             names=("singles", "singles_in_binaries", "binaries",
                    "components_of_multiples", "multiples"))
        self.assertEquals(len(multiples), 1)
        self.assertEquals(len(singles), 8)
        self.assertEquals(len(binaries), 1)
        self.assertEquals(len(singles_in_binaries), 2)
        #self.assertEquals(id(components_of_multiples), id(multiples[0].components[0].particles_set))

        multiples_code_loaded.singles.add_particles(singles)
        multiples_code_loaded.singles_in_binaries.add_particles(
            singles_in_binaries)
        multiples_code_loaded.binaries.add_particles(binaries)
        multiples_code_loaded.components_of_multiples.add_particles(
            components_of_multiples)
        multiples_code_loaded.multiples.add_particles(multiples)

        multiples_code_loaded.commit_particles()

        self.assertEquals(len(multiples_code_loaded.multiples), 1)
        self.assertEquals(len(multiples_code_loaded.particles), 9)
        self.assertEquals(len(multiples_code_loaded.singles), 8)
        self.assertEquals(len(multiples_code_loaded.binaries), 1)
        self.assertEquals(len(multiples_code_loaded.singles_in_binaries), 2)
        #self.assertEquals(id(multiples_code_loaded.components_of_multiples), id(multiples_code_loaded.multiples[0].components[0].particles_set))

        multiples_code.evolve_model(4 | nbody_system.time)

        # need to use 3 here as the model_time is reset when doing a restart and we dit not set it after creating Hermite
        multiples_code_loaded.evolve_model(3.0 | nbody_system.time)

        print len(multiples_code.multiples), multiples_code.particles
        print multiples_code.particles.position - multiples_code_loaded.particles.position
        self.assertAlmostRelativeEquals(
            multiples_code.particles.position -
            multiples_code_loaded.particles.position,
            [0, 0, 0] | nbody_system.length)

        for code in [multiples_code, multiples_code_loaded]:
            self.assertEquals(len(code.multiples), 1)
            self.assertEquals(len(code.particles), 8)
            self.assertEquals(len(code.singles), 7)
            self.assertEquals(len(code.binaries), 1)
            self.assertEquals(len(code.singles_in_binaries), 2)
            self.assertEquals(len(code.components_of_multiples), 3)
            self.assertEquals(
                id(code.components_of_multiples),
                id(code.multiples[0].components[0].particles_set))
示例#22
0
 def cleanup_code(self):
     self.particles = datamodel.Particles()