Chain v3

Материал из Department of Theoretical and Applied Mechanics
Версия от 18:52, 8 марта 2015; Wikiadmin (обсуждение | вклад) (Замена текста — «<source lang="(.*)" first-line="(.*)">» на «<syntaxhighlight lang="$1" line start="$2" enclose="div">»)

Перейти к: навигация, поиск
Виртуальная лаборатория > Динамика одномерного кристалла > Цепь - версии > Chain v3

Скачать программу: Chain_v3_release.zip Текст программы на языке JavaScript (разработчик Цветков Денис): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "Chain_v3_release.js" <syntaxhighlight lang="javascript" line start="1" enclose="div"> function MainChain(canvas, vCanvas) {

   // Предварительные установки
   var context = canvas.getContext("2d");  // на context происходит рисование
   var vContext = vCanvas.getContext("2d");// на context происходит рисование
   var Pi = 3.1415926;                   // число "пи"
   var m0 = 1;                           // масштаб массы
   var T0 = 1;                           // масштаб времени (период колебаний исходной системы)
   var a0 = 1;                           // масштаб расстояния (диаметр шара)
   var k0 = 2 * Pi / T0;                 // масштаб частоты
   var C0 = m0 * k0 * k0;                // масштаб жесткости
   // *** Задание физических параметров ***
   var m = 1 * m0;                 	    // масса
   var C = 1 * C0;                 	    // жесткость
   var numStart = 24;                    // начальное количество частиц
   // *** Задание вычислительных параметров ***
   var fps = 50;             	        // frames per second - число кадров в секунду (качечтво отображения)
   var spf = 10;              		    // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
   var dt  = 0.4 * T0 / fps;      	    // шаг интегрирования (качество расчета)
   // Выполнение программы
   var scale = canvas.height / a0;       // масштабный коэффициент для перехода от расчетных к экранным координатам
   var wScale = canvas.width;		    // ширина окна в экранных координатах
   var hScale = canvas.height;		    // высота окна в экранных координатах
   var w = wScale / scale;		        // ширина окна в расчетных координатах
   var h = hScale / scale;		        // высота окна в расчетных координатах
   var chainHeightScale = hScale/2;      // высота положения цепи в экранных координатах
   // константы для графика скорости
   var vWScale = vCanvas.width;          // ширина окна в экранных координатах
   var vHScale = vCanvas.height;         // высота окна в экранных координатах
   var vHeightScale = vHScale/2;         // высота графика скорости в экранных координатах
   var vAxisScale = vHScale * 0.4;       // масштаб оси "y" графика скорости
   var uvWResize = vWScale/wScale;       // пересчет ширины относительно основного окна
   // Генерорование начальных условий
   var particles;                          // массив частиц
   var num, pDist;                         // количество частиц и расстояние между шарами (в начальном положении)
   MainChain.prototype.setNum = function(n){num = n; pDist = w/(num-1);};       // задать новое количество частиц
   MainChain.prototype.setNum(numStart);
   var uAxisScale;                         // масштаб оси "y" цепи
   MainChain.prototype.newSystem = function(conf){
       MainChain.prototype.actualConf = conf;
       particles = [];
       for (var i = 1; i < num + 1; i++) {
           var b = [];
           b.x0 = pDist*(i-1);             // расчетные координаты начального положения частицы
           b.x0Scale = b.x0*scale;         // экранные координаты начального положения частицы
           b.fu = 0;   b.vu = 0;   b.uu = 0;   //  сила; скорость; смещение отн. нач. положения
           conf(b, i);                     // конфигурации начальных условий заданы ниже
           particles[i] = b;               // добавить элемент в массив
       }
       // здесь задается периодическая система
       particles[0] = particles[num];
       particles[num+1] = particles[1];
       // уравновешивание суммарной скорости по оси х (чтобы частицы не улетали в сторону)
       var sumvu = 0;
       for (var i0 = 1; i0 < num+1; i0++) sumvu += particles[i0].vu;
       var vuAverage = sumvu/num;
       for (var i1 = 1; i1 < num+1; i1++) particles[i1].vu -= vuAverage;
       // настройка оси "y"
       var confCoeff = 1;
       if (conf == MainChain.prototype.conf_random) confCoeff = Math.sqrt(num)/6;
       if (conf == MainChain.prototype.conf_one || conf == MainChain.prototype.conf_stair2) confCoeff = num/5;
       if (conf == MainChain.prototype.conf_stair3) confCoeff = num/10;
       uAxisScale = hScale/(num/35) * confCoeff;
   };
   // настройки для конфигураций
   var v0 = 1*a0/T0;                       // conf_random - начальный разброс скоростей
   var sinNum = 2;                         // conf_sin - количество периодов синуса в цепи
   var hillDiv = 1/4;                      // conf_hill - часть (доля) цепи, которую занимает "холм"
   // конфигурации
   MainChain.prototype.conf_random = function(b){b.vu = v0*(2*Math.random()-1);};
   MainChain.prototype.conf_sin = function(b, i){b.vu = Math.sin(2*Pi * i/num*sinNum);};
   MainChain.prototype.conf_one = function(b, i){if (i == Math.ceil(num/2)) b.vu = 0.5; else b.vu = 0;};
   MainChain.prototype.conf_stair2 = function(b, i){if (i%4 == 0 || (i-1)%4 == 0) b.vu = 1; else b.vu = 0;};
   MainChain.prototype.conf_stair3 = function(b, i){if (i%6 == 0 || (i-1)%6 == 0 || (i-2)%6 == 0) b.vu = 1; else b.vu = 0;};
   MainChain.prototype.conf_hill = function(b, i){
       var nd2 = hillDiv *num/2;            // количество частиц, у которых изменится начальная скорость / 2 (половина параболы)
       if (i > num/2-nd2 && i < num/2+nd2) b.vu = (1 - (i-num/2)*(i-num/2)/(nd2*nd2));    // парабола
       else b.vu = 0;
   };
   // Основной цикл программы
   function control() {
       physics();
       draw();
   }
   // Расчетная часть программы
   function physics(){
       for (var s=1; s<=spf; s++) {// то, что происходит каждый шаг времени
           for (var i=1; i<particles.length-1; i++) {
               particles[i].fu = C*(particles[i+1].uu - 2*particles[i].uu + particles[i-1].uu);
               particles[i].vu += particles[i].fu / m * dt;
           }
           // присваиваем новые перемещения
           for (var i2=1; i2 < particles.length-1; i2++ ) particles[i2].uu += particles[i2].vu * dt;
       }
   }
   // Рисование
   function draw(){
       function clearAndPrepairCtx(ctx, wS, hS, lineHeight){       // очистить экран и нарисовать линию посередине
           ctx.clearRect(0, 0, wS, hS);                            // очистить экран
           ctx.strokeStyle = 'gray';
           ctx.beginPath();
           ctx.moveTo(0, lineHeight);
           ctx.lineTo(wS, lineHeight);
           ctx.stroke();
           ctx.strokeStyle = 'black';
       }
       // цепь
       clearAndPrepairCtx(context, wScale, hScale, chainHeightScale);
       context.beginPath();
       context.moveTo(particles[1].x0Scale, chainHeightScale + particles[1].uu*uAxisScale);
       for (var i = 2; i < particles.length-1; i++)
           context.lineTo(particles[i].x0Scale, chainHeightScale + particles[i].uu*uAxisScale);
       context.stroke();
       // график скорости
       clearAndPrepairCtx(vContext, vWScale, vHScale, vHeightScale);
       vContext.beginPath();
       vContext.moveTo(particles[1].x0Scale * uvWResize, vHeightScale + particles[1].vu*vAxisScale);
       for (var i0 = 2; i0 < particles.length-1; i0++)
           vContext.lineTo(particles[i0].x0Scale * uvWResize, vHeightScale + particles[i0].vu*vAxisScale);
       vContext.stroke();
   }
   // Запуск системы
   MainChain.prototype.newSystem(MainChain.prototype.conf_hill);
   setInterval(control, 1000/fps);

} </source> Файл "Chain_v2_release.html" <syntaxhighlight lang="html" line start="1" enclose="div"> <!DOCTYPE html> <html> <head>

   <title>Chain</title>
   <script src="Chain_v3_release.js"></script>

</head> <body>

u <canvas id="canvasChain" width="800" height="200" style="border:1px solid #000000;"></canvas>
               Конфигурации
(наведите на кнопку,
чтобы увидеть описание):
<input type="button" title="Случайная скорость у каждой частички" style="width: 150px" name="" onclick="app.newSystem(app.conf_random);return false;" value="Random"/>
<input type="button" title="Начальная скорость частиц задается с помощью функции синуса" style="width: 150px" name="" onclick="app.newSystem(app.conf_sin);return false;" value="Sin"/>
<input type="button" title="Скорость равна 0 у всех частичек, кроме одной" style="width: 150px" name="" onclick="app.newSystem(app.conf_one);return false;" value="Impulse"/>
<input type="button" title="Начальная скорость частиц задается ступеньками - две частички движутся, две не движутся" style="width: 150px" name="" onclick="app.newSystem(app.conf_stair2);return false;" value="Stairs (2 particles)"/>
<input type="button" title="Начальная скорость частиц задается ступеньками - три частички движутся, три не движутся" style="width: 150px" name="" onclick="app.newSystem(app.conf_stair3);return false;" value="Stairs (3 particles)"/>
<input type="button" title="Начальная скорость частиц задается холмом, холм занимает 1/4 часть цепи" style="width: 150px" name="" onclick="app.newSystem(app.conf_hill);return false;" value="Hill"/>


                   Количество частиц:
<input type="button" style="width: 40px" name="" onclick="app.setNum(12); app.newSystem(app.actualConf);return false;" value="12"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(24); app.newSystem(app.actualConf);return false;" value="24"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(48); app.newSystem(app.actualConf);return false;" value="48"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(96); app.newSystem(app.actualConf);return false;" value="96"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(300); app.newSystem(app.actualConf);return false;" value="300"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(600); app.newSystem(app.actualConf);return false;" value="600"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(1200); app.newSystem(app.actualConf);return false;" value="1200"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(2400); app.newSystem(app.actualConf);return false;" value="2400"/> <input type="button" style="width: 40px" name="" onclick="app.setNum(4800); app.newSystem(app.actualConf);return false;" value="4800"/>
x
v <canvas id="canvasChainV" width="800" height="100" style="border:1px solid #000000;"></canvas>
x
   <script type="text/javascript">var app = new MainChain(document.getElementById('canvasChain'), document.getElementById('canvasChainV'));</script>

</body> </html> </source> </toggledisplay>