Mirror case for ground effect¶

The ground (in case one speaks about the ground effect) is not a free surface, so we can safely use mirror assumptions. To use a ground, set setup(Mirror=1) and be wary of your definition of aoa and airfoil position. The ground is a ray through the origin in the direction of the free flow, and you can put the airfoil above or below it, either way the flow is mirrored.

Regarding validation: I chose the data in [1] for an airfoil intended for race cars and set Ncrit to a larger value to make it coincide with the measured data better.

In [1]:
import viiflow as vf
import viiflowtools.vf_tools as vft
import viiflowtools.vf_plots as vfp
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'

# Read Airfoil Data
N = 180
AF = vft.repanel(vft.read_selig("Tyrell026m.csv")[:,::-1],N)
ExpData = np.genfromtxt("TyrellPressure1deg.csv",delimiter=";")
colors = ["tab:blue","tab:orange","tab:green","tab:red","tab:purple","tab:pink","tab:olive"]
results = {} # Dictionary of results
heights = np.asarray([np.inf,.671, .313, .179, .134,.090, .067])-np.min(AF[1,:])
AOARange = [0.0]

for h in heights:
    # Settings
    ncrit = 12
    Mach = .087
    s = vf.setup(Re=4.6e5,Ma=Mach,Ncrit=ncrit,Alpha=AOARange[0],IterateWakes=False,Silent=True,Mirror=1 if np.isfinite(h) else 0)

    results[h] = {} # Sub-Dictionary of results
    results[h]["AOA"] = []
    results[h]["CL"] = []
    results[h]["CD"] = []
    results[h]["CP"] = []
    # Go over AOA range
    faults = 0
    init = True
    for alpha in AOARange:

        # Set current alpha and set res/grad to None to tell viiflow that they are not valid
        s.Alpha = alpha
        res = None
        grad = None

        # Set-up and initialize based on inviscid panel solution
        # This calculates panel operator
        AFC = AF.copy()
        if np.isfinite(h):
            AFC[1,:] += np.cos(alpha*np.pi/180)*h # Move TE wrt free flow
            AFC[0,:] += -np.sin(alpha*np.pi/180)*h # Move TE wrt free flow
        [p,bl,x] = vf.init([AFC],s)

        # Run viiflow
        [x,flag,res,grad,_] = vf.iter(x,bl,p,s,res,grad)
        # If converged add to cl/cd vectors (could check flag as well, but this allows custom tolerance 
        # to use the results anyways)
        if flag:
            results[h]["AOA"].append(alpha)
            results[h]["CL"].append(p.CL)
            results[h]["CD"].append(bl[0].CD)
            results[h]["CP"].append(1.0-np.power(p.gamma_viscid,2.0))
            faults = 0
        else:
            faults+=1
            init = True

        # Skip current polar if 4 unconverged results in a row
        if faults>3:
            print("Exiting RE %u polar calculation at AOA %f°"%(RE,alpha))
            break
In [2]:
matplotlib.rcParams['figure.figsize'] = [12, 6]
fig,ax = plt.subplots(1,1)
for cnt in range(len(heights)):
    h = heights[cnt]
    ax.plot(AFC[0,:],-results[h]["CP"][0][0:N],color = colors[cnt],label="h=%3.3g"%(heights[cnt]+np.min(AF[1,:])))
    ax.plot((ExpData[:,2*cnt]-.05)/.95,-ExpData[:,2*cnt+1],'.',color = colors[cnt])
    ax.grid(1)
    ax.set_ylim([-1,5])
    cnt+=1
    ax.legend()
No description has been provided for this image

[6] Zerihan, Jonathan. An investigation into the aerodynamics of wings in ground effect. Diss. University of Southampton, 2001.