diff --git a/blast/interfaces/DSolversInterface.py b/blast/interfaces/DSolversInterface.py index b7542bc56ab9b64d9600921f416f5607e88d3053..29e4081378ddbe88b673f6f82a8d1e312da5df70 100644 --- a/blast/interfaces/DSolversInterface.py +++ b/blast/interfaces/DSolversInterface.py @@ -31,12 +31,16 @@ class SolversInterface: elif self.cfg['interpolator'] == 'Rbf': from blast.interfaces.interpolators.DRbfInterpolator import RbfInterpolator as interp print('Initializing RBF interpolator.') - self.getVWing() + upNodes, lwNodes, upElms, lwElms = self.getVWing2() else: raise RuntimeError('Incorrect interpolator specified in config.') self.interpolator = interp(self.cfg, self.getnDim()) + if self.cfg['interpolator'] == 'Rbf': + self.interpolator.setSides(upNodes, lwNodes, upElms, lwElms) + print('Setting sides in RBF interpolator.') + # Initialize transfer quantities self.deltaStarExt = [[np.zeros(0) for iReg in range(3)]\ for iSec in range(self.cfg['nSections'])] @@ -298,6 +302,171 @@ class SolversInterface: self.vtExt[iSec][i] = np.zeros(reg.getnNodes()) self.vinit = True return 0 + + def getVWing2(self): + from scipy.interpolate import griddata + from scipy.interpolate import interp1d + import matplotlib.pyplot as plt + + upper_elems = [] + lower_elems = [] + upper_nodes = np.zeros((0, 4)) + lower_nodes = np.zeros((0, 4)) + try: + lower_elems = np.loadtxt(self.blw[0].tag.elems[0].ptag.name + '_.dat', dtype=int) + except: + raise RuntimeError('Could not find file containing lower side of wing.') + + for e in self.blw[0].tag.elems: + if e.no in lower_elems: + for n in e.nodes: + if n.row not in lower_nodes[:,3]: + lower_nodes = np.row_stack((lower_nodes, [n.pos[0], n.pos[1], n.pos[2], n.row])) + else: + upper_elems.append(e.no) + for n in e.nodes: + if n.row not in upper_nodes[:,3]: + upper_nodes = np.row_stack((upper_nodes, [n.pos[0], n.pos[1], n.pos[2], n.row])) + + print('Found upper side with', len(upper_nodes), 'points') + print('Found lower side with', len(lower_nodes), 'points') + + # Remove points higher than span + upper_nodes = upper_nodes[upper_nodes[:,1] < self.cfg['span']*0.99, :] + lower_nodes = lower_nodes[lower_nodes[:,1] < self.cfg['span']*0.99, :] + + if upper_nodes.shape[0] == 0 or lower_nodes.shape[0] == 0: + raise RuntimeError('Could not identify upper or lower side.') + + sections = self.cfg['sections'] + interpolated_upper = [] + interpolated_lower = [] + + for y in sections: + x = np.linspace(np.min(upper_nodes[:, 0]), np.max(upper_nodes[:, 0]), 1000) + z_upper = griddata(upper_nodes[:, :2], upper_nodes[:, 2], (x, np.full_like(x, y)), method='cubic') + z_lower = griddata(lower_nodes[:, :2], lower_nodes[:, 2], (x, np.full_like(x, y)), method='cubic') + interpolated_upper.append(np.column_stack((x, np.full_like(x, y), z_upper))) + interpolated_lower.append(np.column_stack((x, np.full_like(x, y), z_lower))) + interpolated_upper[-1] = np.delete(interpolated_upper[-1], np.where(np.isnan(interpolated_upper[-1][:, 2])), axis=0) + interpolated_lower[-1] = np.delete(interpolated_lower[-1], np.where(np.isnan(interpolated_lower[-1][:, 2])), axis=0) + + """# Ensure that we have one LE point after interpolation + for i in range(len(interpolated_upper)): + avrg_le = (interpolated_upper[i][0,2] + interpolated_lower[i][0,2]) / 2 + interpolated_upper[i][0,2] = avrg_le + interpolated_lower[i][0,2] = avrg_le + avrg_te = (interpolated_upper[i][-1,2] + interpolated_lower[i][-1,2]) / 2 + interpolated_upper[i][-1,2] = avrg_te + interpolated_lower[i][-1,2] = avrg_te""" + + # Create sections + sections_final = [] + zeta = np.linspace(0., np.pi, self.cfg['nPoints']) + for i in range(len(interpolated_upper)): + chord_upper = np.max(interpolated_upper[i][:,0]) - np.min(interpolated_upper[i][:,0]) + xu = ( chord_upper / 2) * (np.cos(zeta) + 1) + np.min(interpolated_upper[i][:,0]) + zu = interp1d(interpolated_upper[i][:,0], interpolated_upper[i][:,2], kind='cubic', fill_value='extrapolate')(xu) + + chord_lower = np.max(interpolated_lower[i][:,0]) - np.min(interpolated_lower[i][:,0]) + xl = (chord_lower / 2) * (np.cos(zeta) + 1) + np.min(interpolated_lower[i][:,0]) + zl = interp1d(interpolated_lower[i][:,0], interpolated_lower[i][:,2], kind='cubic', fill_value='extrapolate')(xl) + + uf = np.column_stack((xu, np.full_like(xu, sections[i]), zu)) + lf = np.column_stack((xl, np.full_like(xl, sections[i]), zl)) + + sections_final.append(np.row_stack((uf, np.flip(lf, axis=0)[1:]))) + + # Compute elements positions + elems_coords_wing = [] + for isec, sec in enumerate(sections_final): + elems_coords_wing.append(np.zeros((sec.shape[0]-1, 3))) + for i in range(sec.shape[0]-1): + elems_coords_wing[isec][i, :] = (sec[i, :] + sec[i+1, :]) / 2 + + # Wake + wake = np.zeros((0,3)) + for n in self.blw[1].nodes: + wake = np.row_stack((wake, [n.pos[0], n.pos[1], n.pos[2]])) + + sections = self.cfg['sections'] + interpolated_wake = [] + + for y in sections: + x = np.linspace(np.min(wake[:, 0]), np.max(wake[:, 0]), 1000) + z = griddata(wake[:, :2], wake[:, 2], (x, np.full_like(x, y)), method='cubic') + interpolated_wake.append(np.column_stack((x, np.full_like(x, y), z))) + interpolated_wake[-1] = np.delete(interpolated_wake[-1], np.where(np.isnan(interpolated_wake[-1][:, 2])), axis=0) + + # Ensure that we have one LE point after interpolation + for i in range(len(interpolated_wake)): + avrg_le = interpolated_wake[i][0,2] + interpolated_wake[i][0,2] = avrg_le + avrg_te = interpolated_wake[i][-1,2] + interpolated_wake[i][-1,2] = avrg_te + + # Create sections + wake_final = [] + + for i in range(len(interpolated_wake)): + chord = np.max(interpolated_wake[i][:,0]) - np.min(interpolated_wake[i][:,0]) + x = (chord / 2) * (np.cos(zeta) + 1) + np.min(interpolated_wake[i][:,0]) + z = interp1d(interpolated_wake[i][:,0], interpolated_wake[i][:,2], kind='cubic')(x) + + wf = np.column_stack((x, np.full_like(x, sections[i]), z)) + wake_final.append(np.flip(wf, axis=0)) + + elems_coords_wake = [] + for isec, sec in enumerate(wake_final): + elems_coords_wake.append(np.zeros((sec.shape[0]-1, 3))) + for i in range(sec.shape[0]-1): + elems_coords_wake[isec][i, :] = (sec[i, :] + sec[i+1, :]) / 2 + + for iy in range(len(sections_final)): + self.vBnd[iy][0].initStructures(sections_final[iy].shape[0]) + self.vBnd[iy][0].nodesCoord = sections_final[iy] + self.vBnd[iy][0].elemsCoord = elems_coords_wing[iy] + + for iy in range(len(wake_final)): + self.vBnd[iy][1].initStructures(wake_final[iy].shape[0]) + self.vBnd[iy][1].nodesCoord = wake_final[iy] + self.vBnd[iy][1].elemsCoord = elems_coords_wake[iy] + + print('Created', len(sections_final), 'sections and', len(wake_final), 'wake sections') + # plot + fig, ax = plt.subplots() + ax = fig.add_subplot(111, projection='3d') + ax.plot_trisurf(upper_nodes[:,0], upper_nodes[:,1], upper_nodes[:,2], color='blue', alpha=0.5) + ax.plot_trisurf(lower_nodes[:,0], lower_nodes[:,1], lower_nodes[:,2], color='blue', alpha=0.5) + #ax.plot_trisurf(wake[:,0], wake[:,1], wake[:,2], color='green', alpha=0.5) + for iy in range(len(sections_final)): + ax.plot(sections_final[iy][:,0], sections_final[iy][:,1], sections_final[iy][:,2], '-') + for iy in range(len(wake_final)): + ax.plot(wake_final[iy][:,0], wake_final[iy][:,1], wake_final[iy][:,2], '-', color='red') + #ax.plot_trisurf(ib.nodesCoord[ib.nodesCoord[:,1]<0.99*self.cfg['span'],0], ib.nodesCoord[ib.nodesCoord[:,1]<0.99*self.cfg['span'],1], ib.nodesCoord[ib.nodesCoord[:,1]<0.99*self.cfg['span'],2], color='red', alpha=0.5) + # for sec in sections_final: + # ax.plot(sec[:,0], sec[:,2]) + # for sec in wake_final: + # ax.plot(sec[:,0], sec[:,2]) + plt.axis('equal') + plt.savefig("ax.png") + # plt.draw() + # plt.show() + # quit() + + for i, sec in enumerate(self.vBnd): + plt.figure() + for reg in sec: + if reg.name == 'wake': + plt.plot(reg.nodesCoord[:,0], reg.nodesCoord[:,2], '-') + else: + plt.plot(reg.nodesCoord[:,0], reg.nodesCoord[:,2], '-') + plt.axis('equal') + plt.xlim([0, 1.2]) + #plt.draw() + plt.savefig(f'Sec{i}.png') + + return np.array(upper_nodes[:,3], dtype=int), np.array(lower_nodes[:,3], dtype=int), upper_elems, lower_elems def getVWing(self): """Obtain the nodes' location and row and cg of all elements. diff --git a/blast/interfaces/dart/DartInterface.py b/blast/interfaces/dart/DartInterface.py index 7913ab549b1b745aa332d945590932b7f0633bca..ffa71953eba16204c3d6d41525f4603c1c7dd4b9 100644 --- a/blast/interfaces/dart/DartInterface.py +++ b/blast/interfaces/dart/DartInterface.py @@ -363,7 +363,7 @@ class DartInterface(SolversInterface): """ for iRegion in range(len(self.cfg['iMsh'])): - for e in self.cfg['iMsh'][iRegion].tag.elems: + for e in self.blw[iRegion].tag.elems: # Compute cg position cg_pt = np.zeros(3) for nw in e.nodes: @@ -376,16 +376,15 @@ class DartInterface(SolversInterface): cg_pt/=e.nodes.size() cg_pt = np.hstack((cg_pt, e.no)) cg[iRegion] = np.vstack((cg[iRegion], cg_pt)) - - self.ilwIdx = [] - if 'Sym' in self.cfg: - for s in self.cfg['Sym']: - for iReg in range(len(data)): - dummy = data[iReg].copy() - dummy[:,1] -= s - dummy[:,1] *= -1 - dummy[:,1] += s - data[iReg] = np.row_stack((data[iReg], dummy)) + # self.ilwIdx = [] + # if 'Sym' in self.cfg: + # for s in self.cfg['Sym']: + # for iReg in range(len(data)): + # dummy = data[iReg].copy() + # dummy[:,1] -= s + # dummy[:,1] *= -1 + # dummy[:,1] += s + # data[iReg] = np.row_stack((data[iReg], dummy)) for n in range(len(data)): self.iBnd[n].initStructures(data[n].shape[0]) diff --git a/blast/interfaces/interpolators/DRbfInterpolator.py b/blast/interfaces/interpolators/DRbfInterpolator.py index 1eda4a3e12b525a09907cbdb0fede1241d7d51ba..4f5ae028116fb80d3fb6f0591660de1c0fe20816 100644 --- a/blast/interfaces/interpolators/DRbfInterpolator.py +++ b/blast/interfaces/interpolators/DRbfInterpolator.py @@ -7,7 +7,137 @@ class RbfInterpolator: self.cfg = _cfg self.nDim = _nDim + def setSides(self, _upNodes, _lwNodes, _upElems, _lwElems): + self.upNodes = _upNodes + self.lwNodes = _lwNodes + self.upElems = _upElems + self.lwElems = _lwElems + + def inviscidToViscous(self, iDict, vDict): + + print('Inviscid to viscous') + # upper side + x0_up = np.zeros((0, self.nDim+1)) + for row in self.upNodes: + x0_up = np.row_stack((x0_up, np.unique(iDict[0].nodesCoord[iDict[0].nodesCoord[:,3]==row,:], axis=0))) + M0_up = np.zeros(x0_up.shape[0]) + for i, row in enumerate(x0_up[:,3]): + M0_up[i] = iDict[0].M[iDict[0].nodesCoord[:,3] == row][0] + rho0_up = np.zeros(x0_up.shape[0]) + for i, row in enumerate(x0_up[:,3]): + rho0_up[i] = iDict[0].Rho[iDict[0].nodesCoord[:,3] == row][0] + v0_up = np.zeros((x0_up.shape[0], self.nDim)) + for i, row in enumerate(x0_up[:,3]): + for idim in range(self.nDim): + v0_up[i, idim] = iDict[0].V[iDict[0].nodesCoord[:,3] == row, idim][0] + # lower side + x0_lw = np.zeros((0, self.nDim+1)) + for row in self.lwNodes: + x0_lw = np.row_stack((x0_lw, np.unique(iDict[0].nodesCoord[iDict[0].nodesCoord[:,3]==row,:], axis=0))) + M0_lw = np.zeros(x0_lw.shape[0]) + for i, row in enumerate(x0_lw[:,3]): + M0_lw[i] = iDict[0].M[iDict[0].nodesCoord[:,3] == row][0] + rho0_lw = np.zeros(x0_lw.shape[0]) + for i, row in enumerate(x0_lw[:,3]): + rho0_lw[i] = iDict[0].Rho[iDict[0].nodesCoord[:,3] == row][0] + v0_lw = np.zeros((x0_lw.shape[0], self.nDim)) + for i, row in enumerate(x0_lw[:,3]): + for idim in range(self.nDim): + v0_lw[i, idim] = iDict[0].V[iDict[0].nodesCoord[:,3] == row, idim][0] + + for iSec in range(len(vDict)): + + xInterp_up = vDict[iSec][0].nodesCoord[:np.argmin(vDict[iSec][0].nodesCoord[:,0]), :self.nDim] + M_up = self.__rbfToSection(x0_up[:,:self.nDim], M0_up, xInterp_up) + rho_up = self.__rbfToSection(x0_up[:,:self.nDim], rho0_up, xInterp_up) + v_up = np.zeros((xInterp_up.shape[0], self.nDim)) + for idim in range(self.nDim): + v_up[:,idim] = self.__rbfToSection(x0_up[:,:self.nDim], v0_up[:,idim], xInterp_up) + + xInterp_lw = vDict[iSec][0].nodesCoord[np.argmin(vDict[iSec][0].nodesCoord[:,0]):, :self.nDim] + M_lw = self.__rbfToSection(x0_lw[:,:self.nDim], M0_lw, xInterp_lw) + rho_lw = self.__rbfToSection(x0_lw[:,:self.nDim], rho0_lw, xInterp_lw) + v_lw = np.zeros((xInterp_lw.shape[0], self.nDim)) + for idim in range(self.nDim): + v_lw[:,idim] = self.__rbfToSection(x0_lw[:,:self.nDim], v0_lw[:,idim], xInterp_lw) + + xInterp_wk = vDict[iSec][1].nodesCoord[:, :self.nDim] + M_wk = self.__rbfToSection(iDict[1].nodesCoord[:,:self.nDim], iDict[1].M, xInterp_wk) + rho_wk = self.__rbfToSection(iDict[1].nodesCoord[:,:self.nDim], iDict[1].Rho, xInterp_wk) + v_wk = np.zeros((xInterp_wk.shape[0], self.nDim)) + for idim in range(self.nDim): + v_wk[:,idim] = self.__rbfToSection(iDict[1].nodesCoord[:,:self.nDim], iDict[1].V[:,idim], xInterp_wk) + + M_int = np.concatenate((M_up, M_lw)) + rho_int = np.concatenate((rho_up, rho_lw)) + v_int = np.row_stack((v_up, v_lw)) + + vDict[iSec][0].updateVars(v_int, M_int, rho_int) + + vDict[iSec][1].updateVars(v_wk, M_wk, rho_wk) + + + # M_tot = self.__rbfToSection(iDict[0].nodesCoord[:,:self.nDim], iDict[0].M, vDict[iSec][0].nodesCoord[:,:self.nDim]) + # V_tot = np.zeros((vDict[iSec][0].nodesCoord.shape[0], self.nDim)) + # for idim in range(self.nDim): + # V_tot[:,idim] = self.__rbfToSection(iDict[0].nodesCoord[:,:self.nDim], iDict[0].V[:, idim], vDict[iSec][0].nodesCoord[:,:self.nDim]) + # Rho_tot = self.__rbfToSection(iDict[0].nodesCoord[:,:self.nDim], iDict[0].Rho, vDict[iSec][0].nodesCoord[:,:self.nDim]) + + # from mpl_toolkits.mplot3d import Axes3D + # import matplotlib.pyplot as plt + # fig = plt.figure() + # ax = fig.add_subplot(111, projection='3d') + # ax.plot_trisurf(x0_up[:,0], x0_up[:,1], M0_up) + # ax.plot(xInterp_up[:,0], xInterp_up[:,1], M_up, lw = 2) + # plt.draw() + # fig = plt.figure() + # ax = fig.add_subplot(111, projection='3d') + # ax.plot_trisurf(x0_lw[:,0], x0_lw[:,1], M0_lw) + # ax.plot(xInterp_lw[:,0], xInterp_lw[:,1], M_lw, lw = 2) + # plt.draw() + + # plt.figure() + # plt.plot(xInterp_up[:,0], M_up, label='upper') + # plt.plot(xInterp_lw[:,0], M_lw, label='lower') + # plt.plot(vDict[iSec][0].nodesCoord[:,0], M_tot, '--', label='total') + # plt.legend(frameon=False) + # plt.title('Mach number') + # plt.draw() + + # plt.figure() + # plt.plot(xInterp_up[:,0], rho_up, label='upper') + # plt.plot(xInterp_lw[:,0], rho_lw, label='lower') + # plt.plot(vDict[iSec][0].nodesCoord[:,0], Rho_tot, '--', label='total') + # plt.legend(frameon=False) + # plt.title('Density') + # plt.draw() + + # for idim in range(self.nDim): + # plt.figure() + # plt.plot(xInterp_up[:,0], v_up[:,idim], label='upper') + # plt.plot(xInterp_lw[:,0], v_lw[:,idim], label='lower') + # plt.plot(vDict[iSec][0].nodesCoord[:,0], V_tot[:,idim], '--', label='total') + # plt.legend(frameon=False) + # plt.title('Velocity'+str(idim)) + # plt.draw() + # plt.show() + + + + + # # Plot 3D x0_lw + # fig = plt.figure() + # ax = fig.add_subplot(111, projection='3d') + # ax.scatter(x0_lw[:,0], x0_lw[:,1], x0_lw[:,2]) + # plt.show() + + + + + + + def inviscidToViscous2(self, iDict, vDict): ## Airfoil # Find stagnation point for iSec in range(len(vDict)): @@ -22,6 +152,58 @@ class RbfInterpolator: vDict[iSec][iReg].updateVars(v, M, rho) def viscousToInviscid(self, iDict, vDict): + + # Viscous side + xv_up = np.zeros((0, self.nDim)) + xv_lw = np.zeros((0, self.nDim)) + xv_wk = np.zeros((0, self.nDim)) + blwv_up = np.zeros(0) + blwv_lw = np.zeros(0) + blwv_wk = np.zeros(0) + for iSec, sec in enumerate(vDict): + xv_up = np.row_stack((xv_up, sec[0].elemsCoord[:np.argmin(sec[0].nodesCoord[:,0])-1, :self.nDim])) + xv_lw = np.row_stack((xv_lw, sec[0].elemsCoord[np.argmin(sec[0].nodesCoord[:,0]):, :self.nDim])) + xv_wk = np.row_stack((xv_wk, sec[1].elemsCoord[:,:self.nDim])) + blwv_up = np.concatenate((blwv_up, sec[0].blowingVel[:np.argmin(sec[0].nodesCoord[:,0])-1])) + blwv_lw = np.concatenate((blwv_lw, sec[0].blowingVel[np.argmin(sec[0].nodesCoord[:,0]):])) + blwv_wk = np.concatenate((blwv_wk, sec[1].blowingVel)) + + # Inviscid side + xi_up = np.zeros((0, self.nDim+1)) + xi_lw = np.zeros((0, self.nDim+1)) + for no in self.upElems: + xi_up = np.row_stack((xi_up, np.unique(iDict[0].elemsCoord[iDict[0].elemsCoord[:,3]==no,:], axis=0))) + for no in self.lwElems: + xi_lw = np.row_stack((xi_lw, np.unique(iDict[0].elemsCoord[iDict[0].elemsCoord[:,3]==no,:], axis=0))) + xi_wk = iDict[1].elemsCoord[:,:self.nDim] + + blwi_up = self.__rbfToSection(xv_up, blwv_up, xi_up[:,:self.nDim]) + blwi_lw = self.__rbfToSection(xv_lw, blwv_lw, xi_lw[:,:self.nDim]) + blwi_wk = self.__rbfToSection(xv_wk, blwv_wk, xi_wk[:,:self.nDim]) + + iDict[0].blowingVel = np.concatenate((blwi_up, blwi_lw)) + iDict[1].blowingVel = blwi_wk + + """from matplotlib import pyplot as plt + from mpl_toolkits.mplot3d import Axes3D + # plot 3D x0_up + fig = plt.figure() + ax = fig.add_subplot(111, projection='3d') + + ax.plot_trisurf(xi_up[:,0], xi_up[:,1], blwi_up, color='blue') + ax.plot(xv_up[:,0], xv_up[:,1], blwv_up, color='red') + plt.draw() + + fig = plt.figure() + ax = fig.add_subplot(111, projection='3d') + ax.plot_trisurf(xi_lw[:,0], xi_lw[:,1], blwi_lw, color='blue') + ax.plot(xv_lw[:,0], xv_lw[:,1], blwv_lw, color='red') + plt.draw() + + plt.show()""" + + def viscousToInviscid2(self, iDict, vDict): + print('Viscous to inviscid') if self.nDim == 2: for iReg, reg in enumerate(iDict): iDict[iReg].blowingVel = self.__rbfToSection(vDict[0][iReg].elemsCoordTr[:,:(self.cfg['nDim']-1 if 'vAirfoil' in reg.name else 1)], vDict[0][iReg].blowingVel, reg.elemsCoordTr[:,:(self.cfg['nDim']-1 if reg.name == 'iWing' else 1)]) diff --git a/blast/models/dart/oneraM6.geo b/blast/models/dart/oneraM6.geo new file mode 100644 index 0000000000000000000000000000000000000000..616835e51154fb213fbb6f5289e64be8f80a85c6 --- /dev/null +++ b/blast/models/dart/oneraM6.geo @@ -0,0 +1,591 @@ +/* Onera M6 wing */ +// Initially generated by unsRgridWingGen.m + +// Parameters +// domain and mesh +DefineConstant[ lgt = { 3.0, Name "Channel half length" } ]; +DefineConstant[ wdt = { 2.0, Name "Channel width" } ]; +DefineConstant[ hgt = { 3.0, Name "Channel half height" } ]; +DefineConstant[ msLeRt = { 0.01, Name "Root leading edge mesh size" } ]; +DefineConstant[ msTeRt = { 0.01, Name "Root trailing edge mesh size" } ]; +DefineConstant[ msLeTp = { 0.01, Name "Tip leading edge mesh size" } ]; +DefineConstant[ msTeTp = { 0.01, Name "Tip trailing edge mesh size" } ]; +DefineConstant[ msF = { 1.0, Name "Farfield mesh size" } ]; + + +//// GEOMETRY + + +/// Points + +// Airfoil 1: oneraM6, 143 points +Point(1) = {0.805900,0.000000,0.000000,msTeRt}; +Point(2) = {0.804129,0.000000,0.000232}; +Point(3) = {0.802038,0.000000,0.000505}; +Point(4) = {0.799569,0.000000,0.000828}; +Point(5) = {0.796652,0.000000,0.001210}; +Point(6) = {0.793208,0.000000,0.001661}; +Point(7) = {0.789139,0.000000,0.002193}; +Point(8) = {0.784331,0.000000,0.002822}; +Point(9) = {0.778649,0.000000,0.003565}; +Point(10) = {0.771932,0.000000,0.004444}; +Point(11) = {0.763989,0.000000,0.005483}; +Point(12) = {0.754592,0.000000,0.006710}; +Point(13) = {0.743470,0.000000,0.008151}; +Point(14) = {0.730299,0.000000,0.009828,msTeRt}; +Point(15) = {0.714691,0.000000,0.011690}; +Point(16) = {0.696182,0.000000,0.013774}; +Point(17) = {0.677546,0.000000,0.015783}; +Point(18) = {0.658809,0.000000,0.017717}; +Point(19) = {0.639970,0.000000,0.019586}; +Point(20) = {0.621026,0.000000,0.021397}; +Point(21) = {0.601980,0.000000,0.023159}; +Point(22) = {0.582826,0.000000,0.024875}; +Point(23) = {0.563568,0.000000,0.026547}; +Point(24) = {0.544202,0.000000,0.028170}; +Point(25) = {0.524729,0.000000,0.029737}; +Point(26) = {0.505147,0.000000,0.031238}; +Point(27) = {0.485455,0.000000,0.032658}; +Point(28) = {0.465652,0.000000,0.033984}; +Point(29) = {0.445738,0.000000,0.035197}; +Point(30) = {0.425711,0.000000,0.036282}; +Point(31) = {0.405570,0.000000,0.037225}; +Point(32) = {0.385317,0.000000,0.038011}; +Point(33) = {0.364947,0.000000,0.038631}; +Point(34) = {0.344460,0.000000,0.039073}; +Point(35) = {0.323856,0.000000,0.039344}; +Point(36) = {0.303135,0.000000,0.039432}; +Point(37) = {0.282293,0.000000,0.039343}; +Point(38) = {0.261331,0.000000,0.039078}; +Point(39) = {0.240248,0.000000,0.038642,1.5*msLeRt}; +Point(40) = {0.219042,0.000000,0.038037}; +Point(41) = {0.197712,0.000000,0.037261}; +Point(42) = {0.176258,0.000000,0.036306}; +Point(43) = {0.154679,0.000000,0.035154}; +Point(44) = {0.132972,0.000000,0.033774}; +Point(45) = {0.111131,0.000000,0.032117}; +Point(46) = {0.092662,0.000000,0.030457}; +Point(47) = {0.077073,0.000000,0.028830}; +Point(48) = {0.063937,0.000000,0.027269}; +Point(49) = {0.052891,0.000000,0.025800}; +Point(50) = {0.043619,0.000000,0.024441}; +Point(51) = {0.035851,0.000000,0.023203}; +Point(52) = {0.029356,0.000000,0.022027}; +Point(53) = {0.023936,0.000000,0.020812}; +Point(54) = {0.019428,0.000000,0.019503}; +Point(55) = {0.015684,0.000000,0.018096}; +Point(56) = {0.012586,0.000000,0.016619}; +Point(57) = {0.010032,0.000000,0.015114}; +Point(58) = {0.007931,0.000000,0.013618}; +Point(59) = {0.006214,0.000000,0.012165}; +Point(60) = {0.004815,0.000000,0.010776}; +Point(61) = {0.003683,0.000000,0.009463}; +Point(62) = {0.002775,0.000000,0.008233}; +Point(63) = {0.002050,0.000000,0.007089}; +Point(64) = {0.001480,0.000000,0.006027}; +Point(65) = {0.001037,0.000000,0.005045}; +Point(66) = {0.000698,0.000000,0.004138}; +Point(67) = {0.000444,0.000000,0.003301}; +Point(68) = {0.000260,0.000000,0.002529}; +Point(69) = {0.000135,0.000000,0.001818}; +Point(70) = {0.000056,0.000000,0.001162}; +Point(71) = {0.000013,0.000000,0.000557}; +Point(72) = {0.000000,0.000000,0.000000,msLeRt}; +Point(73) = {0.000013,0.000000,-0.000557}; +Point(74) = {0.000056,0.000000,-0.001162}; +Point(75) = {0.000135,0.000000,-0.001818}; +Point(76) = {0.000260,0.000000,-0.002529}; +Point(77) = {0.000444,0.000000,-0.003301}; +Point(78) = {0.000698,0.000000,-0.004138}; +Point(79) = {0.001037,0.000000,-0.005045}; +Point(80) = {0.001480,0.000000,-0.006027}; +Point(81) = {0.002050,0.000000,-0.007089}; +Point(82) = {0.002775,0.000000,-0.008233}; +Point(83) = {0.003683,0.000000,-0.009463}; +Point(84) = {0.004815,0.000000,-0.010776}; +Point(85) = {0.006214,0.000000,-0.012165}; +Point(86) = {0.007931,0.000000,-0.013618}; +Point(87) = {0.010032,0.000000,-0.015114}; +Point(88) = {0.012586,0.000000,-0.016619}; +Point(89) = {0.015684,0.000000,-0.018096}; +Point(90) = {0.019428,0.000000,-0.019503}; +Point(91) = {0.023936,0.000000,-0.020812}; +Point(92) = {0.029356,0.000000,-0.022027}; +Point(93) = {0.035851,0.000000,-0.023203}; +Point(94) = {0.043619,0.000000,-0.024441}; +Point(95) = {0.052891,0.000000,-0.025800}; +Point(96) = {0.063937,0.000000,-0.027269}; +Point(97) = {0.077073,0.000000,-0.028830}; +Point(98) = {0.092662,0.000000,-0.030457}; +Point(99) = {0.111131,0.000000,-0.032117}; +Point(100) = {0.132972,0.000000,-0.033774}; +Point(101) = {0.154679,0.000000,-0.035154}; +Point(102) = {0.176258,0.000000,-0.036306}; +Point(103) = {0.197712,0.000000,-0.037261}; +Point(104) = {0.219042,0.000000,-0.038037}; +Point(105) = {0.240248,0.000000,-0.038642,1.5*msLeRt}; +Point(106) = {0.261331,0.000000,-0.039078}; +Point(107) = {0.282293,0.000000,-0.039343}; +Point(108) = {0.303135,0.000000,-0.039432}; +Point(109) = {0.323856,0.000000,-0.039344}; +Point(110) = {0.344460,0.000000,-0.039073}; +Point(111) = {0.364947,0.000000,-0.038631}; +Point(112) = {0.385317,0.000000,-0.038011}; +Point(113) = {0.405570,0.000000,-0.037225}; +Point(114) = {0.425711,0.000000,-0.036282}; +Point(115) = {0.445738,0.000000,-0.035197}; +Point(116) = {0.465652,0.000000,-0.033984}; +Point(117) = {0.485455,0.000000,-0.032658}; +Point(118) = {0.505147,0.000000,-0.031238}; +Point(119) = {0.524729,0.000000,-0.029737}; +Point(120) = {0.544202,0.000000,-0.028170}; +Point(121) = {0.563568,0.000000,-0.026547}; +Point(122) = {0.582826,0.000000,-0.024875}; +Point(123) = {0.601980,0.000000,-0.023159}; +Point(124) = {0.621026,0.000000,-0.021397}; +Point(125) = {0.639970,0.000000,-0.019586}; +Point(126) = {0.658809,0.000000,-0.017717}; +Point(127) = {0.677546,0.000000,-0.015783}; +Point(128) = {0.696182,0.000000,-0.013774}; +Point(129) = {0.714691,0.000000,-0.011690}; +Point(130) = {0.730299,0.000000,-0.009828,msTeRt}; +Point(131) = {0.743470,0.000000,-0.008151}; +Point(132) = {0.754592,0.000000,-0.006710}; +Point(133) = {0.763989,0.000000,-0.005483}; +Point(134) = {0.771932,0.000000,-0.004444}; +Point(135) = {0.778649,0.000000,-0.003565}; +Point(136) = {0.784331,0.000000,-0.002822}; +Point(137) = {0.789139,0.000000,-0.002193}; +Point(138) = {0.793208,0.000000,-0.001661}; +Point(139) = {0.796652,0.000000,-0.001210}; +Point(140) = {0.799569,0.000000,-0.000828}; +Point(141) = {0.802038,0.000000,-0.000505}; +Point(142) = {0.804129,0.000000,-0.000232,msTeRt}; + +// Airfoil 2: oneraM6, 143 points +Point(144) = {1.143427,1.196000,0.000000,msTeTp}; +Point(145) = {1.142432,1.196000,0.000130}; +Point(146) = {1.141256,1.196000,0.000284}; +Point(147) = {1.139869,1.196000,0.000466}; +Point(148) = {1.138230,1.196000,0.000680}; +Point(149) = {1.136294,1.196000,0.000933}; +Point(150) = {1.134007,1.196000,0.001232}; +Point(151) = {1.131305,1.196000,0.001586}; +Point(152) = {1.128112,1.196000,0.002004}; +Point(153) = {1.124337,1.196000,0.002498}; +Point(154) = {1.119873,1.196000,0.003082}; +Point(155) = {1.114592,1.196000,0.003771}; +Point(156) = {1.108341,1.196000,0.004581}; +Point(157) = {1.100939,1.196000,0.005523,1.5*msTeTp}; +Point(158) = {1.092167,1.196000,0.006570}; +Point(159) = {1.081765,1.196000,0.007741}; +Point(160) = {1.071292,1.196000,0.008870}; +Point(161) = {1.060762,1.196000,0.009957}; +Point(162) = {1.050174,1.196000,0.011007}; +Point(163) = {1.039528,1.196000,0.012025}; +Point(164) = {1.028824,1.196000,0.013015}; +Point(165) = {1.018059,1.196000,0.013980}; +Point(166) = {1.007236,1.196000,0.014919}; +Point(167) = {0.996353,1.196000,0.015831}; +Point(168) = {0.985409,1.196000,0.016712}; +Point(169) = {0.974403,1.196000,0.017556}; +Point(170) = {0.963336,1.196000,0.018354}; +Point(171) = {0.952208,1.196000,0.019099}; +Point(172) = {0.941016,1.196000,0.019781}; +Point(173) = {0.929760,1.196000,0.020391}; +Point(174) = {0.918441,1.196000,0.020920}; +Point(175) = {0.907059,1.196000,0.021362}; +Point(176) = {0.895611,1.196000,0.021711}; +Point(177) = {0.884097,1.196000,0.021959}; +Point(178) = {0.872518,1.196000,0.022111}; +Point(179) = {0.860873,1.196000,0.022161}; +Point(180) = {0.849160,1.196000,0.022111}; +Point(181) = {0.837379,1.196000,0.021962}; +Point(182) = {0.825530,1.196000,0.021717,1.5*msLeTp}; +Point(183) = {0.813612,1.196000,0.021377}; +Point(184) = {0.801625,1.196000,0.020941}; +Point(185) = {0.789568,1.196000,0.020404}; +Point(186) = {0.777440,1.196000,0.019757}; +Point(187) = {0.765241,1.196000,0.018981}; +Point(188) = {0.752966,1.196000,0.018050}; +Point(189) = {0.742587,1.196000,0.017117}; +Point(190) = {0.733826,1.196000,0.016203}; +Point(191) = {0.726444,1.196000,0.015325}; +Point(192) = {0.720236,1.196000,0.014500}; +Point(193) = {0.715025,1.196000,0.013736}; +Point(194) = {0.710659,1.196000,0.013040}; +Point(195) = {0.707009,1.196000,0.012379}; +Point(196) = {0.703963,1.196000,0.011696}; +Point(197) = {0.701429,1.196000,0.010961}; +Point(198) = {0.699325,1.196000,0.010170}; +Point(199) = {0.697584,1.196000,0.009340}; +Point(200) = {0.696149,1.196000,0.008494}; +Point(201) = {0.694968,1.196000,0.007654}; +Point(202) = {0.694003,1.196000,0.006837}; +Point(203) = {0.693217,1.196000,0.006056}; +Point(204) = {0.692581,1.196000,0.005318}; +Point(205) = {0.692070,1.196000,0.004627}; +Point(206) = {0.691663,1.196000,0.003984}; +Point(207) = {0.691343,1.196000,0.003387}; +Point(208) = {0.691094,1.196000,0.002835}; +Point(209) = {0.690903,1.196000,0.002325}; +Point(210) = {0.690760,1.196000,0.001855}; +Point(211) = {0.690657,1.196000,0.001421}; +Point(212) = {0.690587,1.196000,0.001022}; +Point(213) = {0.690542,1.196000,0.000653}; +Point(214) = {0.690518,1.196000,0.000313}; +Point(215) = {0.690511,1.196000,0.000000,msLeTp}; +Point(216) = {0.690518,1.196000,-0.000313}; +Point(217) = {0.690542,1.196000,-0.000653}; +Point(218) = {0.690587,1.196000,-0.001022}; +Point(219) = {0.690657,1.196000,-0.001421}; +Point(220) = {0.690760,1.196000,-0.001855}; +Point(221) = {0.690903,1.196000,-0.002325}; +Point(222) = {0.691094,1.196000,-0.002835}; +Point(223) = {0.691343,1.196000,-0.003387}; +Point(224) = {0.691663,1.196000,-0.003984}; +Point(225) = {0.692070,1.196000,-0.004627}; +Point(226) = {0.692581,1.196000,-0.005318}; +Point(227) = {0.693217,1.196000,-0.006056}; +Point(228) = {0.694003,1.196000,-0.006837}; +Point(229) = {0.694968,1.196000,-0.007654}; +Point(230) = {0.696149,1.196000,-0.008494}; +Point(231) = {0.697584,1.196000,-0.009340}; +Point(232) = {0.699325,1.196000,-0.010170}; +Point(233) = {0.701429,1.196000,-0.010961}; +Point(234) = {0.703963,1.196000,-0.011696}; +Point(235) = {0.707009,1.196000,-0.012379}; +Point(236) = {0.710659,1.196000,-0.013040}; +Point(237) = {0.715025,1.196000,-0.013736}; +Point(238) = {0.720236,1.196000,-0.014500}; +Point(239) = {0.726444,1.196000,-0.015325}; +Point(240) = {0.733826,1.196000,-0.016203}; +Point(241) = {0.742587,1.196000,-0.017117}; +Point(242) = {0.752966,1.196000,-0.018050}; +Point(243) = {0.765241,1.196000,-0.018981}; +Point(244) = {0.777440,1.196000,-0.019757}; +Point(245) = {0.789568,1.196000,-0.020404}; +Point(246) = {0.801625,1.196000,-0.020941}; +Point(247) = {0.813612,1.196000,-0.021377}; +Point(248) = {0.825530,1.196000,-0.021717,1.5*msLeTp}; +Point(249) = {0.837379,1.196000,-0.021962}; +Point(250) = {0.849160,1.196000,-0.022111}; +Point(251) = {0.860873,1.196000,-0.022161}; +Point(252) = {0.872518,1.196000,-0.022111}; +Point(253) = {0.884097,1.196000,-0.021959}; +Point(254) = {0.895611,1.196000,-0.021711}; +Point(255) = {0.907059,1.196000,-0.021362}; +Point(256) = {0.918441,1.196000,-0.020920}; +Point(257) = {0.929760,1.196000,-0.020391}; +Point(258) = {0.941016,1.196000,-0.019781}; +Point(259) = {0.952208,1.196000,-0.019099}; +Point(260) = {0.963336,1.196000,-0.018354}; +Point(261) = {0.974403,1.196000,-0.017556}; +Point(262) = {0.985409,1.196000,-0.016712}; +Point(263) = {0.996353,1.196000,-0.015831}; +Point(264) = {1.007236,1.196000,-0.014919}; +Point(265) = {1.018059,1.196000,-0.013980}; +Point(266) = {1.028824,1.196000,-0.013015}; +Point(267) = {1.039528,1.196000,-0.012025}; +Point(268) = {1.050174,1.196000,-0.011007}; +Point(269) = {1.060762,1.196000,-0.009957}; +Point(270) = {1.071292,1.196000,-0.008870}; +Point(271) = {1.081765,1.196000,-0.007741}; +Point(272) = {1.092167,1.196000,-0.006570}; +Point(273) = {1.100939,1.196000,-0.005523,1.5*msTeTp}; +Point(274) = {1.108341,1.196000,-0.004581}; +Point(275) = {1.114592,1.196000,-0.003771}; +Point(276) = {1.119873,1.196000,-0.003082}; +Point(277) = {1.124337,1.196000,-0.002498}; +Point(278) = {1.128112,1.196000,-0.002004}; +Point(279) = {1.131305,1.196000,-0.001586}; +Point(280) = {1.134007,1.196000,-0.001232}; +Point(281) = {1.136294,1.196000,-0.000933}; +Point(282) = {1.138230,1.196000,-0.000680}; +Point(283) = {1.139869,1.196000,-0.000466}; +Point(284) = {1.141256,1.196000,-0.000284}; +Point(285) = {1.142432,1.196000,-0.000130,msTeTp}; + +// Box: +Point(5001) = {-lgt,0.000000,-hgt,msF}; +Point(5002) = {1+lgt,0.000000,-hgt,msF}; +Point(5003) = {-lgt,0.000000,hgt,msF}; +Point(5004) = {1+lgt,0.000000,hgt,msF}; +Point(5005) = {-lgt,wdt,-hgt,msF}; +Point(5006) = {1+lgt,wdt,-hgt,msF}; +Point(5007) = {-lgt,wdt,hgt,msF}; +Point(5008) = {1+lgt,wdt,hgt,msF}; + +// Tip: +Point(5101) = {1.142432,1.196000,0.000000}; +Point(5102) = {1.141256,1.196040,0.000000}; +Point(5103) = {1.139869,1.196088,0.000000}; +Point(5104) = {1.138230,1.196144,0.000000}; +Point(5105) = {1.136294,1.196210,0.000000}; +Point(5106) = {1.134007,1.196289,0.000000}; +Point(5107) = {1.131305,1.196381,0.000000}; +Point(5108) = {1.128112,1.196491,0.000000}; +Point(5109) = {1.124337,1.196620,0.000000}; +Point(5110) = {1.119873,1.196773,0.000000}; +Point(5111) = {1.114592,1.196954,0.000000}; +Point(5112) = {1.108341,1.197168,0.000000}; +Point(5113) = {1.100939,1.197422,0.000000,1.5*msTeTp}; +Point(5114) = {1.092167,1.197722,0.000000}; +Point(5115) = {1.081765,1.198079,0.000000}; +Point(5116) = {1.071292,1.198438,0.000000}; +Point(5117) = {1.060762,1.198798,0.000000}; +Point(5118) = {1.050174,1.199161,0.000000}; +Point(5119) = {1.039528,1.199526,0.000000}; +Point(5120) = {1.028824,1.199893,0.000000}; +Point(5121) = {1.018059,1.200262,0.000000}; +Point(5122) = {1.007236,1.200632,0.000000}; +Point(5123) = {0.996353,1.201005,0.000000}; +Point(5124) = {0.985409,1.201380,0.000000}; +Point(5125) = {0.974403,1.201757,0.000000}; +Point(5126) = {0.963336,1.202137,0.000000}; +Point(5127) = {0.952208,1.202518,0.000000}; +Point(5128) = {0.941016,1.202901,0.000000}; +Point(5129) = {0.929760,1.203287,0.000000}; +Point(5130) = {0.918441,1.203675,0.000000}; +Point(5131) = {0.907059,1.204065,0.000000}; +Point(5132) = {0.895611,1.204457,0.000000}; +Point(5133) = {0.884097,1.204852,0.000000}; +Point(5134) = {0.872518,1.205248,0.000000}; +Point(5135) = {0.860873,1.205648,0.000000}; +Point(5136) = {0.849160,1.206049,0.000000}; +Point(5137) = {0.837379,1.206453,0.000000}; +Point(5138) = {0.825530,1.206859,0.000000,1.5*msLeTp}; +Point(5139) = {0.699294,1.211213,0.000000}; + +// Dummy tip center: +Point(5349) = {1.100939,1.196000,0.000000}; +Point(5350) = {0.825530,1.196000,0.000000}; + + +// Midplane: +Point(5351) = {1+lgt,0.000000,0.000000,msF}; +Point(5352) = {1+lgt,1.196000,0.000000,msF}; +Point(5353) = {1+lgt,wdt,0.000000,msF}; +Point(5354) = {1.143427,wdt,0.000000,msF}; +Point(5355) = {1.100939,wdt,0.000000,msF}; +Point(5356) = {0.825530,wdt,0.000000,msF}; +Point(5357) = {0.690511,wdt,0.000000,msF}; +Point(5358) = {-lgt,wdt,0.000000,msF}; +Point(5359) = {-lgt,1.196000,0.000000,msF}; +Point(5360) = {-lgt,0.000000,0.000000,msF}; + +/// Lines + +// Airfoil 1: +Spline(1) = {1,2,3,4,5,6,7,8,9,10,11,12,13,14}; +Spline(2) = {14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39}; +Spline(3) = {39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72}; +Spline(4) = {72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105}; +Spline(5) = {105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130}; +Spline(6) = {130,131,132,133,134,135,136,137,138,139,140,141,142,1}; + +// Airfoil 2: +Spline(7) = {144,145,146,147,148,149,150,151,152,153,154,155,156,157}; +Spline(8) = {157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182}; +Spline(9) = {182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215}; +Spline(10) = {215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248}; +Spline(11) = {248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273}; +Spline(12) = {273,274,275,276,277,278,279,280,281,282,283,284,285,144}; + + +// Box: +Line(41) = {5001,5002}; +Line(42) = {5003,5004}; +Line(43) = {5005,5006}; +Line(44) = {5007,5008}; +Line(45) = {5001,5005}; +Line(46) = {5002,5006}; +Line(47) = {5003,5007}; +Line(48) = {5004,5008}; +Line(49) = {5001,5360}; +Line(50) = {5002,5351}; +Line(51) = {5003,5360}; +Line(52) = {5004,5351}; +Line(53) = {5005,5358}; +Line(54) = {5006,5353}; +Line(55) = {5007,5358}; +Line(56) = {5008,5353}; + +// Airfoil 1 to airfoil 2: +Line(61) = {1,144}; +Line(62) = {14,157}; +Line(63) = {39,182}; +Line(64) = {72,215}; +Line(65) = {105,248}; +Line(66) = {130,273}; + + +// Tip: +Spline(121) = {144,5101,5102,5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,5113}; +Spline(122) = {5113,5114,5115,5116,5117,5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138}; +If(GMSH_MAJOR_VERSION >= 4) + Bezier(123) = {5138,5139,215}; +Else + BSpline(123) = {5138,5139,215}; +EndIf +Ellipse(124) = {157,5349,157,5113}; +Ellipse(125) = {182,5350,182,5138}; +Ellipse(126) = {248,5350,248,5138}; +Ellipse(127) = {273,5349,273,5113}; + +// Midplane: +Line(131) = {5351,5352}; +Line(132) = {5352,5353}; +Line(133) = {5353,5354}; +Line(134) = {5354,5355}; +Line(135) = {5355,5356}; +Line(136) = {5356,5357}; +Line(137) = {5357,5358}; +Line(138) = {5358,5359}; +Line(139) = {5359,5360}; + +// Wing to midplane: +Line(161) = {1,5351}; +Line(162) = {144,5352}; +Line(163) = {144,5354}; +Line(164) = {5113,5355}; +Line(165) = {5138,5356}; +Line(166) = {215,5357}; +Line(167) = {215,5359}; +Line(168) = {72,5360}; + +/// Line loops & Surfaces + +// Box: +Line Loop(1) = {1,2,3,168,-51,42,52,-161}; +Line Loop(2) = {48,56,-132,-131,-52}; +Line Loop(3) = {44,56,133,134,135,136,137,-55}; +Line Loop(4) = {47,55,138,139,-51}; +Line Loop(5) = {42,48,-44,-47}; +Line Loop(6) = {-6,-5,-4,168,-49,41,50,-161}; +Line Loop(7) = {46,54,-132,-131,-50}; +Line Loop(8) = {43,54,133,134,135,136,137,-53}; +Line Loop(9) = {45,53,138,139,-49}; +Line Loop(10) = {41,46,-43,-45}; +Plane Surface(1) = {1}; +Plane Surface(2) = {2}; +Plane Surface(3) = {-3}; +Plane Surface(4) = {-4}; +Plane Surface(5) = {-5}; +Plane Surface(6) = {-6}; +Plane Surface(7) = {-7}; +Plane Surface(8) = {8}; +Plane Surface(9) = {9}; +Plane Surface(10) = {10}; + +// Wing 1: +Line Loop(11) = {1,62,-7,-61}; +Line Loop(12) = {2,63,-8,-62}; +Line Loop(13) = {3,64,-9,-63}; +Line Loop(14) = {4,65,-10,-64}; +Line Loop(15) = {5,66,-11,-65}; +Line Loop(16) = {6,61,-12,-66}; +Surface(11) = {-11}; +Surface(12) = {-12}; +Surface(13) = {-13}; +Surface(14) = {-14}; +Surface(15) = {-15}; +Surface(16) = {-16}; + +// Wingtip: +Line Loop(71) = {7,124,-121}; +Line Loop(72) = {8,125,-122,-124}; +Line Loop(73) = {9,-123,-125}; +Line Loop(74) = {10,126,123}; +Line Loop(75) = {11,127,122,-126}; +Line Loop(76) = {12,121,-127}; +Surface(71) = {-71}; +Surface(72) = {-72}; +Surface(73) = {-73}; +Surface(74) = {-74}; +Surface(75) = {-75}; +Surface(76) = {-76}; + +// Midplane: +Line Loop(81) = {161,131,-162,-61}; +Line Loop(82) = {162,132,133,-163}; +Line Loop(83) = {163,134,-164,-121}; +Line Loop(84) = {164,135,-165,-122}; +Line Loop(85) = {165,136,-166,-123}; +Line Loop(86) = {167,-138,-137,-166}; +Line Loop(87) = {167,139,-168,64}; +Surface(81) = {81}; +Surface(82) = {82}; +Surface(83) = {83}; +Surface(84) = {84}; +Surface(85) = {85}; +Surface(86) = {-86}; +Surface(87) = {87}; + +/// Surface loops & Volumes + +// Upper: +Surface Loop(1) = {11,12,13,71,72,73,1,2,3,4,5,81,82,83,84,85,86,87}; +Volume(1) = {1}; +// Lower: +Surface Loop(2) = {14,15,16,74,75,76,6,7,8,9,10,81,82,83,84,85,86,87}; +Volume(2) = {2}; + + + +//// MESHING ALGORITHM + + +/// 2D: + +///Wing, farfield and symmetry plane: +MeshAlgorithm Surface{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,81,82,83,84,85,86,87} = 5; + +///Tip: +MeshAlgorithm Surface{73,74} = 1; +MeshAlgorithm Surface{71,72,75,76} = 5; + +/// 3D: + +Mesh.Algorithm3D = 2; +Mesh.Optimize = 1; +Mesh.Smoothing = 10; +Mesh.SmoothNormals = 1; + + + +//// PHYSICAL GROUPS + +// Trailing edge and wake tip +Physical Line("wakeTip") = {162}; +Physical Line("te") = {61}; + +// Internal Field: +Physical Volume("field") = {1}; +Physical Volume("field") += {2}; + +// Wing: +Physical Surface("wing") = {11,12,13,71,72,73}; +Physical Surface("wing_") = {14,15,16,74,75,76}; +Physical Surface("wing_upper") = {11,12,13,71,72,73}; +Physical Surface("wing_lower") = {14,15,16,74,75,76}; + +// Tip +//Physical Surface("tip") = {71,72,73,74,75,76}; + +// Symmetry: +Physical Surface("symmetry") = {1}; +Physical Surface("symmetry") += {6}; + +// Farfield: +Physical Surface("upstream") = {10}; +Physical Surface("farfield") = {3,4,5,8,9}; + +// Downstream: +Physical Surface("downstream") = {2}; +Physical Surface("downstream") += {7}; + +// Wake: +Physical Surface("wake") = {81}; + +Coherence; diff --git a/blast/tests/dart/onera_3D.py b/blast/tests/dart/onera_3D.py new file mode 100644 index 0000000000000000000000000000000000000000..2ad42d166fd0c67413dcff7a633233836ee4d034 --- /dev/null +++ b/blast/tests/dart/onera_3D.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright 2022 University of Liège +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# @author Paul Dechamps +# @date 2022 +# Test the blast implementation on the 3D ONERA M6 wing. + +# Imports. + +import blast.utils as viscUtils +import numpy as np +import os.path + +from fwk.wutils import parseargs +import fwk +from fwk.testing import * +from fwk.coloring import ccolors + +import math + +def cfgInviscid(nthrds, verb): + # Parameters + return { + # Options + 'scenario' : 'aerodynamic', + 'task' : 'analysis', + 'Threads' : nthrds, # number of threads + 'Verb' : verb, # verbosity + # Model (geometry or mesh) + 'File' : os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/models/dart/oneraM6.geo', # Input file containing the model + 'Pars' : {'lgt' : 3.0, 'wdt' : 3.0, 'hgt' : 3.0, 'msLeRt' : 0.004, 'msTeRt' : 0.008, 'msLeTp' : 0.002, 'msTeTp' : 0.008, 'msF' : 0.6}, # parameters for input file model + 'Dim' : 3, # problem dimension + 'Format' : 'vtk', # save format (vtk or gmsh) + # Markers + 'Fluid' : 'field', # name of physical group containing the fluid + 'Farfield' : ['upstream', 'farfield', 'downstream'], # LIST of names of physical groups containing the farfield boundaries (upstream/downstream should be first/last element) + 'Wings' : ['wing'], # LIST of names of physical groups containing the lifting surface boundary + 'Wakes' : ['wake'], # LIST of names of physical group containing the wake + 'WakeTips' : ['wakeTip'], # LIST of names of physical group containing the edge of the wake + 'Tes' : ['te'], # LIST of names of physical group containing the trailing edge + 'dbc' : True, + 'Upstream' : 'upstream', + # Freestream + 'M_inf' : 0.839, # freestream Mach number + 'AoA' : 3.06, # freestream angle of attack + # Geometry + 'S_ref' : 0.7528, # reference surface length + 'c_ref' : 0.64, # reference chord length + 'x_ref' : 0.0, # reference point for moment computation (x) + 'y_ref' : 0.0, # reference point for moment computation (y) + 'z_ref' : 0.0, # reference point for moment computation (z) + # Numerical + 'LSolver' : 'GMRES', # inner solver (Pardiso, MUMPS or GMRES) + 'G_fill' : 2, # fill-in factor for GMRES preconditioner + 'G_tol' : 1e-5, # tolerance for GMRES + 'G_restart' : 50, # restart for GMRES + 'Rel_tol' : 1e-6, # relative tolerance on solver residual + 'Abs_tol' : 1e-8, # absolute tolerance on solver residual + 'Max_it' : 50 # solver maximum number of iterations + } + +def cfgBlast(verb): + return { + 'Re' : 11.72*10e6, # Freestream Reynolds number + 'Minf' : 0.839, # Freestream Mach number (used for the computation of the time step only) + 'CFL0' : 1, # Inital CFL number of the calculation + + 'sections' : np.linspace(0.01, 1.1, 20), + 'nPoints': 150, + 'writeSections': [0.20, 0.44, 0.80], + 'Sym':[0.], + 'span':1.196, + 'interpolator': 'Rbf', + 'rbftype': 'linear', + 'smoothing': 1e-8, + 'degree': 0, + 'neighbors': 10, + 'saveTag': 5, + + 'Verb': verb, # Verbosity level of the solver + 'couplIter': 50, # Maximum number of iterations + 'couplTol' : 5e-4, # Tolerance of the VII methodology + 'iterPrint': 5, # int, number of iterations between outputs + 'resetInv' : True, # bool, flag to reset the inviscid calculation at every iteration. + 'xtrF' : [0.01, 0.01],# Forced transition location + 'nDim' : 3 + } + +def main(): + # Timer. + tms = fwk.Timers() + tms['total'].start() + + args = parseargs() + icfg = cfgInviscid(args.k, args.verb) + vcfg = cfgBlast(args.verb) + + parsViscous = {'nLe': 20, 'nTe': 8, 'nMid': 40, 'nSpan': 60, 'nWake': 20} + #vMsh = viscUtils.mesh(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/models/dart/onera_visc.geo', parsViscous) + #vcfg['vMsh'] = vMsh + + tms['pre'].start() + coupler, isol, vsol = viscUtils.initBlast(icfg, vcfg) + tms['pre'].stop() + + print(ccolors.ANSI_BLUE + 'PySolving...' + ccolors.ANSI_RESET) + tms['solver'].start() + aeroCoeffs = coupler.run() + tms['solver'].stop() + + # Display results. + print(ccolors.ANSI_BLUE + 'PyRes...' + ccolors.ANSI_RESET) + print(' Re M alpha Cl Cd Cdp Cdf Cm') + print('{0:6.1f}e6 {1:8.2f} {2:8.1f} {3:8.4f} {4:8.4f} {5:8.4f} {6:8.4f} {7:8.4f}'.format(vcfg['Re']/1e6, isol.getMinf(), isol.getAoA()*180/math.pi, isol.getCl(), vsol.Cdt, vsol.Cdp, vsol.Cdf, isol.getCm())) + + # Write results to file. + vSolution = viscUtils.getSolution(isol.sec, write=True, toW='all', sfx='onera') + + # Save pressure coefficient + isol.save(sfx='_viscous') + tms['total'].stop() + + print(ccolors.ANSI_BLUE + 'PyTiming...' + ccolors.ANSI_RESET) + print('CPU statistics') + print(tms) + print('SOLVERS statistics') + print(coupler.tms) + + # Test solution + print(ccolors.ANSI_BLUE + 'PyTesting...' + ccolors.ANSI_RESET) + tests = CTests() + tests.add(CTest('Cl', isol.getCl(), 0.279, 5e-2)) + tests.add(CTest('Cd wake', vsol.Cdt, 0.00471, 1e-3, forceabs=True)) + tests.add(CTest('Cd int', isol.getCd() + vsol.Cdf, 0.01519, 1e-3, forceabs=True)) + tests.add(CTest('Iterations', len(aeroCoeffs['Cl']), 13, 0, forceabs=True)) + tests.run() + + # eof + print('') + +if __name__ == "__main__": + main()