自定义定期功能,无计数器 [英] Custom periodic function without counter

查看:60
本文介绍了自定义定期功能,无计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ode45来解决一个简单的ODE:

I am using ode45 to solve a simple ODE:

function dCdt=u_vent(t,C)
if t>   600 &&  t<= 720
    Q=Q2;               
elseif t>   1320    &&  t<= 1440
    Q=Q2;           
elseif t>   2040    &&  t<= 2160
    Q=Q2;           
elseif t>   2760    &&  t<= 2880
    Q=Q2;               
elseif t>   3480    &&  t<= 3600
    Q=Q2;
else
    Q=Q1;
end

V=100;
C_i=400;
S=100;

dCdt=Q/V*C_i+S/V-Q/V*C(1);
return

然后我用它来解决:

[t,C]=ode45(@u_vent, [0 1*3600], 400);

我想创建一个周期性函数,例如图中的Q0<t<3600函数,而不使用那些if语句...有什么想法吗?

I would like to create a periodic function such as the one in the picture for Q, 0<t<3600, without using those if statements... any thoughts?

推荐答案

这是常见的问题类型.用户通常希望在Matlab的ODE求解器使用的积分函数中不连续地更改变量.不幸的是,这通常是一个坏主意.这些求解器假定微分方程是平滑且连续的.充其量,您的代码将变慢.在最坏的情况下,您将遇到更大的错误,甚至完全错误的结果.使用诸如 ode15s 这样的刚性求解器可能会有所帮助,但是它也假设连续性.由于您指定的系统具有解析解决方案,因此模拟"的最简单方法实际上可能是通过此时间功能传递脉冲序列.

This is a common type of question. Users often wish to discontinuously change a variable within the integration function used by Matlab's ODE solvers. Unfortunately, this is usually a bad idea. These solvers assume that the differential equations are smooth and continuous. At best your code will be slower. At worst you'll have larger errors or even completely wrong results. Using a stiff solver such as ode15s might help a bit, but it too assumes continuity. As your system as specified has analytic solution, the easiest way so "simulate" it might actually be to pass a pulse train trough this function of time.

很容易解决参数随时间(即相对于自变量)不连续变化的情况.只需在每个时间段内整合所需的时间段即可:

The case when a parameter changes discontinuously in time, i.e., with respect to the independent variable, is easy to solve. Simply integrate over each time span for the number of periods you want:

t1 = 600;
t2 = 120;
TSpan = [0 t1]; % Initial time vector
NPeriods = 5;   % Number of periods
C0 = 400;       % Initial condition
Q1 = ...
Q2 = ...
V = 100;
C_i = 400;
S = 100;
u_vent = @(t,C,Q)(Q*(C_i-C(1))+S)/V; % Integration function as anonymous function
Cout = C0;       % Array to store solution states
tout = Tspan(1); % Array to store solution times
for i = 1:NPeriods
    [t,C] = ode45(@(t,C)u_vent(t,C,Q1), TSpan, C0);
    tout = [tout;t(2:end)];   % Append time, 2:end used to avoid avoid duplicates
    Cout = [Cout;C(2:end,:)]; % Append state
    TSpan = [0 t2]+t(end);    % New time vector
    C0 = C(end);              % New initial conditions
    [t,C] = ode45(@(t,C)u_vent(t,C,Q2), TSpan, C0);
    tout = [tout;t(2:end)];
    Cout = [Cout;C(2:end,:)];
    TSpan = [0 t1]+t(end);
    C0 = C(end);
end

这允许ode45在一组初始条件下的指定时间内集成ODE.然后,在新的不连续初始条件或不同参数的情况下,在先前集成的结束时间重新开始集成.这导致瞬变.您可能不喜欢代码的外观,但这是完成的方式.如果参数相对于状态变量不连续地更改,则更加棘手.

This allows ode45 to integrate an ODE for a specified time from a set of initial conditions. Then the integration is restarted at the end time of the previous integration with new discontinuous initial conditions or different parameters. This results in a transient. You may not like the look of the code, but this is how it's done. It's even trickier if parameters change discontinuously with respect to state variables.

可选.每次调用/重新启动ode45时,该函数必须确定要使用的初始步长.这是重新启动求解器的主要(最低)成本/开销.在某些情况下,您可以通过指定 选项,具体取决于上次调用使用的最后步长.通过在命令窗口中键入edit ballode来查看ballode演示,以获取更多详细信息.

Optional. Each time you call/restart ode45 the function must figure out an initial step size to use. This is the primary (minimal) cost/overhead of restarting the solver. In some cases you may be able to help out the solver by specifying an 'InitialStep' option based on the last step size used from the previous call. See the ballode demo for further details on this by typing edit ballode in your command window.

笔记.在每个集成步骤之后,将toutCout数组附加到其自身.这实际上是动态内存分配.只要NPeriods很小,这就不会有问题,因为在最新版本的Matlab中动态内存分配可以非常快,而您只需要在大块中重新分配一些时间.如果您指定固定步长输出(例如TSpan = 0:1e-2:600;),那么您将确切知道要为toutCout预分配多少内存.

A note. The tout and Cout arrays are appended to themselves after each integration step. This is effectively dynamic memory allocation. As long as NPeriods is reasonably small, this likely won't be a problem as dynamic memory allocation in recent versions of Matlab can be very fast and you're only reallocating a few time in large blocks. If you specify fixed step size output (e.g., TSpan = 0:1e-2:600;) then you'll know exactly how much memory to preallocate to tout and Cout.

这篇关于自定义定期功能,无计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆