Exemple #1
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')
Exemple #2
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_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
Exemple #4
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()
Exemple #6
0
def fit_semicircle(Radius, t1, t2, centre, I, stretching_f=lambda xi: xi):
    # Assuming 2D. centre is a dictionary with 'x' and 'y' as keys
    # t1 and t2 - theta ranges - in radians
    r = np.empty(I + 1, dtype=object)

    for xi in range(I + 1):
        s = stretching_f(xi)
        t = (s * (t2 - t1) / I) + t1
        x = centre['x'] + Radius * np.cos(t)
        y = centre['y'] + Radius * np.sin(t)
        r[xi] = Point(x, y)

    return r
Exemple #7
0
def fit_line_old(start, end, I, stretching_f=lambda xi: xi):
    # I + 1 is the number of grid points
    # start and stop are 2 dictionaries have x and y as keys
    r = np.empty(I + 1, dtype=object)

    for xi in range(I + 1):
        s = stretching_f(xi / I)
        print start['x']
        print xi
        x = ((1 - s) * start['x']) + (s * end['x'])
        y = ((1 - s) * start['y']) + (s * end['y'])
        r[xi] = Point(x, y)

    return r
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')
Exemple #9
0
def extract_control_points(filename):
    f = open(filename, 'r')
    f.readline()  # First line - name of airfoil

    n = int(float(f.readline().split()[0]))
    # n is the number of control points or airfoil coordinates given

    f.readline()  # Blank line

    # Start reading coordinates
    p_list = []
    for i in range(n):
        x, y = f.readline().split()
        x, y = float(x), float(y)
        p_list.append(Point(x, y))

    return p_list
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)
def get_circle(radius, centre, I):
    r = np.empty(I + 1, dtype=object)
    for xi in range(I + 1):
        t = 2 * np.pi * (1 - xi / I)
        x = centre.x + radius * np.cos(t)
        y = centre.y + radius * np.sin(t)
        r[xi] = Point(x, y)

    start = []
    end = []
    normals = []
    for i in range(len(r) - 1):
        start.append([r[i].x, r[i].y])
        end.append([r[i + 1].x, r[i + 1].y])
        # Given a line segment, find dx = x2 - x1 and dy = y2 - y1
        # The normal vector to the line segment is given by (dy, -dx)
        # We also need to normalise it
        dx = r[i + 1].x - r[i].x
        dy = r[i + 1].y - r[i].y
        ds = np.sqrt(dx**2 + dy**2)
        dx = dx / ds
        dy = dy / ds
        normals.append([-dy, dx])
    return (start, end, normals)
def get_boundary_grids():
    # Eta_max boundary
    I = 300
    radius = 0.001
    p1 = Point(21*radius, 5*radius)
    p2 = Point(-6*radius, 5*radius)
    p3 = Point(-6*radius, -5*radius)
    p4 = Point(21*radius, -5*radius)
    bd_eta_max, i_list = get_eta_max_boundary(p1, p2, p3, p4, I)
    I = bd_eta_max.n

    # Eta_min boundary
    centre = Point(0, 0)
    bd_eta_min = get_circle_boundary(radius, centre, bd_eta_max)

    # Xi min and max boundaries
    I = 200
    start = Point(centre.x + radius, centre.y)
    end = 0.5 * (p1 + p4)
    bd_xi_min, bd_xi_max = get_xi_boundaries(start, end, I)

    print 'Index list: ', i_list
    return (bd_xi_min, bd_xi_max, bd_eta_min, bd_eta_max, i_list)
Exemple #13
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')
Exemple #15
0
def fit_cubic_spline(CP, I, xi_spacing_f=lambda xi: xi, s_CP_f=lambda j,n,I: \
                     j*I/n, s_CP_inverse_f=lambda s,n,I: s*n/I):
    # CP is the list of control points
    # It should be a list of dictionaries with keys 'x' and 'y'

    # I + 1 is the number of grid points
    # Note: xi ranges from 0 to I and is an integer only

    # xi_spacing_f is a function handle that transforms the spacing between
    # consecutive xi. This should return values in the same range as that of xi.
    # The default argument is equal spacing.
    # Note that now, s = xi_spacing(xi). Hence the grid generation parameter
    # is 's' and not xi. However since xi is an integer only, it can be used
    # as array index.

    # s_CP_f is a function handle which gives the value of s given the index of
    # control point j, i.e., it return s_j. The values of s at the intermediate
    # control points s_j can be got from equal spacing between s_0 and s_I.

    # s_CP_inverse_f is the function that returns the value of 'j' given a value
    # s. The s_CP_f function can be though of a map between the 'j' space and
    # the 's' space (0<=j<=n and 0<=s<=I). This function is the reverse map.
    # Non integer values of 'j' dont have any physical meaning. But the floor
    # and ceil of j correspond to s_j and s_j+1 which give the location of the
    # j and j+1 th control point respectively. This can be used to give the
    # equation of the jth cubic spline that was generated

    n = len(CP)

    # Solving for second derivative of r, implicitly
    r_dd_CP_x = np.zeros((n))
    r_dd_CP_y = np.zeros((n))
    r_dd_CP_x[0] = 0
    r_dd_CP_x[n - 1] = 0
    r_dd_CP_y[0] = 0
    r_dd_CP_y[n - 1] = 0

    # M is the same for x or y coordinate
    M = np.zeros((n - 2, n - 2))  # No need to solve for first and last r_dd

    b_x = np.zeros((n - 2))  # RHS of the implicit equation
    b_y = np.zeros((n - 2))  # RHS of the implicit equation

    delta = lambda j: s_CP_f(j + 1, n - 1, I) - s_CP_f(j, n - 1, I)

    for j in range(n - 2):
        # The delta function is written taking into account that the value of j
        # ranges from 0 to n-1. The inner points hence take value of j such that
        # 1 <= j <= n-2. But the computational domain is from 0 <= j <= n-3
        # (array index).
        # Hence all delta function calls should be made with j -> j+1
        # Also, all calls to CP should also be made with j -> j+1
        if j > 0:
            M[j, j - 1] = delta(j - 1 + 1) / 6.0  # c_i
        M[j, j] = (delta(j - 1 + 1) + delta(j + 1)) / 3.0  # d_i
        if j < n - 3:
            M[j, j + 1] = delta(j + 1) / 6.0  # a_i

        b_x[j] = (-1 * (CP[j + 1].x - CP[j-1 + 1].x) / delta(j-1 + 1)) + \
                 (+1 * (CP[j+1 + 1].x - CP[j + 1].x) / delta(j + 1))
        b_y[j] = (-1 * (CP[j + 1].y - CP[j-1 + 1].y) / delta(j-1 + 1)) + \
                 (+1 * (CP[j+1 + 1].y - CP[j + 1].y) / delta(j + 1))

    # Now use TDMA solver
    r_dd_CP_x[1:n - 1] = Thomas_algorithm(M, b_x)
    r_dd_CP_y[1:n - 1] = Thomas_algorithm(M, b_y)

    r_dd_CP = np.empty(n, dtype=object)
    for i in range(n):
        r_dd_CP[i] = Point(r_dd_CP_x[i], r_dd_CP_y[i])

    # Now we can construct the cubic spline
    # Note, we will construct the cubic spline at integer values of xi.
    # The equivalent 's' is found as xi_spacing_f(xi).
    # The values of s at the control points are found using the function
    # s_CP_f.

    # Cubic polynomials have been constructed between the control points
    # But, given a value of s, it is necessary to know which interval that s
    # belongs to, i.e., which 'j'
    # That shall be the inverse of the function s_CP_f which is s_CP_inverse_f.
    # But the inverse will return a fractional value. Hence, the floor and ceil
    # of that number will give the required interval
    r = np.empty(I + 1, dtype=object)
    r[0] = Point(CP[0].x, CP[0].y)
    r[I] = Point(CP[n - 1].x, CP[n - 1].y)

    for xi in range(1, I):
        s = xi_spacing_f(xi, I)
        j = s_CP_inverse_f(s, n - 1, I)
        if int(round(j * 10)) % 10 == 0:
            j_l = int(j)
            if j_l == n:
                j_l = n - 1
            j_u = j_l + 1
        else:
            j_l = int(np.floor(j))
            j_u = int(np.ceil(j))
        s_l = s_CP_f(j_l, n - 1, I)
        s_u = s_CP_f(j_u, n - 1, I)

        # xi is used as the array index since it is always an integer
        r[xi] = (s_u - s)**3 * r_dd_CP[j_l] / (6.0 * (s_u - s_l)) + \
                 (s - s_l)**3 * r_dd_CP[j_u] / (6.0 * (s_u - s_l)) + \
                 ( (s_u - s) * \
                   ((CP[j_l] / (s_u - s_l)) - ((s_u - s_l) * \
                                                      r_dd_CP[j_l]/6.0)) ) + \
                 ( (s - s_l) * \
                   ((CP[j_u] / (s_u - s_l)) - ((s_u - s_l) * \
                                                      r_dd_CP[j_u]/6.0)) )

    return r
def read_from_file(filename):
    start = []
    end = []
    normals = []
    f = open(filename, 'r')
    # First line contains number of iblines
    num_iblines = int(f.readline())
    for i in range(num_iblines):
        line = f.readline()
        data = line.split()
        data = [float(d) for d in data]
        start.append([data[0], data[1]])
        end.append([data[2], data[3]])
        normals.append([data[4], data[5]])

    return (start, end, normals)


if __name__ == '__main__':
    #  x, y = get_naca_grid_gridgen()
    #  start, end, normals = get_lines_from_upper_airfoil(x, y)
    radius = 0.005
    centre = Point(0., 0.)
    I = 50
    #  start, end, normals = get_circle(radius, centre, I)
    #  start, end, normals = get_exp_fan_IB()
    start, end, normals = get_concave_polygon()
    plot_start_end_normals(start, end, normals)
    filename = 'concave.dat'
    put_to_file(start, end, normals, filename)