Ejemplo n.º 1
0
def setupDVGeoAxi(base_path):
    FFDFile = os.path.join(base_path, "../../input_files/axiTestFFD.xyz")
    DVGeo = DVGeometryAxi(FFDFile,
                          center=(0.0, 0.0, 0.0),
                          collapse_into=("x", "z"))
    axisPoints = [[0, 0.0, 0.0], [0, 0.0, 1.0]]
    c1 = Curve(X=axisPoints, k=2)
    DVGeo.addRefAxis("stretch", curve=c1, axis="z")

    return DVGeo
Ejemplo n.º 2
0
def setupDVGeo(base_path):
    #create the Parent FFD
    FFDFile =  os.path.join(base_path,'../inputFiles/outerBoxFFD.xyz')
    DVGeo = DVGeometry(FFDFile)

    # create a reference axis for the parent
    axisPoints = [[ -1.0,   0.  ,   0.],[ 1.5,   0.,   0.]]
    c1 = Curve(X=axisPoints,k=2)
    DVGeo.addRefAxis('mainAxis',curve=c1, axis='y')

    # create the child FFD
    FFDFile = os.path.join(base_path,'../inputFiles/simpleInnerFFD.xyz')
    DVGeoChild = DVGeometry(FFDFile,child=True)

    # create a reference axis for the child
    axisPoints = [[ -0.5,   0.  ,   0.],[ 0.5,   0.,   0.]]
    c1 = Curve(X=axisPoints,k=2)
    DVGeoChild.addRefAxis('nestedAxis',curve=c1, axis='y')

    return DVGeo,DVGeoChild
Ejemplo n.º 3
0
def setupDVGeoD8(base_path, isComplex):
    # create the Parent FFD
    FFDFile = os.path.join(base_path, "../../input_files/bodyFFD.xyz")
    DVGeo = DVGeometry(FFDFile, isComplex=isComplex)

    # create a reference axis for the parent
    axisPoints = [[0.0, 0.0, 0.0], [26.0, 0.0, 0.0], [30.5, 0.0, 0.9], [32.5, 0.0, 1.01], [34.0, 0.0, 0.95]]
    c1 = Curve(X=axisPoints, k=2)
    DVGeo.addRefAxis("mainAxis", curve=c1, axis="y")

    # create the child FFD
    FFDFile = os.path.join(base_path, "../../input_files/nozzleFFD.xyz")
    DVGeoChild = DVGeometry(FFDFile, child=True, isComplex=isComplex)

    # create a reference axis for the child
    axisPoints = [[32.4, 1.0, 1.0], [34, 1.0, 0.9]]
    c1 = Curve(X=axisPoints, k=2)
    DVGeoChild.addRefAxis("nestedAxis", curve=c1, axis="y")

    return DVGeo, DVGeoChild
Ejemplo n.º 4
0
def run_project_test(surface, handler, test_name):
    # Run a bunch of point projections: Only try to match to 1e-8
    eps = 1e-8

    # print('------------- These points should be fully inside of domain')
    pts = [[0, 0, 0], [2, 3, -1], [3, 2.5, -0.1]]
    for pt in pts:
        # print('Projecting point (%f %f %f)'%(pt[0],pt[1],pt[2]))
        u, v, D = surface.projectPoint(pt, eps=1e-12)
        handler.root_add_val("{} point {} projection u".format(test_name, pt), u, tol=eps)
        handler.root_add_val("{} point {} projection v".format(test_name, pt), v, tol=eps)
        handler.root_add_val("{} point {} projection D".format(test_name, pt), D, tol=eps * 10)

    # ----------- This should be (0,0) corner
    u, v, D = surface.projectPoint([-1, -1, 0], eps=1e-12)
    handler.root_add_val("{} projected u for (0,0) corner".format(test_name), u, tol=eps)
    handler.root_add_val("{} projected v for (0,0) corner".format(test_name), v, tol=eps)

    # ---------- This should be (0,1) corner
    u, v, D = surface.projectPoint([-1, 5, 0], eps=1e-12)
    handler.root_add_val("{} projected u for (0,1) corner".format(test_name), u, tol=eps)
    handler.root_add_val("{} projected v for (0,1) corner".format(test_name), v, tol=eps)

    # ---------- This should be (1,0) corner
    u, v, D = surface.projectPoint([6, -1, 0], eps=1e-12)
    handler.root_add_val("{} projected u for (1,0) corner".format(test_name), u, tol=eps)
    handler.root_add_val("{} projected v for (1,0) corner".format(test_name), v, tol=eps)

    # ---------- This should be (1,1) corner
    u, v, D = surface.projectPoint([6, 6, 0], eps=1e-12)
    handler.root_add_val("{} projected u for (1,1) corner".format(test_name), u, tol=eps)
    handler.root_add_val("{} projected v for (1,1) corner".format(test_name), v, tol=eps)

    # ---------- This should be edge zero (*,0)
    u, v, D = surface.projectPoint([2.54, -1, 0], eps=1e-12)
    handler.root_add_val("{} projected u for (*,0) edge".format(test_name), u, tol=eps)
    handler.root_add_val("{} projected v for (*,0) edge".format(test_name), v, tol=eps)

    # Curve projection
    for kc in [2, 3, 4]:
        x = [0, 1, 2, 0]
        y = [4, 3, 2, 1]
        z = [-3, 1, 3, 5]

        curve = Curve(k=kc, x=x, y=y, z=z)
        u, v, s, D = surface.projectCurve(curve)
        # ---------- surface-curve projection with kc = kc
        handler.root_add_val("{} projected curve u with kc={}".format(test_name, kc), u, tol=eps)
        handler.root_add_val("{} projected curve v with kc={}".format(test_name, kc), v, tol=eps)
        handler.root_add_val("{} projected curve s with kc={}".format(test_name, kc), s, tol=eps)
        handler.root_add_val("{} projected curve D with kc={}".format(test_name, kc), D, tol=eps * 10)
Ejemplo n.º 5
0
def setupDVGeo(base_path, rotType=None):
    # create the Parent FFD
    FFDFile = os.path.join(base_path, "../inputFiles/outerBoxFFD.xyz")
    DVGeo = DVGeometry(FFDFile)

    # create a reference axis for the parent
    axisPoints = [[-1.0, 0.0, 0.0], [1.5, 0.0, 0.0]]
    c1 = Curve(X=axisPoints, k=2)
    if rotType is not None:
        DVGeo.addRefAxis("mainAxis", curve=c1, axis="y", rotType=rotType)

    else:
        DVGeo.addRefAxis("mainAxis", curve=c1, axis="y")

    # create the child FFD
    FFDFile = os.path.join(base_path, "../inputFiles/simpleInnerFFD.xyz")
    DVGeoChild = DVGeometry(FFDFile, child=True)

    # create a reference axis for the child
    axisPoints = [[-0.5, 0.0, 0.0], [0.5, 0.0, 0.0]]
    c1 = Curve(X=axisPoints, k=2)
    DVGeoChild.addRefAxis("nestedAxis", curve=c1, axis="y")

    return DVGeo, DVGeoChild
Ejemplo n.º 6
0
def setDVGeo(ffdFile, cmplx=False):

    # Setup geometry/mesh
    DVGeo = DVGeometry(ffdFile, complex=cmplx)

    nTwist = 6
    DVGeo.addRefAxis(
        "wing",
        Curve(
            x=numpy.linspace(5.0 / 4.0, 1.5 / 4.0 + 7.5, nTwist),
            y=numpy.zeros(nTwist),
            z=numpy.linspace(0, 14, nTwist),
            k=2,
        ),
    )

    def twist(val, geo):
        for i in range(nTwist):
            geo.rot_z["wing"].coef[i] = val[i]

    def span(val, geo):
        # Span
        C = geo.extractCoef("wing")
        for i in range(len(C) - 1):
            C[-1, 2] = C[-1, 2] + val[0]
        geo.restoreCoef(C, "wing")

    DVGeo.addGeoDVGlobal("twist", [0] * nTwist,
                         twist,
                         lower=-10,
                         upper=10,
                         scale=1.0)
    DVGeo.addGeoDVGlobal("span", [0], span, lower=-10, upper=10, scale=1.0)
    DVGeo.addGeoDVLocal("shape", lower=-0.5, upper=0.5, axis="y", scale=10.0)

    return DVGeo
Ejemplo n.º 7
0
for i in range(1, naf - 1):
    airfoil_list[i] = None

# Use the digitize it data for the planform:
le = np.array(np.loadtxt("bwb_le.out"))
te = np.array(np.loadtxt("bwb_te.out"))
front_up = np.array(np.loadtxt("bwb_front_up.out"))
front_low = np.array(np.loadtxt("bwb_front_low.out"))

le[0, :] = 0
te[0, 0] = 0
front_up[0, 0] = 0
front_low[0, 0] = 0

# Now make a ONE-DIMENSIONAL spline for each of the le and trailing edes
le_spline = Curve(X=le[:, 1], s=le[:, 0], nCtl=11, k=4)
te_spline = Curve(X=te[:, 1], s=te[:, 0], nCtl=11, k=4)
up_spline = Curve(X=front_up[:, 1], s=front_up[:, 0], nCtl=11, k=4)
low_spline = Curve(X=front_low[:, 1], s=front_low[:, 0], nCtl=11, k=4)

# Generate consistent equally spaced spline data
span = np.linspace(0, 1, naf)

le = le_spline(span)
te = te_spline(span)
up = up_spline(span)
low = low_spline(span)

ref_span = 138
chord = te - le
x = le
Ejemplo n.º 8
0
mesh = USMesh(options=meshOptions, comm=gcomm)

coords0 = mesh.getSurfaceCoordinates()

# setup FFD
FFDFile = "./FFD/globalFFD.fmt"
DVGeo = DVGeometry(FFDFile)
# Setup curves for ref_axis
x = [-2.0, 0.0, 0.1, 1.044, 5.0]
y = [0.1, 0.1, 0.1, 0.1, 0.1]
z = [0.1, 0.1, 0.1, 0.1, 0.1]

nLength = len(x)

c1 = Curve(x=x, y=y, z=z, k=2)
DVGeo.addRefAxis("bodyAxis", curve=c1, axis="z")

DVGeoChild = DVGeometry("./FFD/bodyFittedFFD.fmt", child=True)

# Setup curves for ref_axis
x1 = [0.0, 0.1, 0.862, 1.044]
y1 = [0.1, 0.1, 0.1, 0.1]
z1 = [0.194, 0.194, 0.194, 0.13]
# z1 = [0.338,0.338,0.338,0.21]
# z1 = [0.338,0.338,0.338,0.338]

nLengthChild = len(x1)

c2 = Curve(x=x1, y=y1, z=z1, k=2)
DVGeoChild.addRefAxis("localBodyAxis", curve=c2, axis="z")
Ejemplo n.º 9
0
# External modules
import numpy as np

# First party modules
from pyspline import Curve

# Get some Helix-like data

n = 100
theta = np.linspace(0.0000, 2 * np.pi, n)
x = np.cos(theta)
y = np.sin(theta)
z = np.linspace(0, 1, n)
print("Helix Data")
curve = Curve(x=x, y=y, z=z, k=4, Nctl=16, niter=100)
curve.writeTecplot("helix.dat")

# Load naca0012 data
print("Naca 0012 data")
x, y = np.loadtxt("naca0012", unpack=True)
curve = Curve(x=x, y=y, k=4, Nctl=11, niter=500)
curve.writeTecplot("naca_data.dat")

# Projection Tests
print("Projection Tests")
x = [0, 2, 3, 5]
y = [-2, 5, 3, 0]
z = [0, 0, 0, 0]
curve1 = Curve(x=x, y=y, z=z, k=4)
Ejemplo n.º 10
0
        # Set the chord as well
        geo.scale["wing"].coef[-1] = val[3]

    coords = hyp.getSurfaceCoordinates()
    DVGeo = DVGeometry(ffdFile)
    coef = DVGeo.FFD.vols[0].coef.copy()

    # First determine the reference chord lengths:
    nSpan = coef.shape[2]
    ref = numpy.zeros((nSpan, 3))

    for k in range(nSpan):
        max_x = numpy.max(coef[:, :, k, 0])
        min_x = numpy.min(coef[:, :, k, 0])

        ref[k, 0] = min_x + 0.25 * (max_x - min_x)
        ref[k, 1] = numpy.average(coef[:, :, k, 1])
        ref[k, 2] = numpy.average(coef[:, :, k, 2])

    c0 = Curve(X=ref, k=2)
    DVGeo.addRefAxis("wing", c0)
    DVGeo.addGlobalDV("winglet", [0, 0, 0, 1], winglet, lower=-5, upper=5)
    DVGeo.addPointSet(coords, "coords")
    DVGeo.setDesignVars({"winglet": [1.5, 2.5, -2.0, 0.60]})
    hyp.setSurfaceCoordinates(DVGeo.update("coords"))

# Run and write grid
hyp.run()
hyp.writeCGNS(volumeFile)
Ejemplo n.º 11
0
# Create a generic surface
nu = 20
nv = 20
u = np.linspace(0, 4, nu)
v = np.linspace(0, 4, nv)
[V, U] = np.meshgrid(v, u)
Z = np.cos(U) * np.sin(V)
surf = Surface(x=U, y=V, z=Z, ku=4, kv=4, Nctlu=5, Nctlv=5)
surf.writeTecplot("surface.dat")

n = 100
theta = np.linspace(0.0000, 2 * np.pi, n)
x = np.cos(theta) - 1
y = np.sin(theta) + 1
z = np.linspace(0, 1, n) + 2
curve = Curve(x=x, y=y, z=z, k=4, Nctl=16, niter=100)
curve.writeTecplot("helix.dat")

u, v, s, D = surf.projectCurve(curve,
                               Niter=100,
                               eps1=1e-10,
                               eps2=1e-10,
                               u=1,
                               v=1,
                               s=1)

print(u, v, s, D)
print(curve(s))
print(surf(u, v))
Ejemplo n.º 12
0
    def regression_test(self, handler):
        '''
        This is where the actual testing happens.
        '''
        import copy
        from mpi4py import MPI
        from baseclasses import AeroProblem
        from ... import ADFLOW
        from pyspline import Curve
        from pygeo import DVGeometry
        from idwarp import USMesh
        from commonUtils import adjoint_test, adflowDefOpts, IDWarpDefOpts
        comm = MPI.COMM_WORLD

        gridFile = 'input_files/mdo_tutorial_euler_scalar_jst.cgns'
        ffdFile = 'input_files/mdo_tutorial_ffd.fmt'

        options = copy.copy(adflowDefOpts)
        options.update({
            'gridfile':
            gridFile,
            'restartfile':
            gridFile,
            'mgcycle':
            '2w',
            'ncyclescoarse':
            250,
            'ncycles':
            500,
            'monitorvariables': ['cpu', 'resrho', 'cl', 'cd', 'cmz', 'totalr'],
            'usenksolver':
            True,
            'l2convergence':
            1e-14,
            'l2convergencecoarse':
            1e-2,
            'nkswitchtol':
            1e-2,
            'adjointl2convergence':
            1e-14,
            'solutionprecision':
            'double',
            'gridprecision':
            'double',
        })

        # Setup aeroproblem, cfdsolver, mesh and geometry.
        ap = AeroProblem(name='mdo_tutorial',
                         alpha=1.8,
                         mach=0.80,
                         P=20000.0,
                         T=220.0,
                         areaRef=45.5,
                         chordRef=3.25,
                         beta=0.0,
                         R=287.87,
                         xRef=0.0,
                         yRef=0.0,
                         zRef=0.0,
                         evalFuncs=['cl', 'cd'])

        # Create the solver
        CFDSolver = ADFLOW(options=options, comm=comm, debug=False)

        # Create mesh warper
        meshOptions = copy.copy(IDWarpDefOpts)
        meshOptions.update({'gridFile': gridFile})
        mesh = USMesh(options=meshOptions, comm=comm)
        CFDSolver.setMesh(mesh)

        # Setup geometry/mesh
        DVGeo = DVGeometry(ffdFile)
        nTwist = 6
        DVGeo.addRefAxis(
            'wing',
            Curve(x=numpy.linspace(5.0 / 4.0, 1.5 / 4.0 + 7.5, nTwist),
                  y=numpy.zeros(nTwist),
                  z=numpy.linspace(0, 14, nTwist),
                  k=2))

        def twist(val, geo):
            for i in range(nTwist):
                geo.rot_z['wing'].coef[i] = val[i]

        DVGeo.addGeoDVGlobal('twist', [0] * nTwist,
                             twist,
                             lower=-10,
                             upper=10,
                             scale=1.0)
        DVGeo.addGeoDVLocal('shape',
                            lower=-0.5,
                            upper=0.5,
                            axis='y',
                            scale=10.0)
        CFDSolver.setDVGeo(DVGeo)

        # Run adjoint test
        adjoint_test(handler, CFDSolver, ap)
Ejemplo n.º 13
0
    def _init_lifting_surface(
        self,
        xsections,
        X=None,
        x=None,
        y=None,
        z=None,
        rot=None,
        rotX=None,
        rotY=None,
        rotZ=None,
        scale=None,
        offset=None,
        nCtl=None,
        kSpan=3,
        teHeight=None,
        teHeightScaled=None,
        thickness=None,
        bluntTe=False,
        roundedTe=False,
        bluntTaperRange=0.1,
        squareTeTip=True,
        teScale=0.75,
        tip="rounded",
        tipScale=0.25,
        leOffset=0.001,
        teOffset=0.001,
        spanTang=0.5,
        upTang=0.5,
    ):
        """Create a lifting surface by distributing the cross
        sections. See pyGeo module documentation for information on
        the most commonly used options."""

        if X is not None:
            Xsec = np.array(X)
        else:
            # We have to use x, y, z
            Xsec = np.vstack([x, y, z]).T

        N = len(Xsec)

        if rot is not None:
            rot = np.array(rot)
        else:
            if rotX is None:
                rotX = np.zeros(N)
            if rotY is None:
                rotY = np.zeros(N)
            if rotZ is None:
                rotZ = np.zeros(N)
            rot = np.vstack([rotX, rotY, rotZ]).T

        if offset is None:
            offset = np.zeros((N, 2))

        if scale is None:
            scale = np.ones(N)

        # Limit kSpan to 2 if we only have two cross section
        if len(Xsec) == 2:
            kSpan = 2

        if bluntTe:
            if teHeight is None and teHeightScaled is None:
                raise Error("teHeight OR teHeightScaled must be supplied for bluntTe option")

            if teHeight:
                teHeight = np.atleast_1d(teHeight)
                if len(teHeight) == 1:
                    teHeight = np.ones(N) * teHeight
                teHeight /= scale

            if teHeightScaled:
                teHeight = np.atleast_1d(teHeightScaled)
                if len(teHeight) == 1:
                    teHeight = np.ones(N) * teHeight
        else:
            teHeight = [None for i in range(N)]

        # Load in and fit them all
        curves = []
        knots = []
        for i in range(len(xsections)):
            if xsections[i] is not None:
                x, y = geo_utils.readAirfoilFile(
                    xsections[i], bluntTe, bluntThickness=teHeight[i], bluntTaperRange=bluntTaperRange
                )
                weights = np.ones(len(x))
                weights[0] = -1
                weights[-1] = -1
                if nCtl is not None:
                    c = Curve(x=x, y=y, nCtl=nCtl, k=4, weights=weights)
                else:
                    c = Curve(x=x, y=y, localInterp=True)

                curves.append(c)
                knots.append(c.t)
            else:
                curves.append(None)

        # If we are fitting curves, blend knot vectors and recompute
        if nCtl is not None:
            newKnots = geo_utils.blendKnotVectors(knots, True)
            for i in range(len(xsections)):
                if curves[i] is not None:
                    curves[i].t = newKnots.copy()
                    curves[i].recompute(100, computeKnots=False)

            # If we want a pinched tip will will zero everything here.
            if tip == "pinched":
                # Just zero out the last section in y
                if curves[-1] is not None:
                    print("zeroing tip")
                    curves[-1].coef[:, 1] = 0

        else:
            # Otherwise do knot inserions
            origKnots = [None for i in range(N)]
            for i in range(N):
                if curves[i] is not None:
                    origKnots[i] = curves[i].t.copy()

            # First take all the knots of the first curve:
            baseKnots = []
            baseKnots.extend(origKnots[0])

            # For the rest of the curves
            for i in range(1, N):
                if curves[i] is not None:
                    knots = origKnots[i]
                    # Search for all indices
                    indices = np.searchsorted(baseKnots, knots, side="left")

                    toInsert = []
                    # Now go over the indices and see if we need to add
                    for j in range(len(indices)):
                        if abs(baseKnots[indices[j]] - knots[j]) > 1e-12:
                            toInsert.append(knots[j])

                    # Finally add the new indices and resort
                    baseKnots.extend(toInsert)
                    baseKnots.sort()

            # We have to know determine more information about the set
            # of baseKnots: We want just a list of just the knot
            # values and their multiplicity.
            newKnots = []
            mult = []
            i = 0
            Nmax = len(baseKnots)
            while i < len(baseKnots):
                curKnot = baseKnots[i]
                j = 1
                while i + j < Nmax and abs(baseKnots[i + j] - curKnot) < 1e-12:
                    j += 1
                i += j
                newKnots.append(curKnot)
                mult.append(j)

            # Now we have a knot vector that *ALL* curve *MUST* have
            # to form our surface. So we loop back over the curves and
            # insert the knots as necessary.
            for i in range(N):
                if curves[i] is not None:
                    for j in range(len(newKnots)):
                        if not newKnots[j] in curves[i].t:
                            curves[i].insertKnot(newKnots[j], mult[j])

            # If we want a pinched tip will will zero everything here.
            if tip == "pinched":
                # Just zero out the last section in y
                if curves[-1] is not None:
                    curves[-1].coef[:, 1] = 0

            # Finally force ALL curve to have PRECISELY identical knots
            for i in range(len(xsections)):
                if curves[i] is not None:
                    curves[i].t = curves[0].t.copy()

            newKnots = curves[0].t.copy()
        # end if (nCtl is not none)

        # Generate a curve from X just for the parametrization
        Xcurve = Curve(X=Xsec, k=kSpan)

        # Now blend the missing sections
        print("Interpolating missing sections ...")

        for i in range(len(xsections)):
            if xsections[i] is None:
                # Fist two curves bounding this unknown one:
                for j in range(i, -1, -1):
                    if xsections[j] is not None:
                        istart = j
                        break

                for j in range(i, len(xsections), 1):
                    if xsections[j] is not None:
                        iend = j
                        break

                # Now generate blending parameter alpha
                sStart = Xcurve.s[istart]
                sEnd = Xcurve.s[iend]
                s = Xcurve.s[i]

                alpha = (s - sStart) / (sEnd - sStart)

                coef = curves[istart].coef * (1 - alpha) + curves[iend].coef * (alpha)

                curves[i] = Curve(coef=coef, k=4, t=newKnots.copy())
        # end for (xsections)

        # Before we continue the user may want to artificially scale
        # the thickness of the sections. This is useful when a
        # different airfoil thickness is desired than the actual
        # airfoil coordinates.

        if thickness is not None:
            thickness = np.atleast_1d(thickness)
            if len(thickness) == 1:
                thickness = np.ones(len(thickness)) * thickness
            for i in range(N):
                # Only scale the interior control points; not the first and last
                curves[i].coef[1:-1, 1] *= thickness[i]

        # Now split each curve at uSplit which roughly corresponds to LE
        topCurves = []
        botCurves = []
        uSplit = curves[0].t[(curves[0].nCtl + 4 - 1) // 2]

        for i in range(len(xsections)):
            c1, c2 = curves[i].splitCurve(uSplit)
            topCurves.append(c1)
            c2.reverse()
            botCurves.append(c2)

        # Note that the number of control points on the upper and
        # lower surface MAY not be the same. We can fix this by doing
        # more knot insertions.
        knotsTop = topCurves[0].t.copy()
        knotsBot = botCurves[0].t.copy()

        print("Symmetrizing Knot Vectors ...")
        eps = 1e-12
        for i in range(len(knotsTop)):
            # Check if knotsTop[i] is not in knots_bot to within eps
            found = False
            for j in range(len(knotsBot)):
                if abs(knotsTop[i] - knotsBot[j]) < eps:
                    found = True

            if not found:
                # Add to all sections
                for ii in range(len(xsections)):
                    botCurves[ii].insertKnot(knotsTop[i], 1)

        for i in range(len(knotsBot)):
            # Check if knotsBot[i] is not in knotsTop to within eps
            found = False
            for j in range(len(knotsTop)):
                if abs(knotsBot[i] - knotsTop[j]) < eps:
                    found = True

            if not found:
                # Add to all sections
                for ii in range(len(xsections)):
                    topCurves[ii].insertKnot(knotsBot[i], 1)

        # We now have symmetrized knot vectors for the upper and lower
        # surfaces. We will copy the vectors to make sure they are
        # precisely the same:
        for i in range(len(xsections)):
            topCurves[i].t = topCurves[0].t.copy()
            botCurves[i].t = topCurves[0].t.copy()

        # Now we can set the surfaces
        ncoef = topCurves[0].nCtl
        coefTop = np.zeros((ncoef, len(xsections), 3))
        coefBot = np.zeros((ncoef, len(xsections), 3))

        for i in range(len(xsections)):
            # Scale, rotate and translate the coefficients
            coefTop[:, i, 0] = scale[i] * (topCurves[i].coef[:, 0] - offset[i, 0])
            coefTop[:, i, 1] = scale[i] * (topCurves[i].coef[:, 1] - offset[i, 1])
            coefTop[:, i, 2] = 0

            coefBot[:, i, 0] = scale[i] * (botCurves[i].coef[:, 0] - offset[i, 0])
            coefBot[:, i, 1] = scale[i] * (botCurves[i].coef[:, 1] - offset[i, 1])
            coefBot[:, i, 2] = 0

            for j in range(ncoef):
                coefTop[j, i, :] = geo_utils.rotzV(coefTop[j, i, :], rot[i, 2] * np.pi / 180)
                coefTop[j, i, :] = geo_utils.rotxV(coefTop[j, i, :], rot[i, 0] * np.pi / 180)
                coefTop[j, i, :] = geo_utils.rotyV(coefTop[j, i, :], rot[i, 1] * np.pi / 180)

                coefBot[j, i, :] = geo_utils.rotzV(coefBot[j, i, :], rot[i, 2] * np.pi / 180)
                coefBot[j, i, :] = geo_utils.rotxV(coefBot[j, i, :], rot[i, 0] * np.pi / 180)
                coefBot[j, i, :] = geo_utils.rotyV(coefBot[j, i, :], rot[i, 1] * np.pi / 180)

            # Finally translate according to  positions specified
            coefTop[:, i, :] += Xsec[i, :]
            coefBot[:, i, :] += Xsec[i, :]

        # Set the two main surfaces
        self.surfs.append(Surface(coef=coefTop, ku=4, kv=kSpan, tu=topCurves[0].t, tv=Xcurve.t))
        self.surfs.append(Surface(coef=coefBot, ku=4, kv=kSpan, tu=botCurves[0].t, tv=Xcurve.t))

        print("Computing TE surfaces ...")

        if bluntTe:
            if not roundedTe:
                coef = np.zeros((len(xsections), 2, 3), "d")
                coef[:, 0, :] = coefTop[0, :, :]
                coef[:, 1, :] = coefBot[0, :, :]
                self.surfs.append(Surface(coef=coef, ku=kSpan, kv=2, tu=Xcurve.t, tv=[0, 0, 1, 1]))
            else:
                coef = np.zeros((len(xsections), 4, 3), "d")
                coef[:, 0, :] = coefTop[0, :, :]
                coef[:, 3, :] = coefBot[0, :, :]

                # We need to get the tangent for the top and bottom
                # surface, multiply by a scaling factor and this gives
                # us the two inner rows of control points

                for j in range(len(xsections)):
                    projTop = coefTop[0, j] - coefTop[1, j]
                    projBot = coefBot[0, j] - coefBot[1, j]
                    projTop /= np.linalg.norm(projTop)
                    projBot /= np.linalg.norm(projBot)
                    curTeThick = np.linalg.norm(coefTop[0, j] - coefBot[0, j])
                    coef[j, 1] = coef[j, 0] + projTop * 0.5 * curTeThick * teScale
                    coef[j, 2] = coef[j, 3] + projBot * 0.5 * curTeThick * teScale

                self.surfs.append(Surface(coef=coef, ku=kSpan, kv=4, tu=Xcurve.t, tv=[0, 0, 0, 0, 1, 1, 1, 1]))

        self.nSurf = len(self.surfs)

        print("Computing Tip surfaces ...")
        # # Add on additional surfaces if required for a rounded pinch tip
        if tip == "rounded":

            # Generate the midpoint of the coefficients
            midPts = np.zeros([ncoef, 3])
            upVec = np.zeros([ncoef, 3])
            dsNorm = np.zeros([ncoef, 3])
            for j in range(ncoef):
                midPts[j] = 0.5 * (coefTop[j, -1] + coefBot[j, -1])
                upVec[j] = coefTop[j, -1] - coefBot[j, -1]
                ds = 0.5 * ((coefTop[j, -1] - coefTop[j, -2]) + (coefBot[j, -1] - coefBot[j, -2]))
                dsNorm[j] = ds / np.linalg.norm(ds)

            # Generate "average" projection Vector
            projVec = np.zeros((ncoef, 3), "d")
            for j in range(ncoef):
                offset = teOffset + (float(j) / (ncoef - 1)) * (leOffset - teOffset)
                projVec[j] = dsNorm[j] * (np.linalg.norm(upVec[j] * tipScale + offset))

            # Generate the tip "line"
            tipLine = np.zeros([ncoef, 3])
            for j in range(ncoef):
                tipLine[j] = midPts[j] + projVec[j]

            # Generate a k=4 (cubic) surface
            coefTopTip = np.zeros([ncoef, 4, 3])
            coefBotTip = np.zeros([ncoef, 4, 3])

            for j in range(ncoef):
                coefTopTip[j, 0] = coefTop[j, -1]
                coefTopTip[j, 1] = coefTop[j, -1] + projVec[j] * spanTang
                coefTopTip[j, 2] = tipLine[j] + upTang * upVec[j]
                coefTopTip[j, 3] = tipLine[j]

                coefBotTip[j, 0] = coefBot[j, -1]
                coefBotTip[j, 1] = coefBot[j, -1] + projVec[j] * spanTang
                coefBotTip[j, 2] = tipLine[j] - upTang * upVec[j]
                coefBotTip[j, 3] = tipLine[j]

            # Modify for square_te_tip... taper over last 20%
            if squareTeTip and not roundedTe:
                tipDist = geo_utils.eDist(tipLine[0], tipLine[-1])

                for j in range(ncoef):  # Going from back to front:
                    fraction = geo_utils.eDist(tipLine[j], tipLine[0]) / tipDist
                    if fraction < 0.10:
                        fact = (1 - fraction / 0.10) ** 2
                        omfact = 1.0 - fact
                        coefTopTip[j, 1] = (
                            fact * ((5.0 / 6.0) * coefTopTip[j, 0] + (1.0 / 6.0) * coefBotTip[j, 0])
                            + omfact * coefTopTip[j, 1]
                        )
                        coefTopTip[j, 2] = (
                            fact * ((4.0 / 6.0) * coefTopTip[j, 0] + (2.0 / 6.0) * coefBotTip[j, 0])
                            + omfact * coefTopTip[j, 2]
                        )
                        coefTopTip[j, 3] = (
                            fact * ((1.0 / 2.0) * coefTopTip[j, 0] + (1.0 / 2.0) * coefBotTip[j, 0])
                            + omfact * coefTopTip[j, 3]
                        )

                        coefBotTip[j, 1] = (
                            fact * ((1.0 / 6.0) * coefTopTip[j, 0] + (5.0 / 6.0) * coefBotTip[j, 0])
                            + omfact * coefBotTip[j, 1]
                        )
                        coefBotTip[j, 2] = (
                            fact * ((2.0 / 6.0) * coefTopTip[j, 0] + (4.0 / 6.0) * coefBotTip[j, 0])
                            + omfact * coefBotTip[j, 2]
                        )
                        coefBotTip[j, 3] = (
                            fact * ((1.0 / 2.0) * coefTopTip[j, 0] + (1.0 / 2.0) * coefBotTip[j, 0])
                            + omfact * coefBotTip[j, 3]
                        )

            surfTopTip = Surface(coef=coefTopTip, ku=4, kv=4, tu=topCurves[0].t, tv=[0, 0, 0, 0, 1, 1, 1, 1])
            surfBotTip = Surface(coef=coefBotTip, ku=4, kv=4, tu=botCurves[0].t, tv=[0, 0, 0, 0, 1, 1, 1, 1])
            self.surfs.append(surfTopTip)
            self.surfs.append(surfBotTip)
            self.nSurf += 2

            if bluntTe:
                # This is the small surface at the trailing edge
                # tip. There are a couple of different things that can
                # happen: If we rounded TE we MUST have a
                # rounded-spherical-like surface (second piece of code
                # below). Otherwise we only have a surface if
                # square_te_tip is false in which case a flat curved
                # surface results.

                if not roundedTe and not squareTeTip:
                    coef = np.zeros((4, 2, 3), "d")
                    coef[:, 0] = coefTopTip[0, :]
                    coef[:, 1] = coefBotTip[0, :]

                    self.surfs.append(Surface(coef=coef, ku=4, kv=2, tu=[0, 0, 0, 0, 1, 1, 1, 1], tv=[0, 0, 1, 1]))
                    self.nSurf += 1
                elif roundedTe:
                    coef = np.zeros((4, 4, 3), "d")
                    coef[:, 0] = coefTopTip[0, :]
                    coef[:, 3] = coefBotTip[0, :]

                    # We will actually recompute the coefficients
                    # on the last sections since we need to do a
                    # couple of more for this surface
                    for i in range(4):
                        projTop = coefTopTip[0, i] - coefTopTip[1, i]
                        projBot = coefBotTip[0, i] - coefBotTip[1, i]
                        projTop /= np.linalg.norm(projTop)
                        projBot /= np.linalg.norm(projBot)
                        curTeThick = np.linalg.norm(coefTopTip[0, i] - coefBotTip[0, i])
                        coef[i, 1] = coef[i, 0] + projTop * 0.5 * curTeThick * teScale
                        coef[i, 2] = coef[i, 3] + projBot * 0.5 * curTeThick * teScale

                    self.surfs.append(
                        Surface(coef=coef, ku=4, kv=4, tu=[0, 0, 0, 0, 1, 1, 1, 1], tv=[0, 0, 0, 0, 1, 1, 1, 1])
                    )
                    self.nSurf += 1

            # end if bluntTe
        elif tip == "pinched":
            pass
        else:
            print("No tip specified")

        # Cheat and make "original data" so that the edge connectivity works
        u = np.linspace(0, 1, 3)
        v = np.linspace(0, 1, 3)
        [V, U] = np.meshgrid(u, v)
        for i in range(self.nSurf):
            self.surfs[i].origData = True
            self.surfs[i].X = self.surfs[i](U, V)
            self.surfs[i].Nu = 3
            self.surfs[i].Nv = 3

        self._calcConnectivity(1e-6, 1e-6)
        sizes = []
        for isurf in range(self.nSurf):
            sizes.append([self.surfs[isurf].nCtlu, self.surfs[isurf].nCtlv])
        self.topo.calcGlobalNumbering(sizes)

        self.setSurfaceCoef()
Ejemplo n.º 14
0
    def regression_test(self, handler):

        # print('+--------------------------------------+')
        # print('           Create Tests   ')
        # print('+--------------------------------------+')
        # print('-----------  2D k=2 test ----------')
        k = 2
        t = [0, 0, 0.5, 1, 1]
        coef = np.zeros((3, 2))
        coef[0] = [0, 0.6]
        coef[1] = [1.1, 1.4]
        coef[2] = [2.6, 5.1]
        curve = Curve(t=t, k=k, coef=coef)
        run_curve_test(curve, handler, "2D k={}".format(k))
        io_test(curve)

        # print('-----------  2D k=3 test ----------')
        k = 3
        t = [0, 0, 0, 0.5, 1, 1, 1]
        coef = np.zeros((4, 2))
        coef[0] = [0, 0.45]
        coef[1] = [0.71, 1.5]
        coef[2] = [2.5, 5.9]
        coef[3] = [4, -2]
        curve = Curve(t=t, k=k, coef=coef)
        run_curve_test(curve, handler, "2D k={}".format(k))
        io_test(curve)

        # print('-----------  2D k=4 test ----------')
        k = 4
        t = [0, 0, 0, 0, 0.5, 1, 1, 1, 1]
        coef = np.zeros((5, 2))
        coef[0] = [0, -0.60]
        coef[1] = [0.9, 1.6]
        coef[2] = [1.6, 5.2]
        coef[3] = [4.2, -2.24]
        coef[4] = [2.9, 6.2]
        curve = Curve(t=t, k=k, coef=coef)
        run_curve_test(curve, handler, "2D k={}".format(k))
        io_test(curve)

        # Get helix data
        n = 100
        theta = np.linspace(0.0, np.pi * 2, n)
        x = np.cos(theta)
        y = np.sin(theta)
        z = np.linspace(0, 1, n)

        # print('+--------------------------------------+')
        # print('              LMS Tests   ')
        # print('+--------------------------------------+')
        for k in [2, 3, 4]:
            test_name = "LMS test k={}".format(k)
            # print('--------- Test helix data with k=%d-------'%(k))
            curve = Curve(x=x, y=y, z=z, k=k, nCtl=16, niter=50)
            run_curve_test(curve, handler, test_name)
            run_project_test(curve, handler, test_name)

        # print('+--------------------------------------+')
        # print('           Interp Tests   ')
        # print('+--------------------------------------+')
        for k in [2, 3, 4]:
            test_name = "interpolation test k={}".format(k)
            # print('--------- Test helix data with k=%d-------'%(k))
            curve = Curve(x=x, y=y, z=z, k=k)
            run_curve_test(curve, handler, test_name)
            run_project_test(curve, handler, test_name)