Молекулярная динамика
Материал из Department of Theoretical and Applied Mechanics
Описание
Данная работа посвящена визуализации движения частиц в замкнутом объеме. Цель проекта заключается в изучении основных принципов создания рабочей модели взаимодействия. Объект исследования – процесс использования языков программирования, а также физическая теория в области динамики. Предмет исследования – программные инструменты языков 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); } }