Как обновлять переменную, не зависящую от времени, каждый шаг по времени из scipy.odeint - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь решить проблему вытекания жидкости из бака;используя уравнения непрерывности и сохранения энергии.Первоначально резервуар имеет некоторое давление и некоторую энтальпию, которые используются в 2D справочной таблице для получения других свойств жидкости.Когда жидкость покидает резервуар, давление и энтальпия изменяются;Таким образом, приводит к моей проблеме.Энтальпия решается уравнением энергии, поэтому при использовании odeint и задании начального условия энтальпия будет обновляться каждый временной шаг.Проблема заключается в давлении, давление решается путем решения уравнения неразрывности, а затем с помощью корреляции, где давление является функцией плотности.Вопрос в том, как получить переменную, не зависящую от времени, например, давление, которое будет обновляться при каждом шаге odeint.

Я много раз просматривал здесь, чтобы найти что-то похожее, но многое из того, что я 'Видно, что изменение переменной зависит от времени.Таким образом, если время <2, то x = 0 .. если время> = 2, то x = 2. Я пытался найти способ изменить уравнения, чтобы сделать его функцией времени, но это не является прямой функцией временикак у (т) = м * т + б.Я не знаю, может быть, я слишком много думаю об этом.

# Model of Tank:

def model(IC,time,terms,terms2):
    #   Initial Conditions:
    #   IC[0] = Initial Tank Mass
    #   IC[1] = Initial Percent Quality of Vapor in Tank
    #   IC[2] = Initial Pressure for PI Controller
    #   IC[3] = Initial Enthalpy

    #   System of Equations:
    sysdot = [[],[],[],[]]

    #   Continuity Equation:
    # dMdt = mdot_in - mdot_out(pump) - mdot_out(vapor bleed off)
    mdot_in = 0
    mdot_outVapor = terms[2]
    M_total = IC[0]
    sysdot[0] = mdot_in - mdot_outVapor - terms[1]

    #   Transfer Function Equation:
    # NOTE: I was given a Simulink model to write in python, not sure on the use 
    # of the Transfer Function but I need it in the system of equations to solve for 
    # the percent quality which includes the quality lookup tables.
    # dXdt = (X_percent - X)/tau **Note: X = X(h,P,file)
    tau = .125
    if time == 0:
        # Here is where I define the initial Pressure
        P_in = 50e3
        X_percent = IC[1]
        X = X2D(IC[3],P_in,terms[5]) # The terms[5] here is the file location of the lookup table
        sysdot[1] = (X_percent - X)/tau
        density = (M_total*X_percent)/(terms[3] - (M_total*(1 - X_percent))/terms[0])
        P_in = P_sat_vap(density) # Solve for my new pressure
    else:
        X_percent = IC[1]
        X = X2D(IC[3],P_in,terms[5]) # <--- Problem child
        sysdot[1] = (X_percent - X)/tau
        density = (M_total*X_percent)/(terms[3] - (M_total*(1 - X_percent))/terms[0])
        P_in = P_sat_vap(density)

    # … more code …

    return sysdot

В настоящее время при настройке кода возникает ошибка, сообщающая, что P_in не определен первым.Несмотря на то, что в момент времени x = 0 он рассчитывает новый P_in для будущих временных шагов.Нужно ли мне использовать функцию ode в SciPy и поместить все в цикл?

1 Ответ

0 голосов
/ 08 июля 2019

P_in может быть определено только в области действия функции model, но я думаю, что у вас есть более глубокая проблема.

P_in представляется нелинейной функцией, которую необходимо оценивать по переменным состояния, которые, как ни странно, здесь также кодируются как IC. Я бы порекомендовал не пытаться сохранить старое состояние P_in из внутреннего решения ode, так как иногда интегратор может сделать несколько шагов, прежде чем он примет один, и этот метод вызовет странное поведение, при котором он использует P_in от недопустимой попытки шага.

Вместо этого пусть P_in зависит только от текущих значений состояния и использует жесткий решатель.

...