This little notebook compares viiflow and XFOIL runtimes for different panel densities of the S805 airfoil. It is not 100% fair, because
Note: These results were generated with a PC with a AMD Ryzen 3700 processor on a windows 10 64bit OS with numpy built with Intel MKL and the xfoil 6.99 binary version.
import os # For calling xfoil ''' Numpy (with MKL in this case) might want to use multiple threads to do linalg.solve. Solving 150x150->500x500 matrices with multiple cores it not super efficient, especially if your processor uses a higher clock if only one core is used. And even if it would be faster with multiple cores, it would not be fair to compare these results with single-core using XFOIL. ''' #os.environ["OMP_NUM_THREADS"] = "1" os.environ["MKL_NUM_THREADS"] = "1" # viiflow imports import viiflow as vf import viiflowtools.vf_tools as vft import numpy as np import time # For timing # For plotting at the end import matplotlib.pyplot as plt %matplotlib inline %config InlineBackend.figure_format = 'svg' import matplotlib
NVEC = np.arange(100,500,10) # Panel densities to compare # AOA Sweep AOA0 = -5 AOAE = 16 DAOA = .5 RE = 1e6 # Reynolds Number maxiter = 50 # maximum iterations for both methods FOIL = "S805b.dat" # Container for results elapsedXF= elapsedVF= for N in NVEC: ## Build correct file with N panels by XFOIL, compare both solvers with this file # Make XFOIL command com = "load %s\nPPAR\nN %u\n\n\nsave tmpfoil.dat\ny\n"%(FOIL,N) # Save Xfoil Command with open('xfcom.inp', 'w') as f: print(com,file=f) f.close() # Run XFOIL os.system("xfoil < xfcom.inp > xf.out") ## XFOIL # Make XFOIL command com = "load %s\nOPER\nv %u\nITER %u\nASEQ %f %f %f\n\nquit\n"%('tmpfoil.dat',RE,maxiter,AOA0,AOAE,DAOA) #com = "load %s\nOPER\nv %u\nITER %u\nASEQ %f %f %f\n\nquit\n"%('tmpfoil.dat',RE,maxiter,AOA0,AOA0,DAOA) # Save Xfoil Command with open('xfcom.inp', 'w') as f: print(com,file=f) f.close() # Run XFOIL t = time.time() os.system("xfoil < xfcom.inp > xf.out") elapsedXF.append(time.time() - t) # Check for convergence f = open("xf.out", "r") lines = f.readlines() f.close() xf_unconverged=0 for line in lines: if line.startswith(" VISCAL: Convergence failed"): xf_unconverged+=1 ## viiflow s = vf.setup(Re=RE,Ma=0.0,Ncrit=9.0,Alpha=AOA0) s.Silent = True # Do not output residual/iterations internally s.Itermax = maxiter t = time.time() # Set-up and initialize based on inviscid panel solution # This calculates panel operator [p,bl,x] = vf.init(vft.read_selig('tmpfoil.dat'),s) #vf.set_forced_transition(bl,p,[0.5],[0.5]) vf_unconverged = 0 for alpha in np.arange(AOA0,AOAE+DAOA,DAOA): # Set current alpha and set res/grad to None to tell viiflow that they are not valid s.Alpha = alpha res = None grad = None # Run viiflow [x,flag,res,_,_] = vf.iter(x,bl,p,s,res,grad) # Print if not converged if flag<=0: #print('Not converged at AL: %f' % alpha) vf_unconverged+=1 elapsedVF.append(time.time() - t) time.sleep(.1) # Print comparison print("N: %u XF: %5.5ss (%u failed) VF:%5.5ss (%u failed)"%(N,elapsedXF[-1],xf_unconverged,elapsedVF[-1],vf_unconverged))
N: 100 XF: 0.646s (1 failed) VF:0.413s (0 failed)
WARNING:ibl.ibl_classes:solve_delta: laminar bl solve failed (Iterations exceeded) at iter=249 xi=0.106134,delta=0.000350,theta=0.000158,ue=1.803983,n/ct=8.465907
N: 110 XF: 0.758s (1 failed) VF:0.475s (0 failed) N: 120 XF: 0.934s (2 failed) VF:0.495s (0 failed) N: 130 XF: 1.267s (3 failed) VF:0.553s (0 failed) N: 140 XF: 1.026s (0 failed) VF:0.603s (0 failed) N: 150 XF: 1.460s (2 failed) VF:0.685s (0 failed) N: 160 XF: 1.399s (0 failed) VF:0.756s (0 failed) N: 170 XF: 1.826s (1 failed) VF:0.835s (0 failed) N: 180 XF: 1.830s (0 failed) VF:0.874s (0 failed) N: 190 XF: 2.274s (1 failed) VF:0.969s (0 failed) N: 200 XF: 3.159s (2 failed) VF:1.053s (0 failed) N: 210 XF: 3.082s (1 failed) VF:1.106s (0 failed) N: 220 XF: 3.418s (1 failed) VF:1.198s (0 failed) N: 230 XF: 4.511s (2 failed) VF:1.297s (0 failed) N: 240 XF: 3.751s (0 failed) VF:1.348s (0 failed) N: 250 XF: 4.677s (1 failed) VF:1.480s (0 failed) N: 260 XF: 6.022s (2 failed) VF:1.678s (0 failed) N: 270 XF: 5.069s (0 failed) VF:1.819s (0 failed) N: 280 XF: 5.819s (0 failed) VF:1.858s (0 failed) N: 290 XF: 7.928s (2 failed) VF:1.982s (0 failed) N: 300 XF: 8.760s (2 failed) VF:2.091s (0 failed)
WARNING:ibl.ibl_classes:solve_delta: wake bl solve failed (Iterations exceeded) at iter=249 xi=1.035958,delta=0.021720,theta=0.008342,ue=0.914215,n/ct=0.057893
N: 310 XF: 7.783s (0 failed) VF:2.306s (0 failed) N: 320 XF: 8.156s (0 failed) VF:2.485s (0 failed) N: 330 XF: 9.980s (1 failed) VF:2.865s (0 failed) N: 340 XF: 10.73s (1 failed) VF:2.886s (0 failed) N: 350 XF: 12.86s (2 failed) VF:3.015s (0 failed) N: 360 XF: 12.72s (1 failed) VF:3.218s (0 failed) N: 370 XF: 15.25s (2 failed) VF:3.393s (0 failed) N: 380 XF: 15.36s (1 failed) VF:3.583s (0 failed) N: 390 XF: 13.13s (0 failed) VF:3.890s (0 failed) N: 400 XF: 18.49s (1 failed) VF:4.027s (0 failed) N: 410 XF: 18.58s (1 failed) VF:5.116s (0 failed) N: 420 XF: 17.54s (0 failed) VF:5.139s (0 failed) N: 430 XF: 16.94s (0 failed) VF:5.317s (0 failed) N: 440 XF: 18.96s (0 failed) VF:5.654s (0 failed) N: 450 XF: 21.18s (1 failed) VF:5.822s (0 failed) N: 460 XF: 20.31s (0 failed) VF:6.039s (0 failed) N: 470 XF: 21.29s (0 failed) VF:6.275s (0 failed) N: 480 XF: 41.92s (5 failed) VF:6.315s (0 failed) N: 490 XF: 36.48s (3 failed) VF:6.533s (0 failed)
matplotlib.rcParams['figure.figsize'] = [11, 6] # Make plots bigger than default n = len(elapsedVF) plt.plot(NVEC[0:n],elapsedVF,'-o') plt.plot(NVEC[0:n],elapsedXF,'-o') plt.legend(["viiflow","xfoil"]) plt.xlabel("Panels") plt.ylabel("Runtime [s]") plt.grid(1) plt.ylim([0,30]) plt.xlim([90,500]);
The runtime difference increases with increasing panel density. This is to be expected. XFOIL needs to solve a system of 3xNP linear equations at every Newton step, while viiflow only needs to solve a 1xNP system.