Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 解算器在不调用派生回调函数的情况下进行积分_Python_Scipy_Ode - Fatal编程技术网

Python 解算器在不调用派生回调函数的情况下进行积分

Python 解算器在不调用派生回调函数的情况下进行积分,python,scipy,ode,Python,Scipy,Ode,我有一个python代码(),它使用scipy.integrate.ode来解决ode系统。代码运行良好,结果是真实的。然而,我注意到一些关于ode解算器的东西对我来说没有意义 我在函数内部放置了一个print函数(print(“t-inside-ODE-function”,t)),该函数计算导数向量(\uu调用(self,t,y)),并在while循环的该函数外部(print(“t-extender-ODE-function”,solver.t);)。 我希望在解算器进行时间积分时必须调用内部

我有一个python代码(),它使用scipy.integrate.ode来解决ode系统。代码运行良好,结果是真实的。然而,我注意到一些关于ode解算器的东西对我来说没有意义

我在函数内部放置了一个print函数(
print(“t-inside-ODE-function”,t)
),该函数计算导数向量(
\uu调用(self,t,y)
),并在while循环的该函数外部(
print(“t-extender-ODE-function”,solver.t);
)。 我希望在解算器进行时间积分时必须调用内部打印,然后调用外部打印。换言之,两个
“t-outside-ODE-function”
不能在没有
“t-inside-ODE-function”
的情况下紧接着出现。但是,在while循环的某些迭代中会发生这种情况,这意味着解算器在不计算导数的情况下进行积分

我想知道这怎么可能

import cantera as ct
import numpy as np
import scipy.integrate


class ReactorOde:
    def __init__(self, gas):
        # Parameters of the ODE system and auxiliary data are stored in the
        # ReactorOde object.
        self.gas = gas
        self.P = gas.P

    def __call__(self, t, y):
        """the ODE function, y' = f(t,y) """

        # State vector is [T, Y_1, Y_2, ... Y_K]
        self.gas.set_unnormalized_mass_fractions(y[1:])
        self.gas.TP = y[0], self.P
        rho = self.gas.density
        print("t inside ODE function", t)
        wdot = self.gas.net_production_rates
        dTdt = - (np.dot(self.gas.partial_molar_enthalpies, wdot) /
                  (rho * self.gas.cp))
        dYdt = wdot * self.gas.molecular_weights / rho

        return np.hstack((dTdt, dYdt))


gas = ct.Solution('gri30.yaml')

# Initial condition
P = ct.one_atm
gas.TPX = 1001, P, 'H2:2,O2:1,N2:4'
y0 = np.hstack((gas.T, gas.Y))

# Set up objects representing the ODE and the solver
ode = ReactorOde(gas)
solver = scipy.integrate.ode(ode)
solver.set_integrator('vode', method='bdf', with_jacobian=True)
solver.set_initial_value(y0, 0.0)

# Integrate the equations, keeping T(t) and Y(k,t)
t_end = 1e-3
states = ct.SolutionArray(gas, 1, extra={'t': [0.0]})
dt = 1e-5
while solver.successful() and solver.t < t_end:
    solver.integrate(solver.t + dt)
    gas.TPY = solver.y[0], P, solver.y[1:]
    states.append(gas.state, t=solver.t)
    print("t outside ODE function", solver.t);
    print("\n")
    
将cantera导入为ct
将numpy作为np导入
导入scipy.integrate
反应器级:
def u u初始(自身,气体):
#ODE系统的参数和辅助数据存储在
#反应器对象。
self.gas=气体
self.P=gas.P
定义调用(self,t,y):
“”“ODE函数,y'=f(t,y)”
#状态向量是[T,Y_1,Y_2,…Y_K]
自.气.集\非标准化\质量\分数(y[1:])
self.gas.TP=y[0],self.P
rho=自身气体密度
打印(“ODE函数内的t”,t)
wdot=self.gas.net\u生产率
dTdt=-(np.dot(自气体偏摩尔焓,wdot)/
(rho*self.gas.cp))
dYdt=wdot*自身气体分子量/rho
返回np.hstack((dtdtdt,dYdt))
气体=连续溶液('gri30.yaml')
#初始条件
P=ct.1\U atm
gas.TPX=1001,P,'H2:2,O2:1,N2:4'
y0=np.hstack((气体温度,气体温度))
#设置表示ODE和解算器的对象
ode=反应器极(气体)
解算器=scipy.integrate.ode(ode)
solver.set_integrator('vode',method='bdf',且_jacobian=True)
解算器。设置初始值(y0,0.0)
#积分方程,保持T(T)和Y(k,T)
t_端=1e-3
states=ct.SolutionArray(gas,1,extra={'t':[0.0]})
dt=1e-5
而solver.successful()和solver.t
解算器具有自适应步长。这意味着它在内部步骤中进行,以适应给定的误差公差。在从一个步长点到下一个步长点的线段中,将插值解的值。因此,时间循环的一系列外部步骤可能会落入同一个内部段。如果将误差公差设置为较小的默认值,则可能会出现相反的情况,即每个外部值请求需要几个内部步骤。

我理解您关于自适应步长的观点。如果我错了,请纠正我:我设置的步长是1e-5。解算器的内部过程允许执行比1e-5更大的步骤,因此当我的代码运行时,例如solve.integrate(t=5e-5),ode解算器知道答案,因为t已根据前面步骤中的计算计算出t=5e-5的值,因此它忽略了调用函数。是。例如,如果内部步长为
3.2e-5
,则有2个“自由”外部步长等。