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): C = geo.extractCoef("wing") s = geo.extractS("wing") for i in range(len(C)): C[i, 2] += s[i] * val[0] geo.restoreCoef(C, "wing") DVGeo.addGlobalDV("twist", [0] * nTwist, twist, lower=-10, upper=10, scale=1.0) DVGeo.addGlobalDV("span", [0], span, lower=-10, upper=10, scale=1.0) DVGeo.addLocalDV("shape", lower=-0.5, upper=0.5, axis="y", scale=10.0) return DVGeo
def setup_cb(comm): # Create the solver CFDSolver = ADFLOW(options=options, comm=comm, debug=False) # 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) mesh = USMesh(options=meshOptions, comm=comm) CFDSolver.setMesh(mesh) CFDSolver.setDVGeo(DVGeo) return CFDSolver, mesh, DVGeo, None
def setupDVGeoAxi(base_path): FFDFile = os.path.join(base_path,"../inputFiles/axiTestFFD.xyz") DVGeo = DVGeometryAxi(FFDFile, center=(0., 0., 0.), collapse_into=("x", "z")) axisPoints = [[ 0, 0. , 0.],[ 0, 0., 1.]] c1 = Curve(X=axisPoints,k=2) DVGeo.addRefAxis('stretch',curve=c1, axis='z') return DVGeo
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
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
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)
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
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
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")
# 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)
# 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)
# 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))
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)
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()
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)