当前位置: 首页 > 知识库问答 >
问题:

MATLAB:用IF条件在线改变ODE参数

桑思远
2023-03-14

所以,我试图解决描述电力系统响应和稳定性的ODE。精确的方程和理论并不重要。正如标题所暗示的,我希望ode求解器根据一个IF条件改变一些参数。代码如下:

clear; 

E = 10;
X = 10;
R = 0;

T = 5;      % Time Constant
tmax = 100;   
G0 = 0;     % Initial Value

Psc = E^2/X;
P0 = 1.25*Psc; % Power Losses

G = 0:0.001:2;
a = tand (0);
V = E ./ sqrt( (1+R*G+a*X*G).^2 + (X*G-a*R*G).^2 );
P = E^2*G ./ ( (1+R*G+a*X*G).^2 + (X*G-a*R*G).^2 );


% ODE Numerical Solution
[t23, Gsol23s] = ode23s(@(t, G) P0/T - G* (E ./ sqrt( (1+R*G+a*X*G).^2 ...
    + (X*G-a*R*G)).^2 )^2, [0 tmax], G0);

Vsol23s = E ./ sqrt( (1+R*Gsol23s+a*X*Gsol23s).^2 ... 
    + (X*Gsol23s-a*R*Gsol23s).^2 );
Psol23s = E^2*Gsol23s ./ ( (1+R*Gsol23s+a*X*Gsol23s).^2 ...
    + (X*Gsol23s-a*R*Gsol23s).^2 );

figure;
plot(P/Psc, V/E, 'linewidth', 3);
hold on;
grid on;
plot(Psol23s/Psc, Vsol23s/E, 'linewidth', 2);
xlabel('P/Psc'); ylabel('V/E')

figure;
plot(t23, Vsol23s/E, t23, Psol23s/Psc, t23, Gsol23s*X)
legend('V/E', 'P/Psc', 'G*B');

每次V小于0.95*E,我都想把a减5。比如:

if Vsol23s << 0.95*E
a = a - 5;
end

任何想法都非常感谢。

编辑1:一次给出一个ode步骤(而不是tspan的整个矩阵)的解决方案可以做到这一点,但我不知道这是否可能。

共有1个答案

农飞尘
2023-03-14

参数化您的diffeq,然后根据需要将A的更新值传递给它。

E = 10;
X = 10;
R = 0;

tmax = 100;   
G0 = 0;     % Initial Value

Psc = E^2/X;
P0 = 1.25*Psc; % Power Losses

G = 0:0.001:2;
a = tand (0);
V = E ./ sqrt( (1+R*G+a*X*G).^2 + (X*G-a*R*G).^2 );
P = E^2*G ./ ( (1+R*G+a*X*G).^2 + (X*G-a*R*G).^2 );

[t23, Gsol23s] = ode23s(@(t, G) f(t, G, a), [0 tmax], G0);

Vsol23s = E ./ sqrt( (1+R*Gsol23s+a*X*Gsol23s).^2 + (X*Gsol23s-a*R*Gsol23s).^2 );
Psol23s = E^2*Gsol23s ./ ( (1+R*Gsol23s+a*X*Gsol23s).^2 + (X*Gsol23s-a*R*Gsol23s).^2 );

tIdx = find(Vsol23s < 0.95*E, 1, 'first');
if tIdx
    t0 = t23(tIdx);
    G0 = Gsol23s(tIdx);
    tSol = t23(1:tIdx-1);
    gSol = Gsol23s(1:tIdx-1);
    vSol = Vsol23s(1:tIdx-1);
    pSol = Psol23s(1:tIdx-1);
end

while tIdx

    a = a - 5;

    [t23, Gsol23s] = ode23s(@(t, G) f(t, G, a), [t0 tmax], G0);
    Vsol23s = E ./ sqrt( (1+R*Gsol23s+a*X*Gsol23s).^2 + (X*Gsol23s-a*R*Gsol23s).^2 );
    Psol23s = E^2*Gsol23s ./ ( (1+R*Gsol23s+a*X*Gsol23s).^2 + (X*Gsol23s-a*R*Gsol23s).^2 );
    tIdx = find(Vsol23s < 0.95*E, 1, 'first');
    disp(tIdx)
    if tIdx
        t0 = t23(tIdx);
        G0 = Gsol23s(tIdx);
        tSol = [tSol; t23(1:tIdx-1)];
        gSol = [gSol; Gsol23s(1:tIdx-1)];
        vSol = [vSol; Vsol23s(1:tIdx-1)];
        pSol = [pSol; Psol23s(1:tIdx-1)];
    else
        tSol = [tSol; t23];
        gSol = [gSol; Gsol23s];
        vSol = [vSol; Vsol23s];
        pSol = [pSol; Psol23s];
    end

end

figure;
plot(P/Psc, V/E, 'linewidth', 3);
hold on;
grid on;
plot(pSol/Psc, vSol/E, 'linewidth', 2);
xlabel('P/Psc'); ylabel('V/E')

figure;
plot(tSol, vSol/E, tSol, pSol/Psc, tSol, gSol*X)
legend('V/E', 'P/Psc', 'G*B');


function y = f(t, G, a)
    % parameters
    E = 10;
    X = 10;
    R = 0;

    T = 5;      % Time Constant

    Psc = E^2/X;
    P0 = 1.25*Psc; % Power Losses

    y = P0/T - G* (E ./ sqrt( (1+R*G+a*X*G).^2 + (X*G-a*R*G)).^2 )^2;
end
 类似资料:
  • 我正在使用一个僵硬的求解器(ode15s)对一个颂歌系统进行时间积分。它在起作用,但我想加快速度。 方程组以状态空间形式给出: 这里的诀窍部分是强迫函数F,它是高度非线性的,依赖于x和t参数。它利用x参数求解Poisson型二维方程(用有限体积法)。力F与泊松方程解成正比。 用迭代法求解泊松方程需要一个初始条件,我把它设为零()。我想我可以通过提供一个更好的场的初始估计来提高计算速度(一个更好的初

  • 所以,我正在用ODE45在MATLAB中求解一些ODE。它们和代码没有什么特别复杂的,但是每个ODE解决方案需要20-30分钟来获得,我需要获得大约10分钟。(这是一个参数扫描。) 当我坐在那里等待解的到来时,我发现自己希望有一种方法可以在解诗的时候看着解画出来,这样既可以让自己确信正在取得进展,也可以在解似乎有问题的时候结束解。 有没有一种方法从ode45返回当前的(不完整的)解,并在解的时候实

  • 问题内容: 我的Express应用上有一条路线如下: 该ID始终是数字。但是,此路线目前与其他条件匹配,例如。 我想我希望从中得到两点: 仅在ID为数字时使用此路由,并且 仅当尚未为该特定参数定义路线时(例如与冲突)。 能做到吗? 问题答案: 扩展Marius的答案,您可以提供正则表达式和参数名称:

  • 我已经广泛地搜索了,并认为我不会是唯一一个有这个问题的人,但看起来似乎我是。 有人有什么想法吗?提前向大家表示感谢,祝大家假期愉快!

  • 我正在研究哲学家进餐问题,n位哲学家轮流思考和进餐。我想有一个版本,哲学家们会按照id的顺序进食:0,1,2,3,4。。。,但是我的线程一直被阻塞。我的线程从调用PhilosopherThread开始。 我想把哲学家们整理好有点麻烦。我只能在线程堵塞之前吃前2个线程。 编辑:据我所知,我这样做是对的。我首先锁定互斥锁,然后检查pindex是否是当前线程id,如果不是,线程将等待,直到pindex等