def __init__(self, w_s, w_u, u_section, round_order_connection): # orbit_idx = [] # for l_point, orbit_type in [(l_point_1, orbit_type_1), (l_point_2, orbit_type_2)] # df = load_initial_conditions_incl_M('../../data/raw/' + l_point + '_' + orbit_type + '_initial_conditions.txt') # orbit_idx.append(df[abs(df[0] - C) == (abs(df[0] - C)).min()].index) l_point, orbit_type, orbit_id, w, s, sign = w_s.split('_') self.C = [ load_initial_conditions_incl_M('../../data/raw/' + l_point + '_' + orbit_type + '_initial_conditions.txt').xs( int(orbit_id))[0] ] l_point, orbit_type, orbit_id, w, s, sign = w_u.split('_') self.C.append( load_initial_conditions_incl_M('../../data/raw/' + l_point + '_' + orbit_type + '_initial_conditions.txt').xs( int(orbit_id))[0]) self.WS = load_manifold('../../data/raw/' + w_s + '.txt') self.WU = load_manifold('../../data/raw/' + w_u + '.txt') self.numberOfOrbitsPerManifold = len( set(self.WS.index.get_level_values(0))) self.U_section = u_section self.roundOrderConnection = round_order_connection # Select last entry of manifolds ls_s = [] ls_u = [] for i in range(len(set(self.WS.index.get_level_values(0)))): ls_s.append(self.WS.xs(i).tail(1)) ls_u.append(self.WU.xs(i).tail(1)) self.poincareWS = pd.concat(ls_s).reset_index(drop=True) self.poincareWU = pd.concat(ls_u).reset_index(drop=True) self.figSize = (40, 40) self.titleSize = 20 self.suptitleSize = 30 EARTH_GRAVITATIONAL_PARAMETER = 3.986004418E14 SUN_GRAVITATIONAL_PARAMETER = 1.32712440018e20 MOON_GRAVITATIONAL_PARAMETER = SUN_GRAVITATIONAL_PARAMETER / ( 328900.56 * (1.0 + 81.30059)) self.massParameter = MOON_GRAVITATIONAL_PARAMETER / ( MOON_GRAVITATIONAL_PARAMETER + EARTH_GRAVITATIONAL_PARAMETER) pass
def findIdxCorrespondingToC(c_level): # Find index of orbit which is closest to the desired Jacobi energy C orbit_types = ['horizontal', 'halo', 'vertical'] lagrange_point_nrs = [1, 2] print('Index for orbit closest to C = ' + str(c_level) + '\n') for idx, orbit_type in enumerate(orbit_types): for lagrange_point_nr in lagrange_point_nrs: initial_conditions_file_path = '../../data/raw/orbits/L' + str( lagrange_point_nr ) + '_' + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M( initial_conditions_file_path) if (initial_conditions_incl_m_df[ initial_conditions_incl_m_df[0] == c_level - min(abs(initial_conditions_incl_m_df[0] - c_level))]).empty: row = initial_conditions_incl_m_df[ initial_conditions_incl_m_df[0] == c_level + min(abs(initial_conditions_incl_m_df[0] - c_level))] else: row = initial_conditions_incl_m_df[ initial_conditions_incl_m_df[0] == c_level - min(abs(initial_conditions_incl_m_df[0] - c_level))] print('L' + str(lagrange_point_nr) + ' ' + orbit_type + ' at index: ' + str(row.index[0]) + ' (dC = |' + str(abs(row[0].values[0] - c_level)) + '|)') pass
def plot_2d_shooting_conditions(self): fig = plt.figure(figsize=self.figSize) ax = fig.gca() orbit_types = ['horizontal', 'vertical', 'halo'] lagrange_point_nrs = [1, 2] x = [] z = [] ydot = [] c = [] for idx, orbit_type in enumerate(orbit_types): for lagrange_point_nr in lagrange_point_nrs: initial_conditions_file_path = '../../data/raw/orbits/L' + str( lagrange_point_nr) + '_' + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M(initial_conditions_file_path) plot_label = orbit_type.capitalize() if plot_label == 'Horizontal' or plot_label == 'Vertical': plot_label += ' Lyapunov' x.extend(list(initial_conditions_incl_m_df[2].values)) z.extend(list(initial_conditions_incl_m_df[4].values)) c.extend(list(initial_conditions_incl_m_df[0].values)) sc = ax.scatter(x, z, c=c, cmap='viridis', s=20) cb = plt.colorbar(sc) cb.set_label('$C \enskip [-]$') lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] # Lagrange points and bodies for lagrange_point_nr in lagrange_point_nrs: ax.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') bodies_df = load_bodies_location() u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) for body in bodies_df: x = bodies_df[body]['r'] * np.outer(np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) ax.contourf(x, z, y, colors='black') ax.legend(frameon=True, loc='upper right') ax.set_xlabel('x [-]') ax.set_ylabel('z [-]') ax.grid(True, which='both', ls=':') fig.tight_layout() fig.subplots_adjust(top=0.9) plt.suptitle('$L_1, L_2$ - Shooting conditions for H-L, halo, and V-L', size=self.suptitleSize) if self.lowDPI: fig.savefig('../../data/figures/orbits/orbit_shooting_conditions_2d.png', transparent=True, dpi=self.dpi) else: fig.savefig('../../data/figures/orbits/orbit_shooting_conditions_2d.pdf', transparent=True) pass
def plot_3d_shooting_conditions(self): fig = plt.figure(figsize=self.figSize) ax = fig.gca(projection='3d') orbit_types = ['horizontal', 'vertical', 'halo'] lagrange_point_nrs = [1, 2] lines = [] linewidth = 2 for lagrange_point_nr in lagrange_point_nrs: for idx, orbit_type in enumerate(orbit_types): initial_conditions_file_path = '../../data/raw/orbits/L' + str( lagrange_point_nr) + '_' + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M(initial_conditions_file_path) plot_label = orbit_type.capitalize() if plot_label == 'Horizontal' or plot_label == 'Vertical': plot_label += ' Lyapunov' line, = ax.plot(initial_conditions_incl_m_df[2].values, initial_conditions_incl_m_df[6].values, initial_conditions_incl_m_df[4].values, label=plot_label, linewidth=linewidth, color=self.plottingColors['tripleLine'][idx]) lines.append(line) lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] # Lagrange points and bodies for lagrange_point_nr in lagrange_point_nrs: ax.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') bodies_df = load_bodies_location() u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) for body in bodies_df: x = bodies_df[body]['r'] * np.outer(np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) ax.plot_surface(x, y, z, color='black') # print(ax.elev) # print(ax.azim) # ax.view_init(20, -75) plt.plot(ax.get_xlim(), [0, 0], 'black', linewidth=0.5) ax.legend(frameon=True, loc='upper right', handles=lines[:3]) ax.set_xlabel('x [-]') ax.set_ylabel('$\dot{y}$ [-]') ax.set_zlabel('z [-]') ax.grid(True, which='both', ls=':') fig.tight_layout() fig.subplots_adjust(top=0.9) plt.suptitle('$L_1, L_2$ - Shooting conditions', size=self.suptitleSize) fig.savefig('../../data/figures/orbits/orbit_shooting_conditions_3d.pdf', transparent=True) pass
def __init__(self, orbit_type, lagrange_point_nr, orbit_id_per_c): print('=======================') print(str(orbit_type) + ' in L' + str(lagrange_point_nr)) print('=======================') self.orbitType = orbit_type self.orbitIdPerC = orbit_id_per_c self.orbitTypeForTitle = orbit_type.capitalize() if (self.orbitTypeForTitle == 'Horizontal') or (self.orbitTypeForTitle == 'Vertical'): self.orbitTypeForTitle += ' Lyapunov' self.lagrangePointNr = lagrange_point_nr EARTH_GRAVITATIONAL_PARAMETER = 3.986004418E14 SUN_GRAVITATIONAL_PARAMETER = 1.32712440018e20 MOON_GRAVITATIONAL_PARAMETER = SUN_GRAVITATIONAL_PARAMETER / ( 328900.56 * (1.0 + 81.30059)) self.massParameter = MOON_GRAVITATIONAL_PARAMETER / ( MOON_GRAVITATIONAL_PARAMETER + EARTH_GRAVITATIONAL_PARAMETER) initial_conditions_file_path = '../../data/raw/orbits/L' + str( lagrange_point_nr) + '_' + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M( initial_conditions_file_path) self.C = [] self.orbitDf = [] self.W_S_plus = [] self.W_S_min = [] self.W_U_plus = [] self.W_U_min = [] for c_level in reversed(sorted(orbit_id_per_c)): orbit_id = orbit_id_per_c[c_level] # self.C.append(initial_conditions_incl_m_df.iloc[orbit_id][0]) self.orbitDf.append( load_orbit('../../data/raw/orbits/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '.txt')) self.C.append( computeJacobiEnergy(self.orbitDf[-1].iloc[0]['x'], self.orbitDf[-1].iloc[0]['y'], self.orbitDf[-1].iloc[0]['z'], self.orbitDf[-1].iloc[0]['xdot'], self.orbitDf[-1].iloc[0]['ydot'], self.orbitDf[-1].iloc[0]['zdot'])) self.W_S_plus.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_plus.txt')) self.W_S_min.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_min.txt')) self.W_U_plus.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_plus.txt')) self.W_U_min.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_min.txt')) self.numberOfOrbitsPerManifold = len( set(self.W_S_plus[0].index.get_level_values(0))) self.figSize = (7 * (1 + np.sqrt(5)) / 2, 7 * 2) blues = sns.color_palette('Blues', 100) greens = sns.color_palette('BuGn', 100) self.colorPaletteStable = sns.dark_palette( 'green', n_colors=self.numberOfOrbitsPerManifold) self.colorPaletteUnstable = sns.dark_palette( 'red', n_colors=self.numberOfOrbitsPerManifold) self.plottingColors = { 'lambda1': blues[40], 'lambda2': greens[50], 'lambda3': blues[90], 'lambda4': blues[90], 'lambda5': greens[70], 'lambda6': blues[60], 'singleLine': blues[80], 'doubleLine': [greens[50], blues[80]], 'tripleLine': [blues[40], greens[50], blues[80]], 'W_S_plus': self.colorPaletteStable[90], 'W_S_min': self.colorPaletteStable[40], 'W_U_plus': self.colorPaletteUnstable[90], 'W_U_min': self.colorPaletteUnstable[40], 'limit': 'black', 'orbit': 'navy' } self.suptitleSize = 20 pass
def __init__(self, libration_point_nr): self.suptitleSize = 44 self.timeTextSize = 33 axis_bounds = 0.1 * libration_point_nr libration_point_df = load_lagrange_points_location() libration_point_x_loc = libration_point_df[ 'L' + str(libration_point_nr)]['x'] self.xLim = [0.8, 1.2] self.yLim = [-0.5, 0.5] self.zLim = [-0.5, 0.5] # self.xLim = [libration_point_x_loc - axis_bounds, libration_point_x_loc + axis_bounds] # self.yLim = [-axis_bounds, axis_bounds] # self.zLim = self.yLim self.orbitAlpha = 0.8 self.orbitLinewidth = 2 self.lagrangePointMarkerSize = 300 self.orbitColor = 'gray' self.librationPointNr = libration_point_nr self.lines = [] self.horizontalLyapunov = [] self.jacobiEnergyText = '' # Will become a plt.text-object self.jacobiEnergyHorizontalLyapunov = [] self.jacobiEnergyAxial = [] self.jacobiEnergyVerticalLyapunov = [] self.orderOfLinearInstabilityHorizontalLyapunov = [] self.orderOfLinearInstabilityVerticalLyapunov = [] self.orbitIdBifurcationsFromHorizontalLyapunov = [] self.orbitIdBifurcationsFromVerticalLyapunov = [] # Determine the index for bifurcation for horizontal family initial_conditions_incl_m_df = load_initial_conditions_incl_M( '../../../data/raw/orbits/L' + str(self.librationPointNr) + '_horizontal_initial_conditions.txt') for row in initial_conditions_incl_m_df.iterrows(): self.jacobiEnergyHorizontalLyapunov.append(row[1][0]) M = np.matrix([ list(row[1][8:14]), list(row[1][14:20]), list(row[1][20:26]), list(row[1][26:32]), list(row[1][32:38]), list(row[1][38:44]) ]) eigenvalue = np.linalg.eigvals(M) # Determine order of linear instability reduction = 0 for i in range(6): if (abs(eigenvalue[i]) - 1.0) < 1e-2: reduction += 1 if len(self.orderOfLinearInstabilityHorizontalLyapunov) > 0: # Check for a bifurcation, when the order of linear instability changes if (6 - reduction ) != self.orderOfLinearInstabilityHorizontalLyapunov[-1]: self.orbitIdBifurcationsFromHorizontalLyapunov.append( row[0]) self.orderOfLinearInstabilityHorizontalLyapunov.append(6 - reduction) print('Index for bifurcations from horizontal Lyapunov family: ') print(self.orbitIdBifurcationsFromHorizontalLyapunov) # Select the indices to be plotted for the horizontal Lyapunov family (please remember that the bifurcation to the axial family corresponds to the second bifurcation of the horizontal Lyapunov family) self.horizontalLyapunovIndices = list( range(0, self.orbitIdBifurcationsFromHorizontalLyapunov[1])) self.horizontalLyapunovIndices.append( self.orbitIdBifurcationsFromHorizontalLyapunov[1]) # Save jacobi energy values for the axial family initial_conditions_file_path = '../../../data/raw/orbits/L' + str( self.librationPointNr) + '_axial_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M( initial_conditions_file_path) for row in initial_conditions_incl_m_df.iterrows(): self.jacobiEnergyAxial.append(row[1][0]) self.numberOfAxialOrbits = len(self.jacobiEnergyAxial) # Determine the index for bifurcation for vertical family initial_conditions_incl_m_df = load_initial_conditions_incl_M( '../../../data/raw/orbits/L' + str(self.librationPointNr) + '_vertical_initial_conditions.txt') for row in initial_conditions_incl_m_df.iterrows(): self.jacobiEnergyVerticalLyapunov.append(row[1][0]) M = np.matrix([ list(row[1][8:14]), list(row[1][14:20]), list(row[1][20:26]), list(row[1][26:32]), list(row[1][32:38]), list(row[1][38:44]) ]) eigenvalue = np.linalg.eigvals(M) # Determine order of linear instability reduction = 0 for i in range(6): if (abs(eigenvalue[i]) - 1.0) < 1e-2: reduction += 1 if len(self.orderOfLinearInstabilityVerticalLyapunov) > 0: # Check for a bifurcation, when the order of linear instability changes if (6 - reduction ) != self.orderOfLinearInstabilityVerticalLyapunov[-1]: self.orbitIdBifurcationsFromVerticalLyapunov.append(row[0]) self.orderOfLinearInstabilityVerticalLyapunov.append(6 - reduction) print('Index for bifurcations from vertical Lyapunov family: ') print(self.orbitIdBifurcationsFromVerticalLyapunov) # Select the indices to be plotted for the vertical Lyapunov family (please remember that the bifurcation to the axial family corresponds to the first bifurcation of the vertical Lyapunov family) self.verticalLyapunovIndices = list( range(self.orbitIdBifurcationsFromVerticalLyapunov[0], len(self.jacobiEnergyVerticalLyapunov))) pass
lines[2].set_data(vertical_L1[i]['x'].values, vertical_L1[i]['y'].values) lines[2].set_3d_properties(vertical_L1[i]['z'].values) lines[3].set_data(vertical_L2[i]['x'].values, vertical_L2[i]['y'].values) lines[3].set_3d_properties(vertical_L2[i]['z'].values) lines[4].set_data(halo_L1[i]['x'].values, halo_L1[i]['y'].values) lines[4].set_3d_properties(halo_L1[i]['z'].values) lines[5].set_data(halo_L2[i]['x'].values, halo_L2[i]['y'].values) lines[5].set_3d_properties(halo_L2[i]['z'].values) # fig.suptitle('C = ' + str(np.round(initial_conditions_vertical_L1.iloc[i][1], 2)), size=30) return lines orbit_type = 'halo' # Load data initial_conditions_horizontal_L1 = load_initial_conditions_incl_M( '../data/raw/horizontal_L1_initial_conditions.txt') initial_conditions_horizontal_L2 = load_initial_conditions_incl_M( '../data/raw/horizontal_L2_initial_conditions.txt') initial_conditions_vertical_L1 = load_initial_conditions_incl_M( '../data/raw/vertical_L1_initial_conditions.txt') initial_conditions_vertical_L2 = load_initial_conditions_incl_M( '../data/raw/vertical_L2_initial_conditions.txt') initial_conditions_halo_L1 = load_initial_conditions_incl_M( '../data/raw/halo_L1_initial_conditions.txt') initial_conditions_halo_L2 = load_initial_conditions_incl_M( '../data/raw/halo_L2_initial_conditions.txt') horizontal_L1 = [] horizontal_L2 = [] vertical_L1 = [] vertical_L2 = []
sns.color_palette("viridis", n_colors)[0], sns.color_palette("viridis", n_colors)[n_colors - 1], sns.color_palette("viridis", n_colors)[int((n_colors - 1) / 2)] ], 'limit': 'black' } fig = plt.figure(figsize=(7 * (1 + np.sqrt(5)) / 2, 3.5)) ax = fig.gca() for lagrange_point_nr in lagrange_point_nrs: for idx, orbit_type in enumerate(orbit_types): initial_conditions_file_path = '../../data/raw/orbits/L' + str( lagrange_point_nr) + '_' + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M( initial_conditions_file_path) plot_label = orbit_type.capitalize() if plot_label == 'Horizontal' or plot_label == 'Vertical': plot_label += ' Lyapunov' if lagrange_point_nr == 1: linestyle = '-' else: linestyle = '--' ax.plot(initial_conditions_incl_m_df[1].values, initial_conditions_incl_m_df[0].values, label='$L_' + str(lagrange_point_nr) + '$ ' + plot_label, linestyle=linestyle, color=plottingColors['tripleLine'][idx])
def __init__(self, orbit_type, lagrange_point_nr): self.C = [] self.T = [] self.x = [] self.X = [] self.delta_r = [] self.delta_v = [] self.delta_x = [] self.delta_y = [] self.delta_z = [] self.delta_x_dot = [] self.delta_y_dot = [] self.delta_z_dot = [] self.numberOfIterations = [] self.C_half_period = [] self.T_half_period = [] self.X_half_period = [] self.eigenvalues = [] self.D = [] self.orderOfLinearInstability = [] self.orbitIdBifurcations = [] self.lambda1 = [] self.lambda2 = [] self.lambda3 = [] self.lambda4 = [] self.lambda5 = [] self.lambda6 = [] self.v1 = [] self.v2 = [] self.v3 = [] self.lagrangePointNr = lagrange_point_nr print('=======================') print(str(orbit_type) + ' in L' + str(lagrange_point_nr)) print('=======================') self.orbitType = orbit_type self.orbitTypeForTitle = orbit_type.capitalize() if self.orbitTypeForTitle == 'Horizontal' or self.orbitTypeForTitle == 'Vertical': self.orbitTypeForTitle += ' Lyapunov' initial_conditions_file_path = '../../data/raw/orbits/extended/L' + str(lagrange_point_nr) + '_' \ + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M( initial_conditions_file_path) differential_correction_file_path = '../../data/raw/orbits/extended/L' + str(lagrange_point_nr) + '_' \ + orbit_type + '_differential_correction.txt' differential_correction_df = load_differential_corrections( differential_correction_file_path) # Fix for extended v-l self.indexNanEntries = pd.isnull(initial_conditions_incl_m_df).any( 1).nonzero()[0] print(self.indexNanEntries) initial_conditions_incl_m_df.dropna(axis=0, how='any', inplace=True) differential_correction_df.drop( differential_correction_df.index[self.indexNanEntries], inplace=True) for row in differential_correction_df.iterrows(): self.numberOfIterations.append(row[1][0]) self.C_half_period.append(row[1][1]) self.T_half_period.append(row[1][2]) self.X_half_period.append(np.array(row[1][3:9])) self.maxEigenvalueDeviation = 1.0e-3 # Changed from 1e-3 for row in initial_conditions_incl_m_df.iterrows(): self.C.append(row[1][0]) self.T.append(row[1][1]) self.x.append(row[1][2]) self.X.append(np.array(row[1][2:8])) # self.X.append(np.array(row[1][3:9])) M = np.matrix([ list(row[1][8:14]), list(row[1][14:20]), list(row[1][20:26]), list(row[1][26:32]), list(row[1][32:38]), list(row[1][38:44]) ]) eigenvalue = np.linalg.eigvals(M) print(str(row[0]) + ' at x-loc: ' + str(row[1][2])) sorting_indices = [-1, -1, -1, -1, -1, -1] idx_real_one = [] # Find indices of the first pair of real eigenvalue equal to one for idx, l in enumerate(eigenvalue): if abs(l.imag) < self.maxEigenvalueDeviation: if abs(l.real - 1.0) < self.maxEigenvalueDeviation: if sorting_indices[2] == -1: sorting_indices[2] = idx idx_real_one.append(idx) elif sorting_indices[3] == -1: sorting_indices[3] = idx idx_real_one.append(idx) # Find indices of the pair of largest/smallest real eigenvalue (corresponding to the unstable/stable subspace) for idx, l in enumerate(eigenvalue): if idx == (sorting_indices[2] or sorting_indices[3]): continue if abs(l.imag) < self.maxEigenvalueDeviation: if abs(l.real) == max(abs(eigenvalue.real)): sorting_indices[0] = idx elif abs(abs(l.real) - 1.0 / max(abs(eigenvalue.real)) ) < self.maxEigenvalueDeviation: sorting_indices[5] = idx missing_indices = sorted( list(set(list(range(-1, 6))) - set(sorting_indices))) if eigenvalue.imag[missing_indices[0]] > eigenvalue.imag[ missing_indices[1]]: sorting_indices[1] = missing_indices[0] sorting_indices[4] = missing_indices[1] else: sorting_indices[1] = missing_indices[1] sorting_indices[4] = missing_indices[0] # reset sorting index for regime halo in l1 if orbit_type == 'halo' and lagrange_point_nr == 1 and row[ 0] >= 1972 and row[0] <= 2316: sorting_indices = [ -1, -1, idx_real_one[0], idx_real_one[1], -1, -1 ] # # TODO check that all indices are unique and no - if len(sorting_indices) > len(set(sorting_indices)): print('\nWARNING: SORTING INDEX IS NOT UNIQUE FOR ' + self.orbitType + ' AT L' + str(self.lagrangePointNr)) print(eigenvalue) if len(idx_real_one) != 2: idx_real_one = [] # Find indices of the first pair of real eigenvalue equal to one for idx, l in enumerate(eigenvalue): if abs(l.imag) < 2 * self.maxEigenvalueDeviation: if abs(l.real - 1.0) < 2 * self.maxEigenvalueDeviation: if sorting_indices[2] == -1: sorting_indices[2] = idx idx_real_one.append(idx) elif sorting_indices[3] == -1: sorting_indices[3] = idx idx_real_one.append(idx) if len(idx_real_one) == 2: sorting_indices = [-1, -1, -1, -1, -1, -1] sorting_indices[2] = idx_real_one[0] sorting_indices[3] = idx_real_one[1] print('minimum angle = ' + str( min( abs( np.angle(eigenvalue[list( set(range(6)) - set(idx_real_one))], deg=True))))) print('maximum angle = ' + str( max( abs( np.angle(eigenvalue[list( set(range(6)) - set(idx_real_one))], deg=True))))) # Assume two times real one and two conjugate pairs for idx, l in enumerate(eigenvalue): print(idx) print(abs(np.angle(l, deg=True))) # min(abs(np.angle(eigenvalue[list(set(range(6)) - set(idx_real_one))], deg=True))) # if abs(np.angle(l, deg=True))%180 == min(abs(np.angle(eigenvalue[list(set(range(6)) - set(idx_real_one))], deg=True)) %180): if l.real == eigenvalue[list( set(range(6)) - set(idx_real_one))].real.max(): if l.imag > 0: sorting_indices[0] = idx elif l.imag < 0: sorting_indices[5] = idx # if abs(np.angle(l, deg=True))%180 == max(abs(np.angle(eigenvalue[list(set(range(6)) - set(idx_real_one))], deg=True)) %180): if l.real == eigenvalue[list( set(range(6)) - set(idx_real_one))].real.min(): if l.imag > 0: sorting_indices[1] = idx elif l.imag < 0: sorting_indices[4] = idx print(sorting_indices) if len(sorting_indices) > len(set(sorting_indices)): print('\nWARNING: SORTING INDEX IS STILL NOT UNIQUE') # Sorting eigenvalues from largest to smallest norm, excluding real one # Sorting based on previous phase if len(idx_real_one) == 2: sorting_indices = [-1, -1, -1, -1, -1, -1] sorting_indices[2] = idx_real_one[0] sorting_indices[3] = idx_real_one[1] # Assume two times real one and two conjugate pairs for idx, l in enumerate( eigenvalue[list(set(range(6)) - set(idx_real_one))]): print(idx) if abs(l.real - self.lambda1[-1].real) == min( abs(eigenvalue.real - self.lambda1[-1].real) ) and abs(l.imag - self.lambda1[-1].imag) == min( abs(eigenvalue.imag - self.lambda1[-1].imag)): sorting_indices[0] = idx if abs(l.real - self.lambda2[-1].real) == min( abs(eigenvalue.real - self.lambda2[-1].real) ) and abs(l.imag - self.lambda2[-1].imag) == min( abs(eigenvalue.imag - self.lambda2[-1].imag)): sorting_indices[1] = idx if abs(l.real - self.lambda5[-1].real) == min( abs(eigenvalue.real - self.lambda5[-1].real) ) and abs(l.imag - self.lambda5[-1].imag) == min( abs(eigenvalue.imag - self.lambda5[-1].imag)): sorting_indices[4] = idx if abs(l.real - self.lambda6[-1].real) == min( abs(eigenvalue.real - self.lambda6[-1].real) ) and abs(l.imag - self.lambda6[-1].imag) == min( abs(eigenvalue.imag - self.lambda6[-1].imag)): sorting_indices[5] = idx print(sorting_indices) pass if (sorting_indices[1] and sorting_indices[4]) == -1: # Fill two missing values two_missing_indices = list( set(list(range(-1, 6))) - set(sorting_indices)) if abs(eigenvalue[two_missing_indices[0]].real) > abs( eigenvalue[two_missing_indices[1]].real): sorting_indices[1] = two_missing_indices[0] sorting_indices[4] = two_missing_indices[1] else: sorting_indices[1] = two_missing_indices[1] sorting_indices[4] = two_missing_indices[0] print(sorting_indices) if (sorting_indices[0] and sorting_indices[5]) == -1: # Fill two missing values two_missing_indices = list( set(list(range(-1, 6))) - set(sorting_indices)) print(eigenvalue) print(sorting_indices) print(two_missing_indices) # TODO quick fix for extended v-l # if len(two_missing_indices)==1: # print('odd that only one index remains') # if sorting_indices[0] == -1: # sorting_indices[0] = two_missing_indices[0] # else: # sorting_indices[5] = two_missing_indices[0] # sorting_indices = abs(eigenvalue).argsort()[::-1] if abs(eigenvalue[two_missing_indices[0]].real) > abs( eigenvalue[two_missing_indices[1]].real): sorting_indices[0] = two_missing_indices[0] sorting_indices[5] = two_missing_indices[1] else: sorting_indices[0] = two_missing_indices[1] sorting_indices[5] = two_missing_indices[0] print(sorting_indices) if len(sorting_indices) > len(set(sorting_indices)): print('\nWARNING: SORTING INDEX IS STILL STILL NOT UNIQUE') # Sorting eigenvalues from largest to smallest norm, excluding real one sorting_indices = abs(eigenvalue).argsort()[::-1] print(eigenvalue[sorting_indices]) self.eigenvalues.append(eigenvalue[sorting_indices]) self.lambda1.append(eigenvalue[sorting_indices[0]]) self.lambda2.append(eigenvalue[sorting_indices[1]]) self.lambda3.append(eigenvalue[sorting_indices[2]]) self.lambda4.append(eigenvalue[sorting_indices[3]]) self.lambda5.append(eigenvalue[sorting_indices[4]]) self.lambda6.append(eigenvalue[sorting_indices[5]]) # Determine order of linear instability reduction = 0 for i in range(6): if (abs(eigenvalue[i]) - 1.0) < 1e-2: reduction += 1 if len(self.orderOfLinearInstability) > 0: # Check for a bifurcation, when the order of linear instability changes if (6 - reduction) != self.orderOfLinearInstability[-1]: self.orbitIdBifurcations.append(row[0]) self.orderOfLinearInstability.append(6 - reduction) self.v1.append( abs(eigenvalue[sorting_indices[0]] + eigenvalue[sorting_indices[5]]) / 2) self.v2.append( abs(eigenvalue[sorting_indices[1]] + eigenvalue[sorting_indices[4]]) / 2) self.v3.append( abs(eigenvalue[sorting_indices[2]] + eigenvalue[sorting_indices[3]]) / 2) self.D.append(np.linalg.det(M)) print('Index for bifurcations: ') print(self.orbitIdBifurcations) # Determine heatmap for level of C self.numberOfPlotColorIndices = len(self.C) self.plotColorIndexBasedOnC = [] for jacobi_energy in self.C: self.plotColorIndexBasedOnC.append( int( np.round((jacobi_energy - min(self.C)) / (max(self.C) - min(self.C)) * (self.numberOfPlotColorIndices - 1)))) for i in range(0, len(initial_conditions_incl_m_df)): df = load_orbit('../../data/raw/orbits/extended/L' + str(self.lagrangePointNr) + '_' + self.orbitType + '_' + str(i) + '.txt') self.delta_r.append( np.sqrt((df.head(1)['x'].values - df.tail(1)['x'].values)**2 + (df.head(1)['y'].values - df.tail(1)['y'].values)**2 + (df.head(1)['z'].values - df.tail(1)['z'].values)**2)) self.delta_v.append( np.sqrt((df.head(1)['xdot'].values - df.tail(1)['xdot'].values)**2 + (df.head(1)['ydot'].values - df.tail(1)['ydot'].values)**2 + (df.head(1)['zdot'].values - df.tail(1)['zdot'].values)**2)) self.delta_x.append( abs(df.head(1)['x'].values - df.tail(1)['x'].values)) self.delta_y.append( abs(df.head(1)['y'].values - df.tail(1)['y'].values)) self.delta_z.append( abs(df.head(1)['z'].values - df.tail(1)['z'].values)) self.delta_x_dot.append( abs(df.head(1)['xdot'].values - df.tail(1)['xdot'].values)) self.delta_y_dot.append( abs(df.head(1)['ydot'].values - df.tail(1)['ydot'].values)) self.delta_z_dot.append( abs(df.head(1)['zdot'].values - df.tail(1)['zdot'].values)) # self.figSize = (20, 20) self.figSize = (7 * (1 + np.sqrt(5)) / 2, 7) n_colors = 3 n_colors_l = 6 self.plottingColors = { 'lambda1': sns.color_palette("viridis", n_colors_l)[0], 'lambda2': sns.color_palette("viridis", n_colors_l)[2], 'lambda3': sns.color_palette("viridis", n_colors_l)[4], 'lambda4': sns.color_palette("viridis", n_colors_l)[5], 'lambda5': sns.color_palette("viridis", n_colors_l)[3], 'lambda6': sns.color_palette("viridis", n_colors_l)[1], 'singleLine': sns.color_palette("viridis", n_colors)[0], 'doubleLine': [ sns.color_palette("viridis", n_colors)[n_colors - 1], sns.color_palette("viridis", n_colors)[0] ], 'tripleLine': [ sns.color_palette("viridis", n_colors)[n_colors - 1], sns.color_palette("viridis", n_colors)[int( (n_colors - 1) / 2)], sns.color_palette("viridis", n_colors)[0] ], 'limit': 'black' } self.suptitleSize = 20 self.xlim = [min(self.x), max(self.x)] pass
def __init__(self, libration_point_nr): self.suptitleSize = 44 self.timeTextSize = 33 self.xLim = [0.8, 1.2] self.yLim = [-0.15, 0.15] self.zLim = [-0.3, 0.3] self.orbitAlpha = 0.8 self.orbitLinewidth = 2 self.lagrangePointMarkerSize = 300 self.orbitColor = 'gray' self.librationPointNr = libration_point_nr self.t = [] self.lines = [] self.horizontalLyapunov = [] self.halo = [] self.jacobiEnergyText = '' # Will become a plt.text-object self.jacobiEnergyHorizontalLyapunov = [] self.jacobiEnergyHalo = [] self.jacobiEnergyHaloN = [] self.T = [] self.orderOfLinearInstability = [] self.orbitIdBifurcations = [] # Include reverse halo orbit continuation to horizontal Lyapunov tangent bifurcation initial_conditions_file_path = '../../../data/raw/orbits/L' + str(self.librationPointNr) + '_halo_n_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M(initial_conditions_file_path)[::-1] self.numberOfHaloExtensionOrbits = len(initial_conditions_incl_m_df) for row in initial_conditions_incl_m_df.iterrows(): self.jacobiEnergyHaloN.append(row[1][0]) initial_conditions_incl_m_df = load_initial_conditions_incl_M('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_halo_initial_conditions.txt') for row in initial_conditions_incl_m_df.iterrows(): self.jacobiEnergyHalo.append(row[1][0]) # Determine the index for bifurcation initial_conditions_incl_m_df = load_initial_conditions_incl_M('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_horizontal_initial_conditions.txt') for row in initial_conditions_incl_m_df.iterrows(): self.jacobiEnergyHorizontalLyapunov.append(row[1][0]) self.T.append(row[1][1]) M = np.matrix([list(row[1][8:14]), list(row[1][14:20]), list(row[1][20:26]), list(row[1][26:32]), list(row[1][32:38]), list(row[1][38:44])]) eigenvalue = np.linalg.eigvals(M) # Determine order of linear instability reduction = 0 for i in range(6): if (abs(eigenvalue[i]) - 1.0) < 1e-2: reduction += 1 if len(self.orderOfLinearInstability) > 0: # Check for a bifurcation, when the order of linear instability changes if (6 - reduction) != self.orderOfLinearInstability[-1]: self.orbitIdBifurcations.append(row[0]) self.orderOfLinearInstability.append(6 - reduction) print('Index for bifurcations from horizontal Lyapunov family: ') print(self.orbitIdBifurcations) # Select the indices to be plotted for the horizontal Lyapunov family (please remember that the bifurcation to the halo family corresponds to the first bifurcation of the horizontal Lyapunov family) self.horizontalLyapunovIndices = list(range(0, self.orbitIdBifurcations[0])) self.horizontalLyapunovIndices.append(self.orbitIdBifurcations[0]) # Determine the indices for the halo family initial_conditions_incl_m_df = load_initial_conditions_incl_M( '../../../data/raw/orbits/L' + str(self.librationPointNr) + '_halo_initial_conditions.txt') self.haloIndices = list(range(0, initial_conditions_incl_m_df.index.max())) self.haloIndices.append(initial_conditions_incl_m_df.index.max()) pass