def implicitEuler(self, tend, step=None):
        if step is None:
            step = (tend - self.t0) / 1e3
        from ArrayTable import ArrayTable
        result = ArrayTable(2, 0)
        result.setTableHeader(["$t$", "y(t) solved with implicit euler"])
        result.setTableUnit(["/", "/"])
        result.append([self.t0, self.y0])
        t = self.t0
        while t < tend:
            temp = self.fun(t, result.table[1].data[-1])
            ynextinit = result.table[1].data[-1] + step / 2. * (
                temp +
                self.fun(t + step, result.table[1].data[-1] + temp * step))

            def func(w):
                return result.table[1].data[-1] + step * self.fun(t + step,
                                                                  w) - w

            ynext = ynextinit
            h = step / 10.
            while func(ynext) > 1.e-5:
                ynext -= func(ynext) / (
                    (func(ynext + h) - func(ynext - h)) / 2. / h)
            result.append([t + step, ynext])
            t += step
        return result
示例#2
0
    def __init__(self,
                 valveDiameter,
                 open_timing_angle,
                 close_timing_angle,
                 _valve_lift,
                 sigma=0,
                 rock=1,
                 _valve_flow_coeff=None):
        self.valve_diameter = valveDiameter
        self.open_timing_angle = open_timing_angle
        self.close_timing_angle = close_timing_angle
        self.sigma = sigma * math.pi / 180.
        open = _valve_lift.table[0].data[0]
        close = _valve_lift.table[0].data[-1]
        temp = (close_timing_angle - open_timing_angle) / (close - open)
        self.valve_lift = ArrayTable(2, 0)
        self.valve_lift.setTableUnit(["CA", "m"])
        self.valve_lift.setTableHeader(["Crank angle", "Valve lift"])
        for i in range(_valve_lift.row):
            self.valve_lift.append([
                self.open_timing_angle + temp *
                (_valve_lift.table[0].data[i] - _valve_lift.table[0].data[0]),
                _valve_lift.table[1].data[i] * rock
            ])

        self.flow_coeff = _valve_flow_coeff
        if _valve_flow_coeff is None:
            self.flow_coeff = ArrayTable(2, 0)
            self.flow_coeff.setTableHeader(["Crank angle", "Flow coefficient"])
            self.flow_coeff.setTableUnit(["CA", "/"])
            maxlift = self.valve_lift.findMaxValue(1)
            import numpy as np
            for i in np.arange(0, maxlift, 0.001):
                self.flow_coeff.append([i, self.__flowcoefficient(i)])
示例#3
0
    def __init__(self, _flowArea=1.):
        from ArrayTable import ArrayTable
        self.flowArea = _flowArea
        self.data = ArrayTable(2, 0)
        self.data.setTableHeader(["Pressure ratio", "Mass flow rate"])
        self.data.setTableUnit(["/", "kg/s"])

        # 连接关系
        self.next = None
        self.last = None
 def __init__(self, L0=14.3):
     self.L0 = L0
     # self.gf = gf
     from ArrayTable import ArrayTable
     self.data = ArrayTable(8, 0)
     self.data.setTableHeader([
         "已燃百分比", "缸内气体总质量", "空气质量", "废气质量", "已喷燃油量", "广义过量空气系数", "残余废气系数",
         "气体常数"
     ])
     self.data.setTableUnit(
         ["Fraction", "kg", "kg", "kg", "kg", "", "", "J/(kg·k)"])
 def eulersolver(self, tend, step=None):
     if step is None:
         step = (tend - self.t0) / 1e3
     from ArrayTable import ArrayTable
     result = ArrayTable(2, 0)
     result.setTableHeader(["$t$", "y(t) solved with explicit euler"])
     result.setTableUnit(["/", "/"])
     result.append([self.t0, self.y0])
     t = self.t0
     while t < tend:
         ynext = result.table[1].data[-1] + self.fun(
             t, result.table[1].data[-1]) * step
         result.append([t + step, ynext])
         t += step
     return result
 def forecastCorrection(self, tend, step=None):
     if step is None:
         step = (tend - self.t0) / 1e3
     from ArrayTable import ArrayTable
     result = ArrayTable(2, 0)
     result.setTableHeader(["$t$", "y(t) solved with forecast correction"])
     result.setTableUnit(["/", "/"])
     result.append([self.t0, self.y0])
     t = self.t0
     while t < tend:
         dydt = self.fun(t, result.table[1].data[-1])
         ynextpridict = result.table[1].data[-1] + dydt * step
         ynext = result.table[1].data[-1] + step / 2. * (
             dydt + self.fun(t + step, ynextpridict))
         result.append([t + step, ynext])
         t += step
     return result
示例#7
0
    def analyze(self, speed=1500,plot=False):
        from ArrayTable import ArrayTable
        from Cylinder import MeEff

        PV = ArrayTable(3, 0)
        self.data.doQuickSort(0)
        for i in range(self.data.row):
            PV.append(
                [self.data.table[0].data[i], self.CylGeo.V(self.data.table[0].data[i]), self.data.table[1].data[i]])

        PV.plot(2, 1)
        work = PV.integrate(2, _colx=1)
        power=work/(30*4/speed)
        BMEP=work / self.CylGeo.displacedVolume()
        etam = MeEff(self.CylGeo.bore, self.CylGeo.stroke * speed / 30, BMEP)
        etait=work / (self.mix.gf * 42700e3)
        print(work/(self.Hu*etam)/(self.mix.M_air(0)/self.L0/self.alpha))

        print("Injected fuel {} mg".format(self.mix.gf * 1.e6))

        print("Brake power {} kW".format(power/1.e3*self.CylGeo.num_of_cylinders*etam))

        print("Mechanical efficiency {}".format(etam))

        print("BMEP={} bar".format(BMEP/1.e5))

        print("thermal efficiency {}".format(etait))

        if plot:
            self.plot()

        return work
 def Rungekutta4(self, tend, step=None):
     if step is None:
         step = (tend - self.t0) / 1e3
     from ArrayTable import ArrayTable
     result = ArrayTable(2, 0)
     result.setTableHeader(["$t$", "y(t) solved with runge kutta 4"])
     result.setTableUnit(["/", "/"])
     result.append([self.t0, self.y0])
     t = self.t0
     while t < tend:
         s1 = self.fun(t, result.table[1].data[-1])
         s2 = self.fun(t + step / 2.,
                       result.table[1].data[-1] + step / 2. * s1)
         s3 = self.fun(t + step / 2.,
                       result.table[1].data[-1] + step / 2. * s2)
         s4 = self.fun(t + step, result.table[1].data[-1] + step * s3)
         ynext = result.table[1].data[-1] + step / 6. * (s1 + 2 * s2 +
                                                         2 * s3 + s4)
         result.append([t + step, ynext])
         t += step
     return result
示例#9
0
class ValveSimple:
    def __init__(self, _flowArea=1.):
        from ArrayTable import ArrayTable
        self.flowArea = _flowArea
        self.data = ArrayTable(2, 0)
        self.data.setTableHeader(["Pressure ratio", "Mass flow rate"])
        self.data.setTableUnit(["/", "kg/s"])

        # 连接关系
        self.next = None
        self.last = None

    def __massFlowRate(self, p1, T1, R1, k1, p2, T2=0, R2=0, k2=0):
        return self.flowArea * flowUnitArea(p1, T1, R1, k1, p2, T2, R2, k2)

    def connect_to(self, last, next):
        self.last = last
        self.last.next = self

        self.next = next
        self.next.last = self

    def update(self):
        self.dm_record = self.__massFlowRate(self.last.p, self.last.T,
                                             self.last.Rg, self.last.k,
                                             self.next.p, self.next.T,
                                             self.next.Rg, self.next.k)
        # return self.dm_record

    def airFlowExample(self, p1, T1, p2=None, T2=None, K2=None):
        from GasProperty import Rg, k_Justi
        R1 = Rg(T1)
        R2 = Rg(T2)
        k1 = k_Justi(T1)
        k2 = k_Justi(T2)
        step = 1.e-3 * p1
        import numpy as np
        for i in np.arange(0, p1, step):
            self.data.append([i / p1, self.__massFlowRate(p1, T1, R1, k1, i)])

        if p2 is not None and T2 is not None:
            step2 = 0.01 * p2
            for i in np.arange(0.5 * p2, p2, step):
                self.data.append([
                    p2 / i,
                    self.__massFlowRate(i, T1, R1, k1, p2, T2, R2, K2)
                ])

        return self.data
示例#10
0
    def __init__(self, CylGeo, ValveTiming=None):
        from ArrayTable import ArrayTable
        self.CompressData = ArrayTable(5, 0)
        self.ExpanseData = ArrayTable(5, 0)
        self.Rpressure = ArrayTable(2, 0)
        self.GasExchange = ArrayTable(2, 0)
        self.CompressData.setTableHeader(["Crank angle", "V", "p", "T", "m"])
        self.CompressData.setTableUnit(["°CA", "m^3", "Pa", "K", "kg"])
        self.ExpanseData.setTableHeader(["Crank angle", "V", "p", "T", "m"])
        self.ExpanseData.setTableUnit(["°CA", "m^3", "Pa", "K", "kg"])
        self.data = ArrayTable(2, 0)
        self.data.setTableHeader(["Crank angle", "Cylinder pressure"])
        self.data.setTableUnit(["°CA", "Pa"])

        self.CylGeo = CylGeo
        from Valve import ValveDesign
        if ValveTiming is None:
            self.ValveTiming = ValveDesign()
        else:
            self.ValveTiming = ValveTiming
示例#11
0
def AnalyticalSolution(t, left=[], right=[], xlim=None):
    import math
    u1 = left[0]
    u2 = right[0]
    # r1 = left[1];
    # r2 = right[1]
    T1 = left[1]
    T2 = right[1]
    p1 = left[2]
    p2 = right[2]
    # T1 = p1 / r1 / Rg();
    # T2 = p2 / r2 / Rg()
    r1 = p1 / Rg() / T1
    r2 = p2 / Rg() / T2
    k1 = k_Justi(T1)
    k2 = k_Justi(T2)
    a1 = math.sqrt(k1 * p1 / r1)
    a2 = math.sqrt(k2 * p2 / r2)

    # print("-" * 100)
    # print("{0:^50}|{1:^50}".format("ul=%.5gm/s" % u1, "ur=%.5gm/s" % u2))
    # print("{0:^50}|{1:^50}".format("rhol=%.5gkg/m^3" % r1, "rhor=%.5gkg/m^3" % r2))
    # print("{0:^50}|{1:^50}".format("pl=%sPa" % p1, "pr=%sPa" % p2))
    # print("{0:^50}|{1:^50}".format("Tl=%sK" % T1, "Tr=%sK" % T2))
    # print("-" * 100)

    def function(pbar, pj, rhoj, gamma=1.4):
        if pbar == pj:
            return 0
        elif pbar > pj:
            import math
            aj = math.sqrt(gamma * pj / rhoj)
            return (pbar - pj) / rhoj / aj / math.sqrt(
                (gamma + 1) / 2. / gamma * pbar / pj +
                (gamma - 1) / 2. / gamma)
        elif pbar < pj:
            import math
            aj = math.sqrt(gamma * pj / rhoj)
            return 2. * aj / (gamma - 1.) * (pow(pbar / pj,
                                                 (gamma - 1) / 2. / gamma) - 1)

    def F(p):
        return function(p, p1, r1, k1) + function(p, p2, r2, k2)

    pbar = (p1 + p2) / 2
    h = 10.
    while abs(u1 - u2 - F(pbar)) > 1.e-5:
        pbar -= (u1 - u2 - F(pbar)) / ((-F(pbar + h) + F(pbar - h)) / 2. / h)
    # print(pbar)
    ubar = (u1 + u2 - function(pbar, p1, r1, k1) +
            function(pbar, p2, r2, k2)) / 2.
    # print(ubar)

    A1 = r1 * a1 * math.sqrt((k1 + 1.) / (2. * k1) * pbar / p1 +
                             (k1 - 1) / 2. / k1)
    A2 = r2 * a2 * math.sqrt((k2 + 1.) / (2. * k2) * pbar / p2 +
                             (k2 - 1) / 2. / k2)

    if pbar >= p1:
        Z1 = u1 - A1 / r1
    else:
        Z1 = u1 - a1

    if pbar >= p2:
        Z2 = u2 + A2 / r2
    else:
        Z2 = u2 + a2

    if pbar >= p1:
        Z1star = Z1
    elif pbar > 0:
        a1star = a1 + (k1 - 1) / 2. * (u1 - ubar)
        Z1star = ubar - a1star
    else:
        Z1star = u1 - 2. * a1 / (k1 - 1)

    if pbar >= p2:
        Z2star = Z2
    elif pbar > 0:
        a2star = a2 - (k2 - 1) / 2. * (u2 - ubar)
        Z2star = ubar + a2star
    else:
        Z2star = u2 + 2 * a2 / (k2 - 1)

    r1bar = r1 * A1 / (A1 - r1 * (u1 - ubar))
    r2bar = r2 * A2 / (A2 + r2 * (u2 - ubar))

    # print("Z1=", Z1)
    # print("Z1star=", Z1star)
    # print("ubar=", ubar)
    # print("Z2star=", Z2star)
    # print("Z2=", Z2)

    if xlim is None:
        Zlaggest = abs(Z1) if abs(Z1) > abs(Z2) else abs(Z2)
        xlim = [-1.5 * t * Zlaggest, 1.5 * t * Zlaggest]

    # print("Will draw air state between [{},{}]".format(xlim[0],xlim[1]))

    def fun(t, x):
        if x / t > Z2:
            return u2, r2, p2
        elif x / t < Z1:
            return u1, r1, p1
        elif Z1star < x / t < ubar:
            return ubar, r1bar, pbar
        elif ubar < x / t < Z2star:
            return ubar, r2bar, pbar
        elif Z1 < x / t < Z1star:
            a = (k1 - 1) / (k1 + 1) * (u1 - x / t) + 2 * a1 / (k1 + 1)
            u = x / t + a
            p = p1 * pow(a / a1, 2 * k1 / (k1 - 1))
            r = k1 * p / a / a
            return u, r, p
        elif Z2star < x / t < Z2:
            a = (k2 - 1) / (k2 + 1) * (x / t - u2) + 2 * a2 / (k2 - 1)
            u = x / t - a
            p = p2 * pow(a / a2, 2 * k2 / (k2 - 1))
            r = k2 * p / a / a
            return u, r, p

    result = ArrayTable(5, 0)
    result.setTableHeader(
        ["x", "Velocity", "Density", "Pressure", "Temperature"])
    result.setTableUnit(["m", "m/s", "kg/m^3", "Pa", "K"])
    import numpy as np
    step = (xlim[1] - xlim[0]) / 1000.
    xx = np.arange(xlim[0], xlim[1], step)
    for each in xx:
        u, r, p = fun(t, each)
        result.append([each, u, r, p, p / r / Rg()])
    return result
示例#12
0
def laxWendroff1step(t, left=[], right=[], xlim=None, numberOfNode=500, A=1):
    import numpy as np
    init = ArrayTable(2, 0)

    solution = AnalyticalSolution(t, left, right)
    if xlim is None:
        mindata = [min(solution.table[i].data) for i in range(solution.col)]
        maxdata = [max(solution.table[i].data) for i in range(solution.col)]
        xlim = [1.5 * mindata[0], 1.5 * maxdata[0]]
        print(xlim)
    deltax = (xlim[1] - xlim[0]) / numberOfNode

    for i in np.arange(xlim[0], xlim[1], deltax):
        Nodeex = Node()
        if i < 0:
            Nodeex.Uinit(left[0], left[2], left[1])
        else:
            Nodeex.Uinit(right[0], right[2], right[1])
        Nodeex.Jaccobi()
        Nodeex.F()
        init.append([i, Nodeex])

    thisstep = init
    tnow = 0
    Corant = 0.9

    while tnow < t:
        laststep = thisstep
        mm = 0
        for i in range(laststep.row):
            if max(abs(laststep.table[1].data[i].Jeigenvalue)) > mm:
                mm = max(abs(laststep.table[1].data[i].Jeigenvalue))

        deltat = deltax * Corant / mm
        print(deltat)
        thisstep = ArrayTable(2, 0)
        thisstep.append([laststep.table[0].data[0], laststep.table[1].data[0]])
        for i in range(1, laststep.row - 1):
            Aright = 1. / 2. * (laststep.table[1].data[i].J +
                                laststep.table[1].data[i + 1].J)
            Aleft = 1. / 2. * (laststep.table[1].data[i].J +
                               laststep.table[1].data[i - 1].J)
            Uthis = laststep.table[1].data[i].U\
                    - deltat /2./ deltax * (laststep.table[1].data[i + 1].F - laststep.table[1].data[i-1].F)\
                    + deltat**2 /2./ deltax**2*(np.dot(Aright,(laststep.table[1].data[i+1].F - laststep.table[1].data[i].F))
                                                -np.dot(Aleft,(laststep.table[1].data[i].F - laststep.table[1].data[i-1].F)))

            Nodethis = Node()
            Nodethis.solve(Uthis)
            Nodethis.Jaccobi()
            Nodethis.F()
            thisstep.append([laststep.table[0].data[i], Nodethis])
        thisstep.append(
            [laststep.table[0].data[-1], laststep.table[1].data[-1]])

        tnow += deltat
        print("tnow={}".format(tnow))
        print("Row of table {}".format(thisstep.row))

    result = ArrayTable(5, 0)
    result.setTableHeader(
        ["x", "Velocity", "Density", "Pressure", "Temperature"])
    result.setTableUnit(["m", "m/s", "kg/m^3", "Pa", "K"])
    for i in range(thisstep.row):
        result.append([
            thisstep.table[0].data[i], thisstep.table[1].data[i].u,
            thisstep.table[1].data[i].rho, thisstep.table[1].data[i].p,
            thisstep.table[1].data[i].T
        ])
    return result
示例#13
0
class IdealCylcle:
    def __init__(self, CylGeo, ValveTiming=None):
        from ArrayTable import ArrayTable
        self.CompressData = ArrayTable(5, 0)
        self.ExpanseData = ArrayTable(5, 0)
        self.Rpressure = ArrayTable(2, 0)
        self.GasExchange = ArrayTable(2, 0)
        self.CompressData.setTableHeader(["Crank angle", "V", "p", "T", "m"])
        self.CompressData.setTableUnit(["°CA", "m^3", "Pa", "K", "kg"])
        self.ExpanseData.setTableHeader(["Crank angle", "V", "p", "T", "m"])
        self.ExpanseData.setTableUnit(["°CA", "m^3", "Pa", "K", "kg"])
        self.data = ArrayTable(2, 0)
        self.data.setTableHeader(["Crank angle", "Cylinder pressure"])
        self.data.setTableUnit(["°CA", "Pa"])

        self.CylGeo = CylGeo
        from Valve import ValveDesign
        if ValveTiming is None:
            self.ValveTiming = ValveDesign()
        else:
            self.ValveTiming = ValveTiming

    def compress(self, pim=1.e5, Tim=300, Tr=800, xr=0.0, kc=1.3, phic=1):
        self.kc=kc
        from GasProperty import DieselMixture, Rg
        ivc = self.ValveTiming.IVC
        self.pim = pivc = pim
        Tim = 313. + 5. / 6. * (Tim - 273.15)  # 新鲜充量温度
        self.Tim = Tivc = Tim * (1 - xr) + xr * Tr
        # 新鲜充量质量
        mivc = phic * pivc * self.CylGeo.V(180) / Rg() / Tivc
        self.mix = DieselMixture()
        self.mix.init_With_Mc_r(mivc, xr, mivc / 14.3 / 1.1)
        print("Intake air mass {} mg".format(mivc * 1.e6))
        print("Tivc=", Tivc)

        Vivc = self.CylGeo.V(ivc)
        for i in range(ivc, ivc + 720):
            V = self.CylGeo.V(i)
            T = Tivc * pow(Vivc / V, kc - 1)
            p = pivc * pow(Vivc / V, kc)
            m = p * V / self.mix.Rg_gas(0) / T
            self.CompressData.append([i, V, p, T, m])
        from Valve import mod
        for i in range(self.CompressData.row):
            self.CompressData.table[0].data[i] = mod(self.CompressData.table[0].data[i])
        self.CompressData.doQuickSort(0)

    def Burn(self, Rp, SOC=-5, alpha=1, Hu=42700e3, L0=14.3):
        self.Hu=Hu
        from numpy import arange
        for i in arange(self.ValveTiming.IVC, SOC):
            self.data.append([i, self.CompressData.linearInterpolate(i, 2)])

        if Rp < 0 or Rp > 1: raise Exception("premixed burn fraction value error!!")
        self.Rp = Rp
        self.L0 = L0
        self.alpha = alpha
        self.SOC = SOC
        self.mix.gf = self.mix.M_air(0) / L0 / alpha

        def fun(x, T):
            return (Hu - self.mix.u(x, T)) / (alpha * L0 + x) / self.mix.cv(x, T)

        x = 0
        self.T2 = T = self.CompressData.linearInterpolate(SOC, 3)
        self.p2 = self.CompressData.linearInterpolate(SOC, 2)

        step = Rp / 50.
        while x < Rp:
            T += fun(x, T) * step
            x += step

        print("Temperature after premixed burn {}".format(T))
        Ttemp = T
        self.p3 = self.p2 * T / self.T2
        print("Pressure after premixed burn {}".format(self.p3))

        def fun2(x, T):
            return (Hu - self.mix.h(x, T)) / (self.mix.cp(x, T) * (self.alpha * self.L0 + x))

        step2 = (1 - self.Rp) / 100.

        while x < 1:
            T += fun2(x, T) * step2
            x += step2

        print("Temperature after disfusion burn {}".format(T))
        self.V3 = self.CylGeo.V(0) * T / Ttemp
        self.EOC = self.CylGeo.getFi(self.V3)
        print("End of combustion {}".format(self.EOC))
        self.T3 = T
        # self.p3=self.mix.M_total(1)*self.mix.Rg_gas(1)*self.T3/self.V3
        # print("Pressure after burned {}".format(self.p3))

        return T

    def Expense(self, ke=1.33):
        self.ke=ke
        from numpy import arange
        for i in arange(self.SOC, self.SOC + 360):
            V = self.CylGeo.V(i)
            p = self.p3 * pow(self.V3 / V, ke)
            T = self.T3 * pow(self.V3 / V, ke - 1)
            self.ExpanseData.append([i, V, p, T, self.mix.M_total(1)])

        from Valve import mod
        for i in range(self.ExpanseData.row):
            self.ExpanseData.table[0].data[i] = mod(self.ExpanseData.table[0].data[i])
        self.ExpanseData.doQuickSort(0)

        from numpy import arange
        for i in arange(self.EOC, self.ValveTiming.EVO):
            self.data.append([i, self.ExpanseData.linearInterpolate(i, 2)])

    def pressureReconstruct(self, m=1):
        from Cylinder import WibeFunction
        from numpy import arange
        for i in arange(self.SOC, self.EOC):
            temp = WibeFunction(i, self.SOC, self.EOC - self.SOC, m=m)
            p = (1 - temp) * self.CompressData.linearInterpolate(i, 2) + temp * self.ExpanseData.linearInterpolate(i, 2)
            self.Rpressure.append([i, p])

        from numpy import arange
        for i in arange(self.SOC, self.EOC):
            self.data.append([i, self.Rpressure.linearInterpolate(i, 1)])

    def pit(self, pik=2, p0e=1.e5, T0=273.15 + 20, etaTK=0.56):
        from Compressor import piT
        from GasProperty import k_exhaust_gu
        # 计算排气门打开时的压力和温度
        pevo = self.ExpanseData.linearInterpolate(self.ValveTiming.EVO, 2)
        Tevo = self.ExpanseData.linearInterpolate(self.ValveTiming.EVO, 3)
        # pevo = self.ExpanseData.linearInterpolate(180, 2)
        # Tevo = self.ExpanseData.linearInterpolate(180, 3)
        print("Temperature at EVO {}".format(Tevo))

        def fun(x):
            k = k_exhaust_gu(500)
            def Ttfun(kk):
                Tt0=Tevo * pow(x * p0e / pevo, (kk - 1) / kk)
                return k_exhaust_gu(Tt0)-kk
            h=0.01
            while abs(Ttfun(k))>1.e-5:
                k-=Ttfun(k)/((Ttfun(k+h)-Ttfun(k-h))/2./h)
            Tt = Tevo * pow(x * p0e / pevo, (k - 1) / k)
            return piT(pik, etaTK, Tt, T0, self.alpha * 14.7) - x

        def fun2(x):
            Tt=p0e*x/pevo*Tevo
            return piT(pik, etaTK, Tt, T0, self.alpha * 14.7) - x

        x = 2.0
        h = 0.01
        # while abs(fun(x)) > 1.e-5:
        #     x -= fun(x) / ((fun(x + h) - fun(x - h)) / 2. / h)

        while abs(fun2(x)) > 1.e-5:
            x -= fun2(x) / ((fun2(x + h) - fun2(x - h)) / 2. / h)

        print("Pressure ratio of turbine {}".format(x))
        print("pressure before turbine {} bar".format(x * p0e / 1.e5))
        print("Temperature before turbine {} K".format(Tevo * pow(x * p0e / pevo, (1.33 - 1) / 1.33)))
        self.pem = x * p0e
        return x * p0e

    def gasExchange(self):
        pem = self.pem
        from numpy import arange
        evc = self.ValveTiming.EVC
        int = self.ValveTiming.int = (self.ValveTiming.EVC + self.ValveTiming.IVC) / 2.
        for i in arange(self.ValveTiming.EVC, int):
            self.data.append([i, self.pim])
        for i in arange(int, self.ValveTiming.IVC):
            temp = xi(i, int, self.ValveTiming.IVC)
            p = self.pim * (1 - temp) + self.CompressData.linearInterpolate(i, 2) * temp
            self.data.append([i, p])

        exh = self.ValveTiming.exh = (self.ValveTiming.EVO + self.ValveTiming.IVO) / 2.
        for i in arange(self.ValveTiming.EVO, exh):
            temp = xi(i, self.ValveTiming.EVO, exh)
            p = self.ExpanseData.linearInterpolate(i, 2) * (1 - temp) + pem * temp
            self.data.append([i, p])
        for i in arange(exh, self.ValveTiming.IVO):
            self.data.append([i, pem])

        from Valve import mod
        for i in arange(self.ValveTiming.IVO, self.ValveTiming.EVC + 720):
            temp = xi(i, self.ValveTiming.IVO, self.ValveTiming.EVC + 720)
            p = pem * (1 - temp) + self.pim * temp
            self.data.append([mod(i), p])

        # from numpy import arange
        # for i in arange(self.ValveTiming.EVC, self.ValveTiming.IVC):
        #     self.data.append([i, self.GasExchange.linearInterpolate(i, 1)])

    def plot(self):
        self.data.doQuickSort(0)

        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, figsize=(10, 5))
        ax.plot(self.data.table[0].data, self.data.table[1].data)
        plt.xlabel(self.data.table[0].ColName + "(" + self.data.table[0].ColUnit + ")")
        plt.ylabel(self.data.table[1].ColName + "(" + self.data.table[1].ColUnit + ")")

        ax.scatter(self.EOC, self.data.linearInterpolate(self.EOC, 1))
        ax.annotate('EOC %.3g $^\circ$CA' % self.EOC,
                    xy=(self.EOC, self.data.linearInterpolate(self.EOC, 1)), xycoords='data',
                    xytext=(0, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        index = self.data.findMaxValueIndex(1)
        maxpreCA = self.data.table[0].data[index]

        ax.scatter(maxpreCA, self.data.linearInterpolate(maxpreCA, 1))
        ax.annotate('maxium pressure %.5g bar' % (self.data.linearInterpolate(maxpreCA, 1) / 1.e5),
                    xy=(maxpreCA, self.data.linearInterpolate(maxpreCA, 1)), xycoords='data',
                    xytext=(0, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.ValveTiming.IVC, self.data.linearInterpolate(self.ValveTiming.IVC, 1))
        ax.annotate('IVC %.3g $^\circ$CA' % self.ValveTiming.IVC,
                    xy=(self.ValveTiming.IVC, self.data.linearInterpolate(self.ValveTiming.IVC, 1)), xycoords='data',
                    xytext=(0, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.ValveTiming.EVO, self.data.linearInterpolate(self.ValveTiming.EVO, 1))
        ax.annotate('EVO %.3g $^\circ$CA' % self.ValveTiming.EVO,
                    xy=(self.ValveTiming.EVO, self.data.linearInterpolate(self.ValveTiming.EVO, 1)), xycoords='data',
                    xytext=(0, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.ValveTiming.EVC, self.data.linearInterpolate(self.ValveTiming.EVC, 1))
        ax.annotate('EVC %.3g $^\circ$CA' % self.ValveTiming.EVC,
                    xy=(self.ValveTiming.EVC, self.data.linearInterpolate(self.ValveTiming.EVC, 1)), xycoords='data',
                    xytext=(0, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.ValveTiming.IVO, self.data.linearInterpolate(self.ValveTiming.IVO, 1))
        ax.annotate('IVO %.3g $^\circ$CA' % self.ValveTiming.IVO,
                    xy=(self.ValveTiming.IVO, self.data.linearInterpolate(self.ValveTiming.IVO, 1)), xycoords='data',
                    xytext=(0, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        # ax.scatter(self.ValveTiming.int, self.data.linearInterpolate(self.ValveTiming.int, 1))
        ax.annotate('$p_{im}$ %.4g bar' % (self.pim / 1.e5),
                    xy=(self.ValveTiming.int, self.data.linearInterpolate(self.ValveTiming.int, 1)), xycoords='data',
                    xytext=(-28, 40), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))
        ax.annotate('$p_{em}$ %.4g bar' % (self.pem / 1.e5),
                    xy=(self.ValveTiming.exh, self.data.linearInterpolate(self.ValveTiming.exh, 1)), xycoords='data',
                    xytext=(-0, 40), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.SOC, self.data.linearInterpolate(self.SOC, 1))
        ax.annotate('SOC %.3g $^\circ$CA' % self.SOC,
                    xy=(self.SOC, self.data.linearInterpolate(self.SOC, 1)), xycoords='data',
                    xytext=(-80, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))
        #
        # ax.scatter(self.EVC, table.linearInterpolate(self.EVC, 1))
        # ax.annotate('EVC %.3g $^\circ$CA' % self.EVC,
        #             xy=(self.EVC, table.linearInterpolate(self.EVC, 1)), xycoords='data',
        #             xytext=(0, 10), textcoords='offset points',
        #             arrowprops=dict(arrowstyle="->"))
        plt.xticks([-360, -180, 0, 180, 360], ["-360\nTDC", "-180\nBDC", "0\nTDCF", "180\nBDC", "360\nTDC"])

        # ax.axhline(y=0, color='r', linestyle="-.")
        ax.axvline(x=0, color='g', linestyle=":")
        ax.axvline(x=180, color='g', linestyle=":")
        ax.axvline(x=-180, color='g', linestyle=":")
        ax.axvline(x=360, color='g', linestyle=":")
        ax.axvline(x=-360, color='g', linestyle=":")

        plt.tight_layout()
        plt.show()

    def analyze(self, speed=1500,plot=False):
        from ArrayTable import ArrayTable
        from Cylinder import MeEff

        PV = ArrayTable(3, 0)
        self.data.doQuickSort(0)
        for i in range(self.data.row):
            PV.append(
                [self.data.table[0].data[i], self.CylGeo.V(self.data.table[0].data[i]), self.data.table[1].data[i]])

        PV.plot(2, 1)
        work = PV.integrate(2, _colx=1)
        power=work/(30*4/speed)
        BMEP=work / self.CylGeo.displacedVolume()
        etam = MeEff(self.CylGeo.bore, self.CylGeo.stroke * speed / 30, BMEP)
        etait=work / (self.mix.gf * 42700e3)
        print(work/(self.Hu*etam)/(self.mix.M_air(0)/self.L0/self.alpha))

        print("Injected fuel {} mg".format(self.mix.gf * 1.e6))

        print("Brake power {} kW".format(power/1.e3*self.CylGeo.num_of_cylinders*etam))

        print("Mechanical efficiency {}".format(etam))

        print("BMEP={} bar".format(BMEP/1.e5))

        print("thermal efficiency {}".format(etait))

        if plot:
            self.plot()

        return work

    def loop(self):
        pass
class DieselMixture:
    def __init__(self, L0=14.3):
        self.L0 = L0
        # self.gf = gf
        from ArrayTable import ArrayTable
        self.data = ArrayTable(8, 0)
        self.data.setTableHeader([
            "已燃百分比", "缸内气体总质量", "空气质量", "废气质量", "已喷燃油量", "广义过量空气系数", "残余废气系数",
            "气体常数"
        ])
        self.data.setTableUnit(
            ["Fraction", "kg", "kg", "kg", "kg", "", "", "J/(kg·k)"])

    def init_With_Ma_r(self, ma, r, gf):
        self.ma = ma
        self.r = r
        self.gf = gf
        if ma < self.L0 * self.gf:
            print("Charged air is too few to burn all the fuel!!")
            raise Exception(
                "There are must at least {}(kg) air but {} is provided".format(
                    self.L0 * self.gf, ma))
        if r < 0 or r > 1:
            raise Exception(
                "residual gas fraction can not less than 0 and greater than 1!!"
            )
        self.xr = ma * r / (1 - r) / (1 + self.L0) / self.gf
        self.__initPropertyTable()

    def init_With_Mc_r(self, mc, r, gf):
        self.init_With_Ma_r((1 - r) * mc, r, gf)

    def init_With_Mc_AFA(self, mc, afa, gf):
        self.gf = gf
        if afa < 1:
            raise Exception(
                "Excess air fuel ratio must be greater than or equal to 1")
        mr = (1 + self.L0) / (self.L0 * afa + 1) * mc
        self.ma = self.L0 * (afa - 1) / (self.L0 * afa + 1) * mc
        if self.ma < self.L0 * gf:
            print("Charged air is too few to burn all the fuel!!")
            raise Exception(
                "There are must at least {}(kg) air but {} is provided".format(
                    self.L0 * self.gf, self.ma))
        self.r = mr / mc
        self.xr = self.ma * self.r / (1 - self.r) / (1 + self.L0) / self.gf
        self.__initPropertyTable()

    def AFAK(self, x):
        if x < 0: x = 0
        if (self.xr + x) < 1.e-8: return 1.e8
        return (self.L0 * self.gf * self.xr + self.ma) / (self.L0 * self.gf *
                                                          (self.xr + x))

    def M_total(self, x):
        if x < 0: x = 0
        if (self.xr + x) < 1.e-8:
            return self.ma
        return self.gf * (self.xr + x) * (1 + self.AFAK(x) * self.L0)

    def M_exhaust(self, x):
        return self.M_total(x) * (1 + self.L0) / (self.L0 * self.AFAK(x) + 1)

    def M_air(self, x):
        return self.M_total(x) - self.M_exhaust(x)

    def Xk(self, x):
        return self.M_total(x) / (1 + self.L0 * self.AFAK(x)) / self.gf

    def cv(self, x, T):
        return cv_Justi(T, self.AFAK(x))

    def cp(self, x, T):
        return cp_Justi(T, self.AFAK(x))

    def u(self, x, T):
        return u_Justi(T, self.AFAK(x))

    def h(self, x, T):
        return h_Justi(T, self.AFAK(x))

    def U(self, x, T):
        return self.M_total(x) * u_Justi(T, self.AFAK(x))

    def Rg_gas(self, x):
        return Rg(self.AFAK(x))

    def k(self, x, T):
        return k_Justi(T, self.AFAK(x))

    def __initPropertyTable(self):
        from numpy import arange
        for i in arange(0, 1, 0.01):
            self.data.append([
                i,
                self.M_total(i),
                self.M_air(i),
                self.M_exhaust(i), self.gf * i,
                self.AFAK(i),
                self.M_exhaust(i) / self.M_total(i),
                self.Rg_gas(i)
            ])
示例#15
0
    def plot(self):
        from ArrayTable import ArrayTable
        table = ArrayTable()
        table.readSQLiteTable("EngineDB.db", "`Cylinder pressure GT example`")
        for i in range(table.row):
            table.table[0].data[i] = mod(table.table[0].data[i], TDC=self.TDC)
        table.doQuickSort()

        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, figsize=(10, 5))
        ax.plot(table.table[0].data, table.table[1].data)
        plt.xlabel(table.table[0].ColName + "(" + table.table[0].ColUnit + ")")
        plt.ylabel(table.table[1].ColName + "(" + table.table[1].ColUnit + ")")

        ax.scatter(self.IVC, table.linearInterpolate(self.IVC, 1))
        ax.annotate('IVC %.3g $^\circ$CA' % self.IVC,
                    xy=(self.IVC, table.linearInterpolate(self.IVC, 1)),
                    xycoords='data',
                    xytext=(0, 10),
                    textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.IVO, table.linearInterpolate(self.IVO, 1))
        ax.annotate('IVO %.3g $^\circ$CA' % self.IVO,
                    xy=(self.IVO, table.linearInterpolate(self.IVO, 1)),
                    xycoords='data',
                    xytext=(0, 10),
                    textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.EVO, table.linearInterpolate(self.EVO, 1))
        ax.annotate('EVO %.3g $^\circ$CA' % self.EVO,
                    xy=(self.EVO, table.linearInterpolate(self.EVO, 1)),
                    xycoords='data',
                    xytext=(0, 10),
                    textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))

        ax.scatter(self.EVC, table.linearInterpolate(self.EVC, 1))
        ax.annotate('EVC %.3g $^\circ$CA' % self.EVC,
                    xy=(self.EVC, table.linearInterpolate(self.EVC, 1)),
                    xycoords='data',
                    xytext=(0, 10),
                    textcoords='offset points',
                    arrowprops=dict(arrowstyle="->"))
        plt.xticks(
            [-360, -180, 0, 180, 360],
            ["-360\nTDC", "-180\nBDC", "0\nTDCF", "180\nBDC", "360\nTDC"])

        # ax.axhline(y=0, color='r', linestyle="-.")
        ax.axvline(x=0, color='g', linestyle=":")
        ax.axvline(x=180, color='g', linestyle=":")
        ax.axvline(x=-180, color='g', linestyle=":")
        ax.axvline(x=360, color='g', linestyle=":")
        ax.axvline(x=-360, color='g', linestyle=":")

        plt.tight_layout()
        plt.show()