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

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Строка 3: Строка 3:
  
 
Здесь расположена последняя версия программы, моделирующей динамику одномерного кристалла.
 
Здесь расположена последняя версия программы, моделирующей динамику одномерного кристалла.
<addscript src=Chain_v3_release/>
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/Chain/Chain_v3_release/Chain_v3_release.html |width=1030 |height=440 |border=0 }}
<htmlet nocache="yes">Chain_v3_TM</htmlet>
 
  
 
Скачать программу: [[Медиа:Chain_v3_release.zip|Chain_v3_release.zip]]
 
Скачать программу: [[Медиа:Chain_v3_release.zip|Chain_v3_release.zip]]
Строка 11: Строка 10:
 
<source lang="javascript" first-line="1">
 
<source lang="javascript" first-line="1">
 
function MainChain(canvas, vCanvas) {
 
function MainChain(canvas, vCanvas) {
 +
 
     // Предварительные установки
 
     // Предварительные установки
  
Строка 16: Строка 16:
 
     var vContext = vCanvas.getContext("2d");// на context происходит рисование
 
     var vContext = vCanvas.getContext("2d");// на context происходит рисование
  
     const Pi = 3.1415926;                  // число "пи"
+
     var Pi = 3.1415926;                  // число "пи"
  
     const m0 = 1;                          // масштаб массы
+
     var m0 = 1;                          // масштаб массы
     const T0 = 1;                          // масштаб времени (период колебаний исходной системы)
+
     var T0 = 1;                          // масштаб времени (период колебаний исходной системы)
     const a0 = 1;                          // масштаб расстояния (диаметр шара)
+
     var a0 = 1;                          // масштаб расстояния (диаметр шара)
  
     const k0 = 2 * Pi / T0;                // масштаб частоты
+
     var k0 = 2 * Pi / T0;                // масштаб частоты
     const C0 = m0 * k0 * k0;                // масштаб жесткости
+
     var C0 = m0 * k0 * k0;                // масштаб жесткости
  
 
     // *** Задание физических параметров ***
 
     // *** Задание физических параметров ***
  
     const m = 1 * m0;                    // масса
+
     var m = 1 * m0;                    // масса
     const C = 1 * C0;                    // жесткость
+
     var C = 1 * C0;                    // жесткость
     const numStart = 24;                    // начальное количество частиц
+
     var numStart = 24;                    // начальное количество частиц
  
 
     // *** Задание вычислительных параметров ***
 
     // *** Задание вычислительных параметров ***
  
     const fps = 50;                    // frames per second - число кадров в секунду (качечтво отображения)
+
     var fps = 50;                    // frames per second - число кадров в секунду (качечтво отображения)
     const spf = 10;                  // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
+
     var spf = 10;                  // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
     const dt  = 0.4 * T0 / fps;          // шаг интегрирования (качество расчета)
+
     var dt  = 0.4 * T0 / fps;          // шаг интегрирования (качество расчета)
  
 
     // Выполнение программы
 
     // Выполнение программы
  
     const scale = canvas.height / a0;      // масштабный коэффициент для перехода от расчетных к экранным координатам
+
     var scale = canvas.height / a0;      // масштабный коэффициент для перехода от расчетных к экранным координатам
     const wScale = canvas.width;     // ширина окна в экранных координатах
+
     var wScale = canvas.width;     // ширина окна в экранных координатах
     const hScale = canvas.height;     // высота окна в экранных координатах
+
     var hScale = canvas.height;     // высота окна в экранных координатах
     const w = wScale / scale;         // ширина окна в расчетных координатах
+
     var w = wScale / scale;         // ширина окна в расчетных координатах
     const h = hScale / scale;         // высота окна в расчетных координатах
+
     var h = hScale / scale;         // высота окна в расчетных координатах
     const chainHeightScale = hScale/2;      // высота положения цепи в экранных координатах
+
     var chainHeightScale = hScale/2;      // высота положения цепи в экранных координатах
  
 
     // константы для графика скорости
 
     // константы для графика скорости
     const vWScale = vCanvas.width;          // ширина окна в экранных координатах
+
     var vWScale = vCanvas.width;          // ширина окна в экранных координатах
     const vHScale = vCanvas.height;        // высота окна в экранных координатах
+
     var vHScale = vCanvas.height;        // высота окна в экранных координатах
     const vHeightScale = vHScale/2;        // высота графика скорости в экранных координатах
+
     var vHeightScale = vHScale/2;        // высота графика скорости в экранных координатах
     const vAxisScale = vHScale * 0.4;      // масштаб оси "y" графика скорости
+
     var vAxisScale = vHScale * 0.4;      // масштаб оси "y" графика скорости
     const uvWResize = vWScale/wScale;      // пересчет ширины относительно основного окна
+
     var uvWResize = vWScale/wScale;      // пересчет ширины относительно основного окна
  
 
     // Генерорование начальных условий
 
     // Генерорование начальных условий
Строка 120: Строка 120:
 
     function physics(){
 
     function physics(){
 
         for (var s=1; s<=spf; s++) {// то, что происходит каждый шаг времени
 
         for (var s=1; s<=spf; s++) {// то, что происходит каждый шаг времени
             for (var i=1; i<particles.length-1; i++){
+
             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].fu = C*(particles[i+1].uu - 2*particles[i].uu + particles[i-1].uu);
 
                 particles[i].vu += particles[i].fu / m * dt;
 
                 particles[i].vu += particles[i].fu / m * dt;
Строка 227: Строка 227:
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Программирование]]
 
[[Category: Программирование]]
[[Category: JavaScript]]
 

Версия 22:41, 5 ноября 2014

Виртуальная лаборатория > Динамика одномерного кристалла


Здесь расположена последняя версия программы, моделирующей динамику одномерного кристалла.

Скачать программу: Chain_v3_release.zip Текст программы на языке JavaScript (разработчик Цветков Денис): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "Chain_v3_release.js"

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);
}

Файл "Chain_v2_release.html"

<!DOCTYPE html>
<html>
<head>
    <title>Chain</title>
    <script src="Chain_v3_release.js"></script>
</head>
<body>
    <table>
        <tr>
            <td>u</td>
            <td><canvas id="canvasChain" width="800" height="200" style="border:1px solid #000000;"></canvas></td>
            <td rowspan="4" style="width:200px" valign="top">
                Конфигурации<br>(наведите на кнопку,<br>чтобы увидеть описание):<br>
                <input type="button" title="Случайная скорость у каждой частички"                                                       style="width: 150px" name="" onclick="app.newSystem(app.conf_random);return false;" value="Random"/><br>
                <input type="button" title="Начальная скорость частиц задается с помощью функции синуса"                                style="width: 150px" name="" onclick="app.newSystem(app.conf_sin);return false;" value="Sin"/><br>
                <input type="button" title="Скорость равна 0 у всех частичек, кроме одной"                                              style="width: 150px" name="" onclick="app.newSystem(app.conf_one);return false;" value="Impulse"/><br>
                <input type="button" title="Начальная скорость частиц задается ступеньками - две частички движутся, две не движутся"    style="width: 150px" name="" onclick="app.newSystem(app.conf_stair2);return false;" value="Stairs (2 particles)"/><br>
                <input type="button" title="Начальная скорость частиц задается ступеньками - три частички движутся, три не движутся"    style="width: 150px" name="" onclick="app.newSystem(app.conf_stair3);return false;" value="Stairs (3 particles)"/><br>
                <input type="button" title="Начальная скорость частиц задается холмом, холм занимает 1/4 часть цепи"                    style="width: 150px" name="" onclick="app.newSystem(app.conf_hill);return false;" value="Hill"/><br>
                <br><br>
                <div style="width:150px">
                    Количество частиц:<br>
                    <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"/>
                </div>
            </td>
        </tr><tr>
            <td></td>
            <td align="center">x</td>
        </tr ><tr>
            <td style="padding:30px 0 0 0;">v</td>
            <td style="padding:30px 0 0 0;"><canvas id="canvasChainV" width="800" height="100" style="border:1px solid #000000;"></canvas></td>
        </tr><tr>
            <td></td>
            <td align="center">x</td>
        </tr>
    </table>

    <script type="text/javascript">var app = new MainChain(document.getElementById('canvasChain'), document.getElementById('canvasChainV'));</script>
</body>
</html>

</toggledisplay>

Здесь вы можете найти предыдущие версии программы.

Предлагаемые направления развития стенда

  • Реализовать возможность задавать направленный импульс.
  • Добавить управление скоростью моделирования (например, ползунок).
  • Исследовать различные силы взаимодействия (линейную, квадратную, кубическую, их вариации, потенциал).