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" # 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\nPPAR\nN %u\n\n\nOPER\nv %u\nITER %u\nASEQ %f %f %f\n\nquit\n"%(FOIL,N,RE,maxiter,AOA0,AOAE,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) # Print comparison print("N: %u XF: %ss (%u failed) VF:%ss (%u failed)"%(N,elapsedXF[-1],xf_unconverged,elapsedVF[-1],vf_unconverged))
N: 100 XF: 0.6840565204620361s (1 failed) VF:0.4509720802307129s (1 failed) N: 110 XF: 0.8090767860412598s (1 failed) VF:0.6107149124145508s (3 failed) N: 120 XF: 0.987072229385376s (2 failed) VF:0.5428211688995361s (1 failed) N: 130 XF: 1.3206274509429932s (3 failed) VF:0.7539196014404297s (2 failed) N: 140 XF: 1.0725908279418945s (0 failed) VF:0.7836699485778809s (0 failed) N: 150 XF: 1.4965541362762451s (2 failed) VF:0.9116747379302979s (2 failed) N: 160 XF: 1.4344885349273682s (0 failed) VF:0.9375636577606201s (1 failed) N: 170 XF: 1.8785781860351562s (1 failed) VF:0.8217780590057373s (0 failed) N: 180 XF: 1.8888545036315918s (0 failed) VF:0.905815839767456s (0 failed) N: 190 XF: 2.3515498638153076s (1 failed) VF:0.9942631721496582s (0 failed) N: 200 XF: 3.2534189224243164s (2 failed) VF:1.0221242904663086s (0 failed) N: 210 XF: 3.158205509185791s (1 failed) VF:1.1898548603057861s (1 failed) N: 220 XF: 3.5119223594665527s (1 failed) VF:1.2976555824279785s (1 failed) N: 230 XF: 4.639565706253052s (2 failed) VF:1.3758230209350586s (1 failed) N: 240 XF: 3.8558478355407715s (0 failed) VF:1.4716238975524902s (0 failed) N: 250 XF: 4.7753746509552s (1 failed) VF:1.8444180488586426s (4 failed) N: 260 XF: 6.143416166305542s (2 failed) VF:1.7637889385223389s (2 failed) N: 270 XF: 5.0885703563690186s (0 failed) VF:1.9054648876190186s (2 failed) N: 280 XF: 5.897143363952637s (0 failed) VF:2.401510238647461s (4 failed) N: 290 XF: 8.024919748306274s (2 failed) VF:1.9039840698242188s (1 failed) N: 300 XF: 8.888514518737793s (2 failed) VF:2.073086738586426s (1 failed) N: 310 XF: 7.894554853439331s (0 failed) VF:2.2025375366210938s (0 failed) N: 320 XF: 8.397767066955566s (0 failed) VF:2.8669490814208984s (3 failed) N: 330 XF: 10.157093048095703s (1 failed) VF:2.5303802490234375s (1 failed) N: 340 XF: 10.905655860900879s (1 failed) VF:2.915362596511841s (1 failed) N: 350 XF: 13.024067163467407s (2 failed) VF:3.0321521759033203s (1 failed) N: 360 XF: 12.858458280563354s (1 failed) VF:3.4022679328918457s (2 failed) N: 370 XF: 15.392263174057007s (2 failed) VF:3.7118754386901855s (3 failed) N: 380 XF: 15.433239221572876s (1 failed) VF:3.426685333251953s (1 failed) N: 390 XF: 13.310844898223877s (0 failed) VF:4.13565993309021s (3 failed) N: 400 XF: 18.624763011932373s (1 failed) VF:4.071928977966309s (2 failed) N: 410 XF: 18.685773849487305s (1 failed) VF:3.9360122680664062s (1 failed) N: 420 XF: 17.773574352264404s (0 failed) VF:4.77342414855957s (3 failed) N: 430 XF: 17.084173917770386s (0 failed) VF:4.321801424026489s (1 failed) N: 440 XF: 19.13869881629944s (0 failed) VF:5.573310375213623s (4 failed) N: 450 XF: 21.320847272872925s (1 failed) VF:4.657656908035278s (1 failed) N: 460 XF: 20.403927326202393s (0 failed) VF:5.4147257804870605s (2 failed) N: 470 XF: 21.391390085220337s (0 failed) VF:5.043872117996216s (1 failed) N: 480 XF: 41.83203840255737s (5 failed) VF:5.82550835609436s (2 failed) N: 490 XF: 36.53551530838013s (3 failed) VF:5.645160436630249s (1 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.