小编Den*_*nis的帖子

分子动力学模拟:波动偶极子模型实现

我正在进行二氧化硅的分子动力学模拟.前段时间我转向波动的偶极子模型,经过多方努力,我仍然遇到问题.

简而言之,系统中的所有氧原子都是可极化的,它们的偶极矩取决于它们相对于系统中所有其他原子的位置.更具体地说,我使用TS potential(http://digitallibrary.sissa.it/bitstream/handle/1963/2874/tangney.pdf?sequence=2),其中在每个时间步骤迭代地发现偶极子.

这意味着在评估作用于原子的力时,我必须考虑这种对坐标的潜在能量依赖性.以前,我使用的是简单的成对潜在模型,所以我会设置我的程序来使用通过区分潜在能量表达式获得的分析公式来计算力.

现在我不知所措:如何实现这一新潜力?在我发现的所有文章中,他们只给出了公式,而不是算法.在我看来,当我计算力,作用于某个原子时,我必须考虑到这个原子的偶极子的变化,所有相邻原子的偶极子的变化,然后是更多原子的偶极子的变化等等,因为它们彼此依赖.毕竟,正是由于这种相互依赖性,在每个时间步骤迭代地发现了偶极子.显然,我不能迭代地为每个原子计算力,因为算法的计算复杂度太高了.我应该使用一些简单的函数来解释偶极子的变化吗?这看起来也不是一个好主意,因为偶极子是迭代计算的,具有高精度,然后,它实际上很重要(计算力),我们会使用原油函数吗?

那么我该如何实现这个模型呢?此外,是否可以像以前一样分析计算力,或者是否有必要使用导数的有限差分公式计算它们?

我没有在文献中找到我的问题的答案,但是如果你知道一些文章,网站或书籍,这些材料被突出显示,请指导我.

感谢您的时间!

================================================== ================================

更新:

谢谢您的回答.不幸的是,这不是我的问题.我没有问过如何计算偶极子,但是如果计算这些偶极子随着运动的变化而变化很大.

我试图以直接的方式计算力(不考虑偶极子通过它们的距离相互依赖,只计算每一步的偶极子,然后计算力就像那些偶极是静态的),但我得到的结果在物理上是不正确的.

为了分析这种情况,我建立了一个由两个原子组成的系统的模拟:Si和O.它们具有相反的电荷,因此它们会振荡.能量时间依赖图形看起来像这样:

在此输入图像描述

顶部的曲线代表动能,中间的曲线代表潜在的能量而不考虑偶极相互作用,底部的曲线代表系统的势能,其中偶极相互作用被考虑在内.

从图中可以清楚地看到,系统正在做它不应该做的事情:爬上潜在的斜坡.所以我认为这是因为我没有考虑偶极矩坐标依赖性.例如,在给定的时间点,我们计算力,并且它们被定向以便使两个原子彼此相向移动.但是当我们确实将它们朝向彼此移动时(甚至略微移动),偶极矩会发生变化,我们发现实际上我们的能量比以前更高!在下一个时间步骤中情况是相同的.

所以问题是,如何将这种影响考虑在内,导致我能想到的几种方式无论是计算量太强还是太粗糙.

algorithm simulation

8
推荐指数
1
解决办法
604
查看次数

OpenMP:在线程之间共享数组

今天是个好日子!

我正在进行分子动力学模拟,最近我开始尝试并行实现它.乍一看,一切看起来都很简单:在最耗时的循环之前编写#pragma omp parallel for directive.但实际上,这些循环中的函数在数组上运行,或者确切地说,在属于我的类的对象的数组上运行,该数组包含有关此系统的粒子系统和函数的所有信息,因此当我添加#时pragma指令在最耗时的循环之一之前,尽管我的2核4线程处理器已满载,但计算时间实际上增加了几倍.

为了解决这个问题,我写了另一个更简单的程序.该测试程序执行两个相同的循环,一个并行,第二个循环 - 串行.测量执行这两个循环所花费的时间.结果让我感到惊讶:每当第一个循环并行计算时,其计算时间与串行模式(分别为1500和6000毫秒)相比有所下降,但第二个循环的计算时间急剧增加(15000对6000连续).

我尝试使用private()和firstprivate()子句,但结果是一样的.不应该自动共享并行区域之前定义和初始化的每个变量吗?如果在另一个向量上执行,第二个循环的计算时间恢复正常:vec2,但是为每次迭代创建一个新向量显然不是一个选项.我也尝试将vec1的实际更新放到#pragma omp关键区域,但这也没有任何好处.没有帮助添加Shared(vec1)子句.

如果你能指出我的错误并展示正确的方法,我将不胜感激.

是否有必要将私有(i)放入代码中?

这是测试程序:

#include "stdafx.h"
#include <omp.h>
#include <array>
#include <time.h>
#include <vector>
#include <iostream>
#include <Windows.h>
using namespace std;
#define N1  1000
#define N2  4000
#define dim 1000

int main(){
    vector<int>res1,res2;
    vector<double>vec1(dim),vec2(N1);
    clock_t t, tt;
    int k=0;
    for( k = 0; k<dim; k++){
        vec1[k]=1;
    }

    t = clock();

    #pragma omp parallel 
        {
        double temp; 
        int i,j,k;
        #pragma omp for private(i)
            for( i = 0; i<N1; i++){
                for(j = …
Run Code Online (Sandbox Code Playgroud)

parallel-processing multithreading openmp

7
推荐指数
1
解决办法
4843
查看次数

OpenMP和OOP(分子动力学模拟)

我正在进行分子动力学模拟,并且我一直在努力并行实现它,虽然我成功地完全加载了我的4线程处理器,但并行计算时间大于计算时间.串行模式.

研究每个线程在哪个时间点开始并完成其循环迭代,我注意到一个模式:就好像不同的线程正在等待彼此.就在那时,我把注意力转向了程序的结构.我有一个类,其实例代表我的粒子系统,包含有关粒子的所有信息和使用此信息的一些函数.我还有一个类实例,它代表我的原子间势,包含潜在函数的参数以及一些函数(其中一个函数计算两个给定粒子之间的力).

因此在我的程序中存在两个不同类的实例,它们彼此交互:一个类的一些函数引用另一个类的实例.我试图并行实现的块看起来像这样:

      void Run_simulation(Class_system &system, Class_potential &potential, some other arguments){
          #pragma omp parallel for
              for(…) 
      }
Run Code Online (Sandbox Code Playgroud)

对于(...)是实际的计算,使用从数据system中的实例Class_system类,并从一些功能potential的实例Class_potential类.

我是对的,这种结构是我烦恼的根源吗?

你能否告诉我在这种情况下需要做些什么?我必须以完全不同的方式重写我的程序吗?我应该使用一些不同的工具来并行实现我的程序吗?

c++ parallel-processing openmp

4
推荐指数
1
解决办法
909
查看次数