def SmoothBump(ni, nj, Q, ref, TriFlag, FileFormat): fac = 2 if TriFlag else 1 ni = ni*Q*2**ref+1 nj = nj*Q*2**ref+1 print 'Cell size ' + str( int((ni-1)/Q) ) + 'x' + str( int((nj-1)/2) ) + ' with ' + str( fac*int((ni-1)/Q)*int((nj-1)/2) ) + ' Elements' #Create all the vertexes V = npy.zeros((ni,nj,2),float) #Upper boundary y1 = 0.8 x0 = npy.linspace(-1.5, 1.5, ni) for i in xrange(ni): x = x0[i]; y0 = 0.0625*npy.exp(-25.*x**2) y = npy.linspace(y0, y1, nj) V[i,:,0] = x V[i,:,1] = y if FileFormat == 'p2d': writePlot2D('SmoothBump_ref'+str(ref)+ '_Q'+str(Q)+'.p2d.x', V[:,:,0], V[:,:,1]) if FileFormat == 'p3dxy': writeNMF('SmoothBump_ref'+str(ref)+'.nmf', ni, nj) writePlot3D('SmoothBump_ref'+str(ref)+ '_Q'+str(Q)+'.p3d', V[:,:,0], V[:,:,1]) if FileFormat == 'p3dxz': writeNMF('SmoothBump_ref'+str(ref)+'.nmf', ni, nj) writePlot3Dxz('SmoothBump_ref'+str(ref)+'.p3d', V[:,:,0], V[:,:,1]) if FileFormat == 'in': writeOVERFLOW('grid.in.'+str(ref), V[:,:,0], V[:,:,1]) V = V.reshape( (ni*nj,2) ) #---------------------------------------------# # node number matrices for writing out blocks # #---------------------------------------------# NC = npy.arange(ni*nj).reshape( (ni, nj) )+1 #---------------# # form elements # #---------------# E = block_elem(NC, Q); if FileFormat == 'msh': writeGMSH('SmoothBump', ref, Q, TriFlag, E, V, NC, ni, nj) if FileFormat == 'grm': writeGRM('SmoothBump', ref, Q, TriFlag, E, V, NC, ni, nj)
def SmoothBump(ni, nj, Q, ref): ni = ni*Q*2**ref+1 nj = nj*Q*2**ref+1 #Create all the vertexes V = npy.zeros((ni,nj,2),float) #Upper boundary y1 = 0.8 x0 = npy.linspace(-1.5, 1.5, ni) for i in xrange(ni): x = x0[i]; y0 = 0.0625*npy.exp(-25.*x**2) y = npy.linspace(y0, y1, nj) V[i,:,0] = x V[i,:,1] = y writeOVERFLOW('grid.in.'+str(ref), V[:,:,0], V[:,:,1]) writeNMF('SmoothBump_ref'+str(ref)+'.nmf', ni, nj) writePlot3D('SmoothBump_ref'+str(ref)+'.p3d', V[:,:,0], V[:,:,1]) V = V.reshape( (ni*nj,2) ) #---------------------------------------------# # node number matrices for writing out blocks # #---------------------------------------------# NC = npy.arange(ni*nj).reshape( (ni, nj) )+1 #---------------# # form elements # #---------------# E = block_elem(NC, Q); writeGMSH('SmoothBump', ref, Q, E, V, NC, ni, nj)
def make_airfoil(Dfarfield, ref, Q, TriFlag, FileFormat, farang=0.0, nchordwise=20, nxwake=9, rxwakecenter=3.0, rxwakefary=0.35, nnormal=14, rnormal=2.8, rnormalfar=3.0, TEfac=1.0, Ufac=1.0, wakeangle=0.0, reynolds=1.e6, filename_base="Joukowski"): # function make_airfoil(xyfile, UseExact, Dfarfield, ref, Q, TriFlag, farang, varargin) # # Makes a quad or tri .gri mesh for an airfoil using the points # supplied in the file xyfile. This file must have two numbers # per line, each representing an (x,y) coordinate of a point. # The points should start at the trailing edge and loop clockwise. # The trailing-edge is assumed closed (no gap), and the trailing- # edge point should not be repeated. The number of points in # the file should be sufficient to represent the geometry well, but # it need not be a multiple of Q as the points will be re-splined. # An optional hard-coded analytical geometry function can be used to # nudge points to the true geometry (if using the spline is not enough). # The spacing of points on the geometry is done via a quasi-curvature # based method -- the optional mesh size input controls this. # The generated mesh is of the "C" type (see graphic make_airfoil.png). # # INPUTS: # Dfarfield : approximate distance to the farfield, in chords (e.g. 50) # ref : refinement number (useful for convergence studies) # Q : geometry order (e.g. 1,2,3,4,...) # TriFlag : 0 = quad, 1 = tri # farang : angle from horizontal of farfield inflow at min/max y # (useful to keep inflow a true inflow for nonzero alpha) # varargin : mesh size/spacing structure (optional, else default one # defined below will be used). # # OUTPUTS: # A file named: airfoil.gri #--------------------------------------------# # pull off meshsize structure from variable # # input argument; or define it here # #--------------------------------------------# # nchordwise = 20 # number of elements along one side of the airfoil geometry # nxwake = 9 # x-wake on centerline # rxwakecenter = 3.0 # x-wake stretching on centerline # rxwakefary = 0.35 # x-wake stretching far from airfoil (+/-y) # nnormal = 14 # points normal to airfoil surface, 14=viscous, 12=inviscid # rnormal = 2.8 # normal-direction stretching, x close to airfoil # rnormalfar = 3.0 # normal-direction stretching, x far from airfoil # TEfac = 1.0 # factor controlling bunching at TE (high = bunched) # Ufac = 1.0 # factor controlling uniformity of chordwise spacing (high = uniform) # wakeangle=0.0 # angle of wake leaving the airfoil #--------------------# # load/spline points # #--------------------# X, saf = Joukowski(nchordwise*2**ref,Q) # print X; c = max(X[:,0]) - min(X[:,0]) # chord length Hc = Dfarfield*c # farfield distance xte = X[0,:]; # TE point XLE = X[npy.append(range(len(X)),0),:] # rest of airfoil nLE = len(XLE) #-------------------------------------# # put points down along farfield, FLE # #-------------------------------------# dx = XLE[1:,:]-XLE[:-1,:] ds = (dx[:,0]**2 + dx[:,1]**2)**0.5+0.1 s = npy.zeros(nLE) for i in xrange(1,nLE): s[i] = s[i-1]+ds[i-1] x0 = tan(farang)*Hc radius = (x0**2 + Hc**2)**0.5 t0 = s/max(s)*(pi-2*farang) + 3*pi/2 + farang #print t0 #t0 = npy.linspace( 3.*pi/2., 5.*pi/2., t0.shape[0]) #print t0 #dxds, dyds = Joukowski_dxy_ds(saf,0.1) #t0 = npy.arccos(dyds/npy.sqrt(dxds**2+dyds**2)) #print t0 #for i in xrange(t0.shape[0]): # t0[i] = min(t0[i], pi/2.) #print t0 #t0 = npy.append(-t0, t0[-2::-1]) #print t0 FLE = npy.zeros([nLE,2]) FLE[:,0] = x0 - radius*cos(t0) FLE[:,1] = radius*sin(t0) #pyl.plot(FLE[:,0],FLE[:,1],'o') #pyl.show() #----------------------# # x-wake on centerline # #----------------------# nr0 = nxwake*2**ref # 9=inviscid, 11=viscous a = 0.1 b = rxwakecenter # 2.9 for NACA, inviscid dx_te = X[0,0] - X[Q,0]; #print "TE locations\n" #print dx_te, X[0,0], X[Q,0] #print "TE locations done\n" re = (npy.logspace(a,b,nr0+1) - 10**a)/(10**b-10**a) #print re; ratio = FindStretching(nr0, dx_te, Hc) for i in xrange(0, nr0+1): re[i] = Distance(i, dx_te, ratio)/Hc #print re; rw = spaceq(re, ref, Q) #----------------------------------# # C-grid: put points on wake first # #----------------------------------# XWK = npy.flipud(npy.array([rw*Hc+xte[0], npy.zeros(len(rw))]).transpose()) XWK[:,1] = (XWK[:,0]-xte[0])*tan(wakeangle) XWK2 = npy.flipud(XWK) nWK = len(XWK) #----------------------------------------# # x-wake spacing far from airfoil (+/-y) # #----------------------------------------# a = 0.1 b = rxwakefary re = (npy.logspace(a,b,nr0+1) - 10**a)/(10**b-10**a) rbot = npy.flipud(spaceq(re, ref, Q)*(Hc+xte[0])) FWK1 = npy.array([rbot, XWK[:,1] - Hc - rbot*x0/Hc]).transpose() FWK2 = npy.array([npy.flipud(rbot), XWK2[:,1] + Hc + npy.flipud(rbot)*x0/Hc]).transpose() #pyl.plot(XWK[:,0],XWK[:,1],'o') #pyl.plot(FWK1[:,0],FWK1[:,1],'o') #pyl.plot(FWK2[:,0],FWK2[:,1],'o') #pyl.show() #-------------------# # Wake and boundary # #-------------------# XWB = npy.append(XWK, XLE[1:-1,:], axis = 0) XWB = npy.append(XWB, XWK2, axis = 0) FWB = npy.append(FWK1, FLE[1:-1,:], axis = 0) FWB = npy.append(FWB, FWK2, axis = 0) nWB = len(XWB) #------------------# # points on C grid # #------------------# nr0 = nnormal*2**ref # The old spacing; log-linear a = 0.1 b = rnormal re = (npy.logspace(a,b,nr0+1) - 10**a)/(10**b-10**a) # print re # The new spacing; exponential if (reynolds > 5e5): # Turbulent. y+=5 for the first cell at the TE on the coarse mesh coarse_yplus = 5 dy_te = 5.82 * (coarse_yplus / reynolds**0.9) / 2**ref wake_power = 0.8 else: # Laminar. Put two cells across the BL at the TE on the coarse mesh dy_te = 1. / reynolds**0.5 / 2**ref wake_power = 0.5 nr = 1 + (len(re)-1)*Q XC = npy.zeros([nWB, nr]) YC = npy.array(XC) a = 0.1 b = rnormalfar re = (npy.logspace(a,b,nr0+1) - 10**a)/(10**b-10**a) r1 = spaceq(re, ref, Q) #print re for i in xrange(nWB): iplus = min(nWB-1, i+1) iminus = max(0, i-1) ds = ((XWB[iplus,0] - XWB[iminus,0])**2 + (XWB[iplus,1] - XWB[iminus,1])**2)**0.5/ (iplus - iminus) dy = min(dy_te, ds*5*Q) dy = dy_te * max(XWB[i,0],1)**wake_power # print XWB[iplus,0], XWB[iminus,0], ds, dy, iplus, iminus ratio = FindStretching(nr0, dy, Hc) for i2 in xrange(0, nr0+1): #print i2, Distance(i2, dy, ratio)/Hc re[i2] = Distance(i2, dy, ratio)/Hc r0 = spaceq(re, ref, Q) #print re r = r0 #if i < nWK-1 or i > nWB-nWK-1: # xx = (XWB[i,0]-XWK[-1,0])/max(XWB[:,0]) # r = r0 * (1-xx) + r1 * xx XC[i,:] = XWB[i,0] + r*(FWB[i,0]-XWB[i,0]) YC[i,:] = XWB[i,1] + r*(FWB[i,1]-XWB[i,1]) #pyl.plot(XC,YC,'o') #pyl.show() if FileFormat == 'p2d': writePlot2D(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p2d', XC, YC) if FileFormat == 'p3d': writeNMF(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.nmf', XC, nLE, nWK, nWB, nr) writePlot3D(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p3d', XC, YC) if FileFormat == 'in': writeOVERFLOW('grid.in.'+str(ref), XC, YC) #--------------------# # Vertices, unrolled # #--------------------# V = npy.zeros((nWB*nr,2),float) V[:,0] = XC.T.reshape(nWB*nr) V[:,1] = YC.T.reshape(nWB*nr) #pyl.plot(XC.reshape(nWB*nr),YC.reshape(nWB*nr),'o') #pyl.show() #pyl.plot(V[:,0],V[:,1],'o') #pyl.show() #---------------------------------------------# # node number matrices for writing out blocks # #---------------------------------------------# NC = npy.arange(nWB*nr).reshape( (nr, nWB) ).T+1 V = npy.delete(V,NC[nWB-nWK:nWB,0]-1,0) NC[nWB-nWK:nWB,0] = NC[nWK-1::-1,0] NC[:,1:] = NC[:,1:]-nWK #---------------# # form elements # #---------------# E = block_elem(NC, Q); #---------------# # write file # #---------------# if FileFormat == 'grm': writeGRM(filename_base, ref, Q, E, V, nLE, NC, nWK, nWB, nr); if FileFormat == 'fec': writeVTK(filename_base, ref, Q, E, V); writeFEC(filename_base, ref, Q, E, V, nLE, NC, nWK, nWB, nr); if FileFormat == 'msh': writeGMSH(filename_base, ref, Q, E, V, nLE, NC, nWK, nWB, nr); return
def make_joukowski(ref, Q, TriFlag, Distribution, FileFormat, reynolds, filename_base): if Distribution == "Challenge": XC, YC = make_joukowski_challenge(ref, Q, reynolds) nWK = 8*Q*2**ref+1 else: raise ValueError("Distribution should be 'Challenge'") nLE = 16*Q*2**ref+1 nWB = XC.shape[0] nr = XC.shape[1] filename_base += "_tri" if TriFlag else "_quad" fac = 2 if TriFlag else 1 print('Cell size ' + str( int((nWB-1)/Q) ) + 'x' + str( int((nr-1)/Q) ) + ' with ' + str( fac*int((nWB-1)/Q)*int((nr-1)/Q) ) + ' Elements') if FileFormat == 'p2d': writePlot2D(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p2d.x', XC, YC) if FileFormat == 'labl': assert Q == 1 writeLaballiur(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.labl', XC, YC, nWK) if FileFormat == 'p3dxy': writeNMF(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.nmf', XC, nLE, nWK, nWB, nr, 'z') writePlot3D(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p3d.x', XC, YC) if FileFormat == 'p3dxz': writeNMF(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.nmf', XC, nLE, nWK, nWB, nr, 'y') writePlot3Dxz(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p3d.x', XC, YC) if FileFormat == 'in': writeOVERFLOW('grid.in.'+str(ref), XC, YC) if FileFormat == 'hypgen': writePlot2D('joukowski_c.crv', XC[:,0:1], YC[:,0:1]) if FileFormat == 'ebg': writeEBG('joukowski.ebg', XC, YC, nWK) if FileFormat == 'geo': writeGEO('joukowski.geo', XC, YC, nWK) if FileFormat == 'curve': writeCurve(XC, YC, nWK) #--------------------# # Vertices, unrolled # #--------------------# V = npy.zeros((nWB*nr,2),float) V[:,0] = XC.T.reshape(nWB*nr) V[:,1] = YC.T.reshape(nWB*nr) #pyl.plot(XC.reshape(nWB*nr),YC.reshape(nWB*nr),'o') #pyl.show() #pyl.plot(V[:,0],V[:,1],'o') #pyl.show() #---------------------------------------------# # node number matrices for writing out blocks # #---------------------------------------------# NC = npy.arange(nWB*nr).reshape( (nr, nWB) ).T+1 V = npy.delete(V,NC[nWB-nWK:nWB,0]-1,0) NC[nWB-nWK:nWB,0] = NC[nWK-1::-1,0] NC[:,1:] = NC[:,1:]-nWK #---------------# # form elements # #---------------# E = block_elem(NC, Q); #---------------# # write file # #---------------# if FileFormat == 'grm': writeGRM(filename_base, ref, Q, TriFlag, E, V, nLE, NC, nWK, nWB, nr); if FileFormat == 'fec': writeVTK(filename_base, ref, Q, E, V); writeFEC(filename_base, ref, Q, E, V, nLE, NC, nWK, nWB, nr); if FileFormat == 'msh': writeGMSH(filename_base, ref, Q, TriFlag, E, V, nLE, NC, nWK, nWB, nr); print("Done with refinement " + str(ref))
def make_joukowski(ref, Q, TriFlag, Distribution, FileFormat, reynolds, filename_base): if Distribution == "Classic": XC, YC = make_joukowski_classic(ref, Q, reynolds) nWK = 16*Q*2**ref+1 elif Distribution == "Challenge": XC, YC = make_joukowski_challenge(ref, Q, reynolds) nWK = 8*Q*2**ref+1 else: raise ValueError("Distribution should be 'Classic' or 'Challenge'") nLE = 16*Q*2**ref+1 nWB = XC.shape[0] nr = XC.shape[1] filename_base += "_tri" if TriFlag else "_quad" fac = 2 if TriFlag else 1 print 'Cell size ' + str( int((nWB-1)/Q) ) + 'x' + str( int((nr-1)/Q) ) + ' with ' + str( fac*int((nWB-1)/Q)*int((nr-1)/Q) ) + ' Elements' if FileFormat == 'p2d': writePlot2D(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p2d.x', XC, YC) if FileFormat == 'labl': assert Q == 1 writeLaballiur(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.labl', XC, YC, nWK) if FileFormat == 'p3dxy': writeNMF(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.nmf', XC, nLE, nWK, nWB, nr, 'z') writePlot3D(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p3d.x', XC, YC) if FileFormat == 'p3dxz': writeNMF(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.nmf', XC, nLE, nWK, nWB, nr, 'y') writePlot3Dxz(filename_base + '_ref'+str(ref)+ '_Q'+str(Q)+'.p3d.x', XC, YC) if FileFormat == 'in': writeOVERFLOW('grid.in.'+str(ref), XC, YC) if FileFormat == 'hypgen': writePlot2D('joukowski_c.crv', XC[:,0:1], YC[:,0:1]) if FileFormat == 'ebg': writeEBG('joukowski.ebg', XC, YC, nWK) if FileFormat == 'geo': writeGEO('joukowski.geo', XC, YC, nWK) if FileFormat == 'curve': writeCurve(XC, YC, nWK) #--------------------# # Vertices, unrolled # #--------------------# V = npy.zeros((nWB*nr,2),float) V[:,0] = XC.T.reshape(nWB*nr) V[:,1] = YC.T.reshape(nWB*nr) #pyl.plot(XC.reshape(nWB*nr),YC.reshape(nWB*nr),'o') #pyl.show() #pyl.plot(V[:,0],V[:,1],'o') #pyl.show() #---------------------------------------------# # node number matrices for writing out blocks # #---------------------------------------------# NC = npy.arange(nWB*nr).reshape( (nr, nWB) ).T+1 V = npy.delete(V,NC[nWB-nWK:nWB,0]-1,0) NC[nWB-nWK:nWB,0] = NC[nWK-1::-1,0] NC[:,1:] = NC[:,1:]-nWK #---------------# # form elements # #---------------# E = block_elem(NC, Q); #---------------# # write file # #---------------# if FileFormat == 'grm': writeGRM(filename_base, ref, Q, TriFlag, E, V, nLE, NC, nWK, nWB, nr); if FileFormat == 'fec': writeVTK(filename_base, ref, Q, E, V); writeFEC(filename_base, ref, Q, E, V, nLE, NC, nWK, nWB, nr); if FileFormat == 'msh': writeGMSH(filename_base, ref, Q, TriFlag, E, V, nLE, NC, nWK, nWB, nr); print("Done with refinement " + str(ref))