def get_circle_boundary(radius, centre, bd_eta_max):
    # centre is an object of point data type
    I = bd_eta_max.n
    r = np.empty(I+1, dtype=object)

    # Find point on circles such that line from circle
    # to eta_max boundary is normal to circle
    # theta = arctan((y - yc) / (x - xc))
    points = bd_eta_max.Points
    for xi in range(I+1):
        point = points[xi]
        xp, yp = point.x, point.y
        dist = np.sqrt((xp - centre.x)**2 + (yp - centre.y)**2)
        costheta = (xp - centre.x) / dist
        sintheta = (yp - centre.y) / dist
        x = centre.x + radius*costheta
        y = centre.y + radius*sintheta
        r[xi] = Point(x, y)

 #  x = np.empty(I+1)
 #  y = np.empty(I+1)
 #  for i in range(I+1):
 #      x[i] = r[i].x
 #      y[i] = r[i].y

 #  plt.plot(x, y, 'k.')
 #  plt.show()
        
    bd = Boundary(I, BdType.eta_min)
    bd.populate_boundary_ndar_points(r)
    return bd
def get_xi_boundaries(start, end, I):
    # For the flow past a cylinder, the xi boundaries are the same line
    # The points are stretched closer to the start
    delta = 4.5 # trial and error?
    stretching_f = lambda xi: 1 + (np.tanh(delta*(xi - 1)) / np.tanh(delta))
    r = BoundaryGrids.fit_line(start, end, I, stretching_f)
    bd2 = Boundary(I, BdType.xi_min)
    bd2.populate_boundary_ndar_points(r)
    bd3 = Boundary(I, BdType.xi_max)
    bd3.populate_boundary_ndar_points(r)
    return (bd2, bd3)
示例#3
0
def get_trap_grid(I, J):
    # Grid as per ASM2010 AIAA code verification paper
    # eta_min
    start_point = Point(0., 0.)
    end_point = Point(0.3, 0.0)
    r = BoundaryGrids.fit_line(start_point, end_point, I)
    bd1 = Boundary(I, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)

    # eta_max
    start_point = Point(0., 0.1)
    end_point = Point(0.3, 0.005)
    r = BoundaryGrids.fit_line(start_point, end_point, I)
    bd2 = Boundary(I, BdType.eta_max)
    bd2.populate_boundary_ndar_points(r)

    # xi_min
    start_point = Point(0., 0.)
    end_point = Point(0., 0.1)
    r = BoundaryGrids.fit_line(start_point, end_point, J)
    bd3 = Boundary(J, BdType.xi_min)
    bd3.populate_boundary_ndar_points(r)

    # xi_max
    start_point = Point(0.3, 0.)
    end_point = Point(0.3, 0.005)
    r = BoundaryGrids.fit_line(start_point, end_point, J)
    bd4 = Boundary(J, BdType.xi_max)
    bd4.populate_boundary_ndar_points(r)

    Grid_obj = StructuredGridGeneration.get_univariate_grid(bd1, bd2, bd3, bd4)
    Grid_obj.save_to_vtk('trap.vtk')
    Grid_obj.save_to_txt('trap.txt')
def get_eta_max_boundary(p1, p2, p3, p4, I):
    # The eta_max boundary is a rectangle with 4 points.
    # Specify from top right point anti-clockwise
    # We also need to return the indices of the array where 
    # p = pi, i = 1 to 4

    # The actual starting point is midpoint of p1 and p4
    start_point = 0.5 * (p1 + p4)

    # Totally 5 segments
    # L1: start to p1 with I / 4 points
    r1 = BoundaryGrids.fit_line(start_point, p1, int(I/4))
    # L2: p1 to p2 with 3*I/16 points
    r2 = BoundaryGrids.fit_line(p1, p2, int(3*I/16))
    # L3: p2 to p3 with I/8 points
    r3 = BoundaryGrids.fit_line(p2, p3, int(I/8))
    # L4: p3 to p4 with 3*I/16 points
    r4 = BoundaryGrids.fit_line(p3, p4, int(3*I/16))
    # L5: p4 to start with I/4 points
    r5 = BoundaryGrids.fit_line(p4, start_point, int(I/4))

    # Combine them (numpy.append)
    # Skip p1 common
    r = np.append(r1[:-1], r2)
    # Skip p2 common
    r = np.append(r[:-1], r3)
    # Skip p3 common
    r = np.append(r[:-1], r4)
    # Skip p4 common
    r = np.append(r[:-1], r5)
    
    # I is number of number of grid points - 1
    I = len(r) - 1
    
    bd = Boundary(I, BdType.eta_max)
    bd.populate_boundary_ndar_points(r)

    for i in range(len(r)):
        if r[i] == p1:
            i1 = i
        elif r[i] == p2:
            i2 = i
        elif r[i] == p3:
            i3 = i
        elif r[i] == p4:
            i4 = i
    i_list = [i1, i2, i3, i4]

    return (bd, i_list)
示例#5
0
def get_oblique_shock_grid(delta, I):
    # Grid as per ASM2010 AIAA code verification paper
    # Ramp at I/2
    J = int(I / 2)
    x_min = -1
    x_corner = 0
    y = (x_corner - x_min)
    x_end_dist = (x_corner - x_min)

    # eta_min
    start_point = Point(x_min, 0)
    corner_point = Point(x_corner, 0)
    end_point = Point(x_end_dist * np.cos(delta), x_end_dist * np.sin(delta))

    r1 = BoundaryGrids.fit_line(start_point, corner_point, int(I / 2))
    r2 = BoundaryGrids.fit_line(corner_point, end_point, int(I / 2))
    r = np.append(r1[:-1], r2)
    bd1 = Boundary(I, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)
    I = len(bd1.Points) - 1

    # eta_max
    start_point = Point(x_min, y)
    corner_point = Point(x_corner, y)
    # end_point = Point(x_end_dist*np.cos(delta), x_end_dist*np.sin(delta) + y)
    end_point = Point(x_end_dist * np.cos(delta), y)

    # r1 = BoundaryGrids.fit_line(start_point, corner_point, int(I/2))
    # r2 = BoundaryGrids.fit_line(corner_point, end_point, int(I/2))
    # r = np.append(r1[:-1], r2)
    r = BoundaryGrids.fit_line(start_point, end_point, I)
    bd2 = Boundary(I, BdType.eta_max)
    bd2.populate_boundary_ndar_points(r)

    # xi_min
    start_point = Point(x_min, 0)
    end_point = Point(x_min, y)
    r = BoundaryGrids.fit_line(start_point, end_point, J)
    bd3 = Boundary(J, BdType.xi_min)
    bd3.populate_boundary_ndar_points(r)

    # xi_max
    start_point = Point(x_end_dist * np.cos(delta), x_end_dist * np.sin(delta))
    end_point = Point(x_end_dist * np.cos(delta), y)
    r = BoundaryGrids.fit_line(start_point, end_point, J)
    bd4 = Boundary(J, BdType.xi_max)
    bd4.populate_boundary_ndar_points(r)

    Grid_obj = StructuredGridGeneration.get_univariate_grid(bd1, bd2, bd3, bd4)
    Grid_obj.save_to_vtk('oblique_shock.vtk')
    Grid_obj.save_to_txt('oblique_shock.txt')
示例#6
0
def get_shock_BL_grid(delta, I):
    # Grid as per ASM2010 AIAA code verification paper
    # Ramp at I/2
    J = int(I / 2)
    x_min = 0
    x_corner = 0.1
    x_mid = 0.2 * x_corner
    y = 0.0368
    x_end_dist = x_corner - x_min

    # eta_max
    start_point = Point(x_min, y)
    turning_point = Point(x_mid, (x_mid - x_min) * np.tan(delta) + y)
    end_point = Point(x_corner, -(x_corner-x_mid)*np.tan(delta) + \
                                 turning_point.y)
    r1 = BoundaryGrids.fit_line(start_point, turning_point, int(I * 0.2))
    r2 = BoundaryGrids.fit_line(turning_point, end_point, int(I * 0.8))
    r = np.append(r1[:-1], r2)
    bd2 = Boundary(I, BdType.eta_max)
    bd2.populate_boundary_ndar_points(r)

    I = len(bd2.Points) - 1
    # eta_min
    start_point = Point(x_min, 0.)
    end_point = Point(x_corner, .0)
    r = BoundaryGrids.fit_line(start_point, end_point, I)
    bd1 = Boundary(I, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)

    dt = 3.0
    # xi_min
    start_point = Point(x_min, 0)
    end_point = Point(x_min, y)
    stretching_f = lambda xi: 1 + (np.tanh(dt * (xi - 1)) / np.tanh(dt))
    r = BoundaryGrids.fit_line(start_point, end_point, J, stretching_f)
    bd3 = Boundary(J, BdType.xi_min)
    bd3.populate_boundary_ndar_points(r)

    # xi_max
    start_point = Point(x_corner, 0.)
    end_point = Point(x_corner, -(x_corner-x_mid)*np.tan(delta) + \
                                 turning_point.y)
    r = BoundaryGrids.fit_line(start_point, end_point, J, stretching_f)
    bd4 = Boundary(J, BdType.xi_max)
    bd4.populate_boundary_ndar_points(r)

    Grid_obj = StructuredGridGeneration.get_univariate_grid(
        bd1, bd2, bd3, bd4, stretching_f)
    Grid_obj.save_to_vtk('shock_BL.vtk')
    Grid_obj.save_to_txt('shock_BL.txt')
def get_airfoil_dat_gridgen():
    xt, yt = zip(*np.loadtxt('top'))
    xb, yb = zip(*np.loadtxt('bottom'))
    CPt = []
    CPb = []
    for i in range(len(xt)):
        CPt.append(Point(xt[i], yt[i]))
    for i in range(len(xb)):
        CPb.append(Point(xb[i], yb[i]))

    I = 200
    #   xi_spacing_f = lambda xi, I: 0.5 * I * (1 - np.cos(xi * np.pi / I))
    xi_spacing_f = lambda xi, I: xi
    s_CP_f = lambda j, n, I: j * I / n
    s_CP_inverse_f = lambda s, n, I: s * n / I

    rt = fit_cubic_spline(CPt, I, xi_spacing_f, s_CP_f, s_CP_inverse_f)
    rb = fit_cubic_spline(CPb, I, xi_spacing_f, s_CP_f, s_CP_inverse_f)
    bd1 = Boundary(I, BdType.eta_min)
    bd1.populate_boundary_ndar_points(rt)
    bd2 = Boundary(I, BdType.eta_min)
    bd2.populate_boundary_ndar_points(rb)
    xtnew = []
    ytnew = []
    xbnew = []
    ybnew = []
    for i in range(len(rt)):
        xtnew.append(rt[i].x)
        ytnew.append(rt[i].y)
    for i in range(len(rb)):
        xbnew.append(rb[i].x)
        ybnew.append(rb[i].y)

    np.savetxt('top-new', zip(xtnew, ytnew))
    np.savetxt('bottom-new', zip(xbnew, ybnew))

    plt.plot(xtnew, ytnew, '*-')
    plt.plot(xbnew, ybnew, '.-')
    plt.axis('equal')
    plt.show()
def get_exp_plane_grid(I, J):
    delta = -10 * np.pi / 180
    x_min = -1
    x_corner = 0
    y_max = (x_corner - x_min) * 1.5
    x_end_dist = (x_corner - x_min) * 2

    x_max = x_end_dist * np.cos(delta)
    y_min = x_end_dist * np.sin(delta)

    x_min = 0
    x_max = 1
    y_min = 0
    y_max = 0.2

    start_point = Point(x_min, y_min)
    end_point = Point(x_max, y_min)
    r = BoundaryGrids.fit_line(start_point, end_point, int(I))
    bd1 = Boundary(len(r) - 1, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)

    start_point = Point(x_min, y_max)
    end_point = Point(x_max, y_max)
    r = BoundaryGrids.fit_line(start_point, end_point, int(I))
    bd2 = Boundary(len(r) - 1, BdType.eta_max)
    bd2.populate_boundary_ndar_points(r)

    start_point = Point(x_min, y_min)
    end_point = Point(x_min, y_max)
    r = BoundaryGrids.fit_line(start_point, end_point, int(J))
    bd3 = Boundary(len(r) - 1, BdType.xi_min)
    bd3.populate_boundary_ndar_points(r)

    start_point = Point(x_max, y_min)
    end_point = Point(x_max, y_max)
    r = BoundaryGrids.fit_line(start_point, end_point, int(J))
    bd4 = Boundary(len(r) - 1, BdType.xi_max)
    bd4.populate_boundary_ndar_points(r)

    Grid_obj = StructuredGridGeneration.get_univariate_grid(bd1, bd2, \
            bd3, bd4)
    #  Grid_obj.save_to_vtk('ExpFan-IB.vtk', 'ExpFan-IB')

    #   Grid_obj.save_to_txt('ExpFan-IB.txt')
    #  Grid_obj.save_to_vtk('RampChannel-IB.vtk', 'RampChannel-IB')

    Grid_obj.save_to_txt('Rchannel-IB-2.txt')
def get_naca_grid_gridgen():
    # Use points from naca equation as control points so that the trailing
    # edge is sharp
    x, y = get_IB_naca_4_dig('0012', chord_len=1.0, num_points=66)
    CP = []
    for i in range(len(x)):
        CP.append(Point(x[i], y[i]))

    ################ Generating around airfoil
    I = 100
    #   xi_spacing_f = lambda xi, I: 0.5 * I * (1 - np.cos(xi * np.pi / I))
    xi_spacing_f = lambda xi, I: xi
    s_CP_f = lambda j, n, I: j * I / n
    s_CP_inverse_f = lambda s, n, I: s * n / I

    r = fit_cubic_spline(CP, I, xi_spacing_f, s_CP_f, s_CP_inverse_f)
    bd1 = Boundary(I, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)
    x = []
    y = []
    for i in range(len(r)):
        x.append(r[i].x)
        y.append(r[i].y)
    return (x, y)
示例#10
0
def get_ramp_grid(I, J):
    # Grid as per ASM2010 AIAA code verification paper
    # Ramp at I/3
    x_bl = 0.
    y_bl = 0.
    x_rs = 0.25
    y_rs = 0.0
    x_re = 0.5
    y_re = 0.067
    x_br = 1.0
    y_br = 0.067
    x_tl = 0.0
    y_tl = 0.2
    x_tr = 1.0
    y_tr = 0.2

    # eta_min
    start_point = Point(x_bl, y_bl)
    end_point = Point(x_rs, y_rs)
    r1 = BoundaryGrids.fit_line(start_point, end_point, int(I / 4))

    start_point = Point(x_rs, y_rs)
    end_point = Point(x_re, y_re)
    r2 = BoundaryGrids.fit_line(start_point, end_point, int(I / 4))

    start_point = Point(x_re, y_re)
    end_point = Point(x_br, y_br)
    r3 = BoundaryGrids.fit_line(start_point, end_point, int(I / 2))

    r = np.append(r1[:-1], r2)
    r = np.append(r[:-1], r3)
    bd1 = Boundary(I, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)
    I = len(bd1.Points) - 1

    # eta_max
    start_point = Point(x_tl, y_tl)
    end_point = Point(x_tr, y_tr)
    r = BoundaryGrids.fit_line(start_point, end_point, I)
    bd2 = Boundary(I, BdType.eta_max)
    bd2.populate_boundary_ndar_points(r)

    # xi_min
    start_point = Point(x_bl, y_bl)
    end_point = Point(x_tl, y_tl)
    r = BoundaryGrids.fit_line(start_point, end_point, J)
    bd3 = Boundary(J, BdType.xi_min)
    bd3.populate_boundary_ndar_points(r)

    # xi_max
    start_point = Point(x_br, y_br)
    end_point = Point(x_tr, y_tr)
    r = BoundaryGrids.fit_line(start_point, end_point, J)
    bd4 = Boundary(J, BdType.xi_max)
    bd4.populate_boundary_ndar_points(r)

    print len(bd1.Points), len(bd2.Points), len(bd3.Points), len(bd4.Points)

    Grid_obj = StructuredGridGeneration.get_univariate_grid(bd1, bd2, bd3, bd4)
    Grid_obj.save_to_vtk('ramp_channel_uniform.vtk')
    Grid_obj.save_to_txt('ramp_channel_uniform.txt')
def get_plane_IB(delta, I, J):
    global plt
    x_min = -1.0
    x_max = 5.0
    y_min = -5.0
    y_max = 5.0

    airfoil_start = x_min + 43.5 / 100 * (x_max - x_min)
    airfoil_end = x_min + 57.5 / 100 * (x_max - x_min)

    airfoil_y_s = y_min + 48 / 100 * (y_max - y_min)
    airfoil_y_e = y_min + 52 / 100 * (y_max - y_min)

    dx = 0.01
    dy = 0.01

    #  x_min = -6.0 * 0.01
    #  x_max = 21.0 * 0.01
    #  y_min = -5.0 * 0.01
    #  y_max = 5.0 * 0.01

    #  airfoil_start = x_min + 15.38/100*(x_max - x_min)
    #  airfoil_end = x_min + 26.92/100*(x_max - x_min)
    #   airfoil_start = -1 * 0.01
    #   airfoil_end = 1 * 0.01

    #  airfoil_y_s = y_min + 40./100*(y_max - y_min)
    #  airfoil_y_e = y_min + 60./100*(y_max - y_min)
    #   airfoil_y_s = -2.5 * 0.01
    #   airfoil_y_e = 2.5 * 0.01

    #   dx = 0.02 * 0.01
    #   dy = 0.02 * 0.01
    length1 = abs(airfoil_start - y_min)
    length2 = abs(x_max - airfoil_end)
    delta1 = BoundaryGrids.find_hyp_tan_stretching_factor(
        dx, int(I / 4), length1)
    delta2 = BoundaryGrids.find_hyp_tan_stretching_factor(
        dx, int(3 * I / 4), length2)
    stretching_f1 = lambda xi: 1 + (np.tanh(delta1 *
                                            (xi - 1)) / np.tanh(delta1))
    stretching_f2 = lambda xi: 1 + (np.tanh(delta2 *
                                            (xi - 1)) / np.tanh(delta2))

    end_point = Point(x_min, y_min)
    start_point = Point(airfoil_start, y_min)
    r1_t = BoundaryGrids.fit_line(start_point, end_point, int(I / 4),
                                  stretching_f1)
    r1 = np.empty(len(r1_t), dtype=object)
    for i in range(len(r1)):
        r1[i] = r1_t[len(r1) - 1 - i]

    num = int((airfoil_end - airfoil_start) / dx) + 1
    start_point = Point(airfoil_start, y_min)
    end_point = Point(airfoil_end, y_min)
    r2 = BoundaryGrids.fit_line(start_point, end_point, num)

    start_point = Point(airfoil_end, y_min)
    end_point = Point(x_max, y_min)
    r3 = BoundaryGrids.fit_line(start_point, end_point, int(3 * I / 4),
                                stretching_f2)

    r = np.append(r1[:-1], r2)
    r = np.append(r[:-1], r3)
    bd1 = Boundary(len(r) - 1, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)

    f = plt.figure()
    plt = bd1.plot_boundary(plt, 'eta_min')

    end_point = Point(x_min, y_max)
    start_point = Point(airfoil_start, y_max)
    r1_t = BoundaryGrids.fit_line(start_point, end_point, int(I / 4),
                                  stretching_f1)
    r1 = np.empty(len(r1_t), dtype=object)
    for i in range(len(r1)):
        r1[i] = r1_t[len(r1) - 1 - i]

    num = int((airfoil_end - airfoil_start) / dx) + 1
    start_point = Point(airfoil_start, y_max)
    end_point = Point(airfoil_end, y_max)
    r2 = BoundaryGrids.fit_line(start_point, end_point, num)

    start_point = Point(airfoil_end, y_max)
    end_point = Point(x_max, y_max)
    r3 = BoundaryGrids.fit_line(start_point, end_point, int(3 * I / 4),
                                stretching_f2)

    r = np.append(r1[:-1], r2)
    r = np.append(r[:-1], r3)
    bd2 = Boundary(len(r) - 1, BdType.eta_max)
    bd2.populate_boundary_ndar_points(r)
    plt = bd2.plot_boundary(plt, 'eta_max')

    I = len(r) - 1

    #   start_point = Point(x_min, y_min)
    #   end_point = Point(x_min, y_max)
    #   A = 3
    #   L = 1
    #   yc = 0.5
    #   stretching_f = lambda xi: (L*xi) + A*(yc - L*xi)*(1 - xi)*xi
    #   r = BoundaryGrids.fit_line(start_point, end_point, int(J), stretching_f)
    #   bd3 = Boundary(len(r)-1, BdType.xi_min)
    #   bd3.populate_boundary_ndar_points(r)
    #   plt = bd3.plot_boundary(plt, 'xi_min')

    #   start_point = Point(x_max, y_min)
    #   end_point = Point(x_max, y_max)
    #   A = 3
    #   L = 1
    #   yc = 0.5
    #   stretching_f = lambda xi: (L*xi) + A*(yc - L*xi)*(1 - xi)*xi
    #   r = BoundaryGrids.fit_line(start_point, end_point, int(J), stretching_f)
    #   bd4 = Boundary(len(r)-1, BdType.xi_max)
    #   bd4.populate_boundary_ndar_points(r)
    #   plt = bd4.plot_boundary(plt, 'xi_max')

    #  plt.show()

    num = int((airfoil_y_e - airfoil_y_s) / dy) + 1
    K = int(J / 2) + int(J / 2) + num

    Grid_obj = TwoDGrid(I + 1, K + 1)
    Grid_obj.set_boundary(bd1)
    Grid_obj.set_boundary(bd2)
    Grid = Grid_obj.Grid

    length1 = abs(airfoil_y_s - y_min)
    length2 = abs(y_max - airfoil_y_e)
    delta1 = BoundaryGrids.find_hyp_tan_stretching_factor(
        dy, int(J / 2), length1)
    delta2 = BoundaryGrids.find_hyp_tan_stretching_factor(
        dy, int(J / 2), length2)
    stretching_f1 = lambda xi: 1 + (np.tanh(delta1 *
                                            (xi - 1)) / np.tanh(delta1))
    stretching_f2 = lambda xi: 1 + (np.tanh(delta2 *
                                            (xi - 1)) / np.tanh(delta2))

    for xi in range(0, I + 1):
        P_eta_min = Grid[xi, 0]
        P_eta_max = Grid[xi, K]

        end_point = P_eta_min
        start_point = Point(P_eta_min.x, airfoil_y_s)
        r1_t = BoundaryGrids.fit_line(start_point, end_point, int(J / 2),
                                      stretching_f1)
        r1 = np.empty(len(r1_t), dtype=object)
        for i in range(len(r1)):
            r1[i] = r1_t[len(r1) - 1 - i]

    #   num = int((airfoil_y_e - airfoil_y_s)/ 0.005) + 1
        start_point = Point(P_eta_min.x, airfoil_y_s)
        end_point = Point(P_eta_max.x, airfoil_y_e)
        r2 = BoundaryGrids.fit_line(start_point, end_point, num)

        start_point = Point(P_eta_max.x, airfoil_y_e)
        end_point = P_eta_max
        r3 = BoundaryGrids.fit_line(start_point, end_point, int(J / 2),
                                    stretching_f2)

        r = np.append(r1[:-1], r2)
        r = np.append(r[:-1], r3)
        #  K = int(J/2) + int(J/2) + num
        #   print len(r1), len(r2), len(r3), len(r), J, K

        Grid[xi, :] = r

# Grid_obj = StructuredGridGeneration.get_univariate_grid(bd1, bd2, \
#         bd3, bd4, stretching_f)
    Grid_obj.save_to_vtk('Circle-IB.vtk', 'Circle-IB')

    Grid_obj.save_to_txt('Circle-IB.txt')
示例#12
0
def get_Boundaries_Problem1():
    # Grid points go from xi = 0 to I. Hence I+1 grid points
    # n + 1 = number of control points

    global plt
    f = plt.figure()

    ################ Extract grid
    filename = 'n0012.dat'
    CP = extract_control_points(filename)
    CP_x = []
    CP_y = []

    for p in CP:
        CP_x.append(p.x)
        CP_y.append(p.y)

    ################ Generating around airfoil
    I = 100
    xi_spacing_f = lambda xi, I: 0.5 * I * (1 - np.cos(xi * np.pi / I))
    s_CP_f = lambda j, n, I: j * I / n
    s_CP_inverse_f = lambda s, n, I: s * n / I

    r = fit_cubic_spline(CP, I, xi_spacing_f, s_CP_f, s_CP_inverse_f)
    bd1 = Boundary(I, BdType.eta_min)
    bd1.populate_boundary_ndar_points(r)

    #plt = bd1.plot_boundary(plt, '1 - Control points')
    #plt.plot(CP_x, CP_y, marker='.', markevery=3, label = '1 - Control points')

    chord = np.sqrt((CP_x[-1] - CP_x[0])**2 + (CP_y[-1] - CP_y[0])**2)

    ################ Generating the lines
    # Clustering near the start
    I = 100
    start = {'x': 1, 'y': bd1.Points[-1].y}
    end = {'x': 21, 'y': 0}
    length = np.sqrt((end['x'] - start['x'])**2 + (end['y'] - start['y'])**2)
    ds1 = 0.001 * chord
    delta = find_hyp_tan_stretching_factor(ds1, I, length)
    stretching_f = lambda xi: 1 + (np.tanh(delta * (xi - 1)) / np.tanh(delta))
    r = fit_line(start, end, I, stretching_f)
    bd2 = Boundary(I, BdType.xi_max)
    bd2.populate_boundary_ndar_points(r)
    #plt = bd2.plot_boundary(plt, 'Boundary 2')

    # Clustering near the end
    I = 100
    start = {'x': 0, 'y': 0}
    end = {'x': -20, 'y': 0}
    length = np.sqrt((end['x'] - start['x'])**2 + (end['y'] - start['y'])**2)
    ds1 = 0.001 * chord
    delta = find_hyp_tan_stretching_factor(ds1, I, length)
    stretching_f = lambda xi: 1 + (np.tanh(delta * (xi - 1)) / np.tanh(delta))
    r = fit_line(start, end, I, stretching_f)
    bd3 = Boundary(I, BdType.xi_min)
    bd3.populate_boundary_ndar_points(r)
    #plt = bd3.plot_boundary(plt, 'Boundary 3')

    ################ Plotting the semicircle
    I = 100
    Radius = 20.5
    t1 = np.pi
    t2 = 0
    centre = {'x': 0.5, 'y': 0}
    r = fit_semicircle(Radius, t1, t2, centre, I)
    bd4 = Boundary(I, BdType.eta_max)
    bd4.populate_boundary_ndar_points(r)
    #plt = bd4.plot_boundary(plt, 'Boundary 4')

    #plt.legend(loc='best')
    #plt.show()

    return (bd1, bd2, bd3, bd4)