Редактирование: Balls v6

Перейти к: навигация, поиск

Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
[[Виртуальная лаборатория]] > [[Динамика взаимодействующих частиц]] > [[Balls - версии]] > [[Balls v6]] <HR>
+
[[ТМ|Кафедра ТМ]] > [[Программирование]] > [[Программирование и моделирование в Интернет|Интернет]] > [[JavaScript-программирование|JavaScript]] > [[JavaScript - Balls|Balls]] > '''Balls v6''' <HR>
  
 
+
<addscript src=Balls_v6_release/>
<htmlet nocache="yes">Tcvetkov/Balls/Balls_v6_release/Balls_v6_TM</htmlet>
+
<htmlet nocache="yes">Balls_v6_TM</htmlet>
  
  
 
Скачать программу: [[Медиа:Balls_v6_release.zip|Balls_v6_release.zip]]
 
Скачать программу: [[Медиа:Balls_v6_release.zip|Balls_v6_release.zip]]
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
Текст программы на языке JavaScript (разработчики [[Кривцов Антон]], [[Цветков Денис]]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">  
'''Текст программы на языке JavaScript (разработчики [[Кривцов Антон]], [[Цветков Денис]]):''' <div class="mw-collapsible-content">
 
 
Файл '''"Balls_v6_release.js"'''
 
Файл '''"Balls_v6_release.js"'''
<syntaxhighlight lang="javascript" line start="1" enclose="div">
+
<source lang="javascript" first-line="1">
 
function MainBalls(canvas, slider_01, text_01, slider_02, text_02) {
 
function MainBalls(canvas, slider_01, text_01, slider_02, text_02) {
  
Строка 20: Строка 19:
  
 
     var Pi = 3.1415926;                // число "пи"
 
     var Pi = 3.1415926;                // число "пи"
 +
    var k = 1.38; // * 10E-23          // постоянная Больцмана
  
 
     var m0 = 1;                        // масштаб массы
 
     var m0 = 1;                        // масштаб массы
Строка 44: Строка 44:
 
     var a = 2 * r;                      // равновесное расстояние между частицами
 
     var a = 2 * r;                      // равновесное расстояние между частицами
 
     var aCut = 2 * a;                  // радиус обрезания
 
     var aCut = 2 * a;                  // радиус обрезания
    var TGoalK = 2;                    // целевая температура системы равна TGoalK * D
+
 
    var TActualMaxK = 200;              // макимальная температура, при которой работает термостат равна TActualMaxK * D
 
  
 
     // *** Задание вычислительных параметров ***
 
     // *** Задание вычислительных параметров ***
Строка 63: Строка 62:
 
     var SLJDenominator = 1 / (aCut * aCut - b2);    // знаменатель для расчета SLJ потенциала
 
     var SLJDenominator = 1 / (aCut * aCut - b2);    // знаменатель для расчета SLJ потенциала
  
     var thermostatEnabled = document.getElementById('checkbox_02').checked;    // термостат применяется к вязкости среды
+
     var TGoal = 2 * D;                 // целевая температура системы
    var addRandomV = document.getElementById('checkbox_03').checked;            // случайные скорости для разгона
 
    var T0 = 1 * D;                     // масштаб температуры
 
    var TGoal = TGoalK * T0;            // целевая температура системы
 
    var TActualMax = TActualMaxK * T0;  // макимальная температура, при которой работает термостатс (для избежания беск. скоростей)
 
 
     var TActual = 0;                    // актуальная температура
 
     var TActual = 0;                    // актуальная температура
     var k = 1;                         // постоянную Больцмана примем за единицу
+
     var TActualMax = 200 * D;           // максимальная температура, при которой работает термостат (для избежания беск. скоростей)
     var Tk = m / k;                     // ___в целях оптимизации___
+
     var Tk = 1 / (3 * k) * m;           // ___в целях оптимизации___
     var viscFrictionTh = document.getElementById('checkbox_04').checked;        // термостат применяется к вязкости среды
+
     var viscFrictionTh = document.getElementById('checkbox_01').checked;        // термостат применяется к вязкости среды
     var internalFrictionTh = document.getElementById('checkbox_05').checked;    // термостат применяется к внутреннему трению
+
     var internalFrictionTh = document.getElementById('checkbox_01').checked;    // термостат применяется к внутреннему трению
    var TempIntervalID;
 
  
 
     var Ka = K * a;                    // ___в целях оптимизации___
 
     var Ka = K * a;                    // ___в целях оптимизации___
Строка 80: Строка 74:
 
     var dNd = null;                    // ссылка на захваченный курсором шар (drag & drop)
 
     var dNd = null;                    // ссылка на захваченный курсором шар (drag & drop)
 
     var grad;                          // должен ли работать градиент (регулируется в функции setNy())
 
     var grad;                          // должен ли работать градиент (регулируется в функции setNy())
    var SLJEnabled = document.getElementById('checkbox_01').checked;
 
  
 
     this.setSlider_01 = function(c) {mg = c * m * g0;}; // функция для слайдера гравитации
 
     this.setSlider_01 = function(c) {mg = c * m * g0;}; // функция для слайдера гравитации
     this.setSlider_02 = function(c) {TGoal = c;};       // функция для слайдера термостата
+
     this.setSlider_02 = function(c) {TGoal = c * D;};   // функция для слайдера термостата
 
     this.setNy = function(ny) {
 
     this.setNy = function(ny) {
 
         Ny = ny;
 
         Ny = ny;
Строка 93: Строка 86:
 
     };
 
     };
 
     this.setNy(Ny);                        // запускаем с уже присвоенным значением, чтобы обновились настройки градиента
 
     this.setNy(Ny);                        // запускаем с уже присвоенным значением, чтобы обновились настройки градиента
     this.setCheckbox_01 = function(bool) {SLJEnabled = bool;};
+
     this.setCheckbox_01 = function(bool) {viscFrictionTh = bool};
    this.setCheckbox_02 = function(bool) {
+
     this.setCheckbox_02 = function(bool) {internalFrictionTh = bool};
        thermostatEnabled = bool;
 
        document.getElementById('checkbox_03').disabled = !bool;
 
        document.getElementById('checkbox_04').disabled = !bool;
 
        document.getElementById('checkbox_05').disabled = !bool;
 
        document.getElementById('slider_02').disabled = !bool;
 
        document.getElementById('text_02').disabled = !bool;
 
        if (bool) {
 
            TempIntervalID = setInterval(  // обновление информации о температуре
 
                function(){document.getElementById('Temperature').innerHTML = TActual.toFixed(3);}, 1000 / 3);
 
        }
 
        else {
 
            clearInterval(TempIntervalID);  // температура больше не подсчитывается - удаляем обновление информации о ней
 
            document.getElementById('Temperature').innerHTML = "???"
 
        }
 
    };
 
     this.setCheckbox_02(thermostatEnabled); // запускаем сразу, чтобы обновить состояния элементов интерфейса
 
    this.setCheckbox_03 = function(bool) {addRandomV = bool;};
 
    this.setCheckbox_04 = function(bool) {viscFrictionTh = bool;};
 
    this.setCheckbox_05 = function(bool) {internalFrictionTh = bool;};
 
 
 
    // Настройка интерфейса
 
 
 
    slider_01.min = 0;              slider_01.max = 5;
 
    slider_01.step = 0.05;
 
    slider_01.value = mg / m / g0;          // начальное значение ползунка должно задаваться после min и max
 
    text_01.value = mg / m / g0;
 
    slider_02.min = 0;              slider_02.max = 5;
 
    slider_02.step = 0.05;
 
    slider_02.value = TGoal;                // начальное значение ползунка должно задаваться после min и max
 
    text_02.value = TGoal.toFixed(1);
 
  
 
     // Запуск новой системы
 
     // Запуск новой системы
Строка 141: Строка 104:
 
         this.setRandom();                  // задаем случайную конфигурацию
 
         this.setRandom();                  // задаем случайную конфигурацию
 
     };
 
     };
 +
 +
    // настройка интерфейса
 +
    slider_01.min = 0;              slider_01.max = 5;
 +
    slider_01.step = 0.05;
 +
    slider_01.value = mg / m / g0;          // начальное значение ползунка должно задаваться после min и max
 +
    text_01.value = mg / m / g0;
 +
    slider_02.min = 0;              slider_02.max = 5;
 +
    slider_02.step = 0.05;
 +
    slider_02.value = TGoal / D;            // начальное значение ползунка должно задаваться после min и max
 +
    text_02.value = TGoal / D;
  
 
     // Работа с мышью
 
     // Работа с мышью
Строка 255: Строка 228:
 
             var BViscTh = BVisc;
 
             var BViscTh = BVisc;
 
             var BInternalTh = BInternal;
 
             var BInternalTh = BInternal;
 +
 
             // работа термостата
 
             // работа термостата
             if (thermostatEnabled) {
+
             if (balls.length > 0) {
                if (balls.length > 0) {
+
                var v2Sum = 0;
                    var v2Sum = 0;
+
                for (var i1 = 0; i1 < balls.length; i1++)
                    for (var i1 = 0; i1 < balls.length; i1++)
+
                    v2Sum += balls[i1].vx * balls[i1].vx + balls[i1].vy * balls[i1].vy;
                        v2Sum += balls[i1].vx * balls[i1].vx + balls[i1].vy * balls[i1].vy;
+
                var v2Average = v2Sum / balls.length;
                    var v2Average = v2Sum / balls.length;
+
                TActual = Tk * v2Average;
                    TActual = Tk * v2Average;
 
  
                    if (addRandomV) {              // случайные скорости, если температура слишком мала
+
                if (TActual < TActualMax) {        // из за того, что мышкой можно задать шарам запредельную скорость
                        if (TGoal > 0.15 && TActual < 0.1) {
+
                    if (viscFrictionTh) BViscTh = BVisc * (TActual - TGoal);                // действие термостата
                            for (var i2 = 0; i2 < balls.length; i2++) {
+
                    if (internalFrictionTh) BInternalTh = BInternal * (TActual - TGoal);    // действие термостата
                                balls[i2].vx += 0.3 * (1 - 2 * Math.random());
+
                }
                                balls[i2].vy += 0.3 * (1 - 2 * Math.random());
+
            } else
                            }
+
                TActual = 0;                        // для датчика температуры на странице
                        }
 
                    }
 
 
 
                    if (TActual < TActualMax) {        // из за того, что мышкой можно задать шарам запредельную скорость
 
                        if (viscFrictionTh) BViscTh = BVisc * (TActual - TGoal);                // действие термостата
 
                        if (internalFrictionTh) BInternalTh = BInternal * (TActual - TGoal);    // действие термостата
 
                    }
 
                } else
 
                    TActual = 0;                        // для датчика температуры на странице
 
            }
 
  
 
             // пересчет сил идет отдельным массивом, т.к. далее будут добавляться силы взаимодействия между шарами
 
             // пересчет сил идет отдельным массивом, т.к. далее будут добавляться силы взаимодействия между шарами
Строка 311: Строка 274:
 
                     var s2 = a2 / r2;        var s4 = s2 * s2;        // ___в целях оптимизации___
 
                     var s2 = a2 / r2;        var s4 = s2 * s2;        // ___в целях оптимизации___
 
                     var F = LJCoeff * s4 * s4 * (s4 * s2 - 1);          // сила взаимодействия Леннарда-Джонса
 
                     var F = LJCoeff * s4 * s4 * (s4 * s2 - 1);          // сила взаимодействия Леннарда-Джонса
                     if (SLJEnabled) {
+
                     var kSLJ;                                          // k(r) - сглаживающий коэффициент SLJ потенциала
                        var kSLJ;                                          // k(r) - сглаживающий коэффициент SLJ потенциала
+
                    if (r <= b) kSLJ = 1;
                        if (r <= b) kSLJ = 1;
+
                    else {
                        else {
+
                        var brackets = (r2 - b2) * SLJDenominator;
                            var brackets = (r2 - b2) * SLJDenominator;
+
                        kSLJ = 1 - brackets * brackets;
                            kSLJ = 1 - brackets * brackets;
+
                    }                                                  // случай rLen > aCut обработан выше
                        }                                                  // случай rLen > aCut обработан выше
+
                    F *= kSLJ;
                        F *= kSLJ;
 
                    }
 
  
 
                     // сила внутреннего трения между частицами
 
                     // сила внутреннего трения между частицами
Строка 374: Строка 335:
 
     // след. функция обновляет информацию о количестве частиц на поле
 
     // след. функция обновляет информацию о количестве частиц на поле
 
     setInterval(function(){document.getElementById('ballsNum').innerHTML = balls.length;}, 1000 / 20);
 
     setInterval(function(){document.getElementById('ballsNum').innerHTML = balls.length;}, 1000 / 20);
 +
    setInterval(function(){document.getElementById('Temperature').innerHTML = TActual.toFixed(3);}, 1000 / 3);
 
}
 
}
</syntaxhighlight>
+
</source>
 
Файл '''"Balls_v6_release.html"'''
 
Файл '''"Balls_v6_release.html"'''
<syntaxhighlight lang="html5" line start="1" enclose="div">
+
<source lang="html" first-line="1">
 
<!DOCTYPE html>
 
<!DOCTYPE html>
 
<html>
 
<html>
Строка 416: Строка 378:
 
     </div><br>
 
     </div><br>
  
     <div>
+
     <div>Термостат:
        <input type="checkbox" id="checkbox_01" name="" onchange="app.setCheckbox_01(this.checked);"/>
 
        <a href="/SLJ" title="SLJ" class="mw-redirect">Short Lennard-Jones</a> potential
 
    </div><br>
 
 
 
    <div>
 
        <input type="checkbox" id="checkbox_02" name="" onchange="app.setCheckbox_02(this.checked);"/>
 
        Термостат:
 
 
         <input type="range" id="slider_02" style="width: 150px;" oninput="app.setSlider_02(this.value); document.getElementById('text_02').value = this.value;">
 
         <input type="range" id="slider_02" style="width: 150px;" oninput="app.setSlider_02(this.value); document.getElementById('text_02').value = this.value;">
         T ⋅ T0 = <input id="text_02" style="width: 5ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
+
         <input id="text_02" style="width: 5ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
 
             // если введено не число - строка не пройдет валидацию по паттерну выше, и checkValidity() вернет false
 
             // если введено не число - строка не пройдет валидацию по паттерну выше, и checkValidity() вернет false
 
             if (!this.checkValidity()) return;
 
             if (!this.checkValidity()) return;
Строка 431: Строка 386:
 
             document.getElementById('slider_02').value = this.value;
 
             document.getElementById('slider_02').value = this.value;
 
         ">
 
         ">
         <br>
+
         ⋅ D<br>
        <input type="checkbox" checked id="checkbox_03" name="" onchange="app.setCheckbox_03(this.checked);"/>Разгон случайными скоростями
 
        <br>
 
 
         Термостат действует на:
 
         Термостат действует на:
         <input type="checkbox" checked id="checkbox_04" name="" onchange="app.setCheckbox_04(this.checked);"/>Внешнее трение
+
         <input type="checkbox" checked id="checkbox_01" name="" onclick="app.setCheckbox_01(this.checked);"/>Внешнее трение
         <input type="checkbox" checked id="checkbox_05" name="" onchange="app.setCheckbox_05(this.checked);"/>Внутреннее трение
+
         <input type="checkbox" checked id="checkbox_02" name="" onclick="app.setCheckbox_02(this.checked);"/>Внутреннее трение
 
         <div>T ≈ <span id="Temperature"></span></div>
 
         <div>T ≈ <span id="Temperature"></span></div>
 
     </div><br>
 
     </div><br>
Строка 451: Строка 404:
 
</body>
 
</body>
 
</html>
 
</html>
</syntaxhighlight>
+
</source>
</div>
+
</toggledisplay>
</div>
 
  
[[Category: Виртуальная лаборатория]]
 
 
[[Category: Программирование]]
 
[[Category: Программирование]]
 +
[[Category: JavaScript]]
Вам запрещено изменять защиту статьи. Edit Создать редактором

Обратите внимание, что все добавления и изменения текста статьи рассматриваются как выпущенные на условиях лицензии Public Domain (см. Department of Theoretical and Applied Mechanics:Авторские права). Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались любым желающим, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого.
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ, ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Отменить | Справка по редактированию  (в новом окне)
Источник — «http://tm.spbstu.ru/Balls_v6»