Beispiel #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,
            gpu_id=-1,
            accuracy_parameter=0.1,
            softening_length=-1 | nbody_system.length,
            manage_encounters=1):

    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)

    #print "1"; sys.stdout.flush()

    gpu = 0
    if gpu_worker == 1:
        try:
            gravity = grav(number_of_workers=n_workers,
                           redirection="none",
                           mode="gpu")
            #              debugger='valgrind')
            gpu = 1
        except Exception as ex:
            print '*** GPU worker code not found. Reverting to non-GPU code. ***'
            gpu = 0

    if gpu == 0:
        gravity = grav(number_of_workers=n_workers, redirection="none")
        #              debugger='valgrind')

    #print "2"; sys.stdout.flush()
    gravity.initialize_code()

    #print "3"; sys.stdout.flush()
    gravity.parameters.set_defaults()

    gravity.parameters.gpu_id = gpu_id

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

    #print "4"; sys.stdout.flush()
    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
        if 0:
            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()
        if 0:
            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()

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

    #print "5"; 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

    #print "6"; sys.stdout.flush()
    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, cpu0, wall0 = 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()

    while time < end_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.

        try:
            gravity.update_particle_set()
            gravity.particles.synchronize_to(stars)
        except:
            pass

        # 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 stopping_condition.is_set():
            star1 = stopping_condition.particles(0)[0]
            star2 = stopping_condition.particles(1)[0]
            print '\nstopping condition set at time', \
                gravity.get_time().number,'for:\n'
            print star1
            print ''
            print star2
            print ''
            raise Exception("no encounter handling")

        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('', time, gravity, E0, cpu0, wall0)
        sys.stdout.flush()

    print ''
    gravity.stop()
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()
Beispiel #3
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()
Beispiel #4
0
def make_nbody(number_of_stars=100,
               time=0.0,
               n_workers=1,
               use_gpu=1,
               gpu_worker=1,
               salpeter=0,
               delta_t=1.0 | nbody_system.time,
               timestep_parameter=0.1,
               softening_length=0.0 | nbody_system.length,
               random_seed=1234):

    # Make an N-body system, print out some statistics on it, and save
    # it in a restart file.  The restart file name is of the form
    # 't=nnnn.n.xxx', where the default time is 0.0.

    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

    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()

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

    # Make a standard N-body system.

    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'
        mmin = 0.5 | nbody_system.mass
        mmax = 10.0 | nbody_system.mass
        scaled_mass = new_salpeter_mass_distribution_nbody(number_of_stars,
                                                           mass_min=mmin,
                                                           mass_max=mmax)

    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)

    # 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 isolate encounters better, but also place more
    # load on the large-N dynamical module.

    stars.radius = 0.5 * 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

        softening_length = 0.5*float(number_of_stars)**(-0.3333333) \
    | nbody_system.length
    print 'softening length =', softening_length

    gravity.parameters.timestep_parameter = timestep_parameter
    gravity.parameters.epsilon_squared = softening_length * softening_length
    gravity.parameters.use_gpu = use_gpu

    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
    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()

    # -----------------------------------------------------------------
    # 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_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

    # Take a dummy step, just in case...

    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")

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

    # file = 't='+'{:07.2f}'.format(time.number)        # fails in Python 2.6
    file = 't=%07.2f' % time.number
    write_state_to_file(time, stars, gravity, multiples_code, file, delta_t,
                        E0, cpu0)
    tree_copy = multiples_code.root_to_tree.copy()

    del multiples_code
    sys.stdout.flush()

    gravity.stop()
    kep.stop()
    stop_smalln()
    print ''
Beispiel #5
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()
Beispiel #6
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, gpu_id = -1,
             accuracy_parameter = 0.1,
             softening_length = -1 | nbody_system.length,
             manage_encounters = 1):

    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)

    #print "1"; sys.stdout.flush()
    
    gpu = 0
    if gpu_worker == 1:
        try:
            gravity = grav(number_of_workers = n_workers,
                           redirection = "none", mode = "gpu")
            #              debugger='valgrind')
            gpu = 1
        except Exception as ex:
            print '*** GPU worker code not found. Reverting to non-GPU code. ***'
            gpu = 0

    if gpu == 0:
        gravity = grav(number_of_workers = n_workers,
                       redirection = "none")
        #              debugger='valgrind')

    #print "2"; sys.stdout.flush()
    gravity.initialize_code()

    #print "3"; sys.stdout.flush()
    gravity.parameters.set_defaults()

    gravity.parameters.gpu_id = gpu_id

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

    #print "4"; sys.stdout.flush()
    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
        if 0:
            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()
        if 0:
            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()

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

    #print "5"; 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

    #print "6"; sys.stdout.flush()
    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,cpu0,wall0 = 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()
    
    while time < end_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.

        try:
            gravity.update_particle_set()
            gravity.particles.synchronize_to(stars)
        except:
            pass
    
        # 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 stopping_condition.is_set():
            star1 = stopping_condition.particles(0)[0]
            star2 = stopping_condition.particles(1)[0]
            print '\nstopping condition set at time', \
                gravity.get_time().number,'for:\n'
            print star1
            print ''
            print star2
            print ''
            raise Exception("no encounter handling")

        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('', time, gravity, E0, cpu0, wall0)
        sys.stdout.flush()

    print ''
    gravity.stop()
Beispiel #7
0
def run_ph4(initial_file=None,
            end_time=0 | nbody_system.time,
            input_delta_t=0.0 | nbody_system.time,
            input_Delta_t=1.0 | nbody_system.time,
            input_timestep_parameter=0.0,
            input_softening_length=-1.0 | nbody_system.length,
            n_workers=1,
            use_gpu=1,
            gpu_worker=1,
            use_multiples=True,
            save_restart=False,
            strict_restart=False):

    # Read an N-body system from a file and run it to the specified
    # time using the specified steps.  Print log information and
    # optionally save a restart file after every step.  If the
    # specified time is less than the time in the initial file, don't
    # take a step, but still print out the log info.  (Hence run_ph4
    # also functions like Starlab sys_stats.)

    print "initial_file =", initial_file
    print "end_time =", end_time.number
    print "n_workers =", n_workers
    print "use_gpu =", use_gpu
    print "use_multiples =", use_multiples
    print "save_restart =", save_restart
    print "strict_restart =", strict_restart
    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()

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

    stars, time, delta_t, E0, cpu0, multiples_code \
         = read_state_from_file(initial_file, gravity, kep)

    # Allow overrides of the restored data (OK for delta_t, NOT
    # recommended for timestep_parameter or softening_length).  Note
    # that reading the state also commits the particles, and hence
    # calculates the initial time steps.  Probably should reinitialize
    # if timestep_parameter or softening_length are changed.  TODO

    if input_delta_t.number > 0:
        if input_delta_t != delta_t:
            print 'modifying delta_t from stored', delta_t, \
    'to input', input_delta_t
            delta_t = input_delta_t
    else:
        print "using stored delta_t =", delta_t

    print input_timestep_parameter
    print gravity.parameters.timestep_parameter

    if input_timestep_parameter > 0:
        if input_timestep_parameter != gravity.parameters.timestep_parameter:
            print 'modifying timestep_parameter from stored', \
               gravity.parameters.timestep_parameter, \
    'to input', input_timestep_parameter
            gravity.parameters.timestep_parameter \
  = input_timestep_parameter
    else:
        print 'timestep_parameter =', gravity.parameters.timestep_parameter

    if input_softening_length.number >= 0:
        if input_softening_length*input_softening_length \
  != gravity.parameters.epsilon_squared:
            print 'modifying softening_length from stored', \
               gravity.parameters.epsilon_squared.sqrt(), \
    'to input', input_softening_length
            gravity.parameters.epsilon_squared \
                = softening_length*softening_length
    else:
        print 'softening length =', gravity.parameters.epsilon_squared.sqrt()

    gravity.parameters.use_gpu = use_gpu
    gravity.parameters.begin_time = time

    if 0:
        print ''
        print gravity.parameters.begin_time
        print stars.mass
        #print stars.position
        for s in stars:
            print '%.18e %.18e %.18e' % (s.x.number, s.y.number, s.z.number)
        print stars.velocity

    channel = gravity.particles.new_channel_to(stars)

    if use_multiples:
        stopping_condition = gravity.stopping_conditions.collision_detection
        stopping_condition.enable()

    gravity.parameters.force_sync = 1  # end exactly at the specified time

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

    tsave = time + Delta_t
    save_file = ''

    while time < end_time:

        time += delta_t
        multiples_code.evolve_model(time)  #, callback=handle_callback)

        # 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")

        # Write log information.

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

        # Optionally create a restart file.

        if save_restart and time >= tsave:
            #save_file = 't='+'{:07.2f}'.format(time.number) # not in Python 2.6
            save_file = 't=%07.2f' % time.number
            write_state_to_file(time, stars, gravity, multiples_code,
                                save_file, delta_t, E0, cpu0)
            sys.stdout.flush()
            tsave += Delta_t
            if strict_restart: break

    gravity.stop()
    kep.stop()
    stop_smalln()

    return time, save_file
def make_nbody(number_of_stars = 100, time = 0.0,
               n_workers = 1, use_gpu = 1, gpu_worker = 1,
               salpeter = 0,
               delta_t = 1.0 | nbody_system.time,
               timestep_parameter = 0.1,
               softening_length = 0.0 | nbody_system.length,
               random_seed = 1234):

    # Make an N-body system, print out some statistics on it, and save
    # it in a restart file.  The restart file name is of the form
    # 't=nnnn.n.xxx', where the default time is 0.0.

    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

    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()

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

    # Make a standard N-body system.

    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'
        mmin = 0.5 | nbody_system.mass
        mmax = 10.0 | nbody_system.mass
        scaled_mass = new_salpeter_mass_distribution_nbody(number_of_stars,
                                                           mass_min = mmin,
                                                           mass_max = mmax)
        
    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)

    # 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 isolate encounters better, but also place more
    # load on the large-N dynamical module.

    stars.radius = 0.5*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

        softening_length = 0.5*float(number_of_stars)**(-0.3333333) \
				| nbody_system.length
    print 'softening length =', softening_length

    gravity.parameters.timestep_parameter = timestep_parameter
    gravity.parameters.epsilon_squared = softening_length*softening_length
    gravity.parameters.use_gpu = use_gpu

    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
    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()

    # -----------------------------------------------------------------
    # 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_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

    # Take a dummy step, just in case...

    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")

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

    # file = 't='+'{:07.2f}'.format(time.number)        # fails in Python 2.6
    file = 't=%07.2f'%time.number
    write_state_to_file(time, stars, gravity, multiples_code,
                        file, delta_t, E0, cpu0)
    tree_copy = multiples_code.root_to_tree.copy()

    del multiples_code
    sys.stdout.flush()

    gravity.stop()
    kep.stop()
    stop_smalln()
    print ''
Beispiel #9
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, gpu_id = -1,
             accuracy_parameter = 0.1,
             softening_length = -1 | nbody_system.length,
             manage_encounters = 1):

    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 "initializing the gravity module"
    sys.stdout.flush()

    # Note that there are actually really 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)

    #print "1"; sys.stdout.flush()
    
    gpu = 0
    if gpu_worker == 1:
        try:
            gravity = grav(number_of_workers = n_workers,
                           redirection = "none", mode = "gpu")
            #              debugger='valgrind')
            gpu = 1
        except Exception as ex:
            print \
                '*** GPU worker code not found. Reverting to non-GPU code. ***'
            gpu = 0

    if gpu == 0:
        gravity = grav(number_of_workers = n_workers,
                       redirection = "none")
        #              debugger='valgrind')

    #print "2"; sys.stdout.flush()
    gravity.initialize_code()

    #print "3"; sys.stdout.flush()
    gravity.parameters.set_defaults()

    gravity.parameters.gpu_id = gpu_id

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

    #print "4"; sys.stdout.flush()

    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
    if 0:
        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()
    if 0:
        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()

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

    #print "5"; 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

    #print "6"; sys.stdout.flush()
    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
    sys.stdout.flush()

    E0,cpu0,wall0 = 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()

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

    cpu0 = cputime()
    t0 = 0.
    pi = math.pi
    times = [1., 2., pi, 4*pi/3, 5., 2*pi, 2*pi + pi/100,
             2*pi + pi/5, 7., 8., 3*pi, 10.]

    gravity.parameters.force_sync = 1	# stays set until explicitly unset

    for t in times:
        time = t|nbody_system.time

        print "\nEvolving to time", time
        sys.stdout.flush()

        gravity.parameters.block_steps = 0
        gravity.parameters.total_steps = 0
        gravity.evolve_model(time)

        dt = t - t0
        t0 = t
        cpu = cputime()
        dcpu = cpu - cpu0
        cpu0 = cpu

        # 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.

        try:
            gravity.update_particle_set()
            gravity.particles.synchronize_to(stars)
        except:
            pass
    
        # 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 stopping_condition.is_set():
            star1 = stopping_condition.particles(0)[0]
            star2 = stopping_condition.particles(1)[0]
            print '\nstopping condition set at time', \
                gravity.get_time().number,'for:\n'
            print star1
            print ''
            print star2
            print ''
            raise Exception("no encounter handling")

        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('', time, gravity, E0, cpu0, wall0)

        print '@@@'
        print '@@@ t =', time.number, ' dt =', dt
        print '@@@ sync_time =', gravity.parameters.sync_time.number
        print '@@@ dcpu/dt =', dcpu/dt
        nb = gravity.parameters.block_steps
        ns = gravity.parameters.total_steps
        print '@@@ d(block_steps) =', nb, ' #/dt =', nb/dt
        print '@@@ d(total steps) =', ns, ' #/dt =', ns/dt

        #print stars
        sys.stdout.flush()

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

    print ''
    gravity.stop()
Beispiel #10
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()
Beispiel #11
0
def GetValues(cluster_name,
              num_workers=1,
              use_gpu=1,
              gpu_ID=0,
              eps2=0.0 | nbody_system.length**2,
              delta_t=0.05 | nbody_system.time):

    # This function uses calls upon the restart fuction to reload the multiples from the simulation to use
    # the multiples function to get the Energy and it correction, num_files can probably be replaced if we
    # can measure how many files are in a cluster, maybe glob.glob can do that.

    # This function returns the arrays below:
    Energy = []
    UncorrectedEnergy = []
    Time = []
    Kinetic = []
    Potential = []
    L = []
    P = []

    i = 0

    # You will need to change the File Path varibale to run this on anyone else's account
    file_path = "/home/draco/jthornton/Tycho/Restart/"
    file_loc = file_path + cluster_name
    search = glob.glob(file_loc + "*.hdf5")

    for key in search:
        if i % 2 == 0:
            # This loop will go through the restart files of the cluster and append energy and momentum values to the corresponding arrays
            # First get the restart naming correct

            restart_file = key[:-11]
            # Second retrieve the timestep from the file and convert it to a float
            time_grab = []
            time_grab = key.split("_")
            time = float(time_grab[2]) | nbody_system.time
            if use_gpu == 1:
                gravity = ph4(number_of_workers=num_workers,
                              redirection="none",
                              mode="gpu")
            else:
                gravity = grav(number_of_workers=num_workers,
                               redirection="none")

# Initializing PH4 with Initial Conditions
            print "Initializing gravity"
            gravity.initialize_code()
            gravity.parameters.set_defaults()
            gravity.parameters.begin_time = time
            gravity.parameters.epsilon_squared = eps2
            gravity.parameters.timestep_parameter = delta_t.number

            # Setting up the Code to Run with GPUs Provided by Command Line
            gravity.parameters.use_gpu = use_gpu
            gravity.parameters.gpu_id = gpu_ID

            # Initializing Kepler and SmallN
            print "Initializing Kepler"
            kep = Kepler(None, redirection="none")
            kep.initialize_code()
            print "Initializing SmallN"
            util.init_smalln()
            MasterSet = []
            print "Retrieving data"

            MasterSet, multiples_code = read.read_state_from_file(
                restart_file, gravity, kep, util.new_smalln())

            # Setting Up the Stopping Conditions in PH4
            stopping_condition = gravity.stopping_conditions.collision_detection
            stopping_condition.enable()
            sys.stdout.flush()

            # Starting the AMUSE Channel for PH4
            grav_channel = gravity.particles.new_channel_to(MasterSet)

            print "Reload Successful"

            U = multiples_code.potential_energy
            T = multiples_code.kinetic_energy
            Etop = T + U

            print "T: "
            print T
            print "U: "
            print U

            angular_momentum = MasterSet.total_angular_momentum()
            momentum = MasterSet.total_momentum()

            Nmul, Nbin, Emul = multiples_code.get_total_multiple_energy()
            tmp1, tmp2, Emul2 = multiples_code.get_total_multiple_energy2()
            Etot = Etop + Emul
            Eext = multiples_code.multiples_external_tidal_correction
            Eint = multiples_code.multiples_internal_tidal_correction
            Eerr = multiples_code.multiples_integration_energy_error
            Edel = multiples_code.multiples_external_tidal_correction \
                + multiples_code.multiples_internal_tidal_correction \
                    + multiples_code.multiples_integration_energy_error
            Ecor = Etot - Edel
            print "Ecor: "
            print Ecor

            gravity.stop()
            kep.stop()
            util.stop_smalln()

            Energy.append(Ecor.number)
            UncorrectedEnergy.append(Etop.number)
            Time.append(time.number)
            Kinetic.append(T.number)
            Potential.append(U.number)
            L.append(angular_momentum.number)
            P.append(momentum.number)

        i += 1

    return Energy, UncorrectedEnergy, Time, Kinetic, Potential, L, P
Beispiel #12
0
add_planets(objects, number_of_planets, kc_converter, cluster_name, Neptune=True, Double=False)

# Defining Initial Conditions for PH4
time = 0.0 | nbody_system.time
delta_t = options.dt | nbody_system.time
number_of_steps = options.num_steps
end_time = number_of_steps*delta_t
num_workers = 1
eps2 = 0.0 | nbody_system.length**2
use_gpu = options.use_gpu
gpu_ID = options.gpu_ID

# Setting PH4 as the Top-Level Gravity Code
if use_gpu == 1:
	try:
		gravity = grav(number_of_workers = num_workers, redirection = "none", mode = "gpu")
	except Exception as ex:
		gravity = grav(number_of_workers = num_workers, redirection = "none")
        print "*** GPU worker code not found. Reverting to non-GPU code. ***"
else:
	gravity = grav(number_of_workers = num_workers, redirection = "none")

# Initializing PH4 with Initial Conditions
gravity.initialize_code()
gravity.parameters.set_defaults()
gravity.parameters.begin_time = time
gravity.parameters.epsilon_squared = eps2
gravity.parameters.timestep_parameter = delta_t.number

# Setting up the Code to Run with GPUs Provided by Command Line
gravity.parameters.use_gpu = use_gpu