Exemple #1
0
def evolve_coupled_system(binary_system, giant_system, t_end, n_steps, 
        do_energy_evolution_plot, previous_data=None):
    directsum = CalculateFieldForParticles(particles=giant_system.particles, gravity_constant=constants.G)
    directsum.smoothing_length_squared = giant_system.parameters.gas_epsilon**2
    coupled_system = Bridge(timestep=(t_end / (2 * n_steps)), verbose=False, use_threading=True)
    coupled_system.add_system(binary_system, (directsum,), False)
    coupled_system.add_system(giant_system, (binary_system,), False)
    
    times = (t_end * list(range(1, n_steps+1)) / n_steps).as_quantity_in(units.day)
    
    if previous_data:
        with open(previous_data, 'rb') as file:
            (all_times, potential_energies, kinetic_energies, thermal_energies, 
                giant_center_of_mass, ms1_position, ms2_position, 
                giant_center_of_mass_velocity, ms1_velocity, ms2_velocity) = pickle.load(file)
        all_times.extend(times + all_times[-1])
    else:
        all_times = times
        if do_energy_evolution_plot:
            potential_energies = coupled_system.particles.potential_energy().as_vector_with_length(1).as_quantity_in(units.erg)
            kinetic_energies = coupled_system.particles.kinetic_energy().as_vector_with_length(1).as_quantity_in(units.erg)
            thermal_energies = coupled_system.gas_particles.thermal_energy().as_vector_with_length(1).as_quantity_in(units.erg)
        else:
            potential_energies = kinetic_energies = thermal_energies = None
        
        giant_center_of_mass = [] | units.RSun
        ms1_position = [] | units.RSun
        ms2_position = [] | units.RSun
        giant_center_of_mass_velocity = [] | units.km / units.s
        ms1_velocity = [] | units.km / units.s
        ms2_velocity = [] | units.km / units.s
    i_offset = len(giant_center_of_mass)
    
    giant_total_mass = giant_system.particles.total_mass()
    ms1_mass = binary_system.particles[0].mass
    ms2_mass = binary_system.particles[1].mass
    
    print("   Evolving for", t_end)
    for i_step, time in enumerate(times):
        coupled_system.evolve_model(time)
        print("   Evolved to:", time, end=' ')
        
        if do_energy_evolution_plot:
            potential_energies.append(coupled_system.particles.potential_energy())
            kinetic_energies.append(coupled_system.particles.kinetic_energy())
            thermal_energies.append(coupled_system.gas_particles.thermal_energy())
        
        giant_center_of_mass.append(giant_system.particles.center_of_mass())
        ms1_position.append(binary_system.particles[0].position)
        ms2_position.append(binary_system.particles[1].position)
        giant_center_of_mass_velocity.append(giant_system.particles.center_of_mass_velocity())
        ms1_velocity.append(binary_system.particles[0].velocity)
        ms2_velocity.append(binary_system.particles[1].velocity)

        a_giant, e_giant = calculate_orbital_elements(ms1_mass, ms2_mass,
                                                      ms1_position, ms2_position,
                                                      ms1_velocity, ms2_velocity,
                                                      giant_total_mass,
                                                      giant_center_of_mass,
                                                      giant_center_of_mass_velocity)
        print("Outer Orbit:", time.in_(units.day),  a_giant[-1].in_(units.AU), e_giant[-1], ms1_mass.in_(units.MSun), ms2_mass.in_(units.MSun), giant_total_mass.in_(units.MSun))
        
        if i_step % 10 == 9:
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=04}_gas.amuse".format(i_step + i_offset))
            write_set_to_file(giant_system.gas_particles, snapshotfile, format='amuse')
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=04}_core.amuse".format(i_step + i_offset))
            write_set_to_file(giant_system.dm_particles, snapshotfile, format='amuse')
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=04}_binary.amuse".format(i_step + i_offset))
            write_set_to_file(binary_system.particles, snapshotfile, format='amuse')
            
            datafile = os.path.join("snapshots", "hydro_triple_{0:=04}_info.amuse".format(i_step + i_offset))
            with open(datafile, 'wb') as outfile:
                pickle.dump((all_times[:len(giant_center_of_mass)], potential_energies, 
                    kinetic_energies, thermal_energies, giant_center_of_mass, 
                    ms1_position, ms2_position, giant_center_of_mass_velocity,
                    ms1_velocity, ms2_velocity), outfile)
       
        figname1 = os.path.join("plots", "hydro_triple_small{0:=04}.png".format(i_step + i_offset))
        figname2 = os.path.join("plots", "hydro_triple_large{0:=04}.png".format(i_step + i_offset))
        print("  -   Hydroplots are saved to: ", figname1, "and", figname2)
        for plot_range, plot_name in [(8|units.AU, figname1), (40|units.AU, figname2)]:
            if HAS_PYNBODY:
                pynbody_column_density_plot(coupled_system.gas_particles, width=plot_range, vmin=26, vmax=32)
                scatter(coupled_system.dm_particles.x, coupled_system.dm_particles.y, c="w")
            else:
                pyplot.figure(figsize = [16, 16])
                sph_particles_plot(coupled_system.gas_particles, gd_particles=coupled_system.dm_particles, 
                    view=plot_range*[-0.5, 0.5, -0.5, 0.5])
            pyplot.savefig(plot_name)
            pyplot.close()
        
    
    coupled_system.stop()
    
    make_movie()
    
    if do_energy_evolution_plot:
        energy_evolution_plot(all_times[:len(kinetic_energies)-1], kinetic_energies, 
            potential_energies, thermal_energies)
    
    print("   Calculating semimajor axis and eccentricity evolution for inner binary")
    # Some temporary variables to calculate semimajor_axis and eccentricity evolution
    total_mass = ms1_mass + ms2_mass
    rel_position = ms1_position - ms2_position
    rel_velocity = ms1_velocity - ms2_velocity
    separation_in = rel_position.lengths()
    speed_squared_in = rel_velocity.lengths_squared()
    
    # Now calculate the important quantities:
    semimajor_axis_binary = (constants.G * total_mass * separation_in / 
        (2 * constants.G * total_mass - separation_in * speed_squared_in)).as_quantity_in(units.AU)
    eccentricity_binary = numpy.sqrt(1.0 - (rel_position.cross(rel_velocity)**2).sum(axis=1) / 
        (constants.G * total_mass * semimajor_axis_binary))

    print("   Calculating semimajor axis and eccentricity evolution of the giant's orbit")
    # Some temporary variables to calculate semimajor_axis and eccentricity evolution
    rel_position = ((ms1_mass * ms1_position + ms2_mass * ms2_position)/total_mass - 
        giant_center_of_mass)
    rel_velocity = ((ms1_mass * ms1_velocity + ms2_mass * ms2_velocity)/total_mass - 
        giant_center_of_mass_velocity)
    total_mass += giant_total_mass
    separation = rel_position.lengths()
    speed_squared = rel_velocity.lengths_squared()
    
    # Now calculate the important quantities:
    semimajor_axis_giant = (constants.G * total_mass * separation / 
        (2 * constants.G * total_mass - separation * speed_squared)).as_quantity_in(units.AU)
    eccentricity_giant = numpy.sqrt(1.0 - (rel_position.cross(rel_velocity)**2).sum(axis=1) / 
        (constants.G * total_mass * semimajor_axis_giant))
    
    orbit_parameters_plot(semimajor_axis_binary, semimajor_axis_giant, all_times[:len(semimajor_axis_binary)])
    orbit_ecc_plot(eccentricity_binary, eccentricity_giant, all_times[:len(eccentricity_binary)])
    
    orbit_parameters_plot(separation_in.as_quantity_in(units.AU), 
        separation.as_quantity_in(units.AU), 
        all_times[:len(eccentricity_binary)], 
        par_symbol="r", par_name="separation")
    orbit_parameters_plot(speed_squared_in.as_quantity_in(units.km**2 / units.s**2), 
        speed_squared.as_quantity_in(units.km**2 / units.s**2), 
        all_times[:len(eccentricity_binary)], 
        par_symbol="v^2", par_name="speed_squared")
Exemple #2
0
    # Increase the Step Counter
        step_index += 1
    # Log that a Step was Taken
        print '\n-------------'
        print '[UPDATE] Step Taken at %s!' %(tp.strftime("%Y/%m/%d-%H:%M:%S", tp.gmtime()))
        print '-------------\n'
        sys.stdout.flush()
    
# Log that the Simulation Ended & Switch to Terminal Output
    print '\n[UPDATE] Run Finished at %s! \n' %(tp.strftime("%Y/%m/%d-%H:%M:%S", tp.gmtime()))
    sys.stdout = orig_stdout
    f.close()

# Pickle the Final Encounter Information Dictionary
    encounter_file = open("Encounters/"+cluster_name+"_encounters.pkl", "wb")
    pickle.dump(encounterInformation, encounter_file)
    encounter_file.close()

# Alerts the Terminal User that the Run has Ended!
    print '\n[UPDATE] Run Finished at %s! \n' %(tp.strftime("%Y/%m/%d-%H:%M:%S", tp.gmtime()))
    sys.stdout.flush()
    print_diagnostics(multiples_code, E0)

# Closes PH4, Kepler & SmallN Instances
    sev_code.stop()
    gravity.stop()
    kep.stop()
    util.stop_smalln()
    bridge_code.stop()
Exemple #3
0
            stars.stellar_mass += stars.initial_disk_mass - new_mass
            stars.initial_disk_mass = new_mass
            stars.viscous_timescale *= (np.divide(
                new_radius,
                stars.initial_characteristic_disk_radius))**(2 - gamma)
            stars.initial_characteristic_disk_radius = new_radius
            stars.last_encounter = t + t_ini

            write_set_to_file(
                stars, '{0}/R{1}_{2}.hdf5'.format(
                    path, Rvir.value_in(units.parsec),
                    int((t + t_ini).value_in(units.yr))), 'amuse')

    if gas_presence or gas_expulsion:
        gas_gravity.stop()

    gravity.stop()
    E_handle.close()
    Q_handle.close()


def new_option_parser():
    """ Parses command line input for code.
    """
    from amuse.units.optparse import OptionParser

    result = OptionParser()

    # Cluster parameters
    result.add_option("-N",
Exemple #4
0
class GravityHydroStellar(object):
    def __init__(self,
                 gravity,
                 hydro,
                 stellar,
                 gravity_to_hydro,
                 hydro_to_gravity,
                 time_step_bridge,
                 time_step_feedback,
                 feedback_gas_particle_mass,
                 feedback_efficiency=0.01,
                 feedback_radius=0.01 | units.parsec,
                 verbose=True):
        self.gravity = gravity
        self.hydro = hydro
        self.stellar = stellar
        self.gravity_to_hydro = gravity_to_hydro
        self.hydro_to_gravity = hydro_to_gravity

        self.time_step_bridge = time_step_bridge
        self.time_step_feedback = time_step_feedback
        self.feedback_gas_particle_mass = feedback_gas_particle_mass

        self.feedback_efficiency = feedback_efficiency
        self.feedback_radius = feedback_radius
        self.verbose = verbose

        self.bridge = Bridge(verbose=verbose,
                             timestep=self.time_step_bridge,
                             use_threading=False)
        self.bridge.add_system(self.hydro, (self.gravity_to_hydro, ))
        self.bridge.add_system(self.gravity, (self.hydro_to_gravity, ))

        self.star_particles = self.stars_with_mechanical_luminosity(
            self.stellar.particles)
        self.total_feedback_energy = zero
        self.current_time = 0.0 | units.Myr

    def stars_with_mechanical_luminosity(self, particles):
        result = ParticlesOverlay(particles)

        def lmech_function(temperature, mass, luminosity, radius):
            T = temperature.value_in(units.K)
            M = mass.value_in(units.MSun)
            L = luminosity.value_in(units.LSun)
            R = radius.value_in(units.RSun)

            # Reimers wind below 8000K
            mass_loss = (4.0e-13 | units.MSun / units.yr) * L * R / M
            # ... wind above 8000K
            i = numpy.where(temperature > 8000 | units.K)[0]
            mass_loss[i] = (10**-24.06 | units.MSun / units.yr) * (
                L**2.45 * M**(-1.1) * T.clip(1000, 8.0e4)**(1.31))

            t4 = numpy.log10(T * 1.0e-4).clip(0.0, 1.0)
            v_terminal = (30 + 4000 * t4) | units.km / units.s
            return 0.5 * mass_loss * v_terminal**2

        result.add_calculated_attribute(
            "mechanical_luminosity",
            lmech_function,
            attributes_names=["temperature", "mass", "luminosity", "radius"])
        result.L_mech = result.mechanical_luminosity
        result.E_mech = (0.0 | units.Myr) * result.L_mech
        result.E_mech_last_feedback = result.E_mech
        result.previous_mass = result.mass  # Store the mass of the star at the last moment of feedback
        return result

    def evolve_model(self, end_time):
        while self.current_time < end_time - 0.5 * self.time_step_feedback:
            self.current_time += self.time_step_feedback
            if self.verbose:
                time_begin = time.time()
                print
                print "GravityHydroStellar: Start evolving..."
            self.bridge.evolve_model(self.current_time)
            self.stellar.evolve_model(self.current_time)
            if self.verbose:
                print "GravityHydroStellar: Evolved to:", self.current_time
                model_times = [
                    getattr(self, code).model_time.as_quantity_in(units.Myr)
                    for code in ["stellar", "bridge", "gravity", "hydro"]
                ]
                print "   (Stellar: {0}, Bridge: {1}, Gravity: {2}, Hydro: {3})".format(
                    *model_times)
                print "GravityHydroStellar: Call mechanical_feedback"
            self.mechanical_feedback(self.time_step_feedback)
            if self.verbose:
                print "GravityHydroStellar: store system state"
            self.store_system_state()
            if self.verbose:
                print "GravityHydroStellar: Iteration took {0} seconds.".format(
                    time.time() - time_begin)

    def mechanical_feedback(self, time_step):
        L_mech_new = self.star_particles.mechanical_luminosity
        self.star_particles.E_mech += time_step * 0.5 * (
            self.star_particles.L_mech + L_mech_new)
        self.star_particles.L_mech = L_mech_new
        self.star_particles.dmass = self.star_particles.previous_mass - self.star_particles.mass
        self.star_particles.n_feedback_particles = numpy.array(
            self.star_particles.dmass /
            self.feedback_gas_particle_mass).astype(int)

        losers = self.star_particles.select_array(lambda x: x > 0,
                                                  ["n_feedback_particles"])
        if self.verbose:
            print "GravityHydroStellar: Number of particles providing mechanical feedback during this step:", len(
                losers)
        if len(losers) == 0:
            return
        channel = self.gravity.particles.new_channel_to(losers)
        channel.copy_attributes(["x", "y", "z", "vx", "vy", "vz"])
        number_of_new_particles = losers.n_feedback_particles.sum()
        new_sph_all = Particles(number_of_new_particles)
        new_sph_all.mass = self.feedback_gas_particle_mass
        new_sph_all.h_smooth = 0.0 | units.parsec
        offsets = self.draw_random_position_offsets(number_of_new_particles)

        i = 0
        for loser in losers:
            i_next = i + loser.n_feedback_particles
            new = new_sph_all[i:i_next]
            new.position = loser.position + offsets[i:i_next]
            new.velocity = loser.velocity
            new.u = self.feedback_efficiency * (
                loser.E_mech - loser.E_mech_last_feedback) / loser.dmass
            i = i_next

        losers.previous_mass -= self.feedback_gas_particle_mass * losers.n_feedback_particles
        losers.E_mech_last_feedback = losers.E_mech
        channel = losers.new_channel_to(self.gravity.particles)
        channel.copy_attribute("previous_mass", "mass")
        if self.verbose:
            print "GravityHydroStellar: New SPH particles:"
            print new_sph_all
        self.hydro.gas_particles.add_particles(new_sph_all)
        self.total_feedback_energy += (new_sph_all.mass * new_sph_all.u).sum()

    def draw_random_position_offsets(self, number_of_new_particles):
        r = numpy.random.uniform(0.0, 1.0, number_of_new_particles)
        theta = numpy.random.uniform(0.0, numpy.pi, number_of_new_particles)
        phi = numpy.random.uniform(0.0, 2 * numpy.pi, number_of_new_particles)
        return self.feedback_radius * numpy.array(
            (r * sin(theta) * cos(phi), r * sin(theta) * sin(phi),
             r * cos(theta))).transpose()

    @property
    def kinetic_energy(self):
        return self.bridge.kinetic_energy

    @property
    def potential_energy(self):
        return self.bridge.potential_energy

    @property
    def thermal_energy(self):
        return self.bridge.thermal_energy

    @property
    def feedback_energy(self):
        return self.total_feedback_energy

    @property
    def model_time(self):
        return self.bridge.model_time

    @property
    def particles(self):
        return self.bridge.particles

    @property
    def gas_particles(self):
        return self.bridge.gas_particles

    def store_system_state(self):
        snapshot_number = int(0.5 +
                              self.current_time / self.time_step_feedback)
        filename = os.path.join(
            "snapshots", "cluster_snapshot_{0:=06}_".format(snapshot_number))
        stars = Particles(keys=self.star_particles.key)
        self.star_particles.copy_values_of_attributes_to([
            "mass", "temperature", "stellar_type", "radius", "luminosity",
            "age", "L_mech", "E_mech", "E_mech_last_feedback", "previous_mass"
        ], stars)
        self.gravity.particles.copy_values_of_attributes_to(
            ["x", "y", "z", "vx", "vy", "vz"], stars)
        write_set_to_file(stars, filename + "stars.amuse", "amuse")
        write_set_to_file(self.hydro.gas_particles, filename + "gas.amuse",
                          "amuse")
        with open(filename + "info.pkl", "wb") as outfile:
            cPickle.dump(
                (self.gravity.unit_converter, self.hydro.unit_converter,
                 self.time_step_bridge, self.time_step_feedback,
                 self.feedback_gas_particle_mass, self.feedback_efficiency,
                 self.feedback_radius, self.verbose,
                 self.total_feedback_energy, self.current_time), outfile)

    def load_system_state(self, info_file, stars_file):
        stars = read_set_from_file(stars_file, 'amuse')
        channel = stars.new_channel_to(self.star_particles)
        channel.copy_attributes(
            ["L_mech", "E_mech", "E_mech_last_feedback", "previous_mass"])

        with open(info_file, "rb") as infile:
            (tmp1, tmp2, self.time_step_bridge, self.time_step_feedback,
             self.feedback_gas_particle_mass, self.feedback_efficiency,
             self.feedback_radius, self.verbose, self.total_feedback_energy,
             self.current_time) = cPickle.load(infile)

    def stop(self):
        print "STOP fieldcode"
        self.bridge.codes[0].field_codes[0].code.stop()
        print "STOP fieldcode"
        self.bridge.codes[1].field_codes[0].code.stop()
        print "STOP bridge"
        self.bridge.stop()
        print "STOP stellar"
        self.stellar.stop()
Exemple #5
0
def evolve_coupled_system(binary_system, giant_system, t_end, n_steps, 
        do_energy_evolution_plot, previous_data=None):
    directsum = CalculateFieldForParticles(particles=giant_system.particles, gravity_constant=constants.G)
    directsum.smoothing_length_squared = giant_system.parameters.gas_epsilon**2
    coupled_system = Bridge(timestep=(t_end / (2 * n_steps)), verbose=False, use_threading=True)
    coupled_system.add_system(binary_system, (directsum,), False)
    coupled_system.add_system(giant_system, (binary_system,), False)
    
    times = (t_end * range(1, n_steps+1) / n_steps).as_quantity_in(units.day)
    
    if previous_data:
        with open(previous_data, 'rb') as file:
            (all_times, potential_energies, kinetic_energies, thermal_energies, 
                giant_center_of_mass, ms1_position, ms2_position, 
                giant_center_of_mass_velocity, ms1_velocity, ms2_velocity) = pickle.load(file)
        all_times.extend(times + all_times[-1])
    else:
        all_times = times
        if do_energy_evolution_plot:
            potential_energies = coupled_system.particles.potential_energy().as_vector_with_length(1).as_quantity_in(units.erg)
            kinetic_energies = coupled_system.particles.kinetic_energy().as_vector_with_length(1).as_quantity_in(units.erg)
            thermal_energies = coupled_system.gas_particles.thermal_energy().as_vector_with_length(1).as_quantity_in(units.erg)
        else:
            potential_energies = kinetic_energies = thermal_energies = None
        
        giant_center_of_mass = [] | units.RSun
        ms1_position = [] | units.RSun
        ms2_position = [] | units.RSun
        giant_center_of_mass_velocity = [] | units.km / units.s
        ms1_velocity = [] | units.km / units.s
        ms2_velocity = [] | units.km / units.s
    i_offset = len(giant_center_of_mass)
    
    giant_total_mass = giant_system.particles.total_mass()
    ms1_mass = binary_system.particles[0].mass
    ms2_mass = binary_system.particles[1].mass
    
    print "   Evolving for", t_end
    for i_step, time in enumerate(times):
        coupled_system.evolve_model(time)
        print "   Evolved to:", time,
        
        if do_energy_evolution_plot:
            potential_energies.append(coupled_system.particles.potential_energy())
            kinetic_energies.append(coupled_system.particles.kinetic_energy())
            thermal_energies.append(coupled_system.gas_particles.thermal_energy())
        
        giant_center_of_mass.append(giant_system.particles.center_of_mass())
        ms1_position.append(binary_system.particles[0].position)
        ms2_position.append(binary_system.particles[1].position)
        giant_center_of_mass_velocity.append(giant_system.particles.center_of_mass_velocity())
        ms1_velocity.append(binary_system.particles[0].velocity)
        ms2_velocity.append(binary_system.particles[1].velocity)

        a_giant, e_giant = calculate_orbital_elements(ms1_mass, ms2_mass,
                                                      ms1_position, ms2_position,
                                                      ms1_velocity, ms2_velocity,
                                                      giant_total_mass,
                                                      giant_center_of_mass,
                                                      giant_center_of_mass_velocity)
        print "Outer Orbit:", time.in_(units.day),  a_giant[-1].in_(units.AU), e_giant[-1], ms1_mass.in_(units.MSun), ms2_mass.in_(units.MSun), giant_total_mass.in_(units.MSun)
        
        if i_step % 10 == 9:
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=04}_gas.amuse".format(i_step + i_offset))
            write_set_to_file(giant_system.gas_particles, snapshotfile, format='amuse')
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=04}_core.amuse".format(i_step + i_offset))
            write_set_to_file(giant_system.dm_particles, snapshotfile, format='amuse')
            snapshotfile = os.path.join("snapshots", "hydro_triple_{0:=04}_binary.amuse".format(i_step + i_offset))
            write_set_to_file(binary_system.particles, snapshotfile, format='amuse')
            
            datafile = os.path.join("snapshots", "hydro_triple_{0:=04}_info.amuse".format(i_step + i_offset))
            with open(datafile, 'wb') as outfile:
                pickle.dump((all_times[:len(giant_center_of_mass)], potential_energies, 
                    kinetic_energies, thermal_energies, giant_center_of_mass, 
                    ms1_position, ms2_position, giant_center_of_mass_velocity,
                    ms1_velocity, ms2_velocity), outfile)
       
        figname1 = os.path.join("plots", "hydro_triple_small{0:=04}.png".format(i_step + i_offset))
        figname2 = os.path.join("plots", "hydro_triple_large{0:=04}.png".format(i_step + i_offset))
        print "  -   Hydroplots are saved to: ", figname1, "and", figname2
        for plot_range, plot_name in [(8|units.AU, figname1), (40|units.AU, figname2)]:
            if HAS_PYNBODY:
                pynbody_column_density_plot(coupled_system.gas_particles, width=plot_range, vmin=26, vmax=32)
                scatter(coupled_system.dm_particles.x, coupled_system.dm_particles.y, c="w")
            else:
                pyplot.figure(figsize = [16, 16])
                sph_particles_plot(coupled_system.gas_particles, gd_particles=coupled_system.dm_particles, 
                    view=plot_range*[-0.5, 0.5, -0.5, 0.5])
            pyplot.savefig(plot_name)
            pyplot.close()
        
    
    coupled_system.stop()
    
    make_movie()
    
    if do_energy_evolution_plot:
        energy_evolution_plot(all_times[:len(kinetic_energies)-1], kinetic_energies, 
            potential_energies, thermal_energies)
    
    print "   Calculating semimajor axis and eccentricity evolution for inner binary"
    # Some temporary variables to calculate semimajor_axis and eccentricity evolution
    total_mass = ms1_mass + ms2_mass
    rel_position = ms1_position - ms2_position
    rel_velocity = ms1_velocity - ms2_velocity
    separation_in = rel_position.lengths()
    speed_squared_in = rel_velocity.lengths_squared()
    
    # Now calculate the important quantities:
    semimajor_axis_binary = (constants.G * total_mass * separation_in / 
        (2 * constants.G * total_mass - separation_in * speed_squared_in)).as_quantity_in(units.AU)
    eccentricity_binary = numpy.sqrt(1.0 - (rel_position.cross(rel_velocity)**2).sum(axis=1) / 
        (constants.G * total_mass * semimajor_axis_binary))

    print "   Calculating semimajor axis and eccentricity evolution of the giant's orbit"
    # Some temporary variables to calculate semimajor_axis and eccentricity evolution
    rel_position = ((ms1_mass * ms1_position + ms2_mass * ms2_position)/total_mass - 
        giant_center_of_mass)
    rel_velocity = ((ms1_mass * ms1_velocity + ms2_mass * ms2_velocity)/total_mass - 
        giant_center_of_mass_velocity)
    total_mass += giant_total_mass
    separation = rel_position.lengths()
    speed_squared = rel_velocity.lengths_squared()
    
    # Now calculate the important quantities:
    semimajor_axis_giant = (constants.G * total_mass * separation / 
        (2 * constants.G * total_mass - separation * speed_squared)).as_quantity_in(units.AU)
    eccentricity_giant = numpy.sqrt(1.0 - (rel_position.cross(rel_velocity)**2).sum(axis=1) / 
        (constants.G * total_mass * semimajor_axis_giant))
    
    orbit_parameters_plot(semimajor_axis_binary, semimajor_axis_giant, all_times[:len(semimajor_axis_binary)])
    orbit_ecc_plot(eccentricity_binary, eccentricity_giant, all_times[:len(eccentricity_binary)])
    
    orbit_parameters_plot(separation_in.as_quantity_in(units.AU), 
        separation.as_quantity_in(units.AU), 
        all_times[:len(eccentricity_binary)], 
        par_symbol="r", par_name="separation")
    orbit_parameters_plot(speed_squared_in.as_quantity_in(units.km**2 / units.s**2), 
        speed_squared.as_quantity_in(units.km**2 / units.s**2), 
        all_times[:len(eccentricity_binary)], 
        par_symbol="v^2", par_name="speed_squared")