Exemple #1
0
def disk_plot_comparison_old(u1,
                             u2,
                             params,
                             force_dir,
                             location,
                             save=False,
                             cfd=False):

    force = "Lift" if force_dir == "L" else "Drag"
    type_snap = 'cfd' if cfd else 'rmac'
    err_front, err_rear = l2error(u1, params, type_snap, u2, params, type_snap)

    if cfd:
        radial_grid = params['RadialGrid'].reshape(-1, 1)
        dr = np.diff(radial_grid, axis=0)
        dr = np.vstack((radial_grid[1], dr))
        u1 = weighting(u1, 1 / dr, mode='repmat')
        u2 = weighting(u2, 1 / dr, mode='repmat')

    if np.shape(u1)[0] == np.shape(u2)[0]:
        n_row = np.shape(u1)[0]
    else:
        print('Dimensions of Snapshot to compare must be the same')
        return

    dx, dy = get_dx_dy(location, params)

    n_r = params['n_r']
    n_theta = params['n_theta']

    azimuths = np.radians(params['AzimuthalGrid'])
    zeniths = params['RadialGrid']

    theta, r = np.meshgrid(azimuths, zeniths)

    front_rotor = u1[0:n_row // 2]
    rear_rotor = u1[n_row // 2:]

    front_rotor1 = np.reshape(front_rotor, (n_r, n_theta), 'F')
    rear_rotor1 = np.reshape(rear_rotor, (n_r, n_theta), 'F')

    front_rotor = u2[0:n_row // 2]
    rear_rotor = u2[n_row // 2:]

    front_rotor2 = np.reshape(front_rotor, (n_r, n_theta), 'F')
    rear_rotor2 = np.reshape(rear_rotor, (n_r, n_theta), 'F')

    plt.rc('grid', linestyle="-", color='black', lw=0.8)

    fig, axes = plt.subplots(3,
                             2,
                             figsize=(10, 12),
                             subplot_kw=dict(projection='polar'))
    fig.subplots_adjust(wspace=0.3, hspace=0.35)

    # config = "$(d_x, d_y)$ = (" + str(dx) + ", " + str(dy) + ")"
    # title = fig.suptitle(("Disk Plots of {} [N/m] at " + config).format(force), fontsize=14)
    # title.set_position([0.5, 0.95])

    axes[0, 0].set_title('Front Rotor Snapshot', fontsize=12, pad=15)
    axes[0, 1].set_title('Rear Rotor Snapshot', fontsize=12, pad=15)
    axes[1, 0].set_title('Front Rotor Reconstruction', fontsize=12, pad=15)
    axes[1, 1].set_title('Rear Rotor Reconstruction', fontsize=12, pad=15)
    axes[2, 0].set_title('Difference, L2 error =' + str(err_front) + '%',
                         fontsize=12,
                         pad=15)
    axes[2, 1].set_title('Difference, L2 error =' + str(err_rear) + '%',
                         fontsize=12,
                         pad=15)

    im1 = axes[0, 0].contourf(theta,
                              r,
                              front_rotor1,
                              vmax=2700,
                              levels=150,
                              cmap='rainbow')
    axes[0, 0].set_theta_direction(-1)
    fig.colorbar(im1, ax=axes[0, 0], fraction=0.046, pad=0.04)
    plt.grid()

    im2 = axes[0, 1].contourf(theta,
                              r,
                              rear_rotor1,
                              vmax=2700,
                              levels=150,
                              cmap='rainbow')
    fig.colorbar(im2, ax=axes[0, 1], fraction=0.046, pad=0.04)
    plt.grid()

    im3 = axes[1, 0].contourf(theta,
                              r,
                              front_rotor2,
                              vmax=2700,
                              levels=150,
                              cmap='rainbow')
    axes[1, 0].set_theta_direction(-1)
    fig.colorbar(im3, ax=axes[1, 0], fraction=0.046, pad=0.04)
    plt.grid()

    im4 = axes[1, 1].contourf(theta,
                              r,
                              rear_rotor2,
                              vmax=2700,
                              levels=150,
                              cmap='rainbow')
    fig.colorbar(im4, ax=axes[1, 1], fraction=0.046, pad=0.04)
    plt.grid()

    im5 = axes[2, 0].contourf(theta,
                              r,
                              front_rotor1 - front_rotor2,
                              vmax=500,
                              vmin=-500,
                              levels=100,
                              cmap='rainbow')
    axes[2, 0].set_theta_direction(-1)
    fig.colorbar(im5, ax=axes[2, 0], fraction=0.046, pad=0.04)
    plt.grid()

    im6 = axes[2, 1].contourf(theta,
                              r,
                              rear_rotor1 - rear_rotor2,
                              vmax=500,
                              vmin=-500,
                              levels=100,
                              cmap='rainbow')
    fig.colorbar(im6, ax=axes[2, 1], fraction=0.046, pad=0.04)
    plt.grid()

    if save:
        fig_name = ("Disk_Plot_{}_Comparison_dx=" + str(dx) + "dy =" +
                    str(dy) + ".png").format(force)
        plt.savefig(fig_name, bbox_inches='tight')

    plt.show()
Exemple #2
0
def disk_plot_comparison(u1,
                         params1,
                         type1,
                         u2,
                         params2,
                         type2,
                         force_dir,
                         location,
                         save=False):

    force = "Lift" if force_dir == "L" else "Drag"
    err_front, err_rear = l2error(u1, params1, type1, u2, params2, type2)
    dx, dy = get_dx_dy(location, params1)

    if type1 == 'cfd':
        radial_grid = params1['RadialGrid'].reshape(-1, 1)
        dr = np.diff(radial_grid, axis=0)
        dr = np.vstack((radial_grid[1], dr))
        u1 = weighting(u1, 1 / dr, mode='repmat')

    if type2 == 'cfd':
        radial_grid = params2['RadialGrid'].reshape(-1, 1)
        dr = np.diff(radial_grid, axis=0)
        dr = np.vstack((radial_grid[1], dr))
        u2 = weighting(u2, 1 / dr, mode='repmat')

    azimuths1 = np.radians(params1['AzimuthalGrid'])
    zeniths1 = params1['RadialGrid']
    theta1, r1 = np.meshgrid(azimuths1, zeniths1)

    n_row = np.shape(u1)[0]
    n_r, n_theta = params1['n_r'], params1['n_theta']

    front_rotor = u1[0:n_row // 2]
    rear_rotor = u1[n_row // 2:]

    front_rotor1 = np.reshape(front_rotor, (n_r, n_theta), 'F')
    rear_rotor1 = np.reshape(rear_rotor, (n_r, n_theta), 'F')

    azimuths2 = np.radians(params2['AzimuthalGrid'])
    zeniths2 = params2['RadialGrid']
    theta2, r2 = np.meshgrid(azimuths2, zeniths2)

    n_row = np.shape(u2)[0]
    n_r, n_theta = params2['n_r'], params2['n_theta']

    front_rotor = u2[0:n_row // 2]
    rear_rotor = u2[n_row // 2:]

    front_rotor2 = np.reshape(front_rotor, (n_r, n_theta), 'F')
    rear_rotor2 = np.reshape(rear_rotor, (n_r, n_theta), 'F')

    plt.rc('grid', linestyle="-", color='black', lw=0.8)

    fig, axes = plt.subplots(3,
                             2,
                             figsize=(10, 12),
                             subplot_kw=dict(projection='polar'))
    fig.subplots_adjust(wspace=0.3, hspace=0.35)

    config = "$(d_x, d_y)$ = (" + str(dx) + ", " + str(dy) + ")"
    title = fig.suptitle(("Disk Plots of {} [N/m] at " + config).format(force),
                         fontsize=16)
    title.set_position([0.55, 1])

    axes[0, 0].set_title('Front Rotor \nCFD', fontsize=14, pad=15)
    axes[0, 1].set_title('Rear Rotor \nCFD', fontsize=14, pad=15)
    axes[1, 0].set_title('RMAC', fontsize=12, pad=15)
    axes[1, 1].set_title('RMAC', fontsize=12, pad=15)
    axes[2, 0].set_title('Difference $L_2$ Error =' + str(err_front) + '%',
                         fontsize=12,
                         pad=15)
    axes[2, 1].set_title('Difference $L_2$ Error =' + str(err_rear) + '%',
                         fontsize=12,
                         pad=15)

    im1 = axes[0, 0].contourf(theta1,
                              r1,
                              front_rotor1,
                              vmin=0,
                              vmax=450,
                              levels=150,
                              cmap='rainbow')
    axes[0, 0].set_theta_direction(-1)
    fig.colorbar(im1, ax=axes[0, 0], fraction=0.046, pad=0.04)
    plt.grid()

    im2 = axes[0, 1].contourf(theta1,
                              r1,
                              rear_rotor1,
                              vmin=0,
                              vmax=450,
                              levels=150,
                              cmap='rainbow')
    fig.colorbar(im2, ax=axes[0, 1], fraction=0.046, pad=0.04)
    plt.grid()

    im3 = axes[1, 0].contourf(theta2,
                              r2,
                              front_rotor2,
                              vmin=0,
                              vmax=450,
                              levels=150,
                              cmap='rainbow')
    axes[1, 0].set_theta_direction(-1)
    fig.colorbar(im3, ax=axes[1, 0], fraction=0.046, pad=0.04)
    plt.grid()

    im4 = axes[1, 1].contourf(theta2,
                              r2,
                              rear_rotor2,
                              vmin=0,
                              vmax=450,
                              levels=150,
                              cmap='rainbow')
    fig.colorbar(im4, ax=axes[1, 1], fraction=0.046, pad=0.04)
    plt.grid()

    [u1, u2, ax1, ax2] = matrix_interpol(front_rotor1, zeniths1, azimuths1,
                                         front_rotor2, zeniths2, azimuths2)

    im5 = axes[2, 0].contourf(ax2,
                              ax1,
                              u1 - u2,
                              vmin=-150,
                              vmax=150,
                              levels=100,
                              cmap='rainbow')
    axes[2, 0].set_theta_direction(-1)
    fig.colorbar(im5, ax=axes[2, 0], fraction=0.046, pad=0.04)
    plt.grid()

    [u1, u2, ax1, ax2] = matrix_interpol(rear_rotor1, zeniths1, azimuths1,
                                         rear_rotor2, zeniths2, azimuths2)

    im6 = axes[2, 1].contourf(ax2,
                              ax1,
                              u1 - u2,
                              vmin=-150,
                              vmax=150,
                              levels=100,
                              cmap='rainbow')
    fig.colorbar(im6, ax=axes[2, 1], fraction=0.046, pad=0.04)
    plt.grid()

    if save:
        model = 'RMAC' if type2 == 'rmac' else 'CFD'
        fig_name = ("{}_{}_dx=" + str(dx) + "dy =" + str(dy) + ".png").format(
            model, force)
        plt.savefig(fig_name, bbox_inches='tight')

    plt.show()
Exemple #3
0
def disk_plot(u, location, params, force_dir, save=False, cfd=False):
    """ Returns the disk plots of u seen as front and rear rotor r-theta matrix """

    if cfd:
        radial_grid = params['RadialGrid'].reshape(-1, 1)
        dr = np.diff(radial_grid, axis=0)
        dr = np.vstack((radial_grid[1], dr))
        u = weighting(u, 1 / dr, mode='repmat')

    n_row = np.shape(u)[0]

    dx, dy = get_dx_dy(location, params)

    n_r = params['n_r']
    n_theta = params['n_theta']

    azimuths = np.radians(np.linspace(0, 360, n_theta))
    zeniths = params['RadialGrid']

    theta, r = np.meshgrid(azimuths, zeniths)

    front_rotor = u[0:n_row // 2]
    rear_rotor = u[n_row // 2:]

    front_rotor = np.reshape(front_rotor, (n_r, n_theta), 'F')
    rear_rotor = np.reshape(rear_rotor, (n_r, n_theta), 'F')

    plt.rc('grid', linestyle="-", color='black', lw=0.8)

    fig, (ax1, ax2) = plt.subplots(1,
                                   2,
                                   figsize=(12, 8),
                                   subplot_kw=dict(projection='polar'))

    force = "Lift" if force_dir == "L" else "Drag"

    # config = "$(d_x, d_y)$ = (" + str(dx) + ", " + str(dy) + ")"
    # title = fig.suptitle(("Disk plots of {} [N/m] at" + config).format(force), fontsize=16)
    # title.set_position([.5, 0.9])

    # type_snap = 'cfd' if cfd else 'rmac'
    # err_front, err_rear = l2error(u1, params, type_snap, u2, params, type_snap)

    # ax1.set_title('Front L2 Error = ' + str(err_front) + '%', fontsize=20, pad=20)
    # ax2.set_title('Rear L2 Error = ' + str(err_rear) + '%', fontsize=20, pad=20)

    ax1.set_title('Front Rotor', fontsize=20, pad=20)
    ax2.set_title('Rear Rotor', fontsize=20, pad=20)

    im1 = ax1.contourf(theta,
                       r,
                       front_rotor,
                       vmin=0,
                       levels=100,
                       cmap='rainbow')
    ax1.set_theta_direction(-1)
    fig.colorbar(im1, ax=ax1, fraction=0.046, pad=0.04)
    plt.grid()

    im2 = ax2.contourf(theta,
                       r,
                       rear_rotor,
                       vmin=0,
                       levels=100,
                       cmap='rainbow')
    fig.colorbar(im2, ax=ax2, fraction=0.046, pad=0.04)
    plt.grid()
    plt.show()

    if save:
        fig_name = ("Disk_plot_{}_dx=" + str(dx) + "dy=" + str(dy) +
                    ".png").format(force)
        plt.savefig(fig_name, bbox_inches='tight')
Exemple #4
0
snaps_test = np.array([1, 3, 4, 5, 7])
snaps_rmac = np.arange(105)

from paramspace_computation import get_dx_dy
import matplotlib.pyplot as plt

dx_max, dx_min = params['dx_max'], params['dx_min']
dy_max, dy_min = params['dy_max'], params['dy_min']

Ndx, Ndy = params['Ndx'], params['Ndy']

dx = np.linspace(dx_min, dx_max, Ndx)
dy = np.linspace(dy_min, dy_max, Ndy)
dX, dY = np.meshgrid(dx, dy)

dx_rmac, dy_rmac = get_dx_dy(snaps_rmac, params)
dx_test, dy_test = get_dx_dy(snaps_test, params_cfd)
dx_cfd, dy_cfd = get_dx_dy(snaps_cfd, params_cfd)

# Plot a grid
plt.rc('grid', linestyle="-", color='black', lw=0.4)
fig = plt.figure(figsize=(18, 10))
plt.grid()
plt.xticks(rotation=45)
plt.yticks(rotation=20)

# Background
ax = fig.gca()
ax.set_xticks(dx)
ax.set_yticks(dy)
ax.tick_params(labelsize=24)
def visualize_snapshots_sets(params,
                             snaps_rmac,
                             params_cfd,
                             snaps_cfd,
                             save=False):

    dx_max, dx_min = params['dx_max'], params['dx_min']
    dy_max, dy_min = params['dy_max'], params['dy_min']

    Ndx, Ndy = params['Ndx'], params['Ndy']

    dx = np.linspace(dx_min, dx_max, Ndx)
    dy = np.linspace(dy_min, dy_max, Ndy)
    dX, dY = np.meshgrid(dx, dy)

    dx_rmac, dy_rmac = get_dx_dy(snaps_rmac, params)
    dx_cfd, dy_cfd = get_dx_dy(snaps_cfd, params_cfd)

    # Plot a grid
    plt.rc('grid', linestyle="-", color='black', lw=0.5)
    fig = plt.figure(figsize=(20, 12))
    plt.grid()
    plt.xticks(rotation=45)
    plt.yticks(rotation=45)

    # Background
    ax = fig.gca()
    # Ones = dX / dX
    # contour_set = ax.contourf(dX, dY, Ones, cmap='Blues')
    ax.set_xticks(dx)
    ax.set_yticks(dy)
    ax.tick_params(labelsize=24)

    # Plot the RMAC snaps
    basis = plt.scatter(dx_rmac,
                        dy_rmac,
                        s=200,
                        alpha=.8,
                        c='b',
                        marker='o',
                        edgecolors='k',
                        linewidths=1.5)
    basis.set_label('RMAC Snapshots')

    # for i, txt in enumerate(snaps_rmac):
    #      ax.annotate(txt, (dx_rmac[i], dy_rmac[i]), fontsize=22)

    # Plot the CFD snpas
    basis = plt.scatter(dx_cfd, dy_cfd, s=800, alpha=1, c='k', marker='X')
    basis.set_label('CFD Snapshots')

    ax.legend(prop={'size': 20},
              bbox_to_anchor=(0.5, 1.02, 1, 0.2),
              loc="lower left",
              borderaxespad=0,
              ncol=2)
    ax.set_xlabel('$d_x$', fontsize=32)
    ax.set_ylabel('$d_y$', fontsize=32, rotation=0)

    if save:
        plt.savefig('snapshots_sets.png', bbox_inches='tight')

    plt.show()
def visualize_cfd_snapshots(params_cfd,
                            pivot_samples_cfd,
                            reconstructed_samples,
                            force_dir,
                            save=False):

    _, params = load_rmac(force_dir)

    dx_max, dx_min = params['dx_max'], params['dx_min']
    dy_max, dy_min = params['dy_max'], params['dy_min']
    Ndx, Ndy = params['Ndx'], params['Ndy']

    dx = np.linspace(dx_min, dx_max, Ndx)
    dy = np.linspace(dy_min, dy_max, Ndy)
    dX, dY = np.meshgrid(dx, dy)

    Ones = dX / dX

    dx_selected, dy_selected = get_dx_dy(pivot_samples_cfd, params_cfd)

    # Plot a grid
    plt.rc('grid', linestyle="-", color='black', lw=0.8)
    fig = plt.figure(figsize=(20, 12))
    plt.grid()
    plt.xticks(rotation=45)
    plt.yticks(rotation=45)

    # Plot the background
    ax = fig.gca()
    contour_set = ax.contourf(dX, dY, Ones, cmap='Blues', alpha=0.5)

    ax.set_xticks(dx)
    ax.set_yticks(dy)
    ax.tick_params(labelsize=18)

    # Plot the selected samples
    basis = plt.scatter(dx_selected, dy_selected, s=150, alpha=1, c='r')
    basis.set_label('Snapshots used as a Basis for the Reconstruction')

    # Enumerate the selected samples in the plot figure
    # n = np.shape(pivot_samples_cfd)[0]
    for i, txt in enumerate(pivot_samples_cfd + 1):
        ax.annotate(txt, (dx_selected[i], dy_selected[i]), fontsize=35)

    dx_recon, dy_recon = get_dx_dy(reconstructed_samples, params_cfd)

    test = plt.scatter(dx_recon, dy_recon, s=700, alpha=1, c='g', marker='^')
    test.set_label('Reconstructed Snapshots')

    # n = np.shape(reconstructed_samples)[0]
    for i, txt in enumerate(reconstructed_samples + 1):
        ax.annotate(txt, (dx_recon[i], dy_recon[i]), fontsize=35)

    ax.legend(prop={'size': 22},
              bbox_to_anchor=(0., 1.02, 1, 0.2),
              loc="lower left",
              borderaxespad=0,
              ncol=1)
    ax.set_xlabel('$d_x$', fontsize=26)
    ax.set_ylabel('$d_y$', fontsize=26, rotation=0)

    if save:
        plt.savefig('CFD_snapshots.png', bbox_inches='tight')

    plt.show()
def force_surfaces(U_LF_0,
                   params,
                   U_HF,
                   U_HF_hat,
                   params_HF,
                   force_dir,
                   snaps_train,
                   snaps_val,
                   front,
                   save=False):

    # Plot a grid
    plt.rc('grid', linestyle="-", color='black', lw=0.4)
    figure = plt.figure(figsize=(12, 8))
    ax = figure.gca(projection='3d')

    plt.grid()
    plt.rcParams.update({'font.size': 14})
    plt.rcParams.update({'mathtext.default': 'regular'})

    # Mesh Grid
    dx_max, dx_min = params['dx_max'], params['dx_min']
    dy_max, dy_min = params['dy_max'], params['dy_min']
    Ndx, Ndy = params['Ndx'], params['Ndy']
    dx = np.linspace(dx_min, dx_max, Ndx)
    dy = np.linspace(dy_min, dy_max, Ndy)
    dX, dY = np.meshgrid(dx, dy)

    QoI = 'Thrust [N]' if force_dir == 'L' else 'Torque [Nm]'
    Rotor = 'Front Rotor ' if front else 'Rear Rotor '
    title = Rotor + QoI

    # LF surf
    if force_dir == 'L':
        [Q_LF_front,
         Q_LF_rear] = force_computation.compute_thrust_rmac(U_LF_0, params)
        if front:
            surf_LF = Q_LF_front.reshape(Ndx, Ndy)
        else:
            surf_LF = Q_LF_rear.reshape(Ndx, Ndy)
    else:
        [Q_LF_front,
         Q_LF_rear] = force_computation.compute_torque_rmac(U_LF_0, params)
        if front:
            surf_LF = Q_LF_front.reshape(Ndx, Ndy)
        else:
            surf_LF = Q_LF_rear.reshape(Ndx, Ndy)

    # HF Lifted surf
    if force_dir == 'L':
        [Q_HF_front_hat, Q_HF_rear_hat
         ] = force_computation.compute_thrust_cfd(U_HF_hat, params_HF)
        if front:
            surf_HF_hat = Q_HF_front_hat.reshape(Ndx, Ndy)
        else:
            surf_HF_hat = Q_HF_rear_hat.reshape(Ndx, Ndy)
    else:
        [Q_HF_front_hat, Q_HF_rear_hat
         ] = force_computation.compute_torque_cfd(U_HF_hat, params_HF)
        if front:
            surf_HF_hat = Q_HF_front_hat.reshape(Ndx, Ndy)
        else:
            surf_HF_hat = Q_HF_rear_hat.reshape(Ndx, Ndy)

    # HF points
    if force_dir == 'L':
        [Q_HF_front_hat, Q_HF_rear_hat
         ] = force_computation.compute_thrust_cfd(U_HF, params_HF)
        if front:
            z_train = Q_HF_front_hat[:, snaps_train]
            z_val = Q_HF_front_hat[:, snaps_val]
        else:
            z_train = Q_HF_rear_hat[:, snaps_train]
            z_val = Q_HF_rear_hat[:, snaps_val]
    else:
        [Q_HF_front_hat, Q_HF_rear_hat
         ] = force_computation.compute_torque_cfd(U_HF, params_HF)
        if front:
            z_train = Q_HF_front_hat[:, snaps_train]
            z_val = Q_HF_front_hat[:, snaps_val]
        else:
            z_train = Q_HF_rear_hat[:, snaps_train]
            z_val = Q_HF_rear_hat[:, snaps_val]

    # Plot Surf
    # ax.plot_surface(dX1, dY1, surf_LF.T, edgecolor='k', cmap='Reds', alpha=0.8, label='LF')
    # ax.plot_surface(dX1, dY1, surf_HF.T, edgecolor='k', cmap='Greens', alpha=0.6, label="HF lifted")

    ax.plot_wireframe(dX, dY, surf_LF.T, color='b', linewidth=2, label='RMAC')
    ax.plot_wireframe(dX,
                      dY,
                      surf_HF_hat.T,
                      edgecolor='k',
                      linewidth=2,
                      label="CFD lifted")

    # Plot points
    x_train, y_train = get_dx_dy(snaps_train, params_HF)
    ax.scatter(x_train,
               y_train,
               z_train,
               s=150,
               color='k',
               alpha=1,
               label='CFD training')

    x_val, y_val = get_dx_dy(snaps_val, params_HF)
    ax.scatter(x_val,
               y_val,
               z_val,
               s=150,
               color='r',
               alpha=1,
               label='CFD validation')

    # ax.plot([2.5, 2.5], [0.25, 0.25], [1350, z_val[:, 0]], color='r')
    # ax.plot([3.0, 3.0], [0.00, 0.00], [1350, z_val[:, 1]], color='r')
    # ax.plot([3.0, 3.0], [0.25, 0.25], [1350, z_val[:, 2]], color='r')
    # ax.plot([3.0, 3.0], [0.50, 0.50], [1350, z_val[:, 3]], color='r')
    # ax.plot([3.5, 3.5], [0.25, 0.25], [1350, z_val[:, 4]], color='r')

    ax.set_xticks(dx[::2])
    plt.xticks(rotation=30, fontsize=14)
    ax.set_yticks(dy[::2])
    plt.yticks(fontsize=14)

    ax.set_zlim(1350, 1420)
    ax.view_init(20, -70)

    ax.set_xlabel('\n\n$d_x/R$', fontsize=22)
    ax.set_ylabel('\n\n$d_y/R$', fontsize=22)

    ax.set_title(title)
    plt.legend()

    if save:
        plt.savefig(title, bbox_inches='tight')

    plt.show()
def error_contour(Error,
                  selected_samples,
                  params,
                  force_dir,
                  other_samples=None,
                  save=False):
    """ Plots the error distribution in the parameter space """

    plt.rcParams.update({'font.size': 16})
    plt.rcParams.update({'mathtext.default': 'regular'})

    dx_max, dx_min = params['dx_max'], params['dx_min']
    dy_max, dy_min = params['dy_max'], params['dy_min']
    Ndx, Ndy = params['Ndx'], params['Ndy']

    dx = np.linspace(dx_min, dx_max, Ndx)
    dy = np.linspace(dy_min, dy_max, Ndy)
    dX, dY = np.meshgrid(dx, dy)

    Error = Error.reshape(Ndx, Ndy)

    dx_selected, dy_selected = get_dx_dy(selected_samples, params)

    print('')
    print('The most important snapshots are:')
    print(np.array(list(zip(dx_selected, dy_selected))))

    # Plot a grid
    plt.rc('grid', linestyle="-", color='black', lw=0.8)
    fig = plt.figure(figsize=(20, 12))
    plt.grid()
    plt.xticks(rotation=45, fontsize=40)
    plt.yticks(rotation=45, fontsize=40)
    plt.tick_params(labelsize=22)

    # Plot the contour of the error
    ax = fig.gca()
    contour_set = ax.contourf(dX, dY, Error.T, cmap='coolwarm')
    ax.set_xticks(dx)
    ax.set_yticks(dy)

    cbar = fig.colorbar(contour_set)
    cbar.ax.get_yaxis().labelpad = 20
    cbar.ax.set_ylabel('% Error', rotation=90, fontsize=32)

    # Plot the selected samples
    plt.scatter(dx_selected, dy_selected, s=100, alpha=1, c='b')

    # Enumerate the selected samples in the plot figure
    n = np.shape(selected_samples)[0]
    for i, txt in enumerate(np.arange(1, n + 1)):
        ax.annotate(txt, (dx_selected[i], dy_selected[i]), fontsize=70, c='k')

    # Plot other optional sample set
    if other_samples is not None:
        other_samples = np.array(other_samples)
        dx_other, dy_other = get_dx_dy(other_samples, params)

        # Plot the other samples
        plt.scatter(dx_other, dy_other, s=100, alpha=1, c='k')

        # Enumerate the selected samples in the plot figure
        n_other = np.shape(other_samples)[0]
        for i, txt in enumerate(np.arange(1, n_other + 1)):
            ax.annotate(txt, (dx_other[i], dy_other[i]), fontsize=20)

    ax.set_xlabel('$d_x/R$', fontsize=40)
    ax.set_ylabel('$d_y/R$', fontsize=40, rotation=0)

    if force_dir == 'L':
        plt.title('Relative Error Distribution using Lift Snapshots',
                  fontsize=40)
    elif force_dir == 'D':
        plt.title('Relative Error Distribution using Drag Snapshots',
                  fontsize=40)

    if save:
        plt.savefig('Error_dist_n=' + str(n) + '_{}.png'.format(force_dir),
                    bbox_inches='tight')

    plt.show()