Редактирование: Цепочка частиц с вращательными степенями свободы
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 4: | Строка 4: | ||
Рассматривается совокупность твердых тел, образующих цепочки. Центры масс фиксированы. Взаимодействия осуществляются посредством балок Бернулли-Эйлера, соединяющих тела. | Рассматривается совокупность твердых тел, образующих цепочки. Центры масс фиксированы. Взаимодействия осуществляются посредством балок Бернулли-Эйлера, соединяющих тела. | ||
− | |||
Дифференциальное уравнение изгиба балки: | Дифференциальное уравнение изгиба балки: | ||
::<math> | ::<math> | ||
− | EJ {\bf y} | + | EJ\ddddot{\bf y} = 0 |
− | </math>, где | + | </math>, |
− | Момент | + | где E - модуль юнга, J - полярный момент инерции. |
+ | Момент взаимодействия: | ||
::<math> | ::<math> | ||
− | EJ {\bf y} | + | EJ\ddot{\bf y} = M |
</math> | </math> | ||
− | + | Уравнение движения: | |
::<math> | ::<math> | ||
− | {\bf | + | Q\ddot{\bf ϕ}_{k} = -2EJ/l({\bf ϕ}_{k-1}-2{\bf ϕ}_{k}+{\bf ϕ}_{k})-12EJ/l({\bf ϕ}_{k}) |
</math> | </math> | ||
− | |||
− | |||
− | |||
== Реализации цепочки == | == Реализации цепочки == | ||
Строка 25: | Строка 22: | ||
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Aleksandrov_AD/Spin-degree-of-freedom.html |width=1200 |height=1650 |border=0 }} | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Aleksandrov_AD/Spin-degree-of-freedom.html |width=1200 |height=1650 |border=0 }} | ||
− | [https:// | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > |
+ | |||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | |||
+ | window.addEventListener("load", MainSystem, true); | ||
+ | |||
+ | function MainSystem(){ | ||
+ | var context_s = canvasSystem.getContext('2d'); | ||
+ | var context_g = canvasGraph.getContext('2d'); | ||
+ | var context_g_1 = canvasGraph_1.getContext('2d'); | ||
+ | var context_g_2 = canvasGraph_2.getContext('2d'); | ||
+ | |||
+ | const Pi = 3.1415926; | ||
+ | const m0 = 1; | ||
+ | const T0 = 1; | ||
+ | const l0 = 1; | ||
+ | const E0 = 1; | ||
+ | |||
+ | //Width of canvas - width of browser | ||
+ | const distance_between_canvases = 5; //5px | ||
+ | canvasSystem.width = document.body.clientWidth; | ||
+ | canvasGraph.width = document.body.clientWidth / 2 - distance_between_canvases; | ||
+ | canvasGraph_1.width = document.body.clientWidth / 2 - distance_between_canvases; | ||
+ | canvasGraph_2.width = document.body.clientWidth; | ||
+ | |||
+ | /* -- Used constans -- */ | ||
+ | var Db = 0.1 * l0; // Diameter of beam | ||
+ | const l = 30 * l0; //Length of beam | ||
+ | const a = 60 * l0; //Length of object | ||
+ | var Db2 = Db * Db; | ||
+ | var J = Pi * Db2 * Db2 / 64; //Polar moment of inertia | ||
+ | const E = 10000000 * E0; //Youngs modulus | ||
+ | var C = E * J / l; | ||
+ | var N = parseFloat(number_of_objects.value) + 1; //number_of_objects.value is number of objects | ||
+ | const m = 0.01 * m0; //Mass of object | ||
+ | const Q = m * a * a / 12; //Moment of inertia | ||
+ | const w_c = Math.sqrt(2 * C / Q); //Self frequency | ||
+ | |||
+ | const fps = 50; // frames per second | ||
+ | var spf = calcul_speed.value; // steps per frame | ||
+ | const frequency = 1000 / fps; //frequency of call function - 1000 milliseconds/ fps | ||
+ | const dt = 0.05 * T0 / fps; //Step of integration | ||
+ | |||
+ | var scale = canvasSystem.width / N; //Scale of graph of system | ||
+ | var scale1 = canvasGraph_2.width / (N + 2); //Scale of graph of angels | ||
+ | |||
+ | //For wave | ||
+ | const n = 1; //Number of full-wave | ||
+ | var k_ = 2 * Pi / (l * (N - 2) * n); //Spatial frequencyw | ||
+ | var w_ = Math.sqrt((-2 * C / Q * l * l) * k_ * k_ + (12 * C / Q)); | ||
+ | |||
+ | /* -- Used variables -- */ | ||
+ | var K0 = 0; var P0 = 0; var E_p0 = 0; var L0 = 0; //Energies at i-step | ||
+ | var K1 = 0; var P1 = 0; var E_p1 = 0; var L1 = 0; // Energies at (i+1)-step | ||
+ | var E_m = 0; //Maximum of Energy at the first moment | ||
+ | var t = 0; //Time | ||
+ | |||
+ | var U = []; //Exact solution for wave | ||
+ | var shaft = []; //Objects | ||
+ | |||
+ | var pause = false; | ||
+ | const stretch_graphics = 3; | ||
+ | var help = stretch_graphics * canvasGraph.width; //Scale of graph of energies | ||
+ | var firstCalculation = true; | ||
+ | /* -- */ | ||
+ | |||
+ | //Restart the programm with new parameters | ||
+ | restart.onclick = function(){ | ||
+ | N = parseFloat(number_of_objects.value) + 1; | ||
+ | scale = canvasSystem.width / N; | ||
+ | scale1 = canvasGraph_2.width / (N + 2); | ||
+ | spf = calcul_speed.value; | ||
+ | J = Pi * Db2 * Db2 / 64; | ||
+ | C = E * J / l; | ||
+ | |||
+ | context_s.clearRect(0, 0, canvasSystem.width, canvasSystem.height); | ||
+ | context_g.clearRect(0, 0, canvasGraph.width, canvasGraph.height); | ||
+ | context_g_1.clearRect(0, 0, canvasGraph_1.width, canvasGraph_1.height); | ||
+ | context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height); | ||
+ | |||
+ | shaft = []; | ||
+ | addSystem(shaft); | ||
+ | |||
+ | firstCalculation = true; | ||
+ | t = 0; | ||
+ | P1 = 0; | ||
+ | K1 = 0; | ||
+ | E_m = 0; | ||
+ | } | ||
+ | |||
+ | //Pause | ||
+ | pause_button.onclick = function(){ | ||
+ | pause = !pause; | ||
+ | if(pause == false) | ||
+ | pause_button.value = "Pause"; | ||
+ | else | ||
+ | pause_button.value = "Run"; | ||
+ | } | ||
+ | |||
+ | //Calculate all parameters of system | ||
+ | function control(){ | ||
+ | if(!pause){ | ||
+ | /* -- Find the maximum of energy -- */ | ||
+ | if(firstCalculation){ | ||
+ | for (var i = 1; i < N; i++){ | ||
+ | E_m += Q * shaft[i].w * shaft[i].w / 2; | ||
+ | } | ||
+ | |||
+ | for (var i = 1; i < N; i++){ | ||
+ | E_m += C / 2 * (12 * shaft[i].fi * shaft[i].fi - ((shaft[i-1].fi - shaft[i].fi) * (shaft[i-1].fi - shaft[i].fi) + | ||
+ | (shaft[i].fi - shaft[i+1].fi) * (shaft[i].fi - shaft[i+1].fi))); | ||
+ | } | ||
+ | |||
+ | L0 = E_m; | ||
+ | E_p0 = E_m / 2; | ||
+ | firstCalculation = false; | ||
+ | } | ||
+ | /* -- */ | ||
+ | |||
+ | physics(); | ||
+ | draw(); | ||
+ | |||
+ | if(t*help > canvasGraph.width){ | ||
+ | t = 0; | ||
+ | context_g.clearRect(0, 0, canvasGraph.width, canvasGraph.height); | ||
+ | context_g_1.clearRect(0, 0, canvasGraph_1.width, canvasGraph_1.height); | ||
+ | } | ||
+ | |||
+ | draw_Graph_energy(t*help, (t + dt)*help); | ||
+ | draw_Graph_angels(); | ||
+ | |||
+ | //exact_solution_for_wave(t*help); | ||
+ | |||
+ | P0 = P1; | ||
+ | K0 = K1; | ||
+ | L0 = L1; | ||
+ | E_p0 = E_p1; | ||
+ | E_p1 = 0; | ||
+ | L1 = 0; | ||
+ | P1 = 0; | ||
+ | K1 = 0; | ||
+ | t += dt; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //Physics - calculate the positions of objects | ||
+ | function physics(){ | ||
+ | for (var s = 1; s <= spf; s++){ | ||
+ | //Periodic initial conditions | ||
+ | shaft[0].fi = shaft[N-1].fi; | ||
+ | shaft[N].fi = shaft[1].fi; | ||
+ | |||
+ | for (var i = 1; i < N; i++){ | ||
+ | shaft[i].M = - 2 * C * (shaft[i-1].fi + 2 * shaft[i].fi) - 2 * C * (2 * shaft[i].fi + shaft[i+1].fi); | ||
+ | } | ||
+ | |||
+ | for (var i = 1; i < N; i++){ | ||
+ | shaft[i].w += shaft[i].M / Q * dt; | ||
+ | shaft[i].fi += shaft[i].w * dt; | ||
+ | } | ||
+ | |||
+ | for (var i = 1; i < N; i++){ | ||
+ | shaft[i].M = 0; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //Draw the graph of system | ||
+ | function draw(){ | ||
+ | context_s.clearRect(0, 0, canvasSystem.width, canvasSystem.height); | ||
+ | |||
+ | for (var i = 1; i < N; i++){ | ||
+ | context_s.beginPath(); | ||
+ | context_s.moveTo(shaft[i].x - (a/2) * Math.sin(shaft[i].fi), shaft[i].y - (a/2) * Math.cos(shaft[i].fi)); | ||
+ | context_s.lineTo(shaft[i].x + (a/2) * Math.sin(shaft[i].fi), shaft[i].y + (a/2) * Math.cos(shaft[i].fi)); | ||
+ | context_s.closePath(); | ||
+ | context_s.stroke(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //Draw the graph of angels | ||
+ | function draw_Graph_angels(){ | ||
+ | context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height); | ||
+ | |||
+ | for(var i = 0; i < N; i++){ | ||
+ | context_g_2.beginPath(); | ||
+ | context_g_2.moveTo(scale1 * (i+1), -shaft[i].fi / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); | ||
+ | context_g_2.lineTo(scale1 * (i+2), -shaft[i+1].fi / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); | ||
+ | context_g_2.closePath(); | ||
+ | context_g_2.stroke(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //Draw the graphics of energies | ||
+ | function draw_Graph_energy(x0, x1){ | ||
+ | //Potential | ||
+ | context_g_1.beginPath(); | ||
+ | context_g_1.strokeStyle = "#FF0000"; | ||
+ | context_g_1.moveTo(x0, -P0 / E_m * canvasGraph_1.height + canvasGraph_1.height); | ||
+ | |||
+ | for (var i = 1; i < N; i++){ | ||
+ | P1 += C / 2 * (12 * shaft[i].fi * shaft[i].fi - ((shaft[i-1].fi - shaft[i].fi) * (shaft[i-1].fi - shaft[i].fi) + | ||
+ | (shaft[i].fi - shaft[i+1].fi) * (shaft[i].fi - shaft[i+1].fi))); | ||
+ | } | ||
+ | |||
+ | context_g_1.lineTo(x1, -P1 / E_m * canvasGraph_1.height + canvasGraph_1.height); | ||
+ | context_g_1.closePath(); | ||
+ | context_g_1.stroke(); | ||
+ | |||
+ | //Kinetical | ||
+ | context_g_1.beginPath(); | ||
+ | context_g_1.strokeStyle = "#000000"; | ||
+ | context_g_1.moveTo(x0, -K0 / E_m * canvasGraph_1.height + canvasGraph_1.height); | ||
+ | |||
+ | for (var i = 1; i < N; i++){ | ||
+ | K1 += Q * shaft[i].w * shaft[i].w / 2; | ||
+ | } | ||
+ | |||
+ | context_g_1.lineTo(x1, -K1 / E_m * canvasGraph_1.height + canvasGraph_1.height); | ||
+ | context_g_1.closePath(); | ||
+ | context_g_1.stroke(); | ||
+ | |||
+ | //Full energy | ||
+ | context_g_1.beginPath(); | ||
+ | context_g_1.strokeStyle = "blue"; | ||
+ | context_g_1.moveTo(x0, -E_p0 / E_m * canvasGraph.height + canvasGraph.height); | ||
+ | |||
+ | E_p1 = (K1 + P1) / 2; | ||
+ | |||
+ | context_g_1.lineTo(x1, -E_p1 / E_m * canvasGraph.height + canvasGraph.height); | ||
+ | context_g_1.closePath(); | ||
+ | context_g_1.stroke(); | ||
+ | |||
+ | //Lagrangian | ||
+ | context_g.beginPath(); | ||
+ | context_g.strokeStyle = "orange"; | ||
+ | context_g.moveTo(x0, -L0 / E_m * canvasGraph.height / 2 + canvasGraph.height / 2); | ||
+ | |||
+ | L1 = K1 - P1; | ||
+ | |||
+ | context_g.lineTo(x1, -L1 / E_m * canvasGraph.height / 2 + canvasGraph.height / 2); | ||
+ | context_g.closePath(); | ||
+ | context_g.stroke(); | ||
+ | } | ||
+ | |||
+ | //Add the system of objects | ||
+ | function addSystem(shaft){ | ||
+ | for (var i = 0; i < N + 1; i++){ | ||
+ | var shaft_new = []; | ||
+ | |||
+ | shaft_new.x = scale * i; | ||
+ | shaft_new.y = canvasSystem.height / 2; | ||
+ | shaft_new.fi = 0; | ||
+ | shaft_new.w = 0; | ||
+ | shaft_new.M = 0; | ||
+ | shaft[shaft.length] = shaft_new; | ||
+ | } | ||
+ | |||
+ | /* --Initial conditions-- */ | ||
+ | //Random velocities | ||
+ | if(all_.checked){ | ||
+ | var average_w = 0; //Average velocity | ||
+ | |||
+ | for (var i = 0; i < N; i++){ | ||
+ | shaft[i].w = Math.random() * w_c; | ||
+ | average_w += shaft[i].w; | ||
+ | } | ||
+ | |||
+ | average_w /= N; | ||
+ | |||
+ | for (var i = 0; i < N; i++){ | ||
+ | shaft[i].w -= average_w; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // N/10 - Central part of objects by sin | ||
+ | if(part.checked){ | ||
+ | for (var i = Math.floor(-Math.floor(N / 10) / 2); i < Math.floor(Math.floor(N / 10) / 2); i++){ | ||
+ | shaft[Math.floor(N / 2) + i + 1].fi = | ||
+ | Math.sin(2 * Pi * (Math.floor(Math.floor(N / 10) / 2) - i) * (Math.floor(Math.floor(N / 10) / 2) + i) / N/2); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //Central object | ||
+ | if(one.checked){ | ||
+ | shaft[Math.floor(N / 2)].w = w_c; | ||
+ | } | ||
+ | |||
+ | //Wave | ||
+ | if(wave.checked){ | ||
+ | for (var i = 1; i < N; i++){ | ||
+ | shaft[i].fi = Math.sin(k_ * (l * i)); | ||
+ | shaft[i].w = -w_ * Math.cos(k_ * (l * i)); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //Exact solution for wave | ||
+ | function exact_solution_for_wave(t) { | ||
+ | for (var i = 1; i < N; i++){ | ||
+ | U[i] = Math.sin(k_ * (l * i) - w_ * t / 200); | ||
+ | } | ||
+ | //context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height); | ||
+ | for(var i = 0; i < N; i++){ | ||
+ | context_g_2.beginPath(); | ||
+ | context_g_2.moveTo(scale1 * (i+1), -U[i] / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); | ||
+ | context_g_2.lineTo(scale1 * (i+2), -U[i+1] / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); | ||
+ | context_g_2.closePath(); | ||
+ | context_g_2.stroke(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | addSystem(shaft); //Adding our system of objects | ||
+ | |||
+ | setInterval(control, frequency); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang="html5" line start="1" enclose="div"> | ||
+ | <!DOCTYPE html> | ||
+ | <html> | ||
+ | <body> | ||
+ | <canvas id="canvasSystem" width="1200" height="300" style="border:1px solid #000000;"></canvas><br><br> | ||
+ | |||
+ | Number of objects: <input type="number" id="number_of_objects" value="500" step=1 style="width: 5em">, | ||
+ | Calculation speed: <input type="range" id="calcul_speed" value="100" step=0.01 min=10 max=300><br> | ||
+ | |||
+ | Initial conditions:<br> | ||
+ | <input type="radio" checked="checked" name="initial_conditions" id="all_"/>Random velocities<br> | ||
+ | <input type="radio" name="initial_conditions" id="part"/>Central part of objects by sin<br> | ||
+ | <input type="radio" name="initial_conditions" id="one"/>One object<br> | ||
+ | <input type="radio" name="initial_conditions" id="wave"/>Wave<br> | ||
+ | <input type="button" id="restart" value="Restart"> | ||
+ | <input type="button" id="pause_button" value="Pause"><br><br> | ||
+ | |||
+ | Graphics:<br> | ||
+ | <canvas id="canvasGraph" width="600" height="300" style="border:1px solid #000000;"></canvas> | ||
+ | <canvas id="canvasGraph_1" width="600" height="300" style="border:1px solid #000000;"></canvas><br> | ||
+ | L<hr align="left" width="50" size="3" color="orange" /> | ||
+ | E / 2<hr align="left" width="50" size="3" color="blue" /> | ||
+ | K<hr align="left" width="50" size="3" color="#000000" /> | ||
+ | P<hr align="left" width="50" size="3" color="#FF0000" /><br> | ||
+ | |||
+ | Angles:<br> | ||
+ | <canvas id="canvasGraph_2" width="1200" height="300" style="border:1px solid #000000;"></canvas><br> | ||
+ | |||
+ | <script src="simulation.js"></script> | ||
+ | </body> | ||
+ | </html> | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | </div> | ||
+ | [https://bitbucket.org/GA__GA/spin-degree-of-freedom/get/c518f9b3fb9b.zip Скачать архив] | ||
'''Текст программы на языке JavaScript (разработчик [[Александров Александр]]):''' | '''Текст программы на языке JavaScript (разработчик [[Александров Александр]]):''' | ||
− | |||
− |