分子MC模拟不平衡

发布于 2025-01-24 14:15:03 字数 1824 浏览 4 评论 0 原文

假设聚合物在其链中具有 n 单体。我想使用 Bead-Spring 模型来模拟其运动。但是,没有应用周期性的边界条件。 COZ,生成点,使它们永远不会越过边界。

因此,我写了以下程序。

我正在使用100万步。能量不会像预期的那样波动。几千步后,曲线完全平坦。

​Y轴是总能量。

谁能检查源代码并告诉我我应该更改什么?

NB我特别关注计算聚合物总能量的功能。

大概,该算法不正确。

    public double GetTotalPotential()
    {
        double totalBeadPotential = 0.0;
        double totalSpringPotential = 0.0;

        // calculate total bead-energy
        for (int i = 0; i < beadsList.Count; i++)
        {
            Bead item_i = beadsList[i];
            Bead item_i_plus_1 = null;

            try
            {
                item_i_plus_1 = beadsList[i + 1];

                if (i != beadsList.Count - 1)
                {
                    // calculate total spring energy.
                    totalSpringPotential += item_i.GetHarmonicPotential(item_i_plus_1);
                }
            }
            catch { }

            for (int j = 0; j < beadsList.Count; j++)
            {
                if (i != j)
                {
                    Bead item_j = beadsList[j];
                    totalBeadPotential += item_i.GetPairPotential(item_j);
                    //Console.Write(totalBeadPotential + "\n");
                    //Thread.Sleep(100);
                }
            }
        }

        return totalBeadPotential + totalSpringPotential;
    } 

Suppose, a polymer has N monomers in its chain. I want to simulate its movement using the bead-spring model. However, there was no periodic boundary condition applied. Coz, points were generated such that they never cross the boundary.

So, I wrote the following program.

I am using 1 million steps. The energy is not fluctuating as expected. After several thousand steps the curve goes totally flat.

enter image description here

enter image description here

The X-axis is steps. Y-axis is total energy.

Can anyone check the source code and tell me what I should change?

N.B. I am especially concerned with the function that calculates the total energy of the polymer.

Probably, the algorithm is incorrect.

    public double GetTotalPotential()
    {
        double totalBeadPotential = 0.0;
        double totalSpringPotential = 0.0;

        // calculate total bead-energy
        for (int i = 0; i < beadsList.Count; i++)
        {
            Bead item_i = beadsList[i];
            Bead item_i_plus_1 = null;

            try
            {
                item_i_plus_1 = beadsList[i + 1];

                if (i != beadsList.Count - 1)
                {
                    // calculate total spring energy.
                    totalSpringPotential += item_i.GetHarmonicPotential(item_i_plus_1);
                }
            }
            catch { }

            for (int j = 0; j < beadsList.Count; j++)
            {
                if (i != j)
                {
                    Bead item_j = beadsList[j];
                    totalBeadPotential += item_i.GetPairPotential(item_j);
                    //Console.Write(totalBeadPotential + "\n");
                    //Thread.Sleep(100);
                }
            }
        }

        return totalBeadPotential + totalSpringPotential;
    } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄情伤 2025-01-31 14:15:03

此应用程序的问题是,模拟( simulation.simulatemotion )在单独的线程中与draw Timer并行运行( simulationguiform.timer.timer1_tick ),并共享相同的状态( polymerchain )无需任何同步/信号,因此 polymerchain 的某些突变被完全跳过(未绘制),并且仿真完成(远前绘制绘制之前) timer1_tick 将重新绘制相同的 Polymerchain 。您可以通过对 simulation 添加计数器并在 simulateMotion 中增加情况来轻松地检查,

public class Simulation
{
    public static int Simulations = 0; // counter
    public static void SimulateMotion(PolymerChain polymerChain, int iterations)
    {
        Random random = new Random();
        
        for (int i = 0; i < iterations; i++)
        {
            Simulations++; // bump the counter
            // rest of the code
            // ...

并在 timer1_tick 中进行检查:

private void timer1_Tick(object sender, EventArgs e)
{
    // ...
    // previous code
    if (Simulation.Simulations == totalIterations)
    {
        // breakpoint or Console.Writeline() ...
        // will be hit as soon as "the curve goes totally flat" 
    }

    DrawZGraph();            
}

您需要重写应用程序 simulateMotion 在某些集合中存储迭代,该集合被 timer1_tick 消费(例如,基本上实现生产者 - 消费者模式,例如,您可以尝试使用 blockingcollection ,就像我在 pull request 或仅执行动作的操作当渲染当前状态时。

Problem of this application is that simulations (Simulation.SimulateMotion) are run in separate thread in parallel to the draw timer (SimulationGuiForm.timer1_Tick) and share the same state (polymerChain) without any sync/signaling, so some mutations of polymerChain are skipped completely (not drawn) and when the simulation is finished (far before the finish of the drawing) the timer1_Tick will redraw the same polymerChain. You can easily check that by adding counter to Simulation and increasing it in the SimulateMotion:

public class Simulation
{
    public static int Simulations = 0; // counter
    public static void SimulateMotion(PolymerChain polymerChain, int iterations)
    {
        Random random = new Random();
        
        for (int i = 0; i < iterations; i++)
        {
            Simulations++; // bump the counter
            // rest of the code
            // ...

And checking it in timer1_Tick:

private void timer1_Tick(object sender, EventArgs e)
{
    // ...
    // previous code
    if (Simulation.Simulations == totalIterations)
    {
        // breakpoint or Console.Writeline() ...
        // will be hit as soon as "the curve goes totally flat" 
    }

    DrawZGraph();            
}

You need to rewrite your application in such way that SimulateMotion either stores iterations in some collection which is consumed by timer1_Tick (basically implementing producer-consumer pattern, for example you can try using BlockingCollection, like I do in the pull request) or performs it's actions only when the current state is rendered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文