Exemplo n.º 1
0
 def run_trim(self,fc):
     self.create_input_file()
     self.avl = AVL()
     self.run_avl(fc)
     result = self._process_output()
     result.CD0 = float(fc.CD0)
     result.SM = float((result.xNP - fc.cg[0])/fc.Lref)
     self.avl.terminate()
     return result
Exemplo n.º 2
0
 def run_single_point(self,fc,alpha=0,beta=0,elevator=0):
     alpha    = float(alpha)
     beta     = float(beta)
     elevator = float(elevator)
     self.create_input_file()
     self.avl = AVL()
     self.run_avl(fc,False,alpha,beta,elevator)
     result = self._process_output()
     result.CD0 = float(fc.CD0)
     result.SM = float((result.xNP - fc.cg[0])/fc.Lref)
     self.avl.terminate()
     return result
Exemplo n.º 3
0
class AVLsolver(object):
    def __init__(self,aircraft):
        self.ac = aircraft

    def create_input_file(self):
        """
        basic terms
        wing configuration
        control surface - ELEVATOR only for now
        weight and CG
        """
        pth.set_file_prefix('flyingwing')
        path = pth.get_tmp_file('avl')
        cg = self.ac.get_cg()
        CD0 = self.ac.get_drag()
        fid = open(path,'wt')
        # general input
        fid.write('%s\n'%self.ac.name)
        fid.write('0.0\n')
        fid.write('0  0  0.0\n')
        fid.write('%.4f  %.4f  %.4f\n'%(self.ac.wing.area,self.ac.wing.MAC,self.ac.wing.span))
        fid.write('%.4f  %.4f  %.4f\n'%(cg[0],cg[1],cg[2]))
        fid.write('%.8f\n'%CD0)
        # wing input
        fid.write('SURFACE\n')
        fid.write('WING\n')
        fid.write('%d  0  %d  0\n'%(self.ac.vlm.panelsChordwise, self.ac.vlm.panelsSpanwise))
        fid.write('YDUPLICATE\n0\n')
        for i in range(self.ac.wing.nSec):
            fid.write('#--- section %d ---\n'%(i+1))
            pathAf = pth.get_tmp_file('txt','af%d'%(i+1))
            self.ac.wing.airfoils[i].write_txt(pathAf)
            apex = self.ac.wing.secApex[i]
            chord = self.ac.wing.chords[i]
            angle = self.ac.wing.secAngles[i]
            fid.write('SECTION\n')
            fid.write('%.6f  %.6f  %.6f  %.6f  %.6f\n'%(apex[0],apex[1],apex[2],chord,angle))
            fid.write('AFIL\n%s\n'%pathAf)
            fid.write('CONTROL\n')
            fid.write('elevator  1.0  %.4f  0  0  0  +1\n'%(self.ac.wing.elevon.location[i]))
        fid.close()
    
    def run_trim(self,fc):
        self.create_input_file()
        self.avl = AVL()
        self.run_avl(fc)
        result = self._process_output()
        result.CD0 = float(fc.CD0)
        result.SM = float((result.xNP - fc.cg[0])/fc.Lref)
        self.avl.terminate()
        return result

    def run_single_point(self,fc,alpha=0,beta=0,elevator=0):
        alpha    = float(alpha)
        beta     = float(beta)
        elevator = float(elevator)
        self.create_input_file()
        self.avl = AVL()
        self.run_avl(fc,False,alpha,beta,elevator)
        result = self._process_output()
        result.CD0 = float(fc.CD0)
        result.SM = float((result.xNP - fc.cg[0])/fc.Lref)
        self.avl.terminate()
        return result

    def run_avl(self,fc,runTrim=True,alpha=0,beta=0,elevator=0):
        self.avl.cmd('LOAD\n%s'%pth.get_tmp_file('avl'))
        self.avl.cmd('OPER')
        self.avl.cmd('O')
        self.avl.cmd('P')
        self.avl.cmd('T,T,T,T')
        self.avl.cmd('H')
        self.avl.cmd('D')
        self.avl.cmd(' ')
        self.avl.cmd('M')
        self.avl.cmd('M')
        self.avl.cmd(fc.mass*fc.loadFactor)
        self.avl.cmd('MN')
        self.avl.cmd(fc.Mach)
        self.avl.cmd('V')
        self.avl.cmd(fc.velocity)
        self.avl.cmd('D')
        self.avl.cmd(fc.atm.density)
        self.avl.cmd('G')
        self.avl.cmd(fc.g)
        self.avl.cmd('CD')
        self.avl.cmd(fc.CD0)
        self.avl.cmd('IX')
        self.avl.cmd(fc.inertia[0])
        self.avl.cmd('IY')
        self.avl.cmd(fc.inertia[1])
        self.avl.cmd('IZ')
        self.avl.cmd(fc.inertia[2])
        self.avl.cmd('X')
        self.avl.cmd(fc.cg[0])
        self.avl.cmd('Y')
        self.avl.cmd(fc.cg[1])
        self.avl.cmd('Z')
        self.avl.cmd(fc.cg[2])
        self.avl.cmd(' ')
        self.avl.cmd('C1')
        self.avl.cmd('V')
        self.avl.cmd(fc.velocity)
        self.avl.cmd('M')
        self.avl.cmd(fc.mass*fc.loadFactor)
        self.avl.cmd('D')
        self.avl.cmd(fc.atm.density)
        self.avl.cmd('G')
        self.avl.cmd(fc.g)
        self.avl.cmd('X')
        self.avl.cmd(fc.cg[0])
        self.avl.cmd('Y')
        self.avl.cmd(fc.cg[1])
        self.avl.cmd('Z')
        self.avl.cmd(fc.cg[2]) 
        self.avl.cmd(' ')
        # --- set trim constraints ---
        if runTrim:
            CLreq = fc.get_CLreq()
            self.avl.cmd('A')
            self.avl.cmd('C')
            self.avl.cmd(CLreq)
            self.avl.cmd('D1') # elevator
            self.avl.cmd('PM')
            self.avl.cmd(fc.CmTrim)
        else:
            self.avl.cmd('A')
            self.avl.cmd('A')
            self.avl.cmd(alpha)
            self.avl.cmd('B')
            self.avl.cmd('B')
            self.avl.cmd(beta)
            self.avl.cmd('D1')
            self.avl.cmd('D1')
            self.avl.cmd(elevator)
        # --- run analysis ---
        self.avl.cmd('X')
        self.avl.cmd('ST')
        self.avl.cmd(' ')
        # --- system matrix ---
        #FIXME: dynamic output crashes AVL
#        self.avl.cmd(' ')
#        self.avl.cmd('mode')
#        self.avl.cmd('S')
        self.avl.cmd(' ')
        self.avl.cmd('QUIT')
    
    def _process_output(self):
        result = AVLresults(['e'])
        rawOutput = self.avl.get_output()
        coefficientsRaw=self._split_results(rawOutput,'Enter filename, or <return> for screen output   s>',' Neutral point  Xnp =',12)      
        result = self._set_coefficients(coefficientsRaw,result)
        result = self._set_derivatives(coefficientsRaw,result)
        return result

    def _set_coefficients(self,raw,results):
        results.alpha=self._selTxt(raw,'Alpha =','pb/2V')
        results.beta =self._selTxt(raw,'Beta  =','qc/2V')
        results.Mach =self._selTxt(raw,'Mach  =','rb/2V')
        results.Sref =self._selTxt(raw,'Sref =','Cref =')
        results.Cref =self._selTxt(raw,'Cref =','Bref =')
        results.Bref =self._selTxt(raw,'Bref =','    \n  Xref')
        results.ARref=results.Bref**2/results.Sref
        results.coef.CX=self._selTxt(raw,'CXtot =','Cltot =')
        results.coef.CY=self._selTxt(raw,'CYtot =','Cmtot =')
        results.coef.CZ=self._selTxt(raw,'CZtot =','Cntot =')
        results.coef.Cl=self._selTxt(raw,'Cltot =','Cl\'tot =')
        results.coef.Cm=self._selTxt(raw,'Cmtot =','\n  CZtot =')
        results.coef.Cn=self._selTxt(raw,'Cntot =','Cn\'tot =')
        results.coef.CL=self._selTxt(raw,'CLtot =','\n  CDtot')
        results.coef.CD=self._selTxt(raw,'CDtot =','\n  CDvis')
        results.coef.CDind=self._selTxt(raw,'CDff  =','\| Trefftz\n  CYff ')
        results.k=results.coef.CDind/(results.coef.CL**2)    
        results.e=1.0/(results.k*np.pi*results.ARref)       
        results.a=self._selTxt(raw,'CLa =','CLb =')
        results.xNP=self._selNum(raw,'Neutral point  Xnp =   ',10)
        results.CL0=results.coef.CL-results.a*np.pi/180*results.alpha
        results.elevator=self._selNum(raw,'elevator        =',10)
        return results

    def _set_derivatives(self,raw,results):
        results.derivs.CLa=self._selTxt(raw,'CLa =','CLb =')            
        results.derivs.CYa=self._selTxt(raw,'CYa =','CYb =')
        results.derivs.Cla=self._selTxt(raw,'Cla =','Clb =')
        results.derivs.Cma=self._selTxt(raw,'Cma =','Cmb =')
        results.derivs.Cna=self._selTxt(raw,'Cna =','Cnb =')
        
        results.derivs.CLb=self._selNum(raw,'CLb =',11)
        results.derivs.CYb=self._selNum(raw,'CYb =',11)            
        results.derivs.Clb=self._selNum(raw,'Clb =',11)
        results.derivs.Cmb=self._selNum(raw,'Cmb =',11)
        results.derivs.Cnb=self._selNum(raw,'Cnb =',11)            
        
        results.derivs.CLp=self._selTxt(raw,'CLp =','CLq =')      
        results.derivs.CYp=self._selTxt(raw,'CYp =','CYq =')      
        results.derivs.Clp=self._selTxt(raw,'Clp =','Clq =')      
        results.derivs.Cmp=self._selTxt(raw,'Cmp =','Cmq =')      
        results.derivs.Cnp=self._selTxt(raw,'Cnp =','Cnq =')                  
        
        results.derivs.CLp=self._selTxt(raw,'CLq =','CLr =')  
        results.derivs.CLq=self._selTxt(raw,'CYq =','CYr =')  
        results.derivs.CYq=self._selTxt(raw,'Clq =','Clr =')  
        results.derivs.Cmq=self._selTxt(raw,'Cmq =','Cmr =')  
        results.derivs.Cnq=self._selTxt(raw,'Cnq =','Cnr =')  

        results.derivs.CLr=self._selNum(raw,'CLr =',11)
        results.derivs.CYr=self._selNum(raw,'CYr =',11)
        results.derivs.Clr=self._selNum(raw,'Clr =',11)
        results.derivs.Cmr=self._selNum(raw,'Cmr =',11)
        results.derivs.Cnr=self._selNum(raw,'Cnr =',11)

        results.derivs.CLde=self._selNum(raw,'CLd1 =',11)
        results.derivs.CYde=self._selNum(raw,'CYd1 =',11)
        results.derivs.Clde=self._selNum(raw,'Cld1 =',11)
        results.derivs.Cmde=self._selNum(raw,'Cmd1 =',11)
        results.derivs.Cnde=self._selNum(raw,'Cnd1 =',11)
        results.derivs.CDfe=self._selNum(raw,'CDffd1 =',11)
        results.derivs.ede =self._selNum(raw,'ed1 =',11)
        return results

    def _split_results(self,source,fromStr1,toStr2,offset=0):
        a=self._findall(source,fromStr1)
        b=self._findall(source,toStr2)
        return source[a[1]:b[1]+offset]

    def _selTxt(self,source,fromStr1,toStr2=-1):
        a=self._findall(source,fromStr1)
        b=self._findall(source,toStr2)
        num=source[a[1]:b[0]]
        return float(num)

    def _findall(self,source,string):
        out = [(a.start(), a.end()) for a in list(re.finditer(string, source))]
        return out[0]
        
    def _selNum(self,source,fromStr,num):
        a=self._findall(source,fromStr)
        val=source[a[1]:a[1]+num]
        return float(val)

    def set_flight_conditions(self,flightConditions):
        pass
Exemplo n.º 4
0
class AVLsolver(object):
    def __init__(self, aircraft):
        self.ac = aircraft

    def create_input_file(self):
        """
        basic terms
        wing configuration
        control surface - ELEVATOR only for now
        weight and CG
        """
        # pth.set_file_prefix('flyingwing')
        pth.set_file_prefix_random()
        path = pth.get_tmp_file("avl")
        cg = self.ac.get_cg()
        CD0 = self.ac.get_drag()
        fid = open(path, "wt")
        # general input
        fid.write("%s\n" % self.ac.name)
        fid.write("0.0\n")
        fid.write("0  0  0.0\n")
        fid.write("%.6f  %.6f  %.6f\n" % (self.ac.wing.area, self.ac.wing.MAC, self.ac.wing.span))
        fid.write("%.6f  %.6f  %.6f\n" % (cg[0], cg[1], cg[2]))
        fid.write("%.8f\n" % CD0)
        # wing input
        fid.write("SURFACE\n")
        fid.write("WING\n")
        fid.write("%d  0  %d  0\n" % (self.ac.vlm.panelsChordwise, self.ac.vlm.panelsSpanwise))
        fid.write("YDUPLICATE\n0\n")
        for i in range(self.ac.wing.nSec):
            fid.write("#--- section %d ---\n" % (i + 1))
            pathAf = pth.get_tmp_file("txt", "af%d" % (i + 1))
            self.ac.wing.airfoils[i].write_txt(pathAf)
            apex = self.ac.wing.secApex[i]
            chord = self.ac.wing.chords[i]
            angle = self.ac.wing.secAngles[i]
            fid.write("SECTION\n")
            fid.write("%.12f  %.12f  %.12f  %.12f  %.12f\n" % (apex[0], apex[1], apex[2], chord, angle))
            fid.write("AFIL\n%s\n" % pathAf)
            fid.write("CONTROL\n")
            fid.write("elevator  1.0  %.8f  0  0  0  +1\n" % (self.ac.wing.elevon.location[i]))
        fid.close()

    def run_trim(self, fc):
        self.create_input_file()
        self.avl = AVL()
        self.run_avl(fc)
        result = self._process_output()
        result.CD0 = float(fc.CD0)
        result.SM = float((result.xNP - fc.cg[0]) / fc.Lref)
        self.avl.terminate()
        # pth.clean_temp_files()
        return result

    def run_single_point(self, fc, alpha=0, beta=0, elevator=0):
        alpha = float(alpha)
        beta = float(beta)
        elevator = float(elevator)
        self.create_input_file()
        self.avl = AVL()
        self.run_avl(fc, False, alpha, beta, elevator)
        result = self._process_output()
        result.CD0 = float(fc.CD0)
        result.SM = float((result.xNP - fc.cg[0]) / fc.Lref)
        self.avl.terminate()
        # pth.clean_temp_files()
        return result

    def run_avl(self, fc, runTrim=True, alpha=0, beta=0, elevator=0):
        self.avl.cmd("LOAD\n%s" % pth.get_tmp_file("avl"))
        self.avl.cmd("OPER")
        self.avl.cmd("O")
        self.avl.cmd("P")
        self.avl.cmd("T,T,T,T")
        self.avl.cmd("H")
        self.avl.cmd("D")
        self.avl.cmd(" ")
        self.avl.cmd("M")
        self.avl.cmd("M")
        self.avl.cmd(fc.mass * fc.loadFactor)
        self.avl.cmd("MN")
        self.avl.cmd(fc.Mach)
        self.avl.cmd("V")
        self.avl.cmd(fc.velocity)
        self.avl.cmd("D")
        self.avl.cmd(fc.atm.density)
        self.avl.cmd("G")
        self.avl.cmd(fc.g)
        self.avl.cmd("CD")
        self.avl.cmd(fc.CD0)
        self.avl.cmd("IX")
        self.avl.cmd(fc.inertia[0])
        self.avl.cmd("IY")
        self.avl.cmd(fc.inertia[1])
        self.avl.cmd("IZ")
        self.avl.cmd(fc.inertia[2])
        self.avl.cmd("X")
        self.avl.cmd(fc.cg[0])
        self.avl.cmd("Y")
        self.avl.cmd(fc.cg[1])
        self.avl.cmd("Z")
        self.avl.cmd(fc.cg[2])
        self.avl.cmd(" ")
        self.avl.cmd("C1")
        self.avl.cmd("V")
        self.avl.cmd(fc.velocity)
        self.avl.cmd("M")
        self.avl.cmd(fc.mass * fc.loadFactor)
        self.avl.cmd("D")
        self.avl.cmd(fc.atm.density)
        self.avl.cmd("G")
        self.avl.cmd(fc.g)
        self.avl.cmd("X")
        self.avl.cmd(fc.cg[0])
        self.avl.cmd("Y")
        self.avl.cmd(fc.cg[1])
        self.avl.cmd("Z")
        self.avl.cmd(fc.cg[2])
        self.avl.cmd(" ")
        # --- set trim constraints ---
        if runTrim:
            CLreq = fc.get_CLreq()
            self.avl.cmd("A")
            self.avl.cmd("C")
            self.avl.cmd(CLreq)
            self.avl.cmd("D1")  # elevator
            self.avl.cmd("PM")
            self.avl.cmd(fc.CmTrim)
        else:
            self.avl.cmd("A")
            self.avl.cmd("A")
            self.avl.cmd(alpha)
            self.avl.cmd("B")
            self.avl.cmd("B")
            self.avl.cmd(beta)
            self.avl.cmd("D1")
            self.avl.cmd("D1")
            self.avl.cmd(elevator)
        # --- run analysis ---
        self.avl.cmd("X")
        self.avl.cmd("ST")
        self.avl.cmd(" ")
        # --- system matrix ---
        # FIXME: dynamic output crashes AVL
        #        self.avl.cmd(' ')
        #        self.avl.cmd('mode')
        #        self.avl.cmd('S')
        self.avl.cmd(" ")
        self.avl.cmd("QUIT")

    def _process_output(self):
        result = AVLresults(["e"])
        rawOutput = self.avl.get_output()
        coefficientsRaw = self._split_results(
            rawOutput, "Enter filename, or <return> for screen output   s>", " Neutral point  Xnp =", 24
        )
        coefficientsRaw = coefficientsRaw.split()
        result = self._set_coefficients(coefficientsRaw, result)
        result = self._set_derivatives(coefficientsRaw, result)
        return result

    def _set_coefficients(self, raw, results):
        results.alpha = self._get_value(raw, "Alpha")
        results.beta = self._get_value(raw, "Beta")
        results.Mach = self._get_value(raw, "Mach")
        results.Sref = self._get_value(raw, "Sref")
        results.Cref = self._get_value(raw, "Cref")
        results.Bref = self._get_value(raw, "Bref")
        results.ARref = results.Bref ** 2 / results.Sref
        results.coef.CX = self._get_value(raw, "CXtot")
        results.coef.CY = self._get_value(raw, "CYtot")
        results.coef.CZ = self._get_value(raw, "CZtot")
        results.coef.Cl = self._get_value(raw, "Cltot")
        results.coef.Cm = self._get_value(raw, "Cmtot")
        results.coef.Cn = self._get_value(raw, "Cntot")
        results.coef.CL = self._get_value(raw, "CLtot")
        results.coef.CD = self._get_value(raw, "CDtot")
        results.LD = results.coef.CL / results.coef.CD
        results.coef.CDind = self._get_value(raw, "CDind")
        results.k = results.coef.CDind / (results.coef.CL ** 2)
        results.e = 1.0 / (results.k * np.pi * results.ARref)
        results.a = self._get_value(raw, "CLa")
        results.xNP = self._get_value(raw, "Xnp")
        results.CL0 = results.coef.CL - results.a * np.pi / 180 * results.alpha
        results.elevator = self._get_value(raw, "elevator")
        return results

    def _set_derivatives(self, raw, results):
        results.derivs.CLa = self._get_value(raw, "CLa")
        results.derivs.CYa = self._get_value(raw, "CYa")
        results.derivs.Cla = self._get_value(raw, "Cla")
        results.derivs.Cma = self._get_value(raw, "Cma")
        results.derivs.Cna = self._get_value(raw, "Cna")

        results.derivs.CLb = self._get_value(raw, "CLb")
        results.derivs.CYb = self._get_value(raw, "CYb")
        results.derivs.Clb = self._get_value(raw, "Clb")
        results.derivs.Cmb = self._get_value(raw, "Cmb")
        results.derivs.Cnb = self._get_value(raw, "Cnb")

        results.derivs.CLp = self._get_value(raw, "CLp")
        results.derivs.CYp = self._get_value(raw, "CYp")
        results.derivs.Clp = self._get_value(raw, "Clp")
        results.derivs.Cmp = self._get_value(raw, "Cmp")
        results.derivs.Cnp = self._get_value(raw, "Cnp")

        results.derivs.CLp = self._get_value(raw, "CLq")
        results.derivs.CLq = self._get_value(raw, "CYq")
        results.derivs.CYq = self._get_value(raw, "Clq")
        results.derivs.Cmq = self._get_value(raw, "Cmq")
        results.derivs.Cnq = self._get_value(raw, "Cnq")

        results.derivs.CLr = self._get_value(raw, "CLr")
        results.derivs.CYr = self._get_value(raw, "CYr")
        results.derivs.Clr = self._get_value(raw, "Clr")
        results.derivs.Cmr = self._get_value(raw, "Cmr")
        results.derivs.Cnr = self._get_value(raw, "Cnr")

        results.derivs.CLde = self._get_value(raw, "CLd1")
        results.derivs.CYde = self._get_value(raw, "CYd1")
        results.derivs.Clde = self._get_value(raw, "Cld1")
        results.derivs.Cmde = self._get_value(raw, "Cmd1")
        results.derivs.Cnde = self._get_value(raw, "Cnd1")
        results.derivs.CDde = self._get_value(raw, "CDffd1")
        results.derivs.ede = self._get_value(raw, "ed1")
        return results

    def _split_results(self, source, fromStr1, toStr2, offset=0):
        a = self._findall(source, fromStr1)
        b = self._findall(source, toStr2)
        return source[a[1] : b[1] + offset]

    def _selTxt(self, source, fromStr1, toStr2=-1):
        a = self._findall(source, fromStr1)
        b = self._findall(source, toStr2)
        num = source[a[1] : b[0]]
        return float(num)

    def _findall(self, source, string):
        out = [(a.start(), a.end()) for a in list(re.finditer(string, source))]
        return out[0]

    def _selNum(self, source, fromStr, num):
        a = self._findall(source, fromStr)
        val = source[a[1] : a[1] + num]
        return float(val)

    def set_flight_conditions(self, flightConditions):
        pass

    def _get_value(self, raw, name, offset=2):
        idx = raw.index(name)
        val = raw[idx + 2]
        return float(val)