def __init__(self, config, orbit_type):
        self.orbit = []
        self.config = config
        self.orbitType = orbit_type
        self.massParameter = 0.0121505810173
        self.figSize = (20, 20)
        self.titleSize = 20
        self.suptitleSize = 30

        orbit_ids = []
        for orbit_id in list(self.config[self.orbitType].keys()):
            ls = orbit_id.split('_')
            if orbit_type == 'near_vertical':
                orbit_ids.append(int(ls[2]))
            if orbit_type == 'halo':
                orbit_ids.append(int(ls[1]))
        orbit_ids = [
            self.orbitType + '_' + str(idx) for idx in sorted(orbit_ids)
        ]

        for orbit_id in orbit_ids:
            self.orbit.append(
                load_orbit('../data/raw/' + orbit_id + '_final_orbit.txt'))

        self.lagrangePoints = load_lagrange_points_location()
        self.bodies = load_bodies_location()

        sns.set_style("whitegrid")
        pass
    def show_2d_subplots(self):
        df = pd.DataFrame.from_dict(self.config[orbit_type]).T

        # colors = sns.color_palette("Blues", n_colors=6)

        for orbit_id, row in df.iterrows():
            f, axarr = plt.subplots(2, 1, figsize=self.figSize)
            orbit = load_orbit('../data/raw/' + orbit_id + '_final_orbit.txt')
            label = '$x_0$ = ' + str(np.round(row['x'], 3)) \
                    + '\n$y_0$ = ' + str(np.round(row['y'], 3)) \
                    + '\n$z_0$ = ' + str(np.round(row['z'], 3)) \
                    + '\n$\dot{x}_0$ = ' + str(np.round(row['x_dot'], 3)) \
                    + '\n$\dot{y}_0$ = ' + str(np.round(row['y_dot'], 3)) \
                    + '\n$\dot{z}_0$ = ' + str(np.round(row['z_dot'], 3))

            axarr[0].plot(orbit['y'].values,
                          orbit['z'].values,
                          color='darkblue',
                          label=label)

            circ = plt.Circle((0, 0),
                              radius=1,
                              edgecolor='k',
                              facecolor='None',
                              linestyle=':')
            axarr[1].add_patch(circ)

            for j in range(1, 7):
                x = row['l_' + str(j) + '_re']
                y = row['l_' + str(j) + '_im']
                axarr[1].scatter(x,
                                 y,
                                 color='darkblue',
                                 label='$\lambda_' + str(j) + '$ = (' +
                                 str(np.round(x, 2)) + ', ' +
                                 str(np.round(y, 2)) + ')')

            axarr[0].set_title('T = ' + str(np.round(row['T'], 2)) + ', C = ' +
                               str(np.round(row['C'], 2)))

            for k in range(2):
                # Shrink current axis
                box = axarr[k].get_position()
                axarr[k].set_position(
                    [box.x0, box.y0, box.width * 0.75, box.height])

                # Put a legend to the right of the current axis
                axarr[k].legend(loc='center left', bbox_to_anchor=(1, 0.5))

            axarr[1].set_xlim([-10, 10])
            axarr[1].set_ylim([-5, 5])

            plt.suptitle(orbit_id, size=self.suptitleSize)
            plt.savefig('../data/figures/eigenvalues_' + orbit_id + '_2d.png')
            plt.close()
        pass
    def __init__(self, orbit_type, lagrange_point_nr, orbit_id, c_level):
        self.orbitType = orbit_type
        self.orbitId = orbit_id
        self.cLevel = c_level
        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)

        self.eigenvectorDf_S = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_plus_eigenvector.txt', delim_whitespace=True, header=None).filter(list(range(6)))
        self.eigenvectorDf_U = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_plus_eigenvector.txt', delim_whitespace=True, header=None).filter(list(range(6)))
        self.eigenvectorLocationDf_S = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_plus_eigenvector_location.txt', delim_whitespace=True, header=None).filter(list(range(6)))
        self.eigenvectorLocationDf_U = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_plus_eigenvector_location.txt', delim_whitespace=True, header=None).filter(list(range(6)))

        self.W_S_plus = 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 = 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 = 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 = load_manifold_refactored('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_min.txt')

        self.orbitDf = load_orbit('../../data/raw/orbits/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '.txt')

        self.numberOfOrbitsPerManifold = len(set(self.W_S_plus.index.get_level_values(0)))
        self.figSize = (7 * (1 + np.sqrt(5)) / 2, 7)
        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)

        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]],
                               'W_S_plus': self.colorPaletteStable[int(0.9*self.numberOfOrbitsPerManifold)],
                               'W_S_min': self.colorPaletteStable[int(0.4*self.numberOfOrbitsPerManifold)],
                               'W_U_plus': self.colorPaletteUnstable[int(0.9*self.numberOfOrbitsPerManifold)],
                               'W_U_min': self.colorPaletteUnstable[int(0.4*self.numberOfOrbitsPerManifold)],
                               'limit': 'black',
                               'orbit': 'navy'}
        self.suptitleSize = 20
        pass
    def update_lines(self, i):
        if i % 10 == 0:
            print(i)

        for j, line in enumerate(self.lines):
            if i <= self.orbitIdBifurcations[0]:
                jacobi_energy = self.jacobiEnergyHorizontalLyapunov[i]
                self.jacobiEnergyText.set_text('Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format(round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_horizontal_' + str(i) + '.txt')
            elif self.orbitIdBifurcations[0] < i <= self.orbitIdBifurcations[0] + self.numberOfHaloExtensionOrbits:
                index_for_halo = self.numberOfHaloExtensionOrbits - (i - self.orbitIdBifurcations[0])
                jacobi_energy = self.jacobiEnergyHaloN[(i - self.orbitIdBifurcations[0] - 1)]
                self.jacobiEnergyText.set_text('Southern halo family \n $C \\approx$ {:.4f}'.format(round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_halo_n_' + str(index_for_halo) + '.txt')
                pass
            else:
                index_for_halo = i - self.orbitIdBifurcations[0] - self.numberOfHaloExtensionOrbits + 1
                jacobi_energy = self.jacobiEnergyHalo[index_for_halo]
                self.jacobiEnergyText.set_text('Southern halo family \n $C \\approx$ {:.4f}'.format(round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_halo_' + str(index_for_halo) + '.txt')
                pass

            if i == self.orbitIdBifurcations[0]:
                plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='navy', linewidth=2)

            x = orbit_df['x'].tolist()
            y = orbit_df['y'].tolist()
            z = orbit_df['z'].tolist()

            line.set_data(x, y)
            line.set_3d_properties(z)
            pass

        if i % 100 == 0 and i != 0:
            plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='gray', linewidth=1)


        return self.lines
    '../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 = []
halo_L1 = []
halo_L2 = []

for orbit_id in list(range(len(initial_conditions_horizontal_L1))):
    horizontal_L1.append(
        load_orbit('../data/raw/horizontal_L1_' + str(orbit_id) + '.txt'))
for orbit_id in list(range(len(initial_conditions_horizontal_L2))):
    horizontal_L2.append(
        load_orbit('../data/raw/horizontal_L2_' + str(orbit_id) + '.txt'))
for orbit_id in list(range(len(initial_conditions_vertical_L1))):
    vertical_L1.append(
        load_orbit('../data/raw/vertical_L1_' + str(orbit_id) + '.txt'))
for orbit_id in list(range(len(initial_conditions_vertical_L2))):
    vertical_L2.append(
        load_orbit('../data/raw/vertical_L2_' + str(orbit_id) + '.txt'))
for orbit_id in list(range(len(initial_conditions_halo_L1))):
    halo_L1.append(load_orbit('../data/raw/halo_L1_' + str(orbit_id) + '.txt'))
for orbit_id in list(range(len(initial_conditions_halo_L2))):
    halo_L2.append(load_orbit('../data/raw/halo_L2_' + str(orbit_id) + '.txt'))

# Create plot
    def plot(self):
        colors = sns.color_palette("Blues", n_colors=6)

        # Plot: 3d overview
        fig = plt.figure(figsize=(7 * (1 + np.sqrt(5)) / 2, 7))
        ax = fig.gca(projection='3d')

        # Plot both primaries
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        bodies_df = load_bodies_location()
        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')

        # Plot Lagrange points 1 and 2
        lagrange_points_df = load_lagrange_points_location()
        lagrange_point_nrs = ['L1', 'L2']
        for lagrange_point_nr in lagrange_point_nrs:
            ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'],
                         lagrange_points_df[lagrange_point_nr]['y'],
                         lagrange_points_df[lagrange_point_nr]['z'],
                         color='black',
                         marker='x',
                         s=50)

        # ax.annotate('Moon', xy=(-0.002,0.004),
        #             xytext=(-0.002, 0.04), fontsize=20, ha = 'center', va = 'top',
        #             arrowprops=dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'),
        #             )
        # ax.annotate('$L_1$', xy=(-0.023, 0.012),
        #             xytext=(-0.023, 0.04), fontsize=20, ha='center', va='top',
        #             arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0'),
        #             )
        # ax.annotate('$L_2$', xy=(0.023, -0.004),
        #             xytext=(0.023, 0.04), fontsize=20, ha='center', va='top',
        #             arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0'),
        #             )
        # params = {'legend.fontsize': 16}
        # plt.rcParams.update(params)

        C = 3.1
        # x_range = np.arange(0.7, 1.3, 0.001)
        # y_range = np.arange(-0.3, 0.3, 0.001)
        x_range = np.arange(0.8, 1.2, 0.001)
        y_range = np.arange(-0.2, 0.2, 0.001)
        X, Y = np.meshgrid(x_range, y_range)
        Z = cr3bp_velocity(X, Y, C)

        if Z.min() < 0:
            plt.contourf(X, Y, Z, 0, colors='black', alpha=0.05, zorder=1000)

        linewidth = 2
        df = load_orbit('../../data/raw_equal_energy/horizontal_L1_577.txt')
        ax.plot(df['x'],
                df['y'],
                df['z'],
                color=sns.color_palette("viridis", 3)[0],
                alpha=0.75,
                linestyle='-',
                label='Horizontal Lyapunov',
                linewidth=linewidth)

        df = load_orbit('../../data/raw_equal_energy/halo_L1_799.txt')
        ax.plot(df['x'],
                df['y'],
                df['z'],
                color=sns.color_palette("viridis", 3)[2],
                alpha=0.75,
                linestyle='-',
                label='Halo',
                linewidth=linewidth)

        df = load_orbit('../../data/raw_equal_energy/vertical_L1_1163.txt')
        ax.plot(df['x'],
                df['y'],
                df['z'],
                color=sns.color_palette("viridis", 3)[1],
                alpha=0.75,
                linestyle='-',
                label='Vertical Lyapunov',
                linewidth=linewidth)

        ax.legend(frameon=True, loc='lower right')

        df = load_orbit('../../data/raw_equal_energy/horizontal_L2_760.txt')
        ax.plot(df['x'],
                df['y'],
                df['z'],
                color=sns.color_palette("viridis", 3)[0],
                alpha=0.75,
                linestyle='-',
                linewidth=linewidth)
        df = load_orbit('../../data/raw_equal_energy/vertical_L2_1299.txt')
        ax.plot(df['x'],
                df['y'],
                df['z'],
                color=sns.color_palette("viridis", 3)[1],
                alpha=0.75,
                linestyle='-',
                linewidth=linewidth)
        df = load_orbit('../../data/raw_equal_energy/halo_L2_651.txt')
        ax.plot(df['x'],
                df['y'],
                df['z'],
                color=sns.color_palette("viridis", 3)[2],
                alpha=0.75,
                linestyle='-',
                linewidth=linewidth)

        ax.set_xlabel('x [-]')
        ax.set_ylabel('y [-]')
        ax.set_zlabel('z [-]')
        ax.grid(True, which='both', ls=':')
        # ax.view_init(25, -60)
        ax.view_init(20, -60)
        # ax.set_xlim([0.7, 1.3])
        # ax.set_ylim([-0.3, 0.3])
        # ax.set_zlim([-0.3, 0.3])
        ax.set_xlim([0.8, 1.2])
        ax.set_ylim([-0.2, 0.2])
        ax.set_zlim([-0.2, 0.2])
        plt.tight_layout()

        # plt.show()
        # fig.savefig('../../../data/figures/family_of_equal_energy.png')
        if self.lowDPI:
            fig.savefig('../../data/figures/new_family_of_equal_energy.png',
                        transparent=True,
                        dpi=self.dpi)
        else:
            fig.savefig('../../data/figures/new_family_of_equal_energy.pdf',
                        transparent=True)
        # tikz_save('../../../data/figures/family_of_equal_energy.tex')
        plt.close()
        pass
示例#7
0
import numpy as np
import pandas as pd
import json
import matplotlib
# matplotlib.use('Agg')  # Must be before importing matplotlib.pyplot or pylab!
import matplotlib.pyplot as plt
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.axes_grid.inset_locator import inset_axes
# import seaborn as sns

from load_data import load_orbit, load_bodies_location, load_lagrange_points_location, cr3bp_velocity

mpl.rcParams['axes.linewidth'] = 5

orbit = load_orbit('../../data/verification/ver_halo_1_final_orbit.txt')
orbit['x'] = (orbit['x'] - 1) * 384400e-4
orbit['y'] = orbit['y'] * 384400e-4

eigenvectors_S = pd.read_table(
    '../../data/verification/ver_halo_1_W_S_plus.txt',
    delim_whitespace=True,
    header=None).filter(list(range(6)))
eigenvectors_U = pd.read_table(
    '../../data/verification/ver_halo_1_W_U_plus.txt',
    delim_whitespace=True,
    header=None).filter(list(range(6)))
eigenvectors_S.columns = ['x', 'y', 'z', 'xdot', 'ydot', 'zdot']
eigenvectors_U.columns = ['x', 'y', 'z', 'xdot', 'ydot', 'zdot']
eigenvectors_indices = [np.floor(i * len(orbit) / 20) for i in range(20)]
示例#8
0
    def animate(self):
        fig = plt.figure()
        self.ax = fig.add_subplot(111, projection='3d')

        self.horizontalLyapunov = [
            load_orbit('../../../data/raw/orbits/L' + str(1) + '_horizontal_' +
                       str(self.orbitIds['horizontal'][1][self.cLevel]) +
                       '_100.txt'),
            load_orbit('../../../data/raw/orbits/L' + str(2) + '_horizontal_' +
                       str(self.orbitIds['horizontal'][2][self.cLevel]) +
                       '_100.txt')
        ]

        self.verticalLyapunov = [
            load_orbit('../../../data/raw/orbits/L' + str(1) + '_vertical_' +
                       str(self.orbitIds['vertical'][1][self.cLevel]) +
                       '_100.txt'),
            load_orbit('../../../data/raw/orbits/L' + str(2) + '_vertical_' +
                       str(self.orbitIds['vertical'][2][self.cLevel]) +
                       '_100.txt')
        ]

        self.halo = [
            load_orbit('../../../data/raw/orbits/L' + str(1) + '_halo_' +
                       str(self.orbitIds['halo'][1][self.cLevel]) +
                       '_100.txt'),
            load_orbit('../../../data/raw/orbits/L' + str(2) + '_halo_' +
                       str(self.orbitIds['halo'][2][self.cLevel]) + '_100.txt')
        ]

        self.lines = [
            plt.plot([], [],
                     color=self.orbitColor,
                     alpha=self.orbitAlpha,
                     marker='o',
                     markevery=[-1])[0] for idx in range(6)
        ]

        # Text object to display absolute normalized time of trajectories within the manifolds
        self.timeText = self.ax.text2D(0.05,
                                       0.05,
                                       s='$\|t\| \\approx 0$',
                                       transform=self.ax.transAxes,
                                       size=self.timeTextSize)

        # Plot zero velocity surface
        x_range = np.arange(self.xLim[0], self.xLim[1], 0.001)
        y_range = np.arange(self.yLim[0], self.yLim[1], 0.001)
        x_mesh, y_mesh = np.meshgrid(x_range, y_range)
        z_mesh = cr3bp_velocity(x_mesh, y_mesh, c_level)
        if z_mesh.min() < 0:
            plt.contour(x_mesh,
                        y_mesh,
                        z_mesh, [z_mesh.min(), 0],
                        colors='black',
                        alpha=0.3)

        # Plot both orbits
        for k in range(2):
            plt.plot(self.horizontalLyapunov[k]['x'],
                     self.horizontalLyapunov[k]['y'],
                     self.horizontalLyapunov[k]['z'],
                     color=self.orbitColor,
                     alpha=self.orbitAlpha,
                     linewidth=self.orbitLinewidth,
                     linestyle=':')
            plt.plot(self.verticalLyapunov[k]['x'],
                     self.verticalLyapunov[k]['y'],
                     self.verticalLyapunov[k]['z'],
                     color=self.orbitColor,
                     alpha=self.orbitAlpha,
                     linewidth=self.orbitLinewidth,
                     linestyle=':')
            plt.plot(self.halo[k]['x'],
                     self.halo[k]['y'],
                     self.halo[k]['z'],
                     color=self.orbitColor,
                     alpha=self.orbitAlpha,
                     linewidth=self.orbitLinewidth,
                     linestyle=':')

        # Plot both primaries
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        bodies_df = load_bodies_location()
        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))
            self.ax.plot_surface(x, y, z, color='black')

        # Plot Lagrange points 1 and 2
        lagrange_points_df = load_lagrange_points_location()
        lagrange_point_nrs = ['L1', 'L2']
        for lagrange_point_nr in lagrange_point_nrs:
            self.ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'],
                              lagrange_points_df[lagrange_point_nr]['y'],
                              lagrange_points_df[lagrange_point_nr]['z'],
                              color='black',
                              marker='x',
                              s=self.lagrangePointMarkerSize)

        title = 'Types of periodic libration point motion - Rotating spatial overview at C = ' + str(
            c_level)

        self.ax.set_xlim3d(self.xLim)
        self.ax.set_ylim3d(self.yLim)
        self.ax.set_zlim3d(self.zLim)
        self.ax.set_xlabel('x [-]')
        self.ax.set_ylabel('y [-]')
        self.ax.set_zlabel('z [-]')

        self.ax.grid(True, which='both', ls=':')
        fig.tight_layout()
        fig.subplots_adjust(top=0.9)
        plt.suptitle(title, size=self.suptitleSize)

        # Fix overlap between labels and ticks
        self.ax.xaxis._axinfo['label']['space_factor'] = 2.0
        self.ax.yaxis._axinfo['label']['space_factor'] = 2.0
        self.ax.zaxis._axinfo['label']['space_factor'] = 2.0

        self.initialElevation = self.ax.elev
        self.initialAzimuth = self.ax.azim

        # Determine the maximum value of t
        t_max = 0
        for lagrange_point_idx in [0, 1]:
            t_max = max(
                t_max, self.horizontalLyapunov[lagrange_point_idx].tail(1)
                ['time'].values[0])
            t_max = max(
                t_max, self.verticalLyapunov[lagrange_point_idx].tail(1)
                ['time'].values[0])
            t_max = max(
                t_max, self.halo[lagrange_point_idx].tail(1)['time'].values[0])
        print('Maximum value for t = ' + str(t_max) + ', animation t: = ')

        # Introduce a new time-vector for linearly spaced time throughout the animation
        self.t = np.linspace(0, t_max, np.round(t_max / 0.005) + 1)

        animation_function = animation.FuncAnimation(
            fig,
            self.update_lines,
            init_func=self.initiate_lines,
            frames=len(self.t),
            interval=1,
            blit=True)

        empty_writer_object = animation.writers['ffmpeg']
        animation_writer = empty_writer_object(
            fps=30, metadata=dict(artist='Koen Langemeijer'))
        file_name = '../../../data/animations/orbits/spatial_orbits_rotating_' + str(
            c_level) + '.mp4'
        animation_function.save(file_name, writer=animation_writer)
示例#9
0

orbit_type = 'horizontal'
lagrange_point_nr = 1

# Load data
initial_conditions_file_path = '../data/raw/' + orbit_type + '_L' + str(
    lagrange_point_nr) + '_initial_conditions.txt'
initial_conditions_df = load_initial_conditions(initial_conditions_file_path)

orbit_ids = list(range(len(initial_conditions_df)))

orbit = []
for orbit_id in orbit_ids:
    orbit.append(
        load_orbit('../data/raw/' + orbit_type + '_L' +
                   str(lagrange_point_nr) + '_' + str(orbit_id) + '.txt'))

label_orbit = '$x_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['x'], 3)) \
              + '\n$y_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['y'], 3)) \
              + '\n$z_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['z'], 3)) \
              + '\n$\dot{x}_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['xdot'], 3)) \
              + '\n$\dot{y}_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['ydot'], 3)) \
              + '\n$\dot{z}_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['zdot'], 3))

# Create plot
fig = plt.figure(figsize=(20, 20))
plt.rcParams[
    'animation.ffmpeg_path'] = 'ffmpeg-git-20170607-64bit-static/ffmpeg'
gs = GridSpec(2, 2)
ax1 = plt.subplot(gs[0, :-1], projection='3d')
ax2 = plt.subplot(gs[0, -1])
示例#10
0
    def plot_family(self):
        c_normalized = [(value - min(self.C)) / (max(self.C) - min(self.C))
                        for value in self.C]
        colors = matplotlib.colors.ListedColormap(
            sns.color_palette("viridis_r"))(c_normalized)
        # colors = matplotlib.colors.ListedColormap(sns.dark_palette("blue", reverse=True))(c_normalized)

        sm = plt.cm.ScalarMappable(cmap=matplotlib.colors.ListedColormap(
            sns.color_palette("viridis", len(self.C))),
                                   norm=plt.Normalize(vmin=min(self.C),
                                                      vmax=max(self.C)))
        # sm = plt.cm.ScalarMappable(cmap=sns.dark_palette("blue", as_cmap=True, reverse=True), norm=plt.Normalize(vmin=min(self.C), vmax=max(self.C)))
        # clean the array of the scalar mappable
        sm._A = []

        # Plot 1: 3d overview
        fig1 = plt.figure(figsize=self.figSize)
        ax1 = fig1.gca()

        # Plot 2: subplots
        if self.orbitType == 'horizontal':
            fig2 = plt.figure(figsize=(self.figSize[0], self.figSize[1] / 2))
            ax2 = fig2.add_subplot(1, 2, 1, projection='3d')
            ax5 = fig2.add_subplot(1, 2, 2)
        else:
            fig2 = plt.figure(figsize=self.figSize)
            ax2 = fig2.add_subplot(2, 2, 1, projection='3d')
            ax3 = fig2.add_subplot(2, 2, 4)
            ax4 = fig2.add_subplot(2, 2, 3)
            ax5 = fig2.add_subplot(2, 2, 2)

        lagrange_points_df = load_lagrange_points_location()
        lagrange_point_nrs = ['L1', 'L2']
        # Lagrange points and bodies
        for lagrange_point_nr in lagrange_point_nrs:
            ax1.scatter(lagrange_points_df[lagrange_point_nr]['x'],
                        lagrange_points_df[lagrange_point_nr]['y'],
                        color='black',
                        marker='x')
            ax2.scatter(lagrange_points_df[lagrange_point_nr]['x'],
                        lagrange_points_df[lagrange_point_nr]['y'],
                        lagrange_points_df[lagrange_point_nr]['z'],
                        color='black',
                        marker='x')
            ax5.scatter(lagrange_points_df[lagrange_point_nr]['x'],
                        lagrange_points_df[lagrange_point_nr]['y'],
                        color='black',
                        marker='x')
            if self.orbitType != 'horizontal':
                ax3.scatter(lagrange_points_df[lagrange_point_nr]['x'],
                            lagrange_points_df[lagrange_point_nr]['z'],
                            color='black',
                            marker='x')
                ax4.scatter(lagrange_points_df[lagrange_point_nr]['y'],
                            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)
        x = bodies_df['Moon']['r'] * np.outer(
            np.cos(u), np.sin(v)) + bodies_df['Moon']['x']
        y = bodies_df['Moon']['r'] * np.outer(np.sin(u), np.sin(v))
        z = bodies_df['Moon']['r'] * np.outer(np.ones(np.size(u)), np.cos(v))

        ax1.contourf(x, y, z, colors='black')
        ax2.plot_surface(x, y, z, color='black')
        ax5.contourf(x, y, z, colors='black')
        if self.orbitType != 'horizontal':
            ax3.contourf(x, z, y, colors='black')
            ax4.contourf(y, z, x, colors='black')

        # Determine color for plot
        # colorOrderOfLinearInstability = ['whitesmoke', 'silver', 'dimgrey']
        plot_alpha = 1
        line_width = 0.5

        # Plot every 100th member, including the ultimate member of the family
        spacing_factor = 100

        orbitIdsPlot = list(range(0, len(self.C) - 1, spacing_factor))
        if orbitIdsPlot[-1] != len(self.C) - 1:
            orbitIdsPlot.append(len(self.C) - 1)

        # Plot orbits
        for i in orbitIdsPlot:
            # plot_color = colorOrderOfLinearInstability[self.orderOfLinearInstability[i]]
            nan_correction = sum(
                [1 for nan in self.indexNanEntries if nan < i])
            plot_color = colors[self.plotColorIndexBasedOnC[i -
                                                            nan_correction]]
            df = load_orbit('../../data/raw/orbits/extended/L' +
                            str(self.lagrangePointNr) + '_' + self.orbitType +
                            '_' + str(i) + '.txt')
            ax1.plot(df['x'],
                     df['y'],
                     color=plot_color,
                     alpha=plot_alpha,
                     linewidth=line_width)
            ax2.plot(df['x'],
                     df['y'],
                     df['z'],
                     color=plot_color,
                     alpha=plot_alpha,
                     linewidth=line_width)
            ax5.plot(df['x'],
                     df['y'],
                     color=plot_color,
                     alpha=plot_alpha,
                     linewidth=line_width)
            if self.orbitType != 'horizontal':
                ax3.plot(df['x'],
                         df['z'],
                         color=plot_color,
                         alpha=plot_alpha,
                         linewidth=line_width)
                ax4.plot(df['y'],
                         df['z'],
                         color=plot_color,
                         alpha=plot_alpha,
                         linewidth=line_width)

        # # Plot the bifurcations
        # for i in self.orbitIdBifurcations:
        #     # plot_color = 'b'
        #     nan_correction = sum([1 for nan in self.indexNanEntries if nan < i])
        #     plot_color = colors[self.plotColorIndexBasedOnC[i - nan_correction]]
        #     df = load_orbit('../../data/raw/orbits/extended/L' + str(self.lagrangePointNr) + '_' + self.orbitType + '_' + str(i) + '.txt')
        #     ax1.plot(df['x'], df['y'], color=plot_color, linewidth=3)
        #     ax2.plot(df['x'], df['y'], df['z'], color=plot_color, linewidth=3)
        #     ax5.plot(df['x'], df['y'], color=plot_color, linewidth=3)
        #     if self.orbitType != 'horizontal':
        #         ax3.plot(df['x'], df['z'], color=plot_color, linewidth=3)
        #         ax4.plot(df['y'], df['z'], color=plot_color, linewidth=3)

        ax1.set_xlabel('x [-]')
        ax1.set_ylabel('y [-]')
        ax1.grid(True, which='both', ls=':')

        ax2.set_xlabel('x [-]')
        ax2.set_ylabel('y [-]')
        ax2.set_zlabel('z [-]')
        ax2.set_zlim([-1.2, 1.2])
        ax2.grid(True, which='both', ls=':')
        ax2.view_init(30, -120)

        if self.orbitType != 'horizontal':
            ax3.set_xlabel('x [-]')
            ax3.set_ylabel('z [-]')
            ax3.set_ylim([-1.2, 1.2])
            ax3.grid(True, which='both', ls=':')

            ax4.set_xlabel('y [-]')
            ax4.set_ylabel('z [-]')
            ax4.set_ylim([-1.2, 1.2])
            ax4.grid(True, which='both', ls=':')

        ax5.set_xlabel('x [-]')
        ax5.set_ylabel('y [-]')
        ax5.grid(True, which='both', ls=':')

        fig2.tight_layout()
        if self.orbitType == 'horizontal':
            fig2.subplots_adjust(top=0.8)
        else:
            fig2.subplots_adjust(top=0.9)

        if self.orbitType != 'horizontal':
            cax, kw = matplotlib.colorbar.make_axes([ax2, ax3, ax4, ax5])
        else:
            cax, kw = matplotlib.colorbar.make_axes([ax2, ax5])
        cbar = plt.colorbar(sm, cax=cax, label='C [-]', **kw)

        plt.suptitle('$L_' + str(self.lagrangePointNr) + '$ ' +
                     self.orbitTypeForTitle + ' - Orthographic projection',
                     size=self.suptitleSize)

        fig1.suptitle('$L_' + str(self.lagrangePointNr) + '$ ' +
                      self.orbitTypeForTitle + ': family',
                      size=self.suptitleSize)

        fig2.savefig('../../data/figures/orbits/extended/L' +
                     str(self.lagrangePointNr) + '_' + self.orbitType +
                     '_family_subplots.pdf',
                     transparent=True)
        plt.close(fig2)

        plt.close()
        pass
示例#11
0
    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
source_directory = '../src/verification/'
source_name = 'halo_verification_l1'
plot_suptitle = 'Halo verification L1 (Howell)'

with open(source_directory + source_name + '.json') as data_file:
    config = json.load(data_file)

df = pd.DataFrame.from_dict(config[orbit_type]).T

f, axarr = plt.subplots(6, 2, figsize=(10, 15))
colors = sns.color_palette("Blues", n_colors=6)

row_nr = 0
for idx, row in df.iterrows():

    orbit = load_orbit('../src/verification/' + idx + '_l1.txt')
    label = '$x_0$ = ' + str(row['x']) + '\n$y_0$ = ' + str(row['y']) + '\n$z_0$ = ' + str(row['z']) \
            + '\n$\dot{x}_0$ = ' + str(row['x_dot']) + '\n$\dot{y}_0$ = ' + str(row['y_dot']) + '\n$\dot{z}_0$ = ' \
            + str(row['z_dot'])
    axarr[row_nr, 0].plot(orbit['x'],
                          orbit['y'],
                          color='darkblue',
                          label=label)

    circ = plt.Circle((0, 0),
                      radius=1,
                      edgecolor='k',
                      facecolor='None',
                      linestyle=':')
    axarr[row_nr, 1].add_patch(circ)
    def animate(self):
        self.W_S_plus = [
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' +
                self.orbitType + '_' + str(self.orbitIds[0]) +
                '_W_S_plus.txt'),
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' +
                self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_plus.txt')
        ]
        self.W_S_min = [
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' +
                self.orbitType + '_' + str(self.orbitIds[0]) + '_W_S_min.txt'),
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' +
                self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_min.txt')
        ]
        self.W_U_plus = [
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' +
                self.orbitType + '_' + str(self.orbitIds[0]) +
                '_W_U_plus.txt'),
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' +
                self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_plus.txt')
        ]
        self.W_U_min = [
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' +
                self.orbitType + '_' + str(self.orbitIds[0]) + '_W_U_min.txt'),
            load_manifold_refactored(
                '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' +
                self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_min.txt')
        ]

        self.numberOfOrbitsPerManifold = len(
            set(self.W_S_plus[0].index.get_level_values(0)))
        color_palette_green = sns.dark_palette(
            'green', n_colors=self.numberOfOrbitsPerManifold)
        color_palette_red = sns.dark_palette(
            'red', n_colors=self.numberOfOrbitsPerManifold)

        self.lines = [
            self.ax.plot([], [],
                         color=color_palette_red[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ]
        self.lines.extend([
            self.ax.plot([], [],
                         color=color_palette_green[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ])
        self.lines.extend([
            self.ax.plot([], [],
                         color=color_palette_red[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ])
        self.lines.extend([
            self.ax.plot([], [],
                         color=color_palette_green[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ])
        self.lines.extend([
            self.ax.plot([], [],
                         color=color_palette_red[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ])
        self.lines.extend([
            self.ax.plot([], [],
                         color=color_palette_green[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ])
        self.lines.extend([
            self.ax.plot([], [],
                         color=color_palette_green[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ])
        self.lines.extend([
            self.ax.plot([], [],
                         color=color_palette_red[idx],
                         alpha=self.orbitAlpha)[0]
            for idx in range(self.numberOfOrbitsPerManifold)
        ])

        # Text object to display absolute normalized time of trajectories within the manifolds
        self.timeText = self.ax.text2D(0.05,
                                       0.05,
                                       s='$\|t\| \\approx 0$',
                                       transform=self.ax.transAxes,
                                       size=self.timeTextSize)

        # Plot zero velocity surface
        x_range = np.arange(self.xLim[0], self.xLim[1], 0.001)
        y_range = np.arange(self.yLim[0], self.yLim[1], 0.001)
        x_mesh, y_mesh = np.meshgrid(x_range, y_range)
        z_mesh = cr3bp_velocity(x_mesh, y_mesh, self.cLevel)
        if z_mesh.min() < 0:
            self.ax.contour(x_mesh,
                            y_mesh,
                            z_mesh, [z_mesh.min(), 0],
                            colors='black',
                            alpha=0.3)

        # Plot both orbits
        for k in range(2):
            orbit_df = load_orbit('../../../data/raw/orbits/refined_for_c/L' +
                                  str(k + 1) + '_' + self.orbitType + '_' +
                                  str(self.orbitIds[k]) + '.txt')
            self.ax.plot(orbit_df['x'],
                         orbit_df['y'],
                         orbit_df['z'],
                         color=self.orbitColor,
                         alpha=self.orbitAlpha,
                         linewidth=self.orbitLinewidth)

        # Plot both primaries
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        bodies_df = load_bodies_location()
        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))
            self.ax.plot_surface(x, y, z, color='black')

        # Plot Lagrange points 1 and 2
        lagrange_points_df = load_lagrange_points_location()
        lagrange_point_nrs = ['L1', 'L2']
        for lagrange_point_nr in lagrange_point_nrs:
            self.ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'],
                              lagrange_points_df[lagrange_point_nr]['y'],
                              lagrange_points_df[lagrange_point_nr]['z'],
                              color='black',
                              marker='x',
                              s=self.lagrangePointMarkerSize)

        title = self.orbitTypeForTitle + ' $\{ \mathcal{W}^{S \pm}, \mathcal{W}^{U \pm} \}$ - Orthographic projection (C = ' + str(
            c_level) + ')'

        # self.ax.set_xlim3d(self.xLim)
        # self.ax.set_ylim3d(self.yLim)
        # self.ax.set_zlim3d(self.zLim)
        self.ax.set_xlim(self.xLim)
        self.ax.set_ylim(self.yLim)
        self.ax.set_zlim(self.zLim)
        self.ax.axis('off')

        # fig.tight_layout()
        self.fig.subplots_adjust(top=0.9)
        self.fig.suptitle(title, size=self.suptitleSize)

        self.initialElevation = self.ax.elev
        self.initialAzimuth = self.ax.azim

        # Determine the maximum value of t
        t_max = 0
        for lagrange_point_idx in [0, 1]:
            for index in range(self.numberOfOrbitsPerManifold):
                t_max = max(
                    t_max,
                    abs(self.W_S_plus[lagrange_point_idx].xs(index).head(
                        1).index.values[0]))
                t_max = max(
                    t_max,
                    abs(self.W_S_min[lagrange_point_idx].xs(index).head(
                        1).index.values[0]))
                t_max = max(
                    t_max,
                    abs(self.W_U_plus[lagrange_point_idx].xs(index).tail(
                        1).index.values[0]))
                t_max = max(
                    t_max,
                    abs(self.W_U_min[lagrange_point_idx].xs(index).tail(
                        1).index.values[0]))
        print('Maximum value for t = ' + str(t_max) + ', animation t: = ')

        # Introduce a new time-vector for linearly spaced time throughout the animation
        self.t = np.linspace(0, t_max, np.round(t_max / 0.01) + 1)

        self.animation_function = animation.FuncAnimation(
            self.fig,
            self.update_lines,
            init_func=self.initiate_lines,
            frames=len(self.t),
            interval=1,
            blit=True)

        self.empty_writer_object = animation.writers['ffmpeg']
        self.animation_writer = self.empty_writer_object(
            fps=30, metadata=dict(artist='Koen Langemeijer'))
        self.file_name = '../../../data/animations/manifolds/spatial_manifolds_rotating_no_axes_' + self.orbitType + '_' + str(
            self.cLevel) + '.mp4'
        self.animation_function.save(self.file_name,
                                     writer=self.animation_writer)
示例#14
0
    def update_lines(self, i):
        if i % 10 == 0:
            print(i)

        index_for_vertical = 0

        for j, line in enumerate(self.lines):

            if i <= self.orbitIdBifurcationsFromHorizontalLyapunov[1]:
                jacobi_energy = self.jacobiEnergyHorizontalLyapunov[i]
                self.jacobiEnergyText.set_text(
                    'Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format(
                        round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' +
                                      str(self.librationPointNr) +
                                      '_horizontal_' + str(i) + '.txt')

            elif self.orbitIdBifurcationsFromHorizontalLyapunov[
                    1] < i <= self.orbitIdBifurcationsFromHorizontalLyapunov[
                        1] + self.numberOfAxialOrbits:
                index_for_axial = i - self.orbitIdBifurcationsFromHorizontalLyapunov[
                    1] - 1
                jacobi_energy = self.jacobiEnergyAxial[index_for_axial]
                self.jacobiEnergyText.set_text(
                    'Axial family \n $C \\approx$ {:.4f}'.format(
                        round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' +
                                      str(self.librationPointNr) + '_axial_' +
                                      str(index_for_axial) + '.txt')
            else:
                index_for_vertical = self.verticalLyapunovIndices[
                    i - self.orbitIdBifurcationsFromHorizontalLyapunov[1] -
                    self.numberOfAxialOrbits - 1]
                jacobi_energy = self.jacobiEnergyVerticalLyapunov[
                    index_for_vertical]
                self.jacobiEnergyText.set_text(
                    'Vertical Lyapunov family \n $C \\approx$ {:.4f}'.format(
                        round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' +
                                      str(self.librationPointNr) +
                                      '_vertical_' + str(index_for_vertical) +
                                      '.txt')

            if i in self.orbitIdBifurcationsFromHorizontalLyapunov and i <= self.orbitIdBifurcationsFromHorizontalLyapunov[
                    1]:
                plt.plot(orbit_df['x'],
                         orbit_df['y'],
                         orbit_df['z'],
                         color='navy',
                         linewidth=2)

            if index_for_vertical == self.orbitIdBifurcationsFromVerticalLyapunov[
                    0]:
                plt.plot(orbit_df['x'],
                         orbit_df['y'],
                         orbit_df['z'],
                         color='navy',
                         linewidth=2)

            x = orbit_df['x'].tolist()
            y = orbit_df['y'].tolist()
            z = orbit_df['z'].tolist()

            line.set_data(x, y)
            line.set_3d_properties(z)
            pass

        if i % 100 == 0 and i != 0:
            plt.plot(orbit_df['x'],
                     orbit_df['y'],
                     orbit_df['z'],
                     color='gray',
                     linewidth=1)
        return self.lines
示例#15
0
    def update_lines(self, i):
        if i % 10 == 0:
            print(i)

        index_for_vertical = 0

        for j, line in enumerate(self.lines):

            if i <= self.orbitIdBifurcationsFromHorizontalLyapunov[1]:
                jacobi_energy = self.jacobiEnergyHorizontalLyapunov[i]
                self.jacobiEnergyText.set_text(
                    'Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format(
                        round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' +
                                      str(self.librationPointNr) +
                                      '_horizontal_' + str(i) + '.txt')

            elif self.orbitIdBifurcationsFromHorizontalLyapunov[
                    1] < i <= self.orbitIdBifurcationsFromHorizontalLyapunov[
                        1] + self.numberOfAxialOrbits:
                index_for_axial = i - self.orbitIdBifurcationsFromHorizontalLyapunov[
                    1] - 1
                jacobi_energy = self.jacobiEnergyAxial[index_for_axial]
                self.jacobiEnergyText.set_text(
                    'Axial family \n $C \\approx$ {:.4f}'.format(
                        round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' +
                                      str(self.librationPointNr) + '_axial_' +
                                      str(index_for_axial) + '.txt')
                line.set_color(self.orbitColors['halo'])
            else:
                index_for_vertical = self.verticalLyapunovIndices[
                    i - self.orbitIdBifurcationsFromHorizontalLyapunov[1] -
                    self.numberOfAxialOrbits - 1]
                jacobi_energy = self.jacobiEnergyVerticalLyapunov[
                    index_for_vertical]
                self.jacobiEnergyText.set_text(
                    'Vertical Lyapunov family \n $C \\approx$ {:.4f}'.format(
                        round(jacobi_energy, 4)))
                orbit_df = load_orbit('../../../data/raw/orbits/L' +
                                      str(self.librationPointNr) +
                                      '_vertical_' + str(index_for_vertical) +
                                      '.txt')
                line.set_color(self.orbitColors['vertical'])

            if i in self.orbitIdBifurcationsFromHorizontalLyapunov and i <= self.orbitIdBifurcationsFromHorizontalLyapunov[
                    1]:
                self.ax.plot(orbit_df['x'],
                             orbit_df['y'],
                             orbit_df['z'],
                             color=self.orbitColors['horizontal'],
                             linewidth=self.bifurcationLinewidth)

            if index_for_vertical == self.orbitIdBifurcationsFromVerticalLyapunov[
                    0]:
                self.ax.plot(orbit_df['x'],
                             orbit_df['y'],
                             orbit_df['z'],
                             color=self.orbitColors['halo'],
                             linewidth=self.bifurcationLinewidth)

            x = orbit_df['x'].tolist()
            y = orbit_df['y'].tolist()
            z = orbit_df['z'].tolist()

            line.set_data(x, y)
            line.set_3d_properties(z)
            pass

        if self.includeSurfaceHill:
            z_mesh = cr3bp_velocity(self.x_mesh, self.y_mesh, jacobi_energy)
            if self.setContourLastTime:
                for coll in self.contour.collections:
                    self.ax.collections.remove(coll)
            if z_mesh.min() < 0:
                self.contour = self.ax.contour(
                    self.x_mesh,
                    self.y_mesh,
                    z_mesh,
                    list(np.linspace(z_mesh.min(), 0, 10)),
                    cmap='gist_gray_r',
                    alpha=0.5)
                self.setContourLastTime = True
            else:
                self.setContourLastTime = False

        if i % 100 == 0 and i != 0:
            if i <= self.orbitIdBifurcationsFromHorizontalLyapunov[1]:
                plt.plot(orbit_df['x'],
                         orbit_df['y'],
                         orbit_df['z'],
                         color=self.orbitColors['horizontal'],
                         linewidth=self.orbitLinewidth)
            elif self.orbitIdBifurcationsFromHorizontalLyapunov[
                    1] < i <= self.orbitIdBifurcationsFromHorizontalLyapunov[
                        1] + self.numberOfAxialOrbits:
                plt.plot(orbit_df['x'],
                         orbit_df['y'],
                         orbit_df['z'],
                         color=self.orbitColors['halo'],
                         linewidth=self.orbitLinewidth)
            else:
                plt.plot(orbit_df['x'],
                         orbit_df['y'],
                         orbit_df['z'],
                         color=self.orbitColors['vertical'],
                         linewidth=self.orbitLinewidth)
        return self.lines
示例#16
0
    def animate(self):
        print(
            '\nProducing a HorizontalLyapunovBifurcationToAxialAnimation at L'
            + str(self.librationPointNr) + '\n')

        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        self.lines = [
            plt.plot([], [], color=self.orbitColor, alpha=self.orbitAlpha)[0]
        ]

        # Text object to display absolute normalized time of trajectories within the manifolds
        self.jacobiEnergyText = ax.text2D(
            0.05,
            0.05,
            s='Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format(
                round(self.jacobiEnergyHorizontalLyapunov[0], 4)),
            transform=ax.transAxes,
            size=self.timeTextSize)

        # Plot the first orbit
        orbit_df = load_orbit('../../../data/raw/orbits/L' +
                              str(self.librationPointNr) + '_horizontal_' +
                              str(0) + '.txt')
        plt.plot(orbit_df['x'],
                 orbit_df['y'],
                 orbit_df['z'],
                 color='orange',
                 alpha=self.orbitAlpha,
                 linewidth=self.orbitLinewidth)

        # Plot the Moon
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        bodies_df = load_bodies_location()
        x = bodies_df['Moon']['r'] * np.outer(
            np.cos(u), np.sin(v)) + bodies_df['Moon']['x']
        y = bodies_df['Moon']['r'] * np.outer(np.sin(u), np.sin(v))
        z = bodies_df['Moon']['r'] * np.outer(np.ones(np.size(u)), np.cos(v))
        ax.plot_surface(x, y, z, color='black')

        # Plot Lagrange points 1 and 2
        lagrange_points_df = load_lagrange_points_location()
        lagrange_point_nrs = ['L1', 'L2']
        for lagrange_point_nr in lagrange_point_nrs:
            ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'],
                         lagrange_points_df[lagrange_point_nr]['y'],
                         lagrange_points_df[lagrange_point_nr]['z'],
                         color='black',
                         marker='x',
                         s=self.lagrangePointMarkerSize)

        title = 'Bifurcation from horizontal Lyapunov to axial and vertical Lyapunov families at $L_' + str(
            self.librationPointNr) + '$'

        ax.set_xlim3d(self.xLim)
        ax.set_ylim3d(self.yLim)
        ax.set_zlim3d(self.zLim)
        ax.set_xlabel('x [-]')
        ax.set_ylabel('y [-]')
        ax.set_zlabel('z [-]')
        plt.show()
        ax.grid(True, which='both', ls=':')
        fig.tight_layout()
        fig.subplots_adjust(top=0.9)
        plt.suptitle(title, size=self.suptitleSize)

        # Fix overlap between labels and ticks
        ax.xaxis._axinfo['label']['space_factor'] = 2.0
        ax.yaxis._axinfo['label']['space_factor'] = 2.0
        ax.zaxis._axinfo['label']['space_factor'] = 2.0
        # ax.elev = 10
        # ax.azim = -80

        # Determine number of frames
        number_of_frames = int(
            self.orbitIdBifurcationsFromHorizontalLyapunov[1] + 1 +
            self.numberOfAxialOrbits + len(self.verticalLyapunovIndices))
        print('Number of frames equals ' + str(number_of_frames))

        animation_function = animation.FuncAnimation(
            fig,
            self.update_lines,
            init_func=self.initiate_lines,
            frames=number_of_frames,
            interval=1,
            blit=True)

        empty_writer_object = animation.writers['ffmpeg']
        animation_writer = empty_writer_object(
            fps=30, metadata=dict(artist='Koen Langemeijer'))
        file_name = '../../../data/animations/bifurcations/L' + str(
            self.librationPointNr
        ) + '_horizontal_lyapunov_bifurcation_to_axial_family.mp4'
        animation_function.save(file_name, writer=animation_writer)
        fig = plt.figure(figsize=(20, 20))
        ax = fig.add_subplot(111, projection='3d')
        plt.rcParams[
            'animation.ffmpeg_path'] = 'ffmpeg-git-20170607-64bit-static/ffmpeg'

        ax.set_xlim3d([1.1, 1.2])
        ax.set_xlabel('x')
        ax.set_ylim3d([-0.05, 0.05])
        ax.set_ylabel('y')
        ax.set_zlim3d([-0.05, 0.05])
        ax.set_zlabel('z')

        time_text = ax.text(1, 1, 1, s='', transform=ax.transAxes, size=22)

        orbit = load_orbit('../data/raw/' + orbit_name + '_final_orbit.txt')
        manifold_S_plus = load_manifold('../data/raw/' + orbit_name +
                                        '_W_S_plus.txt')
        manifold_S_min = load_manifold('../data/raw/' + orbit_name +
                                       '_W_S_min.txt')
        manifold_U_plus = load_manifold('../data/raw/' + orbit_name +
                                        '_W_U_plus.txt')
        manifold_U_min = load_manifold('../data/raw/' + orbit_name +
                                       '_W_U_min.txt')

        plt.plot(orbit['x'], orbit['y'], orbit['z'], color='blue')

        C = float(config[orbit_type][orbit_name]['C'])
        x_range = np.arange(0.5, 1.5, 0.001)
        y_range = np.arange(-0.5, 0.5, 0.001)
        X, Y = np.meshgrid(x_range, y_range)
    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
示例#19
0
    def plot_horizontal_to_halo(self):
        fig = plt.figure(figsize=self.figSize)
        ax1 = fig.add_subplot(2, 2, 1, projection='3d')
        ax2 = fig.add_subplot(2, 2, 2)
        ax3 = fig.add_subplot(2, 2, 3)
        ax4 = fig.add_subplot(2, 2, 4)

        horizontal_color = self.plottingColors['tripleLine'][2]
        halo_color = self.plottingColors['tripleLine'][0]

        # Plot bifurcations
        line_width = 2
        plot_alpha = 1
        df = load_orbit('../../data/raw/orbits/L1_horizontal_' +
                        str(self.horizontalBifurcations[0]) + '.txt')
        l1, = ax1.plot(df['x'],
                       df['y'],
                       df['z'],
                       color=horizontal_color,
                       alpha=plot_alpha,
                       linewidth=1,
                       label='Horizontal Lyapunov')
        ax1.plot(df['x'],
                 df['y'],
                 df['z'],
                 color=horizontal_color,
                 alpha=plot_alpha,
                 linewidth=line_width)
        ax2.plot(df['x'],
                 df['y'],
                 color=horizontal_color,
                 alpha=plot_alpha,
                 linewidth=line_width)
        ax3.plot(df['y'],
                 df['z'],
                 color=horizontal_color,
                 alpha=plot_alpha,
                 linewidth=line_width)
        ax4.plot(df['x'],
                 df['z'],
                 color=horizontal_color,
                 alpha=plot_alpha,
                 linewidth=line_width)

        number_of_orbits = 10
        line_width = 1
        plot_alpha = 0.5
        for i in [
                int(i)
                for i in (np.linspace(1, self.haloMaxId, number_of_orbits))
        ]:
            df = load_orbit('../../data/raw/orbits/L1_halo_' + str(i) + '.txt')
            l2, = ax1.plot(df['x'],
                           df['y'],
                           df['z'],
                           color=halo_color,
                           alpha=plot_alpha,
                           linewidth=line_width,
                           label='Halo')
            ax2.plot(df['x'],
                     df['y'],
                     color=halo_color,
                     alpha=plot_alpha,
                     linewidth=line_width)
            ax3.plot(df['y'],
                     df['z'],
                     color=halo_color,
                     alpha=plot_alpha,
                     linewidth=line_width)
            ax4.plot(df['x'],
                     df['z'],
                     color=halo_color,
                     alpha=plot_alpha,
                     linewidth=line_width)

            # Lagrange points and bodies
            lagrange_points_df = load_lagrange_points_location()
            lagrange_point_nrs = ['L1', 'L2']
            for lagrange_point_nr in lagrange_point_nrs:
                ax1.scatter(lagrange_points_df[lagrange_point_nr]['x'],
                            lagrange_points_df[lagrange_point_nr]['y'],
                            lagrange_points_df[lagrange_point_nr]['z'],
                            color='black',
                            marker='x')
                ax2.scatter(lagrange_points_df[lagrange_point_nr]['x'],
                            lagrange_points_df[lagrange_point_nr]['y'],
                            color='black',
                            marker='x')
                ax3.scatter(lagrange_points_df[lagrange_point_nr]['y'],
                            lagrange_points_df[lagrange_point_nr]['z'],
                            color='black',
                            marker='x')
                ax4.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 ['Moon']:
                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))
                ax1.plot_surface(x, y, z, color='black')
                ax2.contourf(x, y, z, colors='black')
                ax3.contourf(y, z, x, colors='black')
                ax4.contourf(x, z, y, colors='black')

        ax1.set_xlabel('x [-]')
        ax1.set_ylabel('y [-]')
        ax1.set_zlabel('z [-]')
        ax1.grid(True, which='both', ls=':')

        ax2.set_xlabel('x [-]')
        ax2.set_ylabel('y [-]')
        ax2.grid(True, which='both', ls=':')

        ax3.set_xlabel('y [-]')
        ax3.set_ylabel('z [-]')
        ax3.grid(True, which='both', ls=':')

        ax4.set_xlabel('x [-]')
        ax4.set_ylabel('z [-]')
        ax4.grid(True, which='both', ls=':')

        plt.tight_layout()
        plt.subplots_adjust(top=0.9)
        ax1.legend(frameon=True, handles=[l1, l2])
        plt.suptitle(
            '$L_1$ Bifurcation - Halo family connecting to horizontal Lyapunov orbits',
            size=self.suptitleSize)
        plt.savefig('../../data/figures/orbits/L1_bifurcation_halo.pdf',
                    transparent=True)
        plt.close()
        pass
    def animate(self):
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        self.W_S_plus = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_S_plus.txt'),
                         load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_plus.txt')]
        self.W_S_min = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_S_min.txt'),
                        load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_min.txt')]
        self.W_U_plus = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_U_plus.txt'),
                         load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_plus.txt')]
        self.W_U_min = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_U_min.txt'),
                        load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_min.txt')]

        self.numberOfOrbitsPerManifold = len(set(self.W_S_plus[0].index.get_level_values(0)))
        color_palette_green = sns.dark_palette('green', n_colors=self.numberOfOrbitsPerManifold)
        color_palette_red = sns.dark_palette('red', n_colors=self.numberOfOrbitsPerManifold)

        self.lines = [plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]
        self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)])
        self.lines.extend([plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)])
        self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)])
        self.lines.extend([plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)])
        self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)])
        self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)])
        self.lines.extend([plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)])

        # Text object to display absolute normalized time of trajectories within the manifolds
        self.timeText = ax.text2D(0.05, 0.05, s='$\|t\| \\approx 0$', transform=ax.transAxes, size=self.timeTextSize)

        # Plot zero velocity surface
        x_range = np.arange(self.xLim[0], self.xLim[1], 0.001)
        y_range = np.arange(self.yLim[0], self.yLim[1], 0.001)
        x_mesh, y_mesh = np.meshgrid(x_range, y_range)
        z_mesh = cr3bp_velocity(x_mesh, y_mesh, c_level)
        if z_mesh.min() < 0:
            plt.contour(x_mesh, y_mesh, z_mesh, [z_mesh.min(), 0], colors='black', alpha=0.3)

        # Plot both orbits
        for k in range(2):
            orbit_df = load_orbit('../../../data/raw/orbits/L' + str(k+1) + '_' + self.orbitType + '_' + str(self.orbitIds[k]) + '.txt')
            plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColor, alpha=self.orbitAlpha, linewidth=self.orbitLinewidth)

        # Plot both primaries
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        bodies_df = load_bodies_location()
        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')

        # Plot Lagrange points 1 and 2
        lagrange_points_df = load_lagrange_points_location()
        lagrange_point_nrs = ['L1', 'L2']
        for lagrange_point_nr in lagrange_point_nrs:
            ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'],
                         lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x', s=self.lagrangePointMarkerSize)

        title = self.orbitTypeForTitle + ' $\{ \mathcal{W}^{S \pm}, \mathcal{W}^{U \pm} \}$ - Spatial overview at C = ' + str(c_level)

        ax.set_xlim3d(self.xLim)
        ax.set_ylim3d(self.yLim)
        ax.set_zlim3d(self.zLim)
        ax.set_xlabel('x [-]')
        ax.set_ylabel('y [-]')
        ax.set_zlabel('z [-]')

        ax.grid(True, which='both', ls=':')
        fig.tight_layout()
        fig.subplots_adjust(top=0.9)
        plt.suptitle(title, size=self.suptitleSize)

        # Fix overlap between labels and ticks
        ax.xaxis._axinfo['label']['space_factor'] = 6.0
        ax.yaxis._axinfo['label']['space_factor'] = 6.0
        ax.zaxis._axinfo['label']['space_factor'] = 6.0

        # Determine the maximum value of t
        t_max = 0
        for lagrange_point_idx in [0, 1]:
            for index in range(self.numberOfOrbitsPerManifold):
                t_max = max(t_max, abs(self.W_S_plus[lagrange_point_idx].xs(index).tail(1).index.values[0]))
                t_max = max(t_max, abs(self.W_S_min[lagrange_point_idx].xs(index).tail(1).index.values[0]))
                t_max = max(t_max, abs(self.W_U_plus[lagrange_point_idx].xs(index).tail(1).index.values[0]))
                t_max = max(t_max, abs(self.W_U_min[lagrange_point_idx].xs(index).tail(1).index.values[0]))
        print('Maximum value for t = ' + str(t_max) + ', animation t: = ')

        # Introduce a new time-vector for linearly spaced time throughout the animation
        self.t = np.linspace(0, t_max, np.round(t_max / 0.04) + 1)

        animation_function = animation.FuncAnimation(fig, self.update_lines, init_func=self.initiate_lines,
                                                     frames=len(self.t), interval=1, blit=True)

        #
        # # Determine the maximum number of frames
        # number_of_frames = 0
        # for lagrange_point_idx in [0, 1]:
        #     for index in range(self.numberOfOrbitsPerManifold):
        #         number_of_frames = max(number_of_frames, len(self.W_S_plus[lagrange_point_idx].xs(index)['x']))
        #         number_of_frames = max(number_of_frames, len(self.W_S_min[lagrange_point_idx].xs(index)['x']))
        #         number_of_frames = max(number_of_frames, len(self.W_U_plus[lagrange_point_idx].xs(index)['x']))
        #         number_of_frames = max(number_of_frames, len(self.W_U_min[lagrange_point_idx].xs(index)['x']))
        #
        # animation_function = animation.FuncAnimation(fig, self.update_lines, init_func=self.initiate_lines,
        #                                              frames=int(number_of_frames), interval=1, blit=True)

        empty_writer_object = animation.writers['ffmpeg']
        animation_writer = empty_writer_object(fps=30, metadata=dict(artist='Koen Langemeijer'))
        file_name = '../../../data/animations/manifolds/spatial_manifolds_' + orbit_type + '_' + str(c_level) + '.mp4'
        animation_function.save(file_name, writer=animation_writer)
    def animate(self):

        color_palette_green = sns.dark_palette(
            'green', n_colors=self.numberOfOrbitsPerManifold)
        color_palette_red = sns.dark_palette(
            'red', n_colors=self.numberOfOrbitsPerManifold)

        self.lines = [
            self.ax.plot([], [],
                         color='red',
                         linewidth=self.orbitLinewidth,
                         alpha=self.orbitAlpha)[0],
            self.ax.plot([], [],
                         color='green',
                         linewidth=self.orbitLinewidth,
                         alpha=self.orbitAlpha)[0]
        ]

        # Text object to display absolute normalized time of trajectories within the manifolds
        self.timeText = self.ax.text2D(0.05,
                                       0.05,
                                       s='$\|t\| \\approx 0$',
                                       transform=self.ax.transAxes,
                                       size=self.timeTextSize)

        # Plot zero velocity surface
        x_range = np.arange(self.xLim[0], self.xLim[1], 0.001)
        y_range = np.arange(self.yLim[0], self.yLim[1], 0.001)
        x_mesh, y_mesh = np.meshgrid(x_range, y_range)
        z_mesh = cr3bp_velocity(x_mesh, y_mesh, self.cLevel)
        if z_mesh.min() < 0:
            # plt.contour(x_mesh, y_mesh, z_mesh, [z_mesh.min(), 0], colors='black', alpha=0.3)
            self.ax.contour(x_mesh,
                            y_mesh,
                            z_mesh,
                            list(np.linspace(z_mesh.min(), 0, 10)),
                            cmap='gist_gray_r',
                            alpha=0.5)

        # Plot both orbits
        for k in range(2):
            orbit_df = load_orbit(
                '../../../data/raw/orbits/refined_for_c/L' + str(k + 1) + '_' +
                self.orbitType + '_' +
                str(self.orbitIds[self.orbitType][k + 1][self.cLevel]) +
                '.txt')
            self.ax.plot(orbit_df['x'],
                         orbit_df['y'],
                         orbit_df['z'],
                         color=self.orbitColor,
                         alpha=self.orbitAlpha,
                         linewidth=2,
                         linestyle=':')

        # Plot both primaries
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        bodies_df = load_bodies_location()
        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))
            self.ax.plot_surface(x, y, z, color='black')

        # Plot Lagrange points 1 and 2
        lagrange_points_df = load_lagrange_points_location()
        lagrange_point_nrs = ['L1', 'L2']
        for lagrange_point_nr in lagrange_point_nrs:
            self.ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'],
                              lagrange_points_df[lagrange_point_nr]['y'],
                              lagrange_points_df[lagrange_point_nr]['z'],
                              color='black',
                              marker='x',
                              s=self.lagrangePointMarkerSize)

        title = self.orbitTypeForTitle + ' $\{ \mathcal{W}^{S \pm}, \mathcal{W}^{U \pm} \}$ - Orthographic projection (C = ' + str(
            self.cLevel) + ')'

        self.ax.set_xlim(self.xLim)
        self.ax.set_ylim(self.yLim)
        self.ax.set_zlim(self.zLim)
        self.ax.set_xlabel('x [-]')
        self.ax.set_ylabel('y [-]')
        self.ax.set_zlabel('z [-]')

        self.ax.grid(True, which='both', ls=':')
        # self.fig.tight_layout()
        self.fig.subplots_adjust(top=0.9)
        self.fig.suptitle(title, size=self.suptitleSize)

        # Fix overlap between labels and ticks
        self.ax.xaxis._axinfo['label']['space_factor'] = 6.0
        self.ax.yaxis._axinfo['label']['space_factor'] = 6.0
        self.ax.zaxis._axinfo['label']['space_factor'] = 6.0

        # Determine the maximum value of t
        t_max = max(abs(self.W_U_plus.index)) + max(abs(self.W_S_min.index))
        print('Maximum value for unstable = ' +
              str(max(abs(self.W_U_plus.index))))
        print('Maximum value for stable = ' +
              str(max(abs(self.W_S_min.index))))
        print('Maximum value for t = ' + str(t_max) + ', animation t: = ')

        # Introduce a new time-vector for linearly spaced time throughout the animation
        self.t = np.linspace(0, t_max, 150)

        self.animation_function = animation.FuncAnimation(
            self.fig,
            self.update_lines,
            init_func=self.initiate_lines,
            frames=len(self.t),
            interval=1,
            blit=True)

        self.empty_writer_object = animation.writers['ffmpeg']
        self.animation_writer = self.empty_writer_object(
            fps=30, metadata=dict(artist='Koen Langemeijer'))
        self.file_name = '../../../data/animations/natural_connections/spatial_heteroclinic_' + self.orbitType + '_' + str(
            int(self.theta)) + '.mp4'
        self.animation_function.save(self.file_name,
                                     writer=self.animation_writer)