显式欧拉方法对于反应扩散问题太慢


10

我正在使用以下C ++代码解决Turing的反应扩散系统。它太慢了:对于128x128像素纹理,可接受的迭代次数为200 –导致2.5秒的延迟。我需要进行400次迭代才能获得有趣的图像-但是等待5秒钟太多了。同样,纹理的大小实际上应为512x512-但这会导致大量的等待时间。设备是iPad,iPod。

有没有机会更快地做到这一点?欧拉方法收敛缓慢(维基百科)–使用更快的方法可以减少迭代次数吗?

编辑:正如托马斯·克里姆佩尔(Thomas Klimpel)所指出的,这些行:“ if(m_An [i] [j] <0.0){...}”,“ if(m_Bn [i] [j] <0.0){...}”延迟收敛:移除后,经过75次迭代后会出现有意义的图像。我在下面的代码中注释掉了这些行。

void TuringSystem::solve( int iterations, double CA, double CB ) {
    m_iterations = iterations;
    m_CA = CA;
    m_CB = CB;

    solveProcess();
}

void set_torus( int & x_plus1, int & x_minus1, int x, int size ) {
    // Wrap "edges"
    x_plus1 = x+1;
    x_minus1 = x-1;
    if( x == size - 1 ) { x_plus1 = 0; }
    if( x == 0 ) { x_minus1 = size - 1; }
}

void TuringSystem::solveProcess() {
    int n, i, j, i_add1, i_sub1, j_add1, j_sub1;
    double DiA, ReA, DiB, ReB;

    // uses Euler's method to solve the diff eqns
    for( n=0; n < m_iterations; ++n ) {
        for( i=0; i < m_height; ++i ) {
            set_torus(i_add1, i_sub1, i, m_height);

            for( j=0; j < m_width; ++j ) {
                set_torus(j_add1, j_sub1, j, m_width);

                // Component A
                DiA = m_CA * ( m_Ao[i_add1][j] - 2.0 * m_Ao[i][j] + m_Ao[i_sub1][j]   +   m_Ao[i][j_add1] - 2.0 * m_Ao[i][j] + m_Ao[i][j_sub1] );
                ReA = m_Ao[i][j] * m_Bo[i][j] - m_Ao[i][j] - 12.0;
                m_An[i][j] = m_Ao[i][j] + 0.01 * (ReA + DiA);
                // if( m_An[i][j] < 0.0 ) { m_An[i][j] = 0.0; }

                // Component B
                DiB = m_CB * ( m_Bo[i_add1][j] - 2.0 * m_Bo[i][j] + m_Bo[i_sub1][j]   +   m_Bo[i][j_add1] - 2.0 * m_Bo[i][j] + m_Bo[i][j_sub1] );
                ReB = 16.0 - m_Ao[i][j] * m_Bo[i][j];
                m_Bn[i][j] = m_Bo[i][j] + 0.01 * (ReB + DiB);
                // if( m_Bn[i][j] < 0.0 ) { m_Bn[i][j]=0.0; }
            }
        }

        // Swap Ao for An, Bo for Bn
        swapBuffers();
    }
}

另外,我想提及的是,您最好不要交叉提问,因为看来您在这里这里都提出了非常相似的问题。
Godric Seer 2012年

您是否已经偶然地看到了格雷格·特克(Greg Turk)的作品
JM 2012年

@JM:还没有。我只是尝试运行他的代码:它要求X服务器具有PseudoColor,即8位色深。我想我无法在OSX上提供此功能。我尝试了各种VNC服务器,但没有运气。
AllCoder 2012年

我认为您仍然应该能够使Turk的方法适应当前的问题。如今,反应扩散模式似乎在计算机图形学中被大量使用。
JM 2012年

1
我可能是错的,但是m_An [i] [j] = 0.0的部分;可能实际上会向该系统添加一个元素,而该元素无法用带有连续右手边的微分方程来建模。这使得想出一个更快的求解器有点困难。
Thomas Klimpel

Answers:


9

您似乎受到稳定性的限制,这是可以预期的,因为在优化网格时扩散会很困难。刚性系统的好方法至少是部分隐含的。这将需要一些努力,但是您可以实现一个简单的多网格算法(或使用库)来解决此系统,其成本少于10个“工作单元”(基本上是一个时间步的成本)。优化网格时,迭代次数不会增加。


如果在这里扩散只会很僵硬,他可以使用Douglas-Gunn这样的ADI方法,一切都会好起来的。但是,以我自己的经验,反作用部分除了具有严重的非线性外,在刚度方面通常更差。
Thomas Klimpel,2012年

1
不幸的是,ADI的内存位置非常糟糕。还应注意,无论是否扩散,都可以隐式对待反应。在网格细化下,扩散最终将占主导地位,但是在不知道常数的情况下我们无法确定阈值在哪里。
杰德·布朗

为此(在Python中)实现向后Euler的示例代码在这里:scicomp.stackexchange.com/a/2247/123
David Ketcheson 2012年

@DavidKetcheson:使用隐式方法需要求解方程式吗?这就是为什么代码中有linalg.spsolve()的原因?
AllCoder 2012年

1
@AllCoder是的,它需要一个求解,但是求解可以比使显式方法稳定所需的所有时间步骤快得多。
杰德·布朗

2

从实际的角度来看:A5处理器功能不那么强大,因此您可以等待几次硬件迭代,或者如果您的ipod / ipad要连接到互联网,则可以远程或在云中解决问题。


我很惊讶A5的功率如此之小。Pages,Safari和其他大型应用程序如何工作得如此好?我需要生成随机的,抽象的图像,认为形态将是很简单..
AllCoder

嗯,A5是针对Web和视频(页面,Safari等)进行了优化的节能处理器。相反,大多数数字工作负载执行大量的浮点运算和数据移动,而这些功能并不是低功耗移动处理器的重点。
fcruz 2012年

0

相对于其他方法,Euler的收敛速度很慢,但是我不认为这是您感兴趣的。如果您只是在寻找“有趣的”图像,请增加时间步长并减少迭代次数。正如杰德(Jed)所指出的那样,问题在于,显式欧拉方法存在稳定性问题,并且与网格大小相关的时间步长较大。网格越小(即图像的分辨率越高),说明它的时间步长就越小。

例如,通过使用隐式euler而不是显式的euler,您不会获得任何收敛阶数,但是该解决方案将具有无条件的稳定性,从而允许更大的时间步长。隐式方法的实现更加复杂,并且每个时间步长都要进行更多的计算,但是您应该发现,通过总共减少步长,可以大大提高隐含方法的收益。


此问题受到稳定性的限制,因此简单地增加时间步长将不起作用。
杰德·布朗

如果将0.01更改为例如0.015,则在所有点上都会得到“化学试剂浓度接近零”,即灰色正方形。这是我的代码的来源:drdobbs.com/article/print?articleId=184410024
AllCoder 2012年

是的,那是杰德提到的稳定性问题的结果。正如他在回答中提到的那样,使用以更好的稳定性能为特征的隐式方法将为您解决此问题。我将更新答案以删除不相关的信息。
Godric Seer 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.