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

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
 
(не показано 7 промежуточных версий этого же участника)
Строка 1: Строка 1:
 
[[en:Energy fluctuations in one-dimensional crystal]]
 
[[en:Energy fluctuations in one-dimensional crystal]]
 +
[[ТМ|Кафедра ТМ]] > [[Проект "Термокристалл"]] > [[Колебания энергий в одномерном кристалле]] <HR>
 
[[Виртуальная лаборатория]] > [[Колебания энергий в одномерном кристалле]] <HR>
 
[[Виртуальная лаборатория]] > [[Колебания энергий в одномерном кристалле]] <HR>
 +
[[Д.В. Цветков]] (программирование), [[А.М. Кривцов]] (аналитическое решение) <HR>
  
 
Данная программа демонстрирует колебания кинетической, потенциальной и полной энергий в одномерном кристалле.
 
Данная программа демонстрирует колебания кинетической, потенциальной и полной энергий в одномерном кристалле.
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/Bessel_fluctuations/Bessel_fluctuations_v2.3_no_realiz/Bessel_fluctuations.html |width=1030 |height=640 |border=0 }}
+
Колебания кинетической энергии описываются следующим уравнением:
  
Скачать программу: [[Медиа:Bessel_fluctuations_v2.3_no_realiz.zip|Bessel_fluctuations_v2.3_no_realiz.zip]]
+
:<math>
 +
    K_J(t) = \frac{E}{2}  \left(1 + J_0(4 \omega_0 )\right)
 +
    ,\qquad \omega_0 = \sqrt{C/m},
 +
</math>
 +
где
 +
<math>J_0</math> — Функция Бесселя первого рода в точке 0,
 +
<math>C</math> — жесткость связи между частицами,
 +
<math>m</math> — масса частицы.
 +
 
 +
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/Bessel_fluctuations/Bessel_fluctuations_v3.0/Bessel_fluctuations.html |width=1055 |height=675 |border=0 }}
 +
 
 +
Скачать программу: [[Медиа:Bessel_fluctuations_v3.0.zip|Bessel_fluctuations_v3.0.zip]]
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
'''Текст программы на языке JavaScript (разработчик [[Цветков Денис]]):''' <div class="mw-collapsible-content">
+
'''Текст программы на языке JavaScript (использована библиотека [https://github.com/SheetJS/bessel bessel.js]):''' <div class="mw-collapsible-content">
 
Файл '''"Bessel_fluctuations.js"'''
 
Файл '''"Bessel_fluctuations.js"'''
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
Строка 27: Строка 40:
 
     var dt = 0.02 * t0;                    // шаг интегрирования по времени
 
     var dt = 0.02 * t0;                    // шаг интегрирования по времени
  
     var N = 100000;                         // количество частиц в каждой реализации
+
    var R = 10;                              // количество реализаций
     var T = 15;                             // время расчета
+
     var N = 10000;                         // количество частиц в каждой реализации
 +
     var periods = 10;                       // время расчета в периодах колебаний энергий
  
 
     var koeff = C / (dx * dx) / m * dt;    // коэффициент для уравнения динамики частиц
 
     var koeff = C / (dx * dx) / m * dt;    // коэффициент для уравнения динамики частиц
 +
 +
    var T;
 +
    // функция переводит время в периодах в расчетное время
 +
    function set_periods(n) {
 +
        // первый раз кинетическая и потенциальная энергии доходят до нуля за 0.4 периода колебаний
 +
        var T0 = Math.PI / (Math.sqrt(C / m)) / 2;  // период колебаний
 +
        if (n >= 0.4 * T0) T = T0 * ( 0.4 + 0.75 + (n - 1) );
 +
        else T = n;
 +
    }
 +
    set_periods(periods);
  
 
     // интерфейс программы
 
     // интерфейс программы
 
     N_number.value = N;
 
     N_number.value = N;
 
     N_number.oninput = function() {N = parseInt(N_number.value);};
 
     N_number.oninput = function() {N = parseInt(N_number.value);};
     T_number.value = T;
+
     periods_number.value = periods;
     T_number.oninput = function() {T = parseInt(T_number.value);};
+
     periods_number.oninput = function() {
 +
        set_periods(parseFloat(periods_number.value));
 +
    };
 +
    R_number.value = R;
 +
    R_number.oninput = function() {R = parseInt(R_number.value);};
 
     button_start.onclick = calculate_new_system;
 
     button_start.onclick = calculate_new_system;
 +
    button_stop.onclick = function() {
 +
        working = false;
 +
    };
 +
    checkbox_Bessel.onchange = function() {
 +
        draw();
 +
        if (checkbox_Bessel.checked) div_txt_J0.style.display = "block";
 +
        else div_txt_J0.style.display = "none"
 +
    };
 +
    checkbox_K.onchange = function() {
 +
        draw();
 +
        if (checkbox_K.checked) div_txt_K.style.display = "block";
 +
        else div_txt_K.style.display = "none"
 +
    };
 +
    checkbox_P.onchange = function() {
 +
        draw();
 +
        if (checkbox_P.checked) div_txt_P.style.display = "block";
 +
        else div_txt_P.style.display = "none"
 +
    };
 +
    checkbox_E.onchange = function() {
 +
        draw();
 +
        if (checkbox_E.checked) div_txt_E.style.display = "block";
 +
        else div_txt_E.style.display = "none"
 +
    };
  
    checkbox_K.onchange = function() {if (first_calc) draw();};
+
     var ctx = BF_canvas.getContext("2d");   // на context происходит рисование
    checkbox_P.onchange = function() {if (first_calc) draw();};
+
     var w = BF_canvas.width;               // ширина окна в расчетных координатах
    checkbox_E.onchange = function() {if (first_calc) draw();};
+
     var h = BF_canvas.height;               // высота окна в расчетных координатах
 
 
     var ctx = BF_canvas.getContext("2d");                 // на context происходит рисование
 
     var w = BF_canvas.width;                             // ширина окна в расчетных координатах
 
     var h = BF_canvas.height;                             // высота окна в расчетных координатах
 
  
 
     // основная расчетная функция
 
     // основная расчетная функция
 
     var data_K, data_P, data_E;            // данные для графика
 
     var data_K, data_P, data_E;            // данные для графика
    var first_calc = false;                // произведен ли первый расчет
 
 
     var t, n;
 
     var t, n;
 
     var t_start;
 
     var t_start;
 +
    var working;
 +
    var step;
 
     function calculate_new_system() {
 
     function calculate_new_system() {
        first_calc = true;
 
 
         t = 0;
 
         t = 0;
 
         n = N + 2;                          // количество узлов по оси x + 2 для ГУ
 
         n = N + 2;                          // количество узлов по оси x + 2 для ГУ
 +
        working = true;
 +
        step = 0;
 +
 
         span_time_calc.innerHTML = "";
 
         span_time_calc.innerHTML = "";
 
         div_calc_speed.style.display = "none";
 
         div_calc_speed.style.display = "none";
 +
        button_start.style.display = "none";
 +
        button_stop.style.display = "inline";
  
 
         // задание начальных условий
 
         // задание начальных условий
         var P = [];
+
         var all_P = [];
        for (var i = 1; i < n - 1; i++) {
+
        for (var r = 0; r < R; r++) {
            P[i] = {};
+
            var P = [];
            P[i].u = 0;
+
            for (var i = 1; i < n - 1; i++) {
            P[i].v = (2 * Math.random() - 1) * 0.25;
+
                P[i] = {};
 +
                P[i].u = 0;
 +
                P[i].v = (2 * Math.random() - 1) * 0.25;
 +
            }
 +
            // периодические граничные условия
 +
            P[0] = P[n - 2];
 +
            P[n - 1] = P[1];
 +
            all_P.push(P);
 
         }
 
         }
        // периодические граничные условия
 
        P[0] = P[n - 2];
 
        P[n - 1] = P[1];
 
  
 
         data_K = []; data_P = []; data_E = [];
 
         data_K = []; data_P = []; data_E = [];
Строка 74: Строка 130:
 
         // основной расчет
 
         // основной расчет
 
         t_start = performance.now();
 
         t_start = performance.now();
         calculate(P);
+
         calculate(all_P);
 
     }
 
     }
 +
    calculate_new_system();
  
     function calculate(P) {
+
     function calculate(all_P) {
 
         var t1 = performance.now();
 
         var t1 = performance.now();
 
 
         while (t < T) {
 
         while (t < T) {
 
             // расчет энергий для графиков
 
             // расчет энергий для графиков
 
             var Kin = 0;
 
             var Kin = 0;
 
             var Pot = 0;
 
             var Pot = 0;
             for (var j = 1; j < n - 1; j++) {Kin += P[j].v * P[j].v;}
+
             for (var p = 0; p < all_P.length; p++) {
            for (var j = 1; j < n - 1; j++) {Pot += Math.pow(P[j].u - P[j - 1].u, 2);}
+
                var P = all_P[p];
             Kin = Kin * m;
+
                for (var j = 1; j < n - 1; j++) {Kin += P[j].v * P[j].v;}
             Pot = Pot * C;
+
                for (var j = 1; j < n - 1; j++) {Pot += Math.pow(P[j].u - P[j - 1].u, 2);}
 +
            }
 +
             Kin = Kin * m / all_P.length;
 +
             Pot = Pot * C / all_P.length;
 
             data_K.push(Kin);
 
             data_K.push(Kin);
 
             data_P.push(Pot);
 
             data_P.push(Pot);
Строка 93: Строка 152:
  
 
             // расчет состояния системы на следующем шаге
 
             // расчет состояния системы на следующем шаге
             for (var i = 1; i < n - 1; i++) {
+
             for (var p = 0; p < all_P.length; p++) {
                P[i].v += (P[i + 1].u - 2 * P[i].u + P[i - 1].u) * koeff;
+
                var P = all_P[p];
            }
+
                for (var i = 1; i < n - 1; i++) {
            for (var i = 1; i < n - 1; i++) {
+
                    P[i].v += (P[i + 1].u - 2 * P[i].u + P[i - 1].u) * koeff;
                P[i].u += P[i].v * dt;
+
                }
 +
                for (var i = 1; i < n - 1; i++) {
 +
                    P[i].u += P[i].v * dt;
 +
                }
 
             }
 
             }
 +
            t += dt;
 +
            step++;
  
             t += dt;
+
             // промежуточная прорисовка результатов, работа прогресс-бара
 
             if ((performance.now() - t1) > 200) {
 
             if ((performance.now() - t1) > 200) {
                 draw();
+
                 if (working) {
                setTimeout( function(){calculate(P); }, 10);
+
                    draw();
                div_container_progress.style.display = "block";
+
                    setTimeout( function(){calculate(all_P); }, 10);
                button_start.style.display = "none";
+
                    div_container_progress.style.display = "block";
                progress_bar.style.width = Math.round(t / T * 100) + "%";
+
                    progress_bar.style.width = Math.round(t / T * 100) + "%";
                span_progress.innerHTML = (t / T * 100).toFixed(2) + "%";
+
                    span_progress.innerHTML = (t / T * 100).toFixed(0) + "%";
 +
                } else {
 +
                    stop();
 +
                }
 
                 return;
 
                 return;
 
             }
 
             }
 
         }
 
         }
 +
        stop();
 +
    }
 +
    function stop() {
 +
        // окончательная прорисовка результатов, удаление прогресс-бара, вывод скорости расчета
 
         draw();
 
         draw();
 
         div_container_progress.style.display = "none";
 
         div_container_progress.style.display = "none";
 
         button_start.style.display = "inline";
 
         button_start.style.display = "inline";
 +
        button_stop.style.display = "none";
 
         div_calc_speed.style.display = "block";
 
         div_calc_speed.style.display = "block";
         span_time_calc.innerHTML = ((performance.now() - t_start) / N * 1000 / Math.ceil(T/t)).toFixed(2);
+
         span_time_calc.innerHTML = parseFloat(((performance.now() - t_start) * 1000 * 1000 / N / R / step).toPrecision(2));
 
         return true;
 
         return true;
 
     }
 
     }
Строка 122: Строка 194:
 
         ctx.clearRect(0, 0, w, h);              // очистка экрана
 
         ctx.clearRect(0, 0, w, h);              // очистка экрана
  
         // подпись к оси ("х")
+
         if (checkbox_Bessel.checked) {
        ctx.font = "20pt Arial";
+
            // Функция Бесселя первого рода в точке 0
        ctx.textAlign = "right";
+
            ctx.strokeStyle = "#00dd00";
        ctx.textBaseline = "bottom";
+
            ctx.lineWidth = 2;
        ctx.fillStyle = "#666666";
+
            ctx.beginPath();
        ctx.fillText("x", w - 4, h);
+
            ctx.moveTo(0, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * 0, 0) / data_K[0] * h / 2 - h / 2);
 
+
            for (var i = 0.001; i < t; i += 0.001) {
        var title_y = 3;                       // начальный отступ для подписи
+
                ctx.lineTo(i / t * w, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * i, 0) / data_K[0] * h / 2 - h / 2);
         var title_y_plus = 30;                  // на столько увеличивается отступ для каждой следующей подписи
+
            }
 +
            ctx.stroke();
 +
         }
  
 
         if (checkbox_K.checked) {
 
         if (checkbox_K.checked) {
Строка 142: Строка 216:
 
             }
 
             }
 
             ctx.stroke();
 
             ctx.stroke();
 
            // подпись
 
            ctx.textAlign = "center";
 
            ctx.textBaseline = "top";
 
            ctx.fillStyle = "#ff0000";
 
            ctx.fillText("K", w - 24, title_y);
 
            title_y += title_y_plus;
 
 
         }
 
         }
  
Строка 161: Строка 228:
 
             }
 
             }
 
             ctx.stroke();
 
             ctx.stroke();
 
            ctx.textAlign = "center";
 
            ctx.textBaseline = "top";
 
            ctx.fillStyle = "#0000ff";
 
            ctx.fillText("П", w - 24, title_y);
 
            title_y += title_y_plus;
 
 
         }
 
         }
  
Строка 179: Строка 240:
 
             }
 
             }
 
             ctx.stroke();
 
             ctx.stroke();
 
            ctx.textAlign = "center";
 
            ctx.textBaseline = "top";
 
            ctx.fillStyle = "#880088";
 
            ctx.fillText("E/2", w - 24, title_y);
 
            title_y += title_y_plus;
 
 
         }
 
         }
 
 
     }
 
     }
 
}
 
}
Строка 206: Строка 260:
 
         en:"Full energy",
 
         en:"Full energy",
 
         ru:"Полная энергия"
 
         ru:"Полная энергия"
 +
    }, span_txt_Bessel:{
 +
        field:"innerHTML",
 +
        en:"Analytical sol. for the kinetic energy",
 +
        ru:"Аналит. решение для кин. энергии"
 
     }, button_start:{
 
     }, button_start:{
 
         field:"value",
 
         field:"value",
 
         en:"Start",
 
         en:"Start",
 
         ru:"Старт"
 
         ru:"Старт"
 +
    }, button_stop:{
 +
        field:"value",
 +
        en:"Stop",
 +
        ru:"Стоп"
 
     }, span_progress_txt:{
 
     }, span_progress_txt:{
 
         field:"innerHTML",
 
         field:"innerHTML",
Строка 218: Строка 280:
 
         en:"The calculation of this speed includes the time for processing interface and drawing the intermediate states of the system",
 
         en:"The calculation of this speed includes the time for processing interface and drawing the intermediate states of the system",
 
         ru:"Расчет данной скорости включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы"
 
         ru:"Расчет данной скорости включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы"
     }, span_txt_nubmer_of_particles:{
+
     }, span_txt_molecular_dynamics:{
 
         field:"innerHTML",
 
         field:"innerHTML",
         en:"Number of particles",
+
         en:"Molecular_dynamics:",
         ru:"Количество частиц"
+
        ru:"Молекулярная динамика:"
 +
    }, span_txt_particles:{
 +
        field:"innerHTML",
 +
        en:"particles",
 +
         ru:"частиц"
 +
    }, span_txt_realizations:{
 +
        field:"innerHTML",
 +
        en:"realizations",
 +
        ru:"реализаций"
 
     }, span_txt_calc_time:{
 
     }, span_txt_calc_time:{
 
         field:"innerHTML",
 
         field:"innerHTML",
         en:"Calculation time",
+
         en:"Calculation time:",
         ru:"Время расчета"
+
         ru:"Время расчета:"
 
     }, span_txt_calc_speed:{
 
     }, span_txt_calc_speed:{
 
         field:"innerHTML",
 
         field:"innerHTML",
         en:"Calculation speed",
+
         en:"Calculation speed:",
         ru:"Скорость расчета"
+
         ru:"Скорость расчета:"
 
     }, span_txt_ns_particle_step:{
 
     }, span_txt_ns_particle_step:{
 
         field:"innerHTML",
 
         field:"innerHTML",
 
         en:"ns/(particle&#8901;step)",
 
         en:"ns/(particle&#8901;step)",
 
         ru:"нс/(частица&#8901;шаг)"
 
         ru:"нс/(частица&#8901;шаг)"
 +
    }, span_txt_periods:{
 +
        field:"innerHTML",
 +
        en:"periods",
 +
        ru:"периодов"
 +
    }, div_txt_P:{
 +
        field:"innerHTML",
 +
        en:"P",
 +
        ru:"П"
 
     }
 
     }
 
};
 
};
Строка 253: Строка 331:
 
     <script src="Bessel_fluctuations.js"></script>
 
     <script src="Bessel_fluctuations.js"></script>
 
     <script src="Lang/Lang.js"></script>
 
     <script src="Lang/Lang.js"></script>
 +
    <script src="Libs/bessel.js"></script>
 
     <style>
 
     <style>
 
         table.outer td, table.outer tr {border: 1px solid #ddd; padding-right: 10px; padding-left: 5px}
 
         table.outer td, table.outer tr {border: 1px solid #ddd; padding-right: 10px; padding-left: 5px}
Строка 259: Строка 338:
 
</head>
 
</head>
 
<body>
 
<body>
     <canvas id="BF_canvas" width="1000" height="500" style="border:1px solid #000000;"></canvas><br>
+
     <table style="border-collapse:collapse;">
 +
        <tr><td style="text-align: center; vertical-align: top; width: 25px;">
 +
            <div id="div_txt_J0" style="color: #00dd00; font-style:italic;">K<sub>J</sub></div>
 +
            <div id="div_txt_K" style="color: #ff0000; font-style:italic;">K</div>
 +
            <div id="div_txt_P" style="color: #0000ff; font-style:italic;"></div>
 +
            <div id="div_txt_E" style="color: #880088; font-style:italic;">E/2</div>
 +
        </td><td>
 +
        <canvas id="BF_canvas" width="1000" height="500" style="border:1px solid #000000; display: block "></canvas>
 +
    </td></tr><tr><td></td><td style="text-align: right;">
 +
        <div style="color: #444444; font-style:italic; margin-top:-5px">x</div>
 +
    </td></tr><tr><td colspan="2">
 +
 
 +
        <table class="outer" style="border-collapse: collapse; width:100%">
 +
            <tr>
 +
                <td style="width: 270px">
 +
                    <input type="checkbox" id="checkbox_Bessel" checked/><font color="#00dd00" size="5"><B>—</B></font> <span id="span_txt_Bessel"></span> <br>
 +
                    <input type="checkbox" id="checkbox_K" checked/><font color="#ff0000" size="5"><B>—</B></font> <span id="span_kin_energy"></span> <br>
 +
                    <input type="checkbox" id="checkbox_P"/><font color="#0000ff" size="5"><B>—</B></font> <span id="span_pot_energy"></span> <br>
 +
                    <input type="checkbox" id="checkbox_E"/><font color="#880088" size="5"><B>—</B></font> <span id="span_full_energy"></span> <br>
 +
                </td><td>
 +
                    <input type="button" id="button_start" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold;"/>
 +
                    <input type="button" id="button_stop" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold; display:none"/><br>
 +
                    <input type="image" src="Lang/RU.png" onclick="set_lang('ru')"/>
 +
                    <input type="image" src="Lang/GB.png" onclick="set_lang('en')"/><br>
 +
                    <div id="div_container_progress" style="display: none;">
 +
                        <span id="span_progress_txt"></span><span id="span_progress"></span>
 +
                        <div id="container_bar" style="width:200px; height:20px; border:1px solid black;">
 +
                            <div id="progress_bar" style="width:10%;background-color: orange; height:20px;"></div>
 +
                        </div>
 +
                    </div>
  
    <table class="outer" style="border-collapse: collapse; width:1002px">
+
                    <div id="div_calc_speed" style="display: none">
        <tr>
+
                        <abbr id="abbr_speed" style="border-bottom: 1px dotted black;">
            <td style="width: 300px">
+
                            <span id="span_txt_calc_speed"></span> <span id="span_time_calc"></span> <span id="span_txt_ns_particle_step"></span>
                <input type="checkbox" id="checkbox_K" checked/><font color="#ff0000" size="5"><B>—</B></font> <span id="span_kin_energy"></span> <br>
+
                         </abbr>
                <input type="checkbox" id="checkbox_P" checked/><font color="#0000ff" size="5"><B>—</B></font> <span id="span_pot_energy"></span> <br>
 
                <input type="checkbox" id="checkbox_E" checked/><font color="#880088" size="5"><B>—</B></font> <span id="span_full_energy"></span> <br>
 
            </td><td>
 
                <input type="button" id="button_start" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold;"/><br>
 
                <input type="image" src="Lang/RU.png" onclick="set_lang('ru')"/>
 
                <input type="image" src="Lang/GB.png" onclick="set_lang('en')"/><br>
 
                <div id="div_container_progress" style="display: none;">
 
                    <span id="span_progress_txt"></span><span id="span_progress"></span>
 
                    <div id="container_bar" style="width:200px; height:20px; border:1px solid black;">
 
                         <div id="progress_bar" style="width:10%;background-color: orange; height:20px;"></div>
 
 
                     </div>
 
                     </div>
                </div>
 
  
                 <div id="div_calc_speed" style="display: none">
+
                 </td><td  style="width: 320px">
                    <abbr id="abbr_speed" style="border-bottom: 1px dotted black;" title="Данная скорость включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы">
+
                    <table class="inner">
                         <span id="span_txt_calc_speed"></span> <span id="span_time_calc"></span> <span id="span_txt_ns_particle_step"></span>
+
                        <tr>
                     </abbr>
+
                            <td>
                 </div>
+
                                <span id="span_txt_molecular_dynamics"></span>
 +
                            </td>
 +
                        </tr><tr>
 +
                            <td>
 +
                                <input type="number" id="N_number" step="1" min="2" style="width: 70px;"/> <span id="span_txt_particles"></span>,
 +
                                <input type="number" id="R_number" step="1" min="1" style="width: 70px;"/> <span id="span_txt_realizations"></span><br><br>
 +
                            </td>
 +
                         </tr><tr>
 +
                            <td>
 +
                                <span id="span_txt_calc_time"></span>
 +
                            </td>
 +
                        </tr><tr>
 +
                            <td>
 +
                                <input type="number" id="periods_number" step="0.1" min="0" style="width: 70px;"/> <span id="span_txt_periods"></span>
 +
                            </td>
 +
                        </tr>
 +
 
 +
                     </table>
 +
                 </td>
 +
            </tr>
 +
        </table>
 +
 
 +
    </td></tr></table>
  
            </td><td  style="width: 300px">
 
                <table class="inner">
 
                    <tr>
 
                        <td><span id="span_txt_nubmer_of_particles"></span></td>
 
                        <td><input type="number" id="N_number" step="1" style="width: 70px;"/></td>
 
                    </tr>
 
                    <tr>
 
                        <td><span id="span_txt_calc_time"></span></td>
 
                        <td><input type="number" id="T_number" step="1" style="width: 70px;"/> t0</td>
 
                    </tr>
 
                </table>
 
            </td>
 
        </tr>
 
    </table>
 
 
     <script>set_lang("ru")</script>
 
     <script>set_lang("ru")</script>
 
</body>
 
</body>
Строка 304: Строка 409:
 
</div>
 
</div>
 
</div>
 
</div>
 +
 +
== Старые версии программы ==
 +
* [[Колебания энергий в одномерном кристалле v2.5]]
  
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Программирование]]
 
[[Category: Программирование]]
 +
[[Category: Проект "Термокристалл"]]

Текущая версия на 13:45, 30 марта 2016

Кафедра ТМ > Проект "Термокристалл" > Колебания энергий в одномерном кристалле
Виртуальная лаборатория > Колебания энергий в одномерном кристалле
Д.В. Цветков (программирование), А.М. Кривцов (аналитическое решение)

Данная программа демонстрирует колебания кинетической, потенциальной и полной энергий в одномерном кристалле. Колебания кинетической энергии описываются следующим уравнением:

[math] K_J(t) = \frac{E}{2} \left(1 + J_0(4 \omega_0 )\right) ,\qquad \omega_0 = \sqrt{C/m}, [/math]

где [math]J_0[/math] — Функция Бесселя первого рода в точке 0, [math]C[/math] — жесткость связи между частицами, [math]m[/math] — масса частицы.

Скачать программу: Bessel_fluctuations_v3.0.zip

Текст программы на языке JavaScript (использована библиотека bessel.js):

Файл "Bessel_fluctuations.js"

  1 window.addEventListener("load", main_BF, false);
  2 function main_BF() {
  3 
  4     // Предварительные установки
  5     var a0 = 1;                             // масштаб расстояния
  6     var t0 = 1;                             // масштаб времени
  7     var m0 = 1;                             // масштаб массы
  8 
  9     var k0 = 2 * Math.PI / t0;              // масштаб частоты
 10     var C0 = m0 * k0 * k0;                  // масштаб жесткости
 11 
 12     var m = 1 * m0;                 	    // масса
 13     var C = 0.02 * C0;                 	    // жесткость
 14 
 15     var dx = 1 * a0;                        // шаг сетки по оси x
 16     var dt = 0.02 * t0;                     // шаг интегрирования по времени
 17 
 18     var R = 10;                              // количество реализаций
 19     var N = 10000;                         // количество частиц в каждой реализации
 20     var periods = 10;                       // время расчета в периодах колебаний энергий
 21 
 22     var koeff = C / (dx * dx) / m * dt;     // коэффициент для уравнения динамики частиц
 23 
 24     var T;
 25     // функция переводит время в периодах в расчетное время
 26     function set_periods(n) {
 27         // первый раз кинетическая и потенциальная энергии доходят до нуля за 0.4 периода колебаний
 28         var T0 = Math.PI / (Math.sqrt(C / m)) / 2;  // период колебаний
 29         if (n >= 0.4 * T0) T = T0 * ( 0.4 + 0.75 + (n - 1) );
 30         else T = n;
 31     }
 32     set_periods(periods);
 33 
 34     // интерфейс программы
 35     N_number.value = N;
 36     N_number.oninput = function() {N = parseInt(N_number.value);};
 37     periods_number.value = periods;
 38     periods_number.oninput = function() {
 39         set_periods(parseFloat(periods_number.value));
 40     };
 41     R_number.value = R;
 42     R_number.oninput = function() {R = parseInt(R_number.value);};
 43     button_start.onclick = calculate_new_system;
 44     button_stop.onclick = function() {
 45         working = false;
 46     };
 47     checkbox_Bessel.onchange = function() {
 48         draw();
 49         if (checkbox_Bessel.checked) div_txt_J0.style.display = "block";
 50         else div_txt_J0.style.display = "none"
 51     };
 52     checkbox_K.onchange = function() {
 53         draw();
 54         if (checkbox_K.checked) div_txt_K.style.display = "block";
 55         else div_txt_K.style.display = "none"
 56     };
 57     checkbox_P.onchange = function() {
 58         draw();
 59         if (checkbox_P.checked) div_txt_P.style.display = "block";
 60         else div_txt_P.style.display = "none"
 61     };
 62     checkbox_E.onchange = function() {
 63         draw();
 64         if (checkbox_E.checked) div_txt_E.style.display = "block";
 65         else div_txt_E.style.display = "none"
 66     };
 67 
 68     var ctx = BF_canvas.getContext("2d");   // на context происходит рисование
 69     var w = BF_canvas.width;                // ширина окна в расчетных координатах
 70     var h = BF_canvas.height;               // высота окна в расчетных координатах
 71 
 72     // основная расчетная функция
 73     var data_K, data_P, data_E;             // данные для графика
 74     var t, n;
 75     var t_start;
 76     var working;
 77     var step;
 78     function calculate_new_system() {
 79         t = 0;
 80         n = N + 2;                          // количество узлов по оси x + 2 для ГУ
 81         working = true;
 82         step = 0;
 83 
 84         span_time_calc.innerHTML = "";
 85         div_calc_speed.style.display = "none";
 86         button_start.style.display = "none";
 87         button_stop.style.display = "inline";
 88 
 89         // задание начальных условий
 90         var all_P = [];
 91         for (var r = 0; r < R; r++) {
 92             var P = [];
 93             for (var i = 1; i < n - 1; i++) {
 94                 P[i] = {};
 95                 P[i].u = 0;
 96                 P[i].v = (2 * Math.random() - 1) * 0.25;
 97             }
 98             // периодические граничные условия
 99             P[0] = P[n - 2];
100             P[n - 1] = P[1];
101             all_P.push(P);
102         }
103 
104         data_K = []; data_P = []; data_E = [];
105 
106         // основной расчет
107         t_start = performance.now();
108         calculate(all_P);
109     }
110     calculate_new_system();
111 
112     function calculate(all_P) {
113         var t1 = performance.now();
114         while (t < T) {
115             // расчет энергий для графиков
116             var Kin = 0;
117             var Pot = 0;
118             for (var p = 0; p < all_P.length; p++) {
119                 var P = all_P[p];
120                 for (var j = 1; j < n - 1; j++) {Kin += P[j].v * P[j].v;}
121                 for (var j = 1; j < n - 1; j++) {Pot += Math.pow(P[j].u - P[j - 1].u, 2);}
122             }
123             Kin = Kin * m / all_P.length;
124             Pot = Pot * C / all_P.length;
125             data_K.push(Kin);
126             data_P.push(Pot);
127             data_E.push(Kin + Pot);
128 
129             // расчет состояния системы на следующем шаге
130             for (var p = 0; p < all_P.length; p++) {
131                 var P = all_P[p];
132                 for (var i = 1; i < n - 1; i++) {
133                     P[i].v += (P[i + 1].u - 2 * P[i].u + P[i - 1].u) * koeff;
134                 }
135                 for (var i = 1; i < n - 1; i++) {
136                     P[i].u += P[i].v * dt;
137                 }
138             }
139             t += dt;
140             step++;
141 
142             // промежуточная прорисовка результатов, работа прогресс-бара
143             if ((performance.now() - t1) > 200) {
144                 if (working) {
145                     draw();
146                     setTimeout( function(){calculate(all_P); }, 10);
147                     div_container_progress.style.display = "block";
148                     progress_bar.style.width = Math.round(t / T * 100) + "%";
149                     span_progress.innerHTML = (t / T * 100).toFixed(0) + "%";
150                 } else {
151                     stop();
152                 }
153                 return;
154             }
155         }
156         stop();
157     }
158     function stop() {
159         // окончательная прорисовка результатов, удаление прогресс-бара, вывод скорости расчета
160         draw();
161         div_container_progress.style.display = "none";
162         button_start.style.display = "inline";
163         button_stop.style.display = "none";
164         div_calc_speed.style.display = "block";
165         span_time_calc.innerHTML = parseFloat(((performance.now() - t_start) * 1000 * 1000 / N / R / step).toPrecision(2));
166         return true;
167     }
168 
169     function draw() {
170         ctx.clearRect(0, 0, w, h);              // очистка экрана
171 
172         if (checkbox_Bessel.checked) {
173             // Функция Бесселя первого рода в точке 0
174             ctx.strokeStyle = "#00dd00";
175             ctx.lineWidth = 2;
176             ctx.beginPath();
177             ctx.moveTo(0, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * 0, 0) / data_K[0] * h / 2 - h / 2);
178             for (var i = 0.001; i < t; i += 0.001) {
179                 ctx.lineTo(i / t * w, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * i, 0) / data_K[0] * h / 2 - h / 2);
180             }
181             ctx.stroke();
182         }
183 
184         if (checkbox_K.checked) {
185             // Кинетическая энергия
186             ctx.strokeStyle = "#ff0000";
187             ctx.lineWidth = 1;
188             ctx.beginPath();
189             ctx.moveTo(0, 0);
190             for (var i = 1; i < data_K.length; i++) {
191                 ctx.lineTo(i / (data_K.length - 1) * w, h - data_K[i] / data_K[0] * h);
192             }
193             ctx.stroke();
194         }
195 
196         if (checkbox_P.checked) {
197             // Потенциальная энергия
198             ctx.strokeStyle = "#0000ff";
199             ctx.lineWidth = 1;
200             ctx.beginPath();
201             ctx.moveTo(0, h - data_P[0] / data_K[0] * h);
202             for (var i = 1; i < data_P.length; i++) {
203                 ctx.lineTo(i / (data_P.length - 1) * w, h - data_P[i] / data_K[0] * h);
204             }
205             ctx.stroke();
206         }
207 
208         if (checkbox_E.checked) {
209             // Полная энергия
210             ctx.strokeStyle = "#880088";
211             ctx.lineWidth = 2;
212             ctx.beginPath();
213             ctx.moveTo(0, h - data_E[0] / 2 / data_K[0] * h);
214             for (var i = 1; i < data_E.length; i++) {
215                 ctx.lineTo(i / (data_E.length - 1) * w, h - data_E[i] / 2 / data_K[0] * h);
216             }
217             ctx.stroke();
218         }
219     }
220 }

Файл "Lang.js"

 1 strings = {
 2     span_kin_energy:{
 3         field:"innerHTML",
 4         en:"Kinetic energy",
 5         ru:"Кинетическая энергия"
 6     }, span_pot_energy:{
 7         field:"innerHTML",
 8         en:"Potential energy",
 9         ru:"Потенциальная энергия"
10     }, span_full_energy:{
11         field:"innerHTML",
12         en:"Full energy",
13         ru:"Полная энергия"
14     }, span_txt_Bessel:{
15         field:"innerHTML",
16         en:"Analytical sol. for the kinetic energy",
17         ru:"Аналит. решение для кин. энергии"
18     }, button_start:{
19         field:"value",
20         en:"Start",
21         ru:"Старт"
22     }, button_stop:{
23         field:"value",
24         en:"Stop",
25         ru:"Стоп"
26     }, span_progress_txt:{
27         field:"innerHTML",
28         en:"Progress: ",
29         ru:"Прогресс: "
30     }, abbr_speed:{
31         field:"title",
32         en:"The calculation of this speed includes the time for processing interface and drawing the intermediate states of the system",
33         ru:"Расчет данной скорости включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы"
34     }, span_txt_molecular_dynamics:{
35         field:"innerHTML",
36         en:"Molecular_dynamics:",
37         ru:"Молекулярная динамика:"
38     }, span_txt_particles:{
39         field:"innerHTML",
40         en:"particles",
41         ru:"частиц"
42     }, span_txt_realizations:{
43         field:"innerHTML",
44         en:"realizations",
45         ru:"реализаций"
46     }, span_txt_calc_time:{
47         field:"innerHTML",
48         en:"Calculation time:",
49         ru:"Время расчета:"
50     }, span_txt_calc_speed:{
51         field:"innerHTML",
52         en:"Calculation speed:",
53         ru:"Скорость расчета:"
54     }, span_txt_ns_particle_step:{
55         field:"innerHTML",
56         en:"ns/(particle&#8901;step)",
57         ru:"нс/(частица&#8901;шаг)"
58     }, span_txt_periods:{
59         field:"innerHTML",
60         en:"periods",
61         ru:"периодов"
62     }, div_txt_P:{
63         field:"innerHTML",
64         en:"P",
65         ru:"П"
66     }
67 };
68 
69 function set_lang(lang){
70     for (var s in strings) {
71         document.getElementById(s)[strings[s].field] = strings[s][lang];
72     }
73 }

Файл "Bessel_fluctuations.html"

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Bessel fluctuations</title>
    <script src="Bessel_fluctuations.js"></script>
    <script src="Lang/Lang.js"></script>
    <script src="Libs/bessel.js"></script>
    <style>
        table.outer td, table.outer tr {border: 1px solid #ddd; 	padding-right: 10px; padding-left: 5px}
        table.inner td, table.inner tr {border: 0}
    </style>
</head>
<body>
    <table style="border-collapse:collapse;">
        <tr><td style="text-align: center; vertical-align: top; width: 25px;">
            <div id="div_txt_J0" style="color: #00dd00; font-style:italic;">K<sub>J</sub></div>
            <div id="div_txt_K" style="color: #ff0000; font-style:italic;">K</div>
            <div id="div_txt_P" style="color: #0000ff; font-style:italic;"></div>
            <div id="div_txt_E" style="color: #880088; font-style:italic;">E/2</div>
        </td><td>
        <canvas id="BF_canvas" width="1000" height="500" style="border:1px solid #000000; display: block "></canvas>
    </td></tr><tr><td></td><td style="text-align: right;">
        <div style="color: #444444; font-style:italic; margin-top:-5px">x</div>
    </td></tr><tr><td colspan="2">

        <table class="outer" style="border-collapse: collapse; width:100%">
            <tr>
                <td style="width: 270px">
                    <input type="checkbox" id="checkbox_Bessel" checked/><font color="#00dd00" size="5"><B></B></font> <span id="span_txt_Bessel"></span> <br>
                    <input type="checkbox" id="checkbox_K" checked/><font color="#ff0000" size="5"><B></B></font> <span id="span_kin_energy"></span> <br>
                    <input type="checkbox" id="checkbox_P"/><font color="#0000ff" size="5"><B></B></font> <span id="span_pot_energy"></span> <br>
                    <input type="checkbox" id="checkbox_E"/><font color="#880088" size="5"><B></B></font> <span id="span_full_energy"></span> <br>
                </td><td>
                    <input type="button" id="button_start" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold;"/>
                    <input type="button" id="button_stop" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold; display:none"/><br>
                    <input type="image" src="Lang/RU.png" onclick="set_lang('ru')"/>
                    <input type="image" src="Lang/GB.png" onclick="set_lang('en')"/><br>
                    <div id="div_container_progress" style="display: none;">
                        <span id="span_progress_txt"></span><span id="span_progress"></span>
                        <div id="container_bar" style="width:200px; height:20px; border:1px solid black;">
                            <div id="progress_bar" style="width:10%;background-color: orange; height:20px;"></div>
                        </div>
                    </div>

                    <div id="div_calc_speed" style="display: none">
                        <abbr id="abbr_speed" style="border-bottom: 1px dotted black;">
                            <span id="span_txt_calc_speed"></span> <span id="span_time_calc"></span> <span id="span_txt_ns_particle_step"></span>
                        </abbr>
                    </div>

                </td><td  style="width: 320px">
                    <table class="inner">
                        <tr>
                            <td>
                                <span id="span_txt_molecular_dynamics"></span>
                            </td>
                        </tr><tr>
                            <td>
                                <input type="number" id="N_number" step="1" min="2" style="width: 70px;"/> <span id="span_txt_particles"></span>,
                                <input type="number" id="R_number" step="1" min="1" style="width: 70px;"/> <span id="span_txt_realizations"></span><br><br>
                            </td>
                        </tr><tr>
                            <td>
                                <span id="span_txt_calc_time"></span>
                            </td>
                        </tr><tr>
                            <td>
                                <input type="number" id="periods_number" step="0.1" min="0" style="width: 70px;"/> <span id="span_txt_periods"></span>
                            </td>
                        </tr>

                    </table>
                </td>
            </tr>
        </table>

    </td></tr></table>

    <script>set_lang("ru")</script>
</body>
</html>

Старые версии программы[править]