Difference between revisions of "Driven oscillations of a mass on a nonlinear spring"

From Department of Theoretical and Applied Mechanics
Jump to: navigation, search
Line 6: Line 6:
 
== Formulation of the problem ==
 
== Formulation of the problem ==
 
Let’s put that the cargo on nonlinear spring has mass m and experiencing the action of an external force F, which has a law F = sin (t).
 
Let’s put that the cargo on nonlinear spring has mass m and experiencing the action of an external force F, which has a law F = sin (t).
 +
 
* Task: formulate the problem on JavaScript which modulate motion of the cargo with different parameters of the system.<br>
 
* Task: formulate the problem on JavaScript which modulate motion of the cargo with different parameters of the system.<br>
  
 
== Overview ==
 
== Overview ==
 
If the periodically changing external force is acting on the system, the system performs oscillations which repeat in different ways the nature of change of this force. Such oscillations are '''called forced'''.
 
If the periodically changing external force is acting on the system, the system performs oscillations which repeat in different ways the nature of change of this force. Such oscillations are '''called forced'''.
 +
 
F0 is the force amplitude and the greatest value of the force.
 
F0 is the force amplitude and the greatest value of the force.
 +
 
{|
 
{|
 
|-
 
|-
Line 16: Line 19:
 
|}
 
|}
  
Equation of motion:
+
Equation of motion:  
 
<math>m\ddot x = -kx -{k_1}x^3 + {F_0}sin(t) - B \dot x</math>
 
<math>m\ddot x = -kx -{k_1}x^3 + {F_0}sin(t) - B \dot x</math>
  
Line 23: Line 26:
 
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Kiselev/Spring/Springs.html |width=800 |height=800 |border=0 }}
 
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Kiselev/Spring/Springs.html |width=800 |height=800 |border=0 }}
  
Скачать программу: [[Медиа:SpringNoLine.rar|SpringNoLine.rar]]
+
Download program: [[Медиа:SpringNoLine.rar|SpringNoLine.rar]]
  
'''Текст программы на языке JavaScript (разработчик [[Киселев Павел]]):''' <div class="mw-collapsible-content">  
+
'''Text of the program on JavaScript (creator [[Киселев Павел]]):''' <div class="mw-collapsible-content">  
Файл '''"Spring.js"'''
+
File '''"Spring.js"'''
 
<syntaxhighlight lang="javascript" enclose="div">
 
<syntaxhighlight lang="javascript" enclose="div">
  
Line 32: Line 35:
 
     function Main_Spring() {
 
     function Main_Spring() {
 
     var canvas = spring_canvas;
 
     var canvas = spring_canvas;
     canvas.onselectstart = function () {return false;};    // запрет выделения canvas
+
     canvas.onselectstart = function () {return false;};    // prohibition selection canvas
     var ctx = canvas.getContext("2d");                      // на ctx происходит рисование
+
     var ctx = canvas.getContext("2d");                      // at the ctx is drawing
     var w = canvas.width;                                  // ширина окна в расчетных координатах
+
     var w = canvas.width;                                  // the width of the window in the calculated coordinates
     var h = canvas.height;                                  // высота окна в расчетных координатах
+
     var h = canvas.height;                                  // the height of the window in the calculated coordinates
     var Pi = 3.1415926;                              // число "пи"
+
     var Pi = 3.1415926;                              // Pi
     var m0 = 1;                              // масштаб массы
+
     var m0 = 1;                              // weight scale
     var T0 = 1;                              // масштаб времени (период колебаний исходной системы)
+
     var T0 = 1;                              // time scale (the period of oscillation of the original system)
 
     var t = 0;
 
     var t = 0;
     var k0 = 2 * Pi / T0;                              // масштаб частоты
+
     var k0 = 2 * Pi / T0;                              // frequency scale
     var C0 = m0 * k0 * k0;                              // масштаб жесткости
+
     var C0 = m0 * k0 * k0;                              // hardness scale
     var B0 = 2 * m0 * k0;                            // масштаб вязкости
+
     var B0 = 2 * m0 * k0;                            // viscosity scale
 
     var omega = 10;
 
     var omega = 10;
 
      
 
      
     // *** Задание физических параметров ***
+
     // *** Creating the physical parameters***
 
     var F = 80;
 
     var F = 80;
     var m = 1 * m0;                                    // масса
+
     var m = 1 * m0;                                    // weight
     var C = 1 * C0;                                    // жесткость
+
     var C = 1 * C0;                                    // rigidity
     var C1 = 1 * C0;                                    // жесткость1
+
     var C1 = 1 * C0;                                    // rigidity1
     var B = .1 * B0;                                    // вязкость
+
     var B = .1 * B0;                                    // viscosity
 
      
 
      
 
     slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1);
 
     slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1);
Line 58: Line 61:
 
     slider_F.value = (F / 40).toFixed(1); number_F.value = (F / 40).toFixed(1);
 
     slider_F.value = (F / 40).toFixed(1); number_F.value = (F / 40).toFixed(1);
  
     // *** Задание вычислительных параметров ***
+
     // *** Creating the parameters of computing ***
  
     var fps = 300;                   // frames per second - число кадров в секунду (качечтво отображения)
+
     var fps = 300;                   // frames per second
     var spf = 100;                   // steps per frame   - число шагов интегрирования между кадрами
+
     var spf = 100;                   // steps per frame  
     var dt  = 0.05 * T0 / fps;                // шаг интегрирования (качество расчета)
+
     var dt  = 0.05 * T0 / fps;                // integration step (calculation quality)  
     var steps = 0;                                  // количество шагов интегрирования
+
     var steps = 0;                                  // the number of integration steps
  
 
     function setM(new_m) {m = new_m * m0;}
 
     function setM(new_m) {m = new_m * m0;}
Line 82: Line 85:
 
     number_F.oninput = function() {slider_F.value = number_F.value;      setF(number_F.value);};
 
     number_F.oninput = function() {slider_F.value = number_F.value;      setF(number_F.value);};
  
     var count = true;                  // проводить ли расчет системы
+
     var count = true;                  // system analysis
     var v = 0; // скорость тела
+
     var v = 0; // cargo speed
  
 
     var rw = canvas.width / 30;   
 
     var rw = canvas.width / 30;   
Line 90: Line 93:
 
     var y0 = rh / 1.33 - rh / 2;
 
     var y0 = rh / 1.33 - rh / 2;
  
     // параметры пружины
+
     // spring settings
     var coil = 10;        // количество витков
+
     var coil = 10;        // number of turns
     var startX = 0;      // закрепление пружины
+
     var startX = 0;      // spring fastening
  
     // создаем прямоугольник-грузик
+
     // create a rectangle-cargo
 
     var rect = {
 
     var rect = {
 
         x: x0,  width: rw,
 
         x: x0,  width: rw,
Line 101: Line 104:
 
     };
 
     };
  
     // захват прямоугольника мышью
+
     // capture a rectangle with the mouse
 
     var mx_;                                    // буфер позиции мыши (для расчета скорости при отпускании шара)
 
     var mx_;                                    // буфер позиции мыши (для расчета скорости при отпускании шара)
 
     document.onmousedown = function(e) {        // функция при нажатии клавиши мыши
 
     document.onmousedown = function(e) {        // функция при нажатии клавиши мыши

Revision as of 16:13, 31 May 2016

thumb|Нелинейный колебания груза с вынуждающей силой|500px

Annotation to the project

This project gives an idea about nonlinear oscillation of cargo with the periodic force acting on it.

Formulation of the problem

Let’s put that the cargo on nonlinear spring has mass m and experiencing the action of an external force F, which has a law F = sin (t).

  • Task: formulate the problem on JavaScript which modulate motion of the cargo with different parameters of the system.

Overview

If the periodically changing external force is acting on the system, the system performs oscillations which repeat in different ways the nature of change of this force. Such oscillations are called forced.

F0 is the force amplitude and the greatest value of the force.

Because of the work of an external force, the maximum value of the potential energy of the spring and the kinetic energy of the cargo increase. This will increase the loss on overcome the resistance forces. In the end the work of the external force will exactly offset the energy losses in the system. Further growth of the oscillations in the system will stop and oscillations will be established with a constant amplitude.
Характер амплитуды

Equation of motion: [math]m\ddot x = -kx -{k_1}x^3 + {F_0}sin(t) - B \dot x[/math]

Visualization on JavaScript

Download program: SpringNoLine.rar

Text of the program on JavaScript (creator Киселев Павел):

File "Spring.js" <syntaxhighlight lang="javascript" enclose="div">

   window.addEventListener("load", Main_Spring, true);
   function Main_Spring() {
   var canvas = spring_canvas;
   canvas.onselectstart = function () {return false;};     // prohibition selection canvas
   var ctx = canvas.getContext("2d");                      // at the ctx is drawing
   var w = canvas.width;                                   // the width of the window in the calculated coordinates
   var h = canvas.height;                                  // the height of the window in the calculated coordinates
   var Pi = 3.1415926;    	      	                    // Pi
   var m0 = 1;    		      	                    // weight scale
   var T0 = 1;    		      	                    // time scale (the period of oscillation of the original system)
   var t = 0;
   var k0 = 2 * Pi / T0;           	                    // frequency scale
   var C0 = m0 * k0 * k0;          	                    // hardness scale
   var B0 = 2 * m0 * k0;  	      	                    // viscosity scale
   var omega = 10;
   
   // *** Creating the physical parameters***
   var F = 80;
   var m = 1 * m0;                 	                    // weight
   var C = 1 * C0;                 	                    // rigidity
   var C1 = 1 * C0;                 	                    // rigidity1
   var B = .1 * B0;                 	                    // viscosity
   
   slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1);
   slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1);
   slider_C1.value = (C / C0).toFixed(1); number_C1.value = (C / C0).toFixed(1);
   slider_B.value = (B / B0).toFixed(1); number_B.value = (B / B0).toFixed(1);
   slider_F.value = (F / 40).toFixed(1); number_F.value = (F / 40).toFixed(1);
   // *** Creating the parameters of computing ***
   var fps = 300;		      	            // frames per second
   var spf = 100;		      	            // steps per frame 
   var dt  = 0.05 * T0 / fps;    	            // integration step (calculation quality) 
   var steps = 0;                                  // the number of integration steps
   function setM(new_m) {m = new_m * m0;}
   function setC(new_C) {C = new_C * C0;}
   function setC1(new_C1) {C1 = new_C1 * C0 * 0.067;}
   function setB(new_B) {B = new_B * B0;}
   function setF(new_F) {F = new_F * 40;}
   slider_m.oninput = function() {number_m.value = slider_m.value;       setM(slider_m.value);};
   number_m.oninput = function() {slider_m.value = number_m.value;       setM(number_m.value);};
   slider_C.oninput = function() {number_C.value = slider_C.value;       setC(slider_C.value);};
   number_C.oninput = function() {slider_C.value = number_C.value;       setC(number_C.value);};
   slider_C1.oninput = function() {number_C1.value = slider_C1.value;       setC1(slider_C1.value);};
   number_C1.oninput = function() {slider_C1.value = number_C1.value;       setC1(number_C1.value);};
   slider_B.oninput = function() {number_B.value = slider_B.value;       setB(slider_B.value);};
   number_B.oninput = function() {slider_B.value = number_B.value;       setB(number_B.value);};
   slider_F.oninput = function() {number_F.value = slider_F.value;       setF(slider_F.value);};
   number_F.oninput = function() {slider_F.value = number_F.value;       setF(number_F.value);};
   var count = true;                   // system analysis
   var v = 0;				// cargo speed
   var rw = canvas.width / 30;    	
   var rh = canvas.height / 1.5;
   var x0 = 15 * rw - rw / 2;     	
   var y0 = rh / 1.33 - rh / 2;
   // spring settings
   var coil = 10;        // number of turns
   var startX = 0;       // spring fastening
   // create a rectangle-cargo
   var rect = {
       x: x0,  width: rw,
       y: y0,	height: rh,
       fill: "rgba(0, 0, 255, 1)"    	// цвет
   };
   // capture a rectangle with the mouse
   var mx_;                                    // буфер позиции мыши (для расчета скорости при отпускании шара)
   document.onmousedown = function(e) {        // функция при нажатии клавиши мыши
       var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
       var x = rect.x;
       var xw = rect.x + rect.width;
       var y = rect.y;
       var yh = rect.y + rect.height;
       if (x <= m.x && xw >= m.x   && y <= m.y && yh >= m.y) {
           if (e.which == 1) {                         // нажата левая клавиша мыши
               rect.xPlus = rect.x - m.x;              // сдвиг курсора относительно грузика по x
               rect.yPlus = rect.y - m.y;              // сдвиг курсора относительно грузика по y
               mx_ = m.x;
               count = false;
               document.onmousemove = mouseMove;       // пока клавиша нажата - работает функция перемещения
           }
       }
   };
   document.onmouseup = function(e) {          // функция при отпускании клавиши мыши
       document.onmousemove = null;              // когда клавиша отпущена - функции перемещения нету
       count = true;
   };
   function mouseMove(e) {                     // функция при перемещении мыши, работает только с зажатой ЛКМ
       var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
       rect.x = m.x + rect.xPlus;

// v = 6.0 * (m.x - mx_) / dt / fps; // сохранение инерции

       v = 0;
       mx_ = m.x;
   }
   function mouseCoords(e) {                   // функция возвращает расчетные координаты курсора мыши
       var m = [];
       var rect = canvas.getBoundingClientRect();
       m.x = (e.clientX - rect.left);
       m.y = (e.clientY - rect.top);
       return m;
   }
   // график
   var vGraph = new TM_graph(                  // определить график
       "#vGraph",                              // на html-элементе #vGraph
       250,                                    // сколько шагов по оси "x" отображается
       -1, 1, 0.2);                            // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
   function control() {
       calculate();
       draw();
       requestAnimationFrame(control);
   }
   control();

// setInterval(control, 1000 / fps); // Запуск системы

   function calculate() {
       if (!count) return;
       for (var s=1; s<=spf; s++) {
           var f = -B*v - C * (rect.x - x0) - C1*Math.pow(rect.x - x0,3)+2*F*Math.sin(t);

v += f / m * dt; //console.log(f);

           rect.x += v * dt;

t+= dt;

           steps++;
           if (steps % 80 == 0) vGraph.graphIter(steps, (rect.x-x0)/canvas.width*2);   // подать данные на график
       }
   }
   function draw() {
       ctx.clearRect(0, 0, w, h);

draw_spring(startX, rect.x, h/2, 10, 50);

       ctx.fillStyle = "#0000ff";
       ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
   }


function draw_spring(x_start, x_end, y, n, h) { ctx.lineWidth = 2;

       ctx.strokeStyle = "#7394cb";

var L = x_end - x_start; for (var i = 0; i < n; i++) { var x_st = x_start + L / n * i; var x_end = x_start + L / n * (i + 1); var l = x_end - x_st; ctx.beginPath(); ctx.bezierCurveTo(x_st, y, x_st + l / 4, y + h, x_st + l / 2, y); ctx.bezierCurveTo(x_st + l / 2, y, x_st + 3 * l / 4, y - h, x_st + l, y); ctx.stroke(); } }

}