Молекулярная динамика — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Визуализация)
(Код программы)
Строка 16: Строка 16:
  
 
==Код программы==
 
==Код программы==
 +
Код программы:<br />
 +
    window.addEventListener('load',main,false)
 +
    function main(){
 +
    var N = document.getElementById("num").value;
 +
    Num = document.getElementById("num").value;
 +
    my = document.getElementById("my");
 +
    my.innerHTML =Num + " частиц";
 +
    var animation = 0;
 +
    var za = 0;
 +
    var ctx2 = canvasex2.getContext('2d');
 +
    var cplot = canvasex1.getContext('2d');
 +
    var cpl = canvasex3.getContext('2d');
 +
    var w = canvasex1.width;
 +
    var h = canvasex1.height;
 +
    var particles = [];
 +
    var t_max = 0;
 +
    var E=[];
 +
    var Ep=[];
 +
    una.onclick= function una(){
 +
    animation = 0;
 +
    }
 +
    start.onclick= function start(){
 +
    var D = document.getElementById("D").value;  //энергия связи
 +
    var beta = document.getElementById("b").value;  //вязкость
 +
    animation=1;
 +
    za += 1;
 +
    var l = canvasex2.height;
 +
    var a = 30; //равновесное расстояние
 +
    var m = 1;
 +
    var rad = 10;
 +
    var dt=1/60;
 +
 +
    function Particle(x,y,vx,vy){
 +
    var that=this;
 +
    this.x=x;
 +
    this.y=y;
 +
    this.vx=vx;
 +
    this.vy=vy;
 +
    this.info = function (){
 +
    console.log('Position: ('+that.x+','+that.y+')\nVelocity: ('+that.vx+','+that.vy+')')
 +
    }
 +
    this.move=function(){
 +
    if ((that.x-rad)<0||(that.x+rad)>l){
 +
    that.vx*=-1;
 +
    }
 +
    if ((that.y-rad)<0||(that.y+rad)>l){
 +
    that.vy*=-1;
 +
    }
 +
    that.x+=that.vx*dt;
 +
    that.y+=that.vy*dt;
 +
    }
 +
    this.draw = function(){
 +
    ctx2.beginPath();
 +
    ctx2.arc(that.x,that.y,rad,0,2*Math.PI);
 +
    ctx2.fillStyle = '#9999FF';
 +
    ctx2.fill();
 +
    }
 +
    }
 +
 +
    if (za==1){ // создание частиц
 +
    for(var i=0;i<N;i++){
 +
    var fi= Math.random()*2*Math.PI;
 +
    particles.push(
 +
    new Particle(
 +
      50+Math.random()*400,
 +
      50+Math.random()*400,
 +
      20*Math.cos(fi),
 +
      20*Math.sin(fi),
 +
        )
 +
        );
 +
    if (i!=0){
 +
      for (var z = 1;i-z>=0;z++)
 +
        {
 +
          if (Math.sqrt((particles[i].x-particles[i-z].x)*(particles[i].x-particles[i-z].x)+(particles[i].y-particles[i-z].y)*(particles[i].y-particles[i-z].y))<a)
 +
            { particles.length = particles.length-1;
 +
                    i = i-1;
 +
            }
 +
        }
 +
        }
 +
      particles[i].draw();
 +
      }
 +
    }
 +
 +
    function phys(){
 +
        var ep = 0;
 +
      for(var i=0;i<N;i++){
 +
          particles[i].move();
 +
          for(var j=0;j<N;j++){;
 +
            if(i!=j){
 +
                var F = 0;
 +
                var rx = particles[j].x-particles[i].x;
 +
                var ry = particles[j].y-particles[i].y;
 +
                var r = Math.sqrt(Math.pow(rx,2)+Math.pow(ry,2));
 +
                var K = Math.pow(1-Math.pow((r*r-1.21*a*a)/(16-1.21)/a/a,2),2);
 +
                if (r<1.1*a){  K = 1;  }
 +
                if (r>4*a){    K = 0;  }
 +
                if (r<15){  r = 15;  }
 +
                F = K*(12*D/a)*(Math.pow((a/r),13)-Math.pow((a/r),7));
 +
                ep+=D*(Math.pow((a/r),12)-2*Math.pow((a/r),6));
 +
                particles[i].vx = (particles[i].vx*Math.exp(-beta*dt) - (rx/r)*F*dt/m);
 +
                particles[i].vy = (particles[i].vy*Math.exp(-beta*dt) - (ry/r)*F*dt/m);
 +
                  }
 +
                }
 +
            }
 +
        for (var i=0;i<N;i++){
 +
              particles[i].x = particles[i].x+particles[i].vx*dt;
 +
              particles[i].y = particles[i].y+particles[i].vy*dt;
 +
            }
 +
        Ep.push(ep);
 +
        var e = 0;
 +
        for (var ii=0;ii<N;ii++){
 +
              e+=(particles[ii].vx*particles[ii].vx+particles[ii].vy*particles[ii].vy)/2;
 +
            }
 +
        E.push(e);
 +
        t_max+=dt;
 +
      }
 +
 +
    function draw(){
 +
        ctx2.clearRect(0,0,500,500);
 +
        for(var i=0;i<N;i++){
 +
        particles[i].draw();}
 +
        var Ep_scale =(h-20)/Math.max.apply(null,Ep);
 +
        var E_scale =(h-20)/Math.max.apply(null,E);
 +
        var t_scale= w/t_max;
 +
        cplot.beginPath();
 +
        cpl.beginPath();
 +
        for (var i =0; i<E.length-1; i++){
 +
            cplot.clearRect(0,0,w,h);
 +
            cpl.clearRect(0,0,w,h);
 +
            cplot.moveTo(dt*i*t_scale,3*h/4-Ep[i]*(Ep_scale));
 +
            cplot.lineTo(dt*(i+1)*t_scale, 3*h/4-Ep[i+1]*(Ep_scale));
 +
            cplot.font = "28px calibri";
 +
            cplot.strokeText("Ep="+Ep[i].toFixed(1),20,280)
 +
            cpl.moveTo(dt*i*t_scale,h-E[i]*(E_scale));
 +
            cpl.lineTo(dt*(i+1)*t_scale, h-E[i+1]*(E_scale));
 +
            cpl.font = "28px calibri";
 +
            cpl.strokeText("Ek="+E[i].toFixed(1),20,280)
 +
            cplot.stroke();
 +
            cpl.stroke();
 +
            }
 +
        }
 +
 +
    function control(){
 +
        if (animation!=0){
 +
            phys();
 +
            draw();
 +
          }
 +
        }
 +
    setInterval(control,1000*dt);
 +
    }
 +
  }

Версия 19:02, 31 мая 2020

Описание

Данная работа посвящена визуализации движения частиц в замкнутом объеме. Цель проекта заключается в изучении основных принципов создания рабочей модели взаимодействия. Объект исследования – процесс использования языков программирования, а также физическая теория в области динамики. Предмет исследования – программные инструменты языков JavaScript и HTML.
Исполнители :Жукин Александр, Литвинова Ярослава

Математическая модель

В данном проекте при расчете движения частиц применялась модель парного взаимодействия неполярных молекул Леннарда-Джонса, описывающая зависимость энергии взаимодействия двух частиц от расстояния между ними. Эта модель позволяет достаточно реалистично передать свойства реального взаимодействия сферических неполярных молекул.

Входные данные

  • Количество частиц
  • Вязкость среды
  • Энергия связи

Визуализация

Код программы

Код программы:

   window.addEventListener('load',main,false)
   function main(){
   var N = document.getElementById("num").value;
   Num = document.getElementById("num").value;
   my = document.getElementById("my");
   my.innerHTML =Num + " частиц";
   var animation = 0;
   var za = 0;
   var ctx2 = canvasex2.getContext('2d');
   var cplot = canvasex1.getContext('2d');
   var cpl = canvasex3.getContext('2d');
   var w = canvasex1.width;
   var h = canvasex1.height;
   var particles = [];
   var t_max = 0;
   var E=[];
   var Ep=[];
   una.onclick= function una(){
   animation = 0;
   }
   start.onclick= function start(){
   var D = document.getElementById("D").value;  //энергия связи
   var beta = document.getElementById("b").value;  //вязкость
   animation=1;
   za += 1;
   var l = canvasex2.height;
   var a = 30; //равновесное расстояние
   var m = 1;
   var rad = 10;
   var dt=1/60;
   function Particle(x,y,vx,vy){
   var that=this;
   this.x=x;
   this.y=y;
   this.vx=vx;
   this.vy=vy;
   this.info = function (){
   console.log('Position: ('+that.x+','+that.y+')\nVelocity: ('+that.vx+','+that.vy+')')
   }	
   this.move=function(){
   if ((that.x-rad)<0||(that.x+rad)>l){
   that.vx*=-1;
   }
   if ((that.y-rad)<0||(that.y+rad)>l){
   that.vy*=-1;
   }
   that.x+=that.vx*dt;
   that.y+=that.vy*dt;
   }		
   this.draw = function(){
   ctx2.beginPath();
   ctx2.arc(that.x,that.y,rad,0,2*Math.PI);
   ctx2.fillStyle = '#9999FF';
   ctx2.fill();
   }
   }
   if (za==1){	// создание частиц
   for(var i=0;i<N;i++){
   var fi= Math.random()*2*Math.PI;
   particles.push(
   new Particle(
      50+Math.random()*400,
      50+Math.random()*400,
      20*Math.cos(fi),
      20*Math.sin(fi),
       )
       );	
   if (i!=0){
     for (var z = 1;i-z>=0;z++)
       {
         if (Math.sqrt((particles[i].x-particles[i-z].x)*(particles[i].x-particles[i-z].x)+(particles[i].y-particles[i-z].y)*(particles[i].y-particles[i-z].y))<a)
            { particles.length = particles.length-1;
                   i = i-1;
            }
        }
       }
      particles[i].draw();		
     }
    }
    function phys(){
       var ep = 0;
      for(var i=0;i<N;i++){
         particles[i].move();
         for(var j=0;j<N;j++){;
            if(i!=j){
                var F = 0;
                var rx = particles[j].x-particles[i].x;
                var ry = particles[j].y-particles[i].y;
                var r = Math.sqrt(Math.pow(rx,2)+Math.pow(ry,2));
                var K = Math.pow(1-Math.pow((r*r-1.21*a*a)/(16-1.21)/a/a,2),2);
                if (r<1.1*a){   K = 1;   }
                if (r>4*a){     K = 0;   }
                if (r<15){   r = 15;   }
                F = K*(12*D/a)*(Math.pow((a/r),13)-Math.pow((a/r),7));
                ep+=D*(Math.pow((a/r),12)-2*Math.pow((a/r),6));
                particles[i].vx = (particles[i].vx*Math.exp(-beta*dt) - (rx/r)*F*dt/m);
                particles[i].vy = (particles[i].vy*Math.exp(-beta*dt) - (ry/r)*F*dt/m);
                  }
               }
            }
        for (var i=0;i<N;i++){
             particles[i].x = particles[i].x+particles[i].vx*dt;
             particles[i].y = particles[i].y+particles[i].vy*dt;
           }
        Ep.push(ep);
        var e = 0;
        for (var ii=0;ii<N;ii++){
             e+=(particles[ii].vx*particles[ii].vx+particles[ii].vy*particles[ii].vy)/2;
           }
       E.push(e);
       t_max+=dt;
     }
   function draw(){
       ctx2.clearRect(0,0,500,500);
       for(var i=0;i<N;i++){
       particles[i].draw();}
       var Ep_scale =(h-20)/Math.max.apply(null,Ep);
       var E_scale =(h-20)/Math.max.apply(null,E);
       var t_scale= w/t_max;
       cplot.beginPath();
       cpl.beginPath();
       for (var i =0; i<E.length-1; i++){
           cplot.clearRect(0,0,w,h);
           cpl.clearRect(0,0,w,h);	
           cplot.moveTo(dt*i*t_scale,3*h/4-Ep[i]*(Ep_scale));
           cplot.lineTo(dt*(i+1)*t_scale, 3*h/4-Ep[i+1]*(Ep_scale));
           cplot.font = "28px calibri";
           cplot.strokeText("Ep="+Ep[i].toFixed(1),20,280)	
           cpl.moveTo(dt*i*t_scale,h-E[i]*(E_scale));
           cpl.lineTo(dt*(i+1)*t_scale, h-E[i+1]*(E_scale));
           cpl.font = "28px calibri";
           cpl.strokeText("Ek="+E[i].toFixed(1),20,280)
           cplot.stroke();
           cpl.stroke();						
           }
       }
   function control(){
       if (animation!=0){
           phys();
           draw();
         }
       }
   setInterval(control,1000*dt);
   }
  }