コード例 #1
0
ファイル: airfoil.py プロジェクト: sunstarchan/Genair
 def _fit(self, func, p, xargs, show):
     ''' Fit a pth-degree Curve through the data Points using the
     approximation function func and the extra argument xargs. '''
     lo, up = [points_to_obj_mat(self.data[si]) for si in ('lo', 'up')]
     Q = np.vstack((lo[-1:0:-1], up))
     i = self.intersection
     if i:
         xyzw = i.xyzw[np.newaxis, :]
         Q = np.vstack((xyzw, Q, xyzw))
     r = Q.shape[0] - 1
     args = (r, Q, p) + xargs
     U, Pw = func(*args)
     nurbs = Curve(ControlPolygon(Pw=Pw), (p, ), (U, ))
     print('geom.airfoil.Airfoil.fit :: '
           'fit with {} control points'.format(Pw.shape[0]))
     self._halve(nurbs)
     if not self.issharp:
         print('geom.airfoil.Airfoil.fit :: '
               'warning, fit but blunt airfoil')
     if show:
         d = self.get_curvature_cplots()
         d += self.data['lo'] + self.data['up']
         if i:
             d += [i]
         fig = draw(self, *d, stride=0.1)
         fig.c.setup_preset('xz')
         return fig
コード例 #2
0
ファイル: wing.py プロジェクト: sunstarchan/Genair
    def fit(self, r=100, n=50):

        ''' Sample and fit a B-spline function that shall fit a Wing
        such that it smoothly connects two other closely distanced
        Wings.

        Parameters
        ----------
        r = the number of points to sample the Curves extensions with
        n = the number of control points to fit the sampled points with

        Returns
        -------
        T = the trajectory Curve to use for the Wing transition
        B = the B-spline function B(v)

        '''

        T0, T1 = self.Ts
        T = T0.copy()
        #T.cobj.Pw[:] = 0.75 * T0.cobj.Pw + 0.25 * T1.cobj.Pw
        us = np.linspace(0, 1, r)
        Q0 = T0.eval_points(us).T
        Q1 = T1.eval_points(us).T
        Q = np.zeros_like(Q0)
        Q[:,0] = Q1[:,0] - Q0[:,0]
        U, Pw = global_curve_approx_fixedn(r - 1, Q, 3, n, us)
        return T, Curve(ControlPolygon(Pw=Pw), (3,), (U,))
コード例 #3
0
ファイル: wing.py プロジェクト: sunstarchan/Genair
    def fit(self, r=100, n=50, di=0):

        ''' Sample and fit a B-spline function that shall scale a Wing
        such that its XY planform view matches exactly the previously
        designed LE and TE Curves.

        Parameters
        ----------
        r = the number of points to sample the LE and TE Curves with
        n = the number of control points to fit the sampled points with
        di = the sampling direction (0 or 2)

        Returns
        -------
        B = the B-spline function B(v)

        '''

        T0, T1 = self.Ts
        us = np.linspace(0, 1, r)
        Q0 = T0.eval_points(us).T
        Q1 = T1.eval_points(us).T
        Q = np.zeros_like(Q0)
        Q[:,0] = Q1[:,di] - Q0[:,di]
        U, Pw = global_curve_approx_fixedn(r - 1, Q, T0.p[0], n, us)
        return Curve(ControlPolygon(Pw=Pw), (T0.p[0],), (U,))
コード例 #4
0
ファイル: junction.py プロジェクト: sunstarchan/Genair
    def intersect(self, CRT=5e-3, ANT=1e-2, show=True):

        '''

        '''

        P0 = find_LE_starting_point(self.wing.LE, self.S)
        print('geom.junction.TrimmedJunction.intersect :: '
              'LE starting point found: {}'.format(P0))

        IP = []
        for half, h in zip((0, 1), self.wing.halves):
            if self.half in (2, half):

                args = h, self.S, P0, CRT, ANT
                Q, stuv = surface_surface_intersect(*args)

                if show:
                    Qw = obj_mat_to_4D(Q)
                    IP += obj_mat_to_points(Qw).tolist()

                n = stuv.shape[0] - 1
                z = np.zeros((n + 1, 1))
                st = stuv[:,:2]
                Q = np.hstack((st, z))
                U, Pw = local_curve_interp(n, Q)
                IC = Curve(ControlPolygon(Pw=Pw), (3,), (U,))
                self.ICs[half] = IC

        if show:
            return draw(self.S, self.wing, *IP)
コード例 #5
0
ファイル: wing.py プロジェクト: sunstarchan/Genair
    def __init__(self, end=(1.0, 1.0), p=1, n=2):

        ''' Instantiate a default representation Curve that linearly
        interpolates the end point values.

        Parameters
        ----------
        end = the end point values
        p, n = the degree and number of control points to define the
               representation Curve with

        '''

        Pw = np.zeros((n, 4)); Pw[:,-1] = 1.0
        Pw[ 0,1] = end[0]
        Pw[-1,1] = end[1]; Pw[-1,0] = 1.0
        if n > 2:
            xs = np.linspace(0, 1, n)
            ys = np.linspace(end[0], end[1], n)
            Pw[1:-1,0] = xs[1:-1]
            Pw[1:-1,1] = ys[1:-1]
        self.R = Curve(ControlPolygon(Pw=Pw), (p,))
        self._p = p
コード例 #6
0
ファイル: wing.py プロジェクト: sunstarchan/Genair
    def design(self):

        ''' Automatically create LE and TE Curve extensions attaching
        the two Wings.  If not satisfied, the Wing objects can be
        repositioned before repeating the process.

        '''

        w0, w1 = self.ws

        Q0, D0 = w0.LE.eval_derivatives(1, 1)
        Q1, D1 = w1.LE.eval_derivatives(0, 1)

        U, Pw = local_curve_interp(1, (Q0, Q1), D0, D1)
        T0 = Curve(ControlPolygon(Pw=Pw), (3,), (U,))

        Q0, D0 = w0.TE.eval_derivatives(1, 1)
        Q1, D1 = w1.TE.eval_derivatives(0, 1)

        U, Pw = local_curve_interp(1, (Q0, Q1), D0, D1)
        T1 = Curve(ControlPolygon(Pw=Pw), (3,), (U,))

        self.Ts = [T0, T1]
        return draw(w0, w1, T0, T1)
コード例 #7
0
ファイル: wing.py プロジェクト: sunstarchan/Genair
    def fit(self, r=100, n=50):

        ''' Sample and fit the representation Curve.

        Parameters
        ----------
        r = the number of points to sample the representation Curve with
        n = the number of control points to fit the sampled points with

        Returns
        -------
        B = the B-spline function B(v)

        '''

        us = np.linspace(0, 1, r)
        Q0 = self.R.eval_points(us).T
        Q = np.zeros_like(Q0)
        uk, Q[:,0] = Q0[:,0], Q0[:,1]
        U, Pw = global_curve_approx_fixedn(r - 1, Q, self._p, n, uk)
        return Curve(ControlPolygon(Pw=Pw), (self._p,), (U,))
コード例 #8
0
ファイル: airfoil.py プロジェクト: sunstarchan/Genair
    def get_curvature_cplots(self, npt=500):
        ''' Get the curvature Curve plots corresponding to the lower and
        upper halves of the Airfoil.  To ease inspection each Curve plot
        is clamped chordwise and vertically between 0 and 1.

        Parameters
        ----------
        npt = the number of points to sample each halve with

        Returns
        -------
        [Curve, Curve] = the lower and upper curvature Curve plots

        '''

        if not self.nurbs:
            raise UnfitAirfoil()
        us = np.linspace(0, 1, npt)
        Cs = []
        for h in self.halves:
            Q = np.zeros((npt, 3))
            Q[:, 0] = us
            for i, u in enumerate(us):
                Q[i, 2] = h.eval_curvature(u)
            U, Pw = global_curve_interp(npt - 1, Q, 1, uk=us)
            c = Curve(ControlPolygon(Pw=Pw), (1, ), (U, ))
            sf1 = self.chord
            sf2 = 1.0 / max(c.cobj.Pw[:, 2])
            w = self.nurbs.eval_point(0.5)
            w[1:] = 0.0
            c.scale(sf1, L=(1, 0, 0))
            c.scale(sf2, L=(0, 0, 1))
            c.translate(w)
            c.visible.pop('cobj')
            Cs.append(c)
        Cs[0].mirror(N=(0, 0, 1))
        return Cs
コード例 #9
0
ファイル: wingtip.py プロジェクト: sunstarchan/Genair
    def _network(self, l, dl, xb, ul, vk):
        ''' Populate a smooth network of Curves suitable for
        interpolation in the Gordon sense. '''

        wi = self.wing
        wh0, wh1 = wi.halves

        l *= wi.chords[1] / 100.0
        dl *= wi.chords[1] / 100.0
        xb *= 2.0

        def fnc(x):
            return x**xb * (1 - x)**(2 - xb)

        mfnc = fnc(xb / 2.0)

        pairs = [(wh0.extract(u, 0), wh1.extract(u, 0)) for u in ul]

        Cl = []
        for ip, pair in enumerate(pairs):
            P0, D0 = pair[0].eval_derivatives(1, 1)
            P2, D2 = pair[1].eval_derivatives(1, 1)

            Pm = (P0 + P2) / 2.0
            W = normalize((D0 + D2) / 2.0)

            dli = fnc(ul[ip]) / mfnc * dl
            Pmi = Pm + (l + dli) * W

            Pw = obj_mat_to_4D(np.array((P0, Pmi, P2)))
            C = Curve(ControlPolygon(Pw=Pw), (1, ))

            if pair not in (pairs[0], pairs[-1]):
                N = np.cross(P2 - P0, W)
                D0 = point_to_plane((0, 0, 0), N, D0)
                D2 = point_to_plane((0, 0, 0), N, D2)

                P1, w1 = make_one_arc(P0, D0, P2, D2, Pmi)

                Pw = obj_mat_to_4D(np.array((P0, P1, P2)))
                if w1 != 0.0:
                    Pw[1, :] *= w1
                else:  # infinite point
                    Pw[1, -1] = 0.0

                C2 = Curve(ControlPolygon(Pw=Pw), (2, ))
                C2 = refit_curve(C2, 15)  #knob

                n, dummy, dummy, CC2 = make_curves_compatible1([C, C2])
                C, C2 = CC2

                # linear morphing
                for i in xrange(1, n):
                    lmy = np.sin(np.pi * float(i - 1) / float(n - 2))
                    cpt, cpt2 = [c.cobj.cpts[i].xyz for c in C, C2]
                    x, y, z = lmy * cpt + (1.0 - lmy) * cpt2
                    C.cobj.cpts[i].xyzw = x, y, z, 1.0

            Cl.append(C)

        Ck0 = wh0.extract(1, 1)
        Ck2 = wh1.extract(1, 1)

        Q = np.array([C.eval_point(0.5) for C in Cl])
        r = Q.shape[0] - 1
        U, Pw = global_curve_interp(r, Q, 3, ul)
        Ck1 = Curve(ControlPolygon(Pw=Pw), (3, ), (U, ))

        Ck = [Ck0, Ck1, Ck2]
        return Ck, Cl
コード例 #10
0
ファイル: wing.py プロジェクト: sunstarchan/Genair
class BSplineFunctionCreator1(BSplineFunctionCreator):

    ''' Create a Type 1 B-spline function B(v).

    Just like any y = f(x) function, a Type 1 B-spline scaling function
    is best visualized in a XY coordinate system; here the X axis refers
    to v, (0 <= v <= 1), and the Y axis to B.  The idea is to design a
    so-called "representation Curve" in this plane, sample it at evenly
    spaced parameter values, and then finally fit the sampled points to
    retrieve the actual B(v).  The best way to understand this is to
    simply try it.

    Intended usage
    --------------
    >>> Bs = BSplineFunctionCreator1(end=(1.0,2.0))
    >>> Bs.design() # optional
    >>> B = Bs.fit()

    '''

    def __init__(self, end=(1.0, 1.0), p=1, n=2):

        ''' Instantiate a default representation Curve that linearly
        interpolates the end point values.

        Parameters
        ----------
        end = the end point values
        p, n = the degree and number of control points to define the
               representation Curve with

        '''

        Pw = np.zeros((n, 4)); Pw[:,-1] = 1.0
        Pw[ 0,1] = end[0]
        Pw[-1,1] = end[1]; Pw[-1,0] = 1.0
        if n > 2:
            xs = np.linspace(0, 1, n)
            ys = np.linspace(end[0], end[1], n)
            Pw[1:-1,0] = xs[1:-1]
            Pw[1:-1,1] = ys[1:-1]
        self.R = Curve(ControlPolygon(Pw=Pw), (p,))
        self._p = p

    def design(self):

        ''' Design the representation Curve interactively.  The first
        and last control points are constrained to the (x = 0) and (x =
        1) lines, respectively.

        '''

        cpts = self.R.cobj.cpts
        cpt0, cpt1 = cpts[0], cpts[-1]
        cpt0.line = (0,0,0), (0,1,0)
        cpt1.line = (1,0,0), (0,1,0)
        fig = draw(self.R)
        fig.c.setup_preset(r=(0,0,0))
        return fig

    def fit(self, r=100, n=50):

        ''' Sample and fit the representation Curve.

        Parameters
        ----------
        r = the number of points to sample the representation Curve with
        n = the number of control points to fit the sampled points with

        Returns
        -------
        B = the B-spline function B(v)

        '''

        us = np.linspace(0, 1, r)
        Q0 = self.R.eval_points(us).T
        Q = np.zeros_like(Q0)
        uk, Q[:,0] = Q0[:,0], Q0[:,1]
        U, Pw = global_curve_approx_fixedn(r - 1, Q, self._p, n, uk)
        return Curve(ControlPolygon(Pw=Pw), (self._p,), (U,))