Esempio n. 1
0
 def _calc_area(self):
     # Calculates the panel area from the two constituent triangles
     A = 0.5 * norm(
         cross(self.vertices[1] - self.vertices[0],
               self.vertices[2] - self.vertices[0]))
     return A + 0.5 * norm(
         cross(self.vertices[2] - self.vertices[0],
               self.vertices[3] - self.vertices[0]))
Esempio n. 2
0
    def calc_local_coords(self, **kwargs):
        """Calculates panel local coords (dependent on flow properties).

        Parameters
        ----------
        M : float
            Freestream Mach number.
        """

        # Get kwargs
        M = kwargs["M"]
        c_0 = kwargs["c_0"]
        C_0 = kwargs["C_0"]
        B_0 = kwargs["B_0"]
        s = kwargs["s"]
        B = kwargs["B"]

        # Calculate tangent vector compressible norms (if applicable)
        if hasattr(self, "t"):
            self.t_comp_norm = np.zeros(3)
            for i, t in enumerate(self.t):
                self.t_comp_norm[i] = inner(t, t)-M**2*inner(c_0, t)**2

        # Calculate conormal vector
        self.n_co = self.n-M**2*inner(c_0, self.n)*c_0

        # Check inclination
        self.n_co = np.einsum('ij,j', B_0, self.n)
        self._incl = inner(self.n, self.n_co)
        if abs(self._incl)<1e-10:
            raise MachInclinedError
        self._r = np.sign(self._incl)

        # Get panel coordinate directions
        v_0 = cross(self.n, c_0)
        v_0 /= norm(v_0)
        u_0 = cross(v_0, self.n)
        u_0 /= norm(u_0)

        # Calculate transformation matrix
        # It should be that det(A) = B**2 (see Epton & Magnus pp. E.3-16)
        self._A = np.zeros((3,3))
        denom = abs(self._incl)**-0.5
        self._A[0,:] = denom*np.einsum('ij,j', C_0, u_0)
        self._A[1,:] = self._r*s/B*np.einsum('ij,j', C_0, v_0)
        self._A[2,:] = B*denom*self.n

        # Calculate area Jacobian
        self._J = 1.0/B*denom
Esempio n. 3
0
    def _calc_skewness(self):
        # Calculates the skewness parameters for this panel (if not triangular)

        # Get skewness parameters for 4-sided panel
        if self.N==4:
            self.C_skew = np.zeros((2,4))
            denom = inner(cross(self.midpoints[3]-self.center, self.midpoints[0]-self.center), self.n)
            self.C_skew[0,0] = inner(cross(self.vertices[0]-self.midpoints[3], self.midpoints[0]-self.center), self.n)/denom
            self.C_skew[1,0] = inner(cross(self.midpoints[3]-self.center, self.vertices[0]-self.center), self.n)/denom
            self.C_skew[0,1] = self.C_skew[0,0]
            self.C_skew[1,1] = -self.C_skew[1,0]
            self.C_skew[0,2] = -self.C_skew[0,0]
            self.C_skew[1,2] = -self.C_skew[1,0]
            self.C_skew[0,3] = -self.C_skew[0,0]
            self.C_skew[1,3] = self.C_skew[1,0]
Esempio n. 4
0
    def __init__(self, **kwargs):

        # Store vertices
        self.vertices = np.zeros((3,3))
        self.vertices[0] = kwargs["v0"]
        self.vertices[1] = kwargs["v1"]
        self.vertices[2] = kwargs["v2"]
        self._projected = kwargs.get("projected", False)

        # Calculate area and normal vector
        n = cross(self.vertices[1]-self.vertices[0], self.vertices[2]-self.vertices[1])
        N = norm(n)
        self.A = 0.5*N
        self.n = n/N

        # Check for zero area in projected panel
        if self.A<1e-10 and self._projected:
            self.null_panel = True
        else:
            self.null_panel = False

            # Calculate edge tangents
            self.t = np.roll(self.vertices, 1, axis=0)-self.vertices
            self.t /= np.linalg.norm(self.t, axis=1, keepdims=True)

            self._calc_geom_props()
Esempio n. 5
0
 def _calc_normal(self):
     # Calculates the panel unit normal vector
     # Assumes the panel is planar
     d1 = self.vertices[1] - self.vertices[0]
     d2 = self.vertices[2] - self.vertices[1]
     N = cross(d1, d2)
     return N / norm(N)
Esempio n. 6
0
    def __init__(self, **kwargs):

        # Store vertices
        self.vertices = np.zeros((4,3))
        self.vertices[0] = kwargs.get("v0")
        self.vertices[1] = kwargs.get("v1")
        self.vertices[2] = kwargs.get("v2")
        self.vertices[3] = kwargs.get("v3", self.vertices[2]) # Will get removed by _check_collapsed_vertices()

        # Store edge number
        self.edge = kwargs.get("edge", [0])

        # Determine if this is a projected panel
        self._projected = kwargs.get("projected", False)

        # Check for collapsed points
        self._check_collapsed_vertices(kwargs.get("tol", 1e-8))

        # Calculate midpoints
        self.midpoints = 0.5*(self.vertices+np.roll(self.vertices, 1, axis=0))

        # Calculate normal vector; this is simpler than the method used in PAN AIR, which is able to handle
        # the case where the midpoints and center point do not lie in a flat plane [Epton & Magnus section D.2]
        self.n = cross(self.midpoints[1]-self.midpoints[0], self.midpoints[2]-self.midpoints[1])
        self.n /= norm(self.n)

        # Other calculations
        self._calc_geom_props()
        self._calc_skewness()

        # Setup projected panel
        if not self._projected:
            self._initialize_projected_panel()

        # Initialize subpanels
        self.subpanels = []
        for i in range(self.N):

            # Outer subpanel
            self.subpanels.append(Subpanel(v0=self.midpoints[i-1], v1=self.vertices[i], v2=self.midpoints[i], projected=self._projected))

            # Inner subpanel
            self.subpanels.append(Subpanel(v0=self.midpoints[i], v1=self.center, v2=self.midpoints[i-1], projected=self._projected))

        # Initialize half panels (only if the panel is not already triangular)
        if self.N==4:
            self.half_panels = []
            for i in range(self.N):
                self.half_panels.append(Subpanel(v0=self.vertices[i-2], v1=self.vertices[i-1], v2=self.vertices[i]))
        else:
            self.half_panels = False
Esempio n. 7
0
    def __init__(self, **kwargs):

        # Store vertices
        self.vertices = np.zeros((3, 3))
        self.vertices[0] = kwargs.get("v0")
        self.vertices[1] = kwargs.get("v1")
        self.vertices[2] = kwargs.get("v2")

        self.N = 3

        super().__init__(**kwargs)

        # Set up local coordinate transformation
        n, _, _ = self.get_info()
        self.A_t = np.zeros((3, 3))
        self.A_t[0] = self.vertices[1] - self.vertices[0]
        self.A_t[0] /= norm(self.A_t[0])
        self.A_t[1] = cross(n, self.A_t[0])
        self.A_t[2] = n
Esempio n. 8
0
    def __init__(self, **kwargs):

        # Store vertices
        self.vertices = np.zeros((4, 3))
        self.vertices[0] = kwargs.get("v0")
        self.vertices[1] = kwargs.get("v1")
        self.vertices[2] = kwargs.get("v2")
        self.vertices[3] = kwargs.get("v3")
        self.midpoints = 0.5 * (self.vertices +
                                np.roll(self.vertices, 1, axis=0))

        self.N = 4

        super().__init__(**kwargs)

        # Set up local coordinate transformation
        n = self._calc_normal()
        self.A_t = np.zeros((3, 3))
        self.A_t[0] = self.midpoints[1] - self.midpoints[0]
        self.A_t[0] /= norm(self.A_t[0])
        self.A_t[1] = cross(n, self.A_t[0])
        self.A_t[2] = n
Esempio n. 9
0
 def _calc_area(self):
     # Calculates the panel area
     return 0.5 * norm(
         cross(self.vertices[1] - self.vertices[0],
               self.vertices[2] - self.vertices[0]))
Esempio n. 10
0
 def _calc_normal(self):
     # Calculates the normal based off of the edge midpoints
     n = cross(self.midpoints[1] - self.midpoints[0],
               self.midpoints[2] - self.midpoints[1])
     return n / norm(n)