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

在ode MATLAB求解器中使用中间值

孟茂学
2023-03-14

我正在使用一个僵硬的求解器(ode15s)对一个颂歌系统进行时间积分。它在起作用,但我想加快速度。

方程组以状态空间形式给出:

function [dx] = fun(t,x,M,C,K,other_parameters)
    % Mx'' + Cx' + Kx = F(t)
    % BUNCH OF CALCULATIONS
    F = solveP(x,t);

    A = [zeros(n) eye(n) ; -M\K -M\C];
    b = M\F;

    dx = A*x + b
end

这里的诀窍部分是强迫函数F,它是高度非线性的,依赖于x和t参数。它利用x参数求解Poisson型二维方程(用有限体积法)。力F与泊松方程解成正比。

function [F] = solveP(x,t)
    % initialize solution
    Phi = zeros(Ni,Nj);

    % solve iteratively
    % ...
    while (~converged)
         % some calculations

         % iterative solver
         Phi(i,j) = (aE*Phi(i,j+1) + aW*Phi(i,j-1) + aN*Phi(i+1,j) +...
                     aS*Phi(i-1,j) + S(i,j))/aP;
    end


    % calculate F
    F = sum(Phi(:)); % discrete integration over domain
end

用迭代法求解泊松方程需要一个初始条件,我把它设为零(phi=zeros(Ni,Nj))。我想我可以通过提供一个更好的场的初始估计来提高计算速度(一个更好的初始条件会更快地到达所寻求的答案)。我能想到的最优初始条件(除了=0)是ode求解器前一次迭代(最后一步)中获得的字段的值((k)_initial=(k-1))。

PS:我尝试使用持久变量,但这不是一个好的解决方案。ode解算器在时间前进之前分几点计算函数。persistent变量在每次ode调用odefun时保存收敛字段。这并不完全是我想要的,而且随着时间的推移,这实际上提供了错误的答案。

共有1个答案

丰超
2023-03-14

一种可能的修复方法是在一次迭代后将找到的phi解决方案写入基本工作区。首先,您必须在基本工作区中初始化phi:

Phi = zeros(Ni, Nj);

然后,您可以通过使用evalinsolvep函数中调用这个phi。然后,在找到PHI的更新解决方案后,确保使用assignin在基本工作区中再次分配它。solvep将如下所示:

function [F] = solveP(x,t)
    % initialize solution
    Phi = evalin('base','Phi');

    % solve iteratively
    % ...
    while (~converged)
         % some calculations

         % iterative solver
         Phi(i,j) = (aE*Phi(i,j+1) + aW*Phi(i,j-1) + aN*Phi(i+1,j) +...
                     aS*Phi(i-1,j) + S(i,j))/aP;
    end


    % calculate F
    F = sum(Phi(:)); % discrete integration over domain

    % assign updated Phi in base workspace
    assignin('base', 'Phi2', Phi)
end
 类似资料:
  • 我已经广泛地搜索了,并认为我不会是唯一一个有这个问题的人,但看起来似乎我是。 有人有什么想法吗?提前向大家表示感谢,祝大家假期愉快!

  • 我很难理解非线性优化中的性能如何受到求解器引擎接口的特定方式的影响。 我们有一个优化模型,在它的第一个版本中,是用GAMS编写的。IPOPT(一个常见的FOOS非线性求解器引擎)在IPOPT(无函数评估)中为每个优化返回1.4 CPU秒的执行时间,在函数评估中返回0.2 CPU秒的执行时间。 当我们将模型转换为C(以便更好地考虑模型的非优化组件)并通过其C API接口IPOPT时(使用ADOL-C

  • 所以,我在这个快速的应用程序中工作,所有路线都有有限的身体大小,除非你是管理员,因为管理员需要几个路线的无限身体大小。我有限制的身体大小中间件,我这样使用它: 但最终我的身体没有被解析,一切都没有定义。 我怎么能解决这个问题,只有一个中间件,而不是通过传递身体解析器中间件到每一个路由或路由器分开。

  • 问题内容: 我尝试“要求”一个父控制器(不是指令),但是AngularJS返回一个异常。代码是这样的: HTML 错误 错误:找不到指令’myDirective’所需的[$ compile:ctreq]控制器’myController’! 为什么? 也许,属性必须引用 指令 的控制器? 谢谢 问题答案: 要求在另一个指令中使用其他指令控制器,请参考以下示例

  • 在我的php文件中,我有以下内容来创建一个带有FPDF库的PDF: 但是请求是响应这个,而不是打开一个保存对话框来保存我的PDF。 %PDF-1.3 3 0 obj<>endobj 4 0 obj<>stream x 3 R@2π35 W(çR qπw 3 t04多30 pispéz*[(hx·ääää+çó)·(j*dé7 w endstream endobj 1 0 obj /xobject<

  • 问题内容: 我正在尝试解析Java中的SOAP请求,但代码未返回任何节点,这里的代码可以使任何人找到错误 问题答案: 您需要设置一个上: 演示版 输出量