def panel_positions(self, DSTEP1, DSTEP2, DSTEP3, T, THETA, HEAVE): """Updates all the absolute-frame coordinates of the body. Args: DSTEP: Small incremental distance to pass into neutral_plane(). T: Time of current step. THETA: Current pitching angle. """ bfx = self.BF.x bfy = self.BF.y #No y information coming from the geometry class yet bfz = self.BF.z bfz_col = self.BF.z_col V0 = self.V0 # Used only for x_le (x_neut, y_neut, z_neut) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE) # Infinitesimal differences on the neutral axis to calculate the tangential and normal vectors v1 = (xdp_y, ydp_y, zdp_y) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, 0, DSTEP2, DSTEP3) v2 = (xdm_y, ydm_y, zdm_y) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, 0, -DSTEP2, -DSTEP3) v3 = (xdp_x, ydp_x, zdp_x) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, DSTEP1, 0, 0) v4 = (xdm_x, ydm_x, zdm_x) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, -DSTEP1, 0, 0) # Absolute-frame panel endpoint positions for time t afx = x_neut + point_vectors(v1,v2,v3,v4)[1]*bfz afy = y_neut + point_vectors(v1,v2,v3,v4)[2]*bfz afz = z_neut + point_vectors(v1,v2,v3,v4)[3]*bfz # Absolute-frame panel midpoint positions x_mid = (afx[1:,:-1]+afx[:-1,:-1])/2 y_mid = (afy[1:,:-1]+afy[:-1,:-1])/2 z_mid = (afz[1:,:-1]+afz[:-1,:-1])/2 # Collocation points are the points where impermeable boundary condition is forced # They should be shifted inside or outside of the boundary depending on the dirichlet or neumann condition # Shifting surface collocation points some percent of the height from the neutral axis # Normal vectors point outward but positive S is inward, so the shift must be subtracted from the panel midpoints afx_col = x_mid - self.S*panel_vectors(afx, afz)[2]*np.absolute(bfz_col) afy_col = y_mid - self.S*panel_vectors(afx, afz)[2]*np.absolute(bfz_col) afz_col = z_mid - self.S*panel_vectors(afx, afz)[3]*np.absolute(bfz_col) self.AF.x = afx self.AF.y = afy self.AF.z = afz self.AF.x_col = afx_col self.AF.y_col = afy_col self.AF.z_col = afz_col self.AF.x_mid = x_mid self.AF.y_mid = y_mid self.AF.z_mid = z_mid self.AF.x_neut = x_neut self.AF.y_neut = y_neut self.AF.z_neut = z_neut # Location of leading edge (currently pitching motion only) self.AF.x_le = V0*T self.AF.y_le = 0 self.AF.z_le = HEAVE
def surface_kinematics(self, DSTEP, TSTEP, THETA_MINUS, THETA_PLUS, HEAVE_MINUS, HEAVE_PLUS, DEL_T, T, i): """Calculates the body-frame surface velocities of body panels. Also finds the body panel source strengths based on these surface velocities. Args: DSTEP, TSTEP: Incremental distance/time passed into neutral_axis(). DEL_T: Time step length. T: Time of current step. i: Time step number. THETA_MINUS: Pitching angle minus a small time difference (TSTEP) THETA_PLUS: Pitching angle plus a small time difference (TSTEP) """ if i == 0: x_col = self.BF.x_col z_col = self.BF.z_col # Panel midpoint velocity calculations # Calculating the surface positions at tplus(tp) and tminus(tm) (xtpneut, ztpneut) = self.neutral_axis(x_col, T, THETA_PLUS, HEAVE_PLUS, 0) (xtpdp, ztpdp) = self.neutral_axis(x_col, T, THETA_PLUS, HEAVE_PLUS, DSTEP) (xtpdm, ztpdm) = self.neutral_axis(x_col, T, THETA_PLUS, HEAVE_PLUS, -DSTEP) (xtmneut, ztmneut) = self.neutral_axis(x_col, T, THETA_MINUS, HEAVE_MINUS, 0) (xtmdp, ztmdp) = self.neutral_axis(x_col, T, THETA_MINUS, HEAVE_MINUS, DSTEP) (xtmdm, ztmdm) = self.neutral_axis(x_col, T, THETA_MINUS, HEAVE_MINUS, -DSTEP) # Displaced airfoil's panel midpoints for times tplus(tp) and tminus(tm) xctp = xtpneut + point_vectors(xtpdp, xtpdm, ztpdp, ztpdm)[2]*z_col xctm = xtmneut + point_vectors(xtmdp, xtmdm, ztmdp, ztmdm)[2]*z_col zctp = ztpneut + point_vectors(xtpdp, xtpdm, ztpdp, ztpdm)[3]*z_col zctm = ztmneut + point_vectors(xtmdp, xtmdm, ztmdp, ztmdm)[3]*z_col # Velocity calculations on the surface panel midpoints self.vx = (xctp - xctm)/(2*TSTEP) self.vz = (zctp - zctm)/(2*TSTEP) elif i == 1: # First-order backwards differencing of body collocation point positions self.vx = (self.AF.x_mid[0,:]-self.AF.x_mid[1,:])/DEL_T - self.V0 self.vz = (self.AF.z_mid[0,:]-self.AF.z_mid[1,:])/DEL_T else: # Second-order backwards differencing of body collocation point positions self.vx = (3*self.AF.x_mid[0,:]-4*self.AF.x_mid[1,:]+self.AF.x_mid[2,:])/(2*DEL_T) - self.V0 self.vz = (3*self.AF.z_mid[0,:]-4*self.AF.z_mid[1,:]+self.AF.z_mid[2,:])/(2*DEL_T) # Body source strengths with normal vector pointing outward (overall sigma pointing outward) (nx,nz) = panel_vectors(self.AF.x,self.AF.z)[2:4] self.sigma = nx*(self.V0 + self.vx) + nz*self.vz
def surface_kinematics(self, DSTEP, TSTEP, DEL_T, T, i): """Calculates the body-frame surface velocities of body panels. Args: DSTEP, TSTEP: Incremental distance/time passed into neutral_axis(). DEL_T: Time step length. T: Time of current step. i: Time step number. x_col, z_col: Unshifted body-frame collocation point coordinates. """ if i == 0: x_col = self.BF.x_col z_col = self.BF.z_col # Panel midpoint velocity calculations # Calculating the surface positions at tplus(tp) and tminus(tm) (xtpneut, ztpneut) = self.neutral_axis(x_col, T, 0, TSTEP) (xtpdp, ztpdp) = self.neutral_axis(x_col, T, DSTEP, TSTEP) (xtpdm, ztpdm) = self.neutral_axis(x_col, T, -DSTEP, TSTEP) (xtmneut, ztmneut) = self.neutral_axis(x_col, T, 0, -TSTEP) (xtmdp, ztmdp) = self.neutral_axis(x_col, T, DSTEP, -TSTEP) (xtmdm, ztmdm) = self.neutral_axis(x_col, T, -DSTEP, -TSTEP) # Displaced airfoil's panel midpoints for times tplus(tp) and tminus(tm) xctp = xtpneut + point_vectors(xtpdp, xtpdm, ztpdp, ztpdm)[2]*z_col xctm = xtmneut + point_vectors(xtmdp, xtmdm, ztmdp, ztmdm)[2]*z_col zctp = ztpneut + point_vectors(xtpdp, xtpdm, ztpdp, ztpdm)[3]*z_col zctm = ztmneut + point_vectors(xtmdp, xtmdm, ztmdp, ztmdm)[3]*z_col # Velocity calculations on the surface panel midpoints self.vx = (xctp - xctm)/(2*TSTEP) self.vz = (zctp - zctm)/(2*TSTEP) elif i == 1: # First-order backwards differencing of body collocation point positions self.vx = (self.AF.x_mid[0,:]-self.AF.x_mid[1,:])/DEL_T - self.V0 self.vz = (self.AF.z_mid[0,:]-self.AF.z_mid[1,:])/DEL_T else: # Second-order backwards differencing of body collocation point positions self.vx = (3*self.AF.x_mid[0,:]-4*self.AF.x_mid[1,:]+self.AF.x_mid[2,:])/(2*DEL_T) - self.V0 self.vz = (3*self.AF.z_mid[0,:]-4*self.AF.z_mid[1,:]+self.AF.z_mid[2,:])/(2*DEL_T) (nx,nz) = panel_vectors(self.AF.x,self.AF.z)[2:4] self.sigma = nx*(self.V0 + self.vx) + nz*self.vz
def panel_positions(self, DSTEP, T): """Updates all the absolute-frame coordinates of the body. Args: DSTEP: Small incremental distance to pass into neutral_axis(). T: Time of current step. bfx, bfz: Body-frame x- and z-coordinates. bfz_col: Body-frame collocation z-coordinates (unshifted) V0: Free-stream velocity. """ bfx = self.BF.x bfz = self.BF.z bfz_col = self.BF.z_col V0 = self.V0 # Used only for x_le (x_neut, z_neut) = self.neutral_axis(bfx, T) # Infinitesimal differences on the neutral axis to calculate the tangential and normal vectors (xdp_s, zdp_s) = self.neutral_axis(bfx, T, DSTEP) (xdm_s, zdm_s) = self.neutral_axis(bfx, T, -DSTEP) # Absolute-frame panel endpoint positions for time t afx = x_neut + point_vectors(xdp_s, xdm_s, zdp_s, zdm_s)[2]*bfz afz = z_neut + point_vectors(xdp_s, xdm_s, zdp_s, zdm_s)[3]*bfz # Absolute-frame panel midpoint positions x_mid = (afx[:-1]+afx[1:])/2 z_mid = (afz[:-1]+afz[1:])/2 # Collocation points are the points where impermeable boundary condition is forced # They should be shifted inside or outside of the boundary depending on the dirichlet or neumann condition # Shifting surface collocation points some percent of the height from the neutral axis # Normal vectors point outward but positive S is inward, so the shift must be subtracted from the panel midpoints afx_col = x_mid - self.S*panel_vectors(afx, afz)[2]*np.absolute(bfz_col) afz_col = z_mid - self.S*panel_vectors(afx, afz)[3]*np.absolute(bfz_col) self.AF.x = afx self.AF.z = afz self.AF.x_col = afx_col self.AF.z_col = afz_col self.AF.x_mid[0,:] = x_mid self.AF.z_mid[0,:] = z_mid self.AF.x_neut = x_neut self.AF.z_neut = z_neut # Location of leading edge (assuming pitching motion only) self.AF.x_le = V0*T self.AF.z_le = 0.
def surface_kinematics(self, DSTEP1, DSTEP2, DSTEP3, TSTEP, THETA_MINUS, THETA_PLUS, HEAVE_MINUS, HEAVE_PLUS, DEL_T, T, i): """Calculates the body-frame surface velocities of body panels. Also finds the body panel source strengths based on these surface velocities. Args: DSTEP, TSTEP: Incremental distance/time passed into neutral_axis(). DEL_T: Time step length. T: Time of current step. i: Time step number. THETA_MINUS: Pitching angle minus a small time difference (TSTEP) THETA_PLUS: Pitching angle plus a small time difference (TSTEP) """ Nc = self.BF.x_mid.shape[0] Ns = self.BF.x_mid.shape[1] if i == 0: x_col = self.BF.x_mid y_col = self.BF.y_mid z_col = self.BF.z_mid # Panel midpoint velocity calculations # Calculating the surface positions at tplus(tp) and tminus(tm) (xtpneut, ytpneut, ztpneut) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, 0, 0, 0) (xtpdp_y, ytpdp_y, ztpdp_y) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, 0, DSTEP2, DSTEP3) (xtpdp_x, ytpdp_x, ztpdp_x) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, DSTEP1, 0, 0) (xtpdm_y, ytpdm_y, ztpdm_y) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, 0, -DSTEP2, -DSTEP3) (xtpdm_x, ytpdm_x, ztpdm_x) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, -DSTEP1, 0, 0) (xtmneut, ytmneut, ztmneut) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, 0, 0, 0) (xtmdp_y, ytmdp_y, ztmdp_y) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, 0, DSTEP2, DSTEP3) (xtmdp_x, ytmdp_x, ztmdp_x) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, DSTEP1, 0, 0) (xtmdm_y, ytmdm_y, ztmdm_y) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, 0, -DSTEP2, -DSTEP3) (xtmdm_x, ytmdm_x, ztmdm_x) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, -DSTEP1, 0, 0) # Displaced airfoil's panel midpoints for times tplus(tp) and tminus(tm) xctp = xtpneut + point_vectors(Nc, Ns, (xtpdp_y, ytpdp_y, ztpdp_y), (xtpdm_y, ytpdm_y, ztpdm_y), (xtpdp_x, ytpdp_x, ztpdp_x), (xtpdm_x, ytpdm_x, ztpdm_x))[0]*z_col xctm = xtmneut + point_vectors(Nc, Ns, (xtmdp_y, ytmdp_y, ztmdp_y), (xtmdm_y, ytmdm_y, ztmdm_y), (xtmdp_x, ytmdp_x, ztmdp_x), (xtmdm_x, ytmdm_x, ztmdm_x))[0]*z_col yctp = ytpneut + point_vectors(Nc, Ns, (xtpdp_y, ytpdp_y, ztpdp_y), (xtpdm_y, ytpdm_y, ztpdm_y), (xtpdp_x, ytpdp_x, ztpdp_x), (xtpdm_x, ytpdm_x, ztpdm_x))[1]*z_col yctm = ytmneut + point_vectors(Nc, Ns, (xtmdp_y, ytmdp_y, ztmdp_y), (xtmdm_y, ytmdm_y, ztmdm_y), (xtmdp_x, ytmdp_x, ztmdp_x), (xtmdm_x, ytmdm_x, ztmdm_x))[1]*z_col zctp = ztpneut + point_vectors(Nc, Ns, (xtpdp_y, ytpdp_y, ztpdp_y), (xtpdm_y, ytpdm_y, ztpdm_y), (xtpdp_x, ytpdp_x, ztpdp_x), (xtpdm_x, ytpdm_x, ztpdm_x))[2]*z_col zctm = ztmneut + point_vectors(Nc, Ns, (xtmdp_y, ytmdp_y, ztmdp_y), (xtmdm_y, ytmdm_y, ztmdm_y), (xtmdp_x, ytmdp_x, ztmdp_x), (xtmdm_x, ytmdm_x, ztmdm_x))[2]*z_col # Velocity calculations on the surface panel midpoints self.vx = (xctp - xctm)/(2*TSTEP) self.vy = (yctp - yctm)/(2*TSTEP) self.vz = (zctp - zctm)/(2*TSTEP) elif i == 1: # First-order backwards differencing of body collocation point positions self.vx = (self.AF.x_mid[:,:,0]-self.AF.x_mid[:,:,1])/DEL_T - self.V0 self.vy = (self.AF.y_mid[:,:,0]-self.AF.y_mid[:,:,1])/DEL_T self.vz = (self.AF.z_mid[:,:,0]-self.AF.z_mid[:,:,1])/DEL_T else: # Second-order backwards differencing of body collocation point positions self.vx = (3*self.AF.x_mid[:,:,0]-4*self.AF.x_mid[:,:,1]+self.AF.x_mid[:,:,2])/(2*DEL_T) - self.V0 self.vy = (3*self.AF.y_mid[:,:,0]-4*self.AF.y_mid[:,:,1]+self.AF.y_mid[:,:,2])/(2*DEL_T) self.vz = (3*self.AF.z_mid[:,:,0]-4*self.AF.z_mid[:,:,1]+self.AF.z_mid[:,:,2])/(2*DEL_T) # # Body source strengths with normal vector pointing outward (overall sigma pointing outward) (nx, ny, nz) = panel_vectors(self.AF.x, self.AF.y, self.AF.z)[0:3] self.sigma = nx*(self.V0 + self.vx) + ny*self.vy + nz*self.vz
def surface_kinematics(self, DSTEP1, DSTEP2, DSTEP3, TSTEP, THETA_MINUS, THETA_PLUS, HEAVE_MINUS, HEAVE_PLUS, DEL_T, T, i): """Calculates the body-frame surface velocities of body panels. Also finds the body panel source strengths based on these surface velocities. Args: DSTEP, TSTEP: Incremental distance/time passed into neutral_axis(). DEL_T: Time step length. T: Time of current step. i: Time step number. THETA_MINUS: Pitching angle minus a small time difference (TSTEP) THETA_PLUS: Pitching angle plus a small time difference (TSTEP) """ Nc = self.BF.x_mid.shape[0] Ns = self.BF.x_mid.shape[1] if i == 0: x_col = self.BF.x_mid y_col = self.BF.y_mid z_col = self.BF.z_mid # Panel midpoint velocity calculations # Calculating the surface positions at tplus(tp) and tminus(tm) (xtpneut, ytpneut, ztpneut) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, 0, 0, 0) (xtpdp_y, ytpdp_y, ztpdp_y) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, 0, DSTEP2, DSTEP3) (xtpdp_x, ytpdp_x, ztpdp_x) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, DSTEP1, 0, 0) (xtpdm_y, ytpdm_y, ztpdm_y) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, 0, -DSTEP2, -DSTEP3) (xtpdm_x, ytpdm_x, ztpdm_x) = self.neutral_plane(x_col, y_col, T, THETA_PLUS, HEAVE_PLUS, -DSTEP1, 0, 0) (xtmneut, ytmneut, ztmneut) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, 0, 0, 0) (xtmdp_y, ytmdp_y, ztmdp_y) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, 0, DSTEP2, DSTEP3) (xtmdp_x, ytmdp_x, ztmdp_x) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, DSTEP1, 0, 0) (xtmdm_y, ytmdm_y, ztmdm_y) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, 0, -DSTEP2, -DSTEP3) (xtmdm_x, ytmdm_x, ztmdm_x) = self.neutral_plane(x_col, y_col, T, THETA_MINUS, HEAVE_MINUS, -DSTEP1, 0, 0) # Displaced airfoil's panel midpoints for times tplus(tp) and tminus(tm) xctp = xtpneut + point_vectors( Nc, Ns, (xtpdp_y, ytpdp_y, ztpdp_y), (xtpdm_y, ytpdm_y, ztpdm_y), (xtpdp_x, ytpdp_x, ztpdp_x), (xtpdm_x, ytpdm_x, ztpdm_x))[0] * z_col xctm = xtmneut + point_vectors( Nc, Ns, (xtmdp_y, ytmdp_y, ztmdp_y), (xtmdm_y, ytmdm_y, ztmdm_y), (xtmdp_x, ytmdp_x, ztmdp_x), (xtmdm_x, ytmdm_x, ztmdm_x))[0] * z_col yctp = ytpneut + point_vectors( Nc, Ns, (xtpdp_y, ytpdp_y, ztpdp_y), (xtpdm_y, ytpdm_y, ztpdm_y), (xtpdp_x, ytpdp_x, ztpdp_x), (xtpdm_x, ytpdm_x, ztpdm_x))[1] * z_col yctm = ytmneut + point_vectors( Nc, Ns, (xtmdp_y, ytmdp_y, ztmdp_y), (xtmdm_y, ytmdm_y, ztmdm_y), (xtmdp_x, ytmdp_x, ztmdp_x), (xtmdm_x, ytmdm_x, ztmdm_x))[1] * z_col zctp = ztpneut + point_vectors( Nc, Ns, (xtpdp_y, ytpdp_y, ztpdp_y), (xtpdm_y, ytpdm_y, ztpdm_y), (xtpdp_x, ytpdp_x, ztpdp_x), (xtpdm_x, ytpdm_x, ztpdm_x))[2] * z_col zctm = ztmneut + point_vectors( Nc, Ns, (xtmdp_y, ytmdp_y, ztmdp_y), (xtmdm_y, ytmdm_y, ztmdm_y), (xtmdp_x, ytmdp_x, ztmdp_x), (xtmdm_x, ytmdm_x, ztmdm_x))[2] * z_col # Velocity calculations on the surface panel midpoints self.vx = (xctp - xctm) / (2 * TSTEP) self.vy = (yctp - yctm) / (2 * TSTEP) self.vz = (zctp - zctm) / (2 * TSTEP) elif i == 1: # First-order backwards differencing of body collocation point positions self.vx = (self.AF.x_mid[:, :, 0] - self.AF.x_mid[:, :, 1]) / DEL_T - self.V0 self.vy = (self.AF.y_mid[:, :, 0] - self.AF.y_mid[:, :, 1]) / DEL_T self.vz = (self.AF.z_mid[:, :, 0] - self.AF.z_mid[:, :, 1]) / DEL_T else: # Second-order backwards differencing of body collocation point positions self.vx = (3 * self.AF.x_mid[:, :, 0] - 4 * self.AF.x_mid[:, :, 1] + self.AF.x_mid[:, :, 2]) / (2 * DEL_T) - self.V0 self.vy = (3 * self.AF.y_mid[:, :, 0] - 4 * self.AF.y_mid[:, :, 1] + self.AF.y_mid[:, :, 2]) / (2 * DEL_T) self.vz = (3 * self.AF.z_mid[:, :, 0] - 4 * self.AF.z_mid[:, :, 1] + self.AF.z_mid[:, :, 2]) / (2 * DEL_T) # # Body source strengths with normal vector pointing outward (overall sigma pointing outward) (nx, ny, nz) = panel_vectors(self.AF.x, self.AF.y, self.AF.z)[0:3] self.sigma = nx * (self.V0 + self.vx) + ny * self.vy + nz * self.vz
def panel_positions(self, DSTEP1, DSTEP2, DSTEP3, T, THETA, HEAVE): """Updates all the absolute-frame coordinates of the body. Args: DSTEP: Small incremental distance to pass into neutral_plane(). T: Time of current step. THETA: Current pitching angle. """ # Nc = int(0.5*(self.BF.x.shape[0]-1)) Nc = self.BF.x.shape[0] Ns = self.BF.x.shape[1] bfx = self.BF.x bfy = self.BF.y #No y information coming from the geometry class yet bfz = self.BF.z bfz_col = self.BF.z_mid V0 = self.V0 # Used only for x_le (x_neut, y_neut, z_neut) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE) # Infinitesimal differences on the neutral axis to calculate the tangential and normal vectors v1 = (xdp_y, ydp_y, zdp_y) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, 0, DSTEP2, DSTEP3) v2 = (xdm_y, ydm_y, zdm_y) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, 0, -DSTEP2, -DSTEP3) v3 = (xdp_x, ydp_x, zdp_x) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, DSTEP1, 0, 0) v4 = (xdm_x, ydm_x, zdm_x) = self.neutral_plane(bfx, bfy, T, THETA, HEAVE, -DSTEP1, 0, 0) # Absolute-frame panel endpoint positions for time t afx = x_neut + point_vectors(Nc, Ns, v1, v2, v3, v4)[0] * bfz afy = y_neut + point_vectors(Nc, Ns, v1, v2, v3, v4)[1] * bfz afz = z_neut + point_vectors(Nc, Ns, v1, v2, v3, v4)[2] * bfz # Absolute-frame panel midpoint positions x_mid = (afx[1:, :-1] + afx[:-1, :-1]) / 2 y_mid = (afy[1:, :-1] + afy[:-1, :-1]) / 2 z_mid = (afz[1:, :-1] + afz[:-1, :-1]) / 2 # Collocation points are the points where impermeable boundary condition is forced # They should be shifted inside or outside of the boundary depending on the dirichlet or neumann condition # Shifting surface collocation points some percent of the height from the neutral axis # Normal vectors point outward but positive S is inward, so the shift must be subtracted from the panel midpoints afx_col = x_mid - self.S * panel_vectors(bfx, bfy, bfz)[0] * np.absolute(bfz_col) afy_col = y_mid - self.S * panel_vectors(bfy, bfy, bfz)[1] * np.absolute(bfz_col) afz_col = z_mid - self.S * panel_vectors(bfz, bfy, bfz)[2] * np.absolute(bfz_col) self.AF.x = afx self.AF.y = afy self.AF.z = afz self.AF.x_col = afx_col self.AF.y_col = afy_col self.AF.z_col = afz_col self.AF.x_mid[:, :, 0] = x_mid self.AF.y_mid[:, :, 0] = y_mid self.AF.z_mid[:, :, 0] = z_mid self.AF.x_neut = x_neut self.AF.y_neut = y_neut self.AF.z_neut = z_neut # Location of leading edge (currently pitching motion only) self.AF.x_le = V0 * T self.AF.y_le = 0 self.AF.z_le = HEAVE
def surface_kinematics(self, DSTEP, TSTEP, THETA_MINUS, THETA_PLUS, HEAVE_MINUS, HEAVE_PLUS, DEL_T, T, i): """Calculates the body-frame surface velocities of body panels. Also finds the body panel source strengths based on these surface velocities. Args: DSTEP, TSTEP: Incremental distance/time passed into neutral_axis(). DEL_T: Time step length. T: Time of current step. i: Time step number. THETA_MINUS: Pitching angle minus a small time difference (TSTEP) THETA_PLUS: Pitching angle plus a small time difference (TSTEP) """ if i == 0: x_col = self.BF.x_col z_col = self.BF.z_col # Panel midpoint velocity calculations # Calculating the surface positions at tplus(tp) and tminus(tm) (xtpneut, ztpneut) = self.neutral_axis(x_col, T, THETA_PLUS, HEAVE_PLUS, 0) (xtpdp, ztpdp) = self.neutral_axis(x_col, T, THETA_PLUS, HEAVE_PLUS, DSTEP) (xtpdm, ztpdm) = self.neutral_axis(x_col, T, THETA_PLUS, HEAVE_PLUS, -DSTEP) (xtmneut, ztmneut) = self.neutral_axis(x_col, T, THETA_MINUS, HEAVE_MINUS, 0) (xtmdp, ztmdp) = self.neutral_axis(x_col, T, THETA_MINUS, HEAVE_MINUS, DSTEP) (xtmdm, ztmdm) = self.neutral_axis(x_col, T, THETA_MINUS, HEAVE_MINUS, -DSTEP) # Displaced airfoil's panel midpoints for times tplus(tp) and tminus(tm) xctp = xtpneut + point_vectors(xtpdp, xtpdm, ztpdp, ztpdm)[2] * z_col xctm = xtmneut + point_vectors(xtmdp, xtmdm, ztmdp, ztmdm)[2] * z_col zctp = ztpneut + point_vectors(xtpdp, xtpdm, ztpdp, ztpdm)[3] * z_col zctm = ztmneut + point_vectors(xtmdp, xtmdm, ztmdp, ztmdm)[3] * z_col # Velocity calculations on the surface panel midpoints self.vx = (xctp - xctm) / (2 * TSTEP) self.vz = (zctp - zctm) / (2 * TSTEP) elif i == 1: # First-order backwards differencing of body collocation point positions self.vx = (self.AF.x_mid[0, :] - self.AF.x_mid[1, :]) / DEL_T - self.V0 self.vz = (self.AF.z_mid[0, :] - self.AF.z_mid[1, :]) / DEL_T else: # Second-order backwards differencing of body collocation point positions self.vx = (3 * self.AF.x_mid[0, :] - 4 * self.AF.x_mid[1, :] + self.AF.x_mid[2, :]) / (2 * DEL_T) - self.V0 self.vz = (3 * self.AF.z_mid[0, :] - 4 * self.AF.z_mid[1, :] + self.AF.z_mid[2, :]) / (2 * DEL_T) # Body source strengths with normal vector pointing outward (overall sigma pointing outward) (nx, nz) = panel_vectors(self.AF.x, self.AF.z)[2:4] self.sigma = nx * (self.V0 + self.vx) + nz * self.vz