def __init__(self, m, A, c, pos, vel, steps): '''Initialises sail with mass,area, charge, position, velocity''' self.mass = m self.area = A self.charge = c self.position = pos self.velocity = vel self.sail_normal = vector.Vector3D(0.0, 0.0, 0.0) self.F_grav = vector.Vector3D(0.0, 0.0, 0.0) self.F_photon = vector.Vector3D(0.0, 0.0, 0.0) self.F_mag = vector.Vector3D(0.0, 0.0, 0.0) self.F_tot = vector.Vector3D(0.0, 0.0, 0.0) self.nsteps = steps # Initialise array to store self.telemetry for output self.telemetry = np.zeros( (self.nsteps, ), dtype=[('step', 'int32'), ('time', 'f8'), ('px', 'f8'), ('py', 'f8'), ('pz', 'f8'), ('vx', 'f8'), ('vy', 'f8'), ('vz', 'f8'), ('sail_x', 'f8'), ('sail_y', 'f8'), ('sail_z', 'f8'), ('sail_angle', 'f8'), ('F_gravity', 'f8'), ('F_photon', 'f8'), ('F_magnetic', 'f8'), ('F_total', 'f8'), ('F_photon_x', 'f8'), ('F_photon_y', 'f8'), ('F_photon_z', 'f8'), ('F_mag_x', 'f8'), ('F_mag_y', 'f8'), ('F_mag_z', 'f8'), ('F_grav_x', 'f8'), ('F_grav_y', 'f8'), ('F_grav_z', 'f8'), ('F_tot_x', 'f8'), ('F_tot_y', 'f8'), ('F_tot_z', 'f8'), ('photon_acceleration', 'f8'), ('ship_speed', 'f8'), ('stellar_distance', 'f8'), ('sail_not_parallel', 'bool')]) self.telemetry[:] = np.NAN
def optimise_sail(self, star): """Finds the sail normal (n) that optimises the craft's deceleration Optimised when (n.r)(n.v) is minimised""" def sailfunction(nvalues, position, velocity): r = position.unitVector() v = velocity.unitVector() n = vector.Vector3D(nvalues[0], nvalues[1], nvalues[2]).unitVector() return n.dot(v) * n.dot(r) firstguess = [1.0, 0.0, 0.0] n_optimal = optimize.minimize(sailfunction, firstguess, args=(self.position, self.velocity), method='SLSQP', bounds=((-1, 1), (-1, 1), (-1, 1)), tol=1.0e-10) sail_normal = vector.Vector3D(n_optimal.x[0], n_optimal.x[1], n_optimal.x[2]) sail_normal = sail_normal.unitVector() return sail_normal
def sailfunction(nvalues, position, velocity): r = position.unitVector() v = velocity.unitVector() n = vector.Vector3D(nvalues[0], nvalues[1], nvalues[2]).unitVector() return n.dot(v) * n.dot(r)
def __init__(self, m, R, L, B, pos, vel, magmom=vector.Vector3D(0.0, 0.0, 1.0)): '''Initialises star with mass, radius, B-field, position, velocity''' self.M = m self.R = R self.L = L self.B1AU = B self.position = pos self.velocity = vel self.magmoment = magmom
nstars = 20 stararray = [] rotation_angle = linspace(0.0, pi, num=nstars) # Define sail: nsteps = 10000 # Number of timesteps to compute timestep = 60 * 5 # 0.1 One timestep every 5 minutes speed = 1270 # [km/sec], initial speed of spaceship ship_sail_area = 10 # sail surface im square meters. ship_mass = .001 # [kg] ship_charge = 1.0e-3 # Charge in Coulomb ship_position = vector.Vector3D( 3.0 * star.R_star_CenA, 10.0 * AU, 0.0) # start position vertical / distance travelled ship_velocity = vector.Vector3D(0.0, -speed * 1000, 0.0) # unit conversion; sign: fly downwards # Create sail ship = sail.Sail(ship_mass, ship_sail_area, ship_charge, ship_position, ship_velocity, nsteps) # Now define star star_position = vector.Vector3D(0.0, 0.0, 0.0) star_velocity = vector.Vector3D(0.0, 0.0, 0.0) # Create star object for istar in range(nstars):
def fly(self, star, minimum_distance_from_star, afterburner_distance, timestep, return_mission=False): """Loops through the simulation, returns result array""" self.telemetry[:] = np.NAN deceleration_phase = True print 'Beginning flight' # Main loop for step in range(self.nsteps): # Check distance from star star_distance = self.position.subtract(star.position).mag() # Inferno time: If we are inside the star, the simulation ends if star_distance < star.R: print('Exit due to ship being inside the star.') break self.F_tot = vector.Vector3D(0.0, 0.0, 0.0) ################# # Compute forces ################# # Gravity force self.get_gravity_force(star) self.F_tot = self.F_tot.add(self.F_grav) # Magnetic Force is velocity dependent! self.get_magnetic_force(star) self.F_tot = self.F_tot.add(self.F_mag) # Now photon pressure force # Check if we are past closest encounter. If yes, switch sail off previous_distance = self.telemetry['stellar_distance'][step - 1] * star.R if step > 2 and star_distance > previous_distance: #if deceleration_phase:print "Past closest approach at time ",str(step),str(self.telemetry['time'][step]),": disengaging sail" deceleration_phase = False # Check if we are past the star and at afterburner distance # If yes, switch sail on again if not return_mission and self.position.y < 0 and star_distance > afterburner_distance: #print "At Afterburner distance" deceleration_phase = True # Actually acceleration now! # In case we are inside the minimum distance, the simulation ends if star_distance < minimum_distance_from_star / star.R: print('Exit due to ship being inside the minimum distance') break # Special case return mission # This is an ugly hardcoded special case. To be optimized in the future if return_mission and self.position.x < 0 and self.position.y / star.R > 4.75: deceleration_phase = True # Actually acceleration now! # Photon pressure force self.get_photon_force(star) if deceleration_phase: self.F_tot = self.F_tot.add(self.F_photon) # If we do not decelerate: sail shall be parallel with zero photon force if not deceleration_phase: self.sail_normal = self.position.cross( self.velocity).unitVector( ) # sail normal to both position and velocity (zero force) self.F_photon = vector.Vector3D(0.0, 0.0, 0.0) # Update positions self.integrate(timestep) """Calculate interesting values""" # Write interesting values into return array self.telemetry['step'][step] = step self.telemetry['time'][step] = step * timestep self.telemetry['px'][step] = self.position.x / sun_radius self.telemetry['py'][step] = self.position.y / sun_radius self.telemetry['pz'][step] = self.position.z / sun_radius self.telemetry['vx'][step] = self.velocity.x / 1000 self.telemetry['vy'][step] = self.velocity.y / 1000 self.telemetry['vz'][step] = self.velocity.z / 1000 self.telemetry['F_gravity'][step] = self.F_grav.mag() self.telemetry['F_photon'][step] = self.F_photon.mag() self.telemetry['F_magnetic'][step] = self.F_mag.mag() self.telemetry['F_total'][step] = self.F_tot.mag() self.telemetry['F_grav_x'][step] = self.F_grav.x self.telemetry['F_grav_y'][step] = self.F_grav.y self.telemetry['F_grav_z'][step] = self.F_grav.z self.telemetry['F_photon_x'][step] = self.F_photon.x self.telemetry['F_photon_y'][step] = self.F_photon.y self.telemetry['F_photon_z'][step] = self.F_photon.z self.telemetry['F_mag_x'][step] = self.F_mag.x self.telemetry['F_mag_y'][step] = self.F_mag.y self.telemetry['F_mag_z'][step] = self.F_mag.z self.telemetry['F_tot_x'][step] = self.F_tot.x self.telemetry['F_tot_y'][step] = self.F_tot.y self.telemetry['F_tot_z'][step] = self.F_tot.z self.telemetry['sail_x'][step] = self.sail_normal.x self.telemetry['sail_y'][step] = self.sail_normal.y self.telemetry['sail_z'][step] = self.sail_normal.z self.telemetry['sail_angle'][step] = np.arccos( self.sail_normal.dot(self.position.unitVector())) self.telemetry['photon_acceleration'][step] = self.F_photon.mag( ) / self.mass self.telemetry['ship_speed'][step] = self.velocity.mag() / 1000. self.telemetry['stellar_distance'][step] = star_distance / star.R self.telemetry['sail_not_parallel'][step] = deceleration_phase print 'Flight complete'
import orbitalelements as orb import vector # Test script - reads in position/velocity data # computes orbits, then modifies a and recomputes new positions/velocities G = orb.GmsolAUday totalmass = 1.0 x = 1.537969e01 y = -2.591931e01 z = 1.7925877e-01 position = vector.Vector3D(x, y, z) vx = 2.68067772e-3 vy = 1.6282417e-3 vz = -9.5159225e-5 velocity = vector.Vector3D(vx, vy, vz) orbit = orb.orbitalElements(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, position, velocity, G, totalmass) orbit.calcOrbitFromVector() orbit.a = 15.0 orbit.calcVectorFromOrbit() print orbit.position print orbit.velocity
# Written 17/5/17 by dh4gan # Script tests the magnetic field implementation # Computes the field on a cartesian grid and plots the results import vector import numpy as np import matplotlib.pyplot as plt import star starposition = vector.Vector3D(0.0, 0.0, 0.0) starvelocity = vector.Vector3D(0.0, 0.0, 0.0) magmoment = vector.Vector3D(0.0, 0.0, 1.0) # unit vector describing the stellar dipole #magmoment.rotateX(0.5*np.pi) # Create star (Alpha Cen A Parameters) s = star.Star(star.M_star_CenA, star.R_star_CenA, star.L_star_CenA, star.sun_Bfield_1AU, starposition, starvelocity, magmom=magmoment) npoints = 100 AU = star.AU # Define grid for plotting field