Моделирование падения закрепленной цепочки — различия между версиями
(Новая страница: «'''''Курсовой проект по Введение в механику дискретных сред|Введению в механику дискретн…») |
|||
Строка 6: | Строка 6: | ||
'''Семестр:''' осень 2022 | '''Семестр:''' осень 2022 | ||
+ | |||
+ | |||
+ | ==Постановка задачи== | ||
+ | Данная работа посвящена визуализации статического провисания и падения цепочки. | ||
+ | Цепочка состоит из частиц, соединенных упругими связями. Необходимо показать, как цепочка придет в положение равновесия под воздействем силы тяжести, и смоделировать движение цепочки при отпускании одного края, а также исследовать зависимость ускорения отпущенной крайней частицы от времени. | ||
+ | |||
+ | ==Математическая модель== | ||
+ | |||
+ | <math> | ||
+ | m\underline{\ddot{r}}_i(t)=\underline{F}_{R_1}+\underline{F}_{R_2} + \underline{F}_{g}\\ | ||
+ | \underline{r}_i(0)=\underline{r}_i^0,~\underline{v}_i(0)=0~~~i=1,\ldots,n | ||
+ | </math> | ||
+ | |||
+ | |||
+ | где | ||
+ | <math> | ||
+ | \underline{F}_{R_1}, \underline{F}_{R_2}\\ | ||
+ | </math> - силы упругости действующие на <math>i</math>-ую частицу со стороны <math>i-1</math> и <math>i+1</math> соответственно; | ||
+ | |||
+ | <math> | ||
+ | \underline{F}_{g} = -mg\underline{k} \\ | ||
+ | </math> - сила тяжести; | ||
+ | |||
+ | Сила упругости, возникающая в пружине соединяющей частицу 1 и 2, вычисляется по следующей формуле: | ||
+ | |||
+ | <math> | ||
+ | \underline{F}_{R}= c(||\underline{r}_2-\underline{r}_1|| - l_0)\frac{(\underline{r}_2-\underline{r}_1)}{||\underline{r}_2-\underline{r}_1||} | ||
+ | </math>, где <math>c</math> - коэффициент жесткости пружины. | ||
+ | |||
+ | Обезразмеренное уравнение будет иметь вид: | ||
+ | |||
+ | <math> | ||
+ | \underline{\ddot{r}}_i(t)= \frac{cl_0}{mg}(||\underline{r}_{i+1}-\underline{r}_i|| - 1)\frac{(\underline{r}_{i+1}-\underline{r}_i)}{||\underline{r}_{i+1}-\underline{r}_i||} + \frac{cl_0}{mg}(||\underline{r}_{i-1}-\underline{r}_i|| - 1)\frac{(\underline{r}_{i-1}-\underline{r}_i)}{||\underline{r}_{i-1}-\underline{r}_i||} - \underline{k}\\ | ||
+ | |||
+ | </math> | ||
+ | |||
+ | Интегрирование по времени производится явной схемой интегрирования методом Верле. | ||
+ | |||
+ | == Визуализация == | ||
+ | {{#widget:Iframe | url= http://tm.spbstu.ru/htmlets/js2020/Litvinova/particleshtml.html |width=600 | height=1250| border=0}} | ||
+ | |||
+ | ==Код программы== | ||
+ | Код программы: | ||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | '''JS:''' <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | <br /> | ||
+ | window.addEventListener('load',main,false) | ||
+ | function main(){ | ||
+ | |||
+ | Num = document.getElementById("num").value; | ||
+ | my = document.getElementById("my"); | ||
+ | my.innerHTML =Num + " numbers"; | ||
+ | var animation = 0; | ||
+ | var za = 0; | ||
+ | var padenie = 0; | ||
+ | var ctx2 = canvasex2.getContext('2d'); | ||
+ | var cplot = canvasex1.getContext('2d'); | ||
+ | var width = canvasex1.width; | ||
+ | var height = canvasex1.height; | ||
+ | |||
+ | var t_max = 0; | ||
+ | var q = 0; | ||
+ | var W=[]; // массив | ||
+ | var V = []; // массив скоростей | ||
+ | var c=0; | ||
+ | una.onclick= function una(){animation = 0; } | ||
+ | |||
+ | start.onclick= function start(){ | ||
+ | |||
+ | // Изменяемые параметры | ||
+ | var b = document.getElementById("b").value; // вязкость | ||
+ | var C = document.getElementById("D").value; // жесткость пружины | ||
+ | var N = document.getElementById("num").value; // количество элементов в цепочке | ||
+ | var m= document.getElementById("mass").value; // масса цепочки | ||
+ | |||
+ | animation=1; | ||
+ | za = za + 1; | ||
+ | // Неизменяемые параметры | ||
+ | //var N=41; var Mass = 50; var C = 50000; b=0.3; | ||
+ | var L0 = 10; //равновесное растояние | ||
+ | var Lenght = (N-1)*L0; | ||
+ | //var m = Mass/N; | ||
+ | var g = 9.81; | ||
+ | var rad = 5; | ||
+ | var eps = 0.9; | ||
+ | var voln = 0.1; | ||
+ | var dt=voln/Math.pow(C/m, 1/2); | ||
+ | |||
+ | |||
+ | function Particle(x,y,vx,vy,wx,wy,vxpred,vypred){ | ||
+ | var that=this; | ||
+ | this.x=x; | ||
+ | this.y=y; | ||
+ | this.vx=vx; | ||
+ | this.vy=vy; | ||
+ | this.wx=wx; | ||
+ | this.wy=wy; | ||
+ | this.vxpred=vxpred; | ||
+ | this.vypred=vypred; | ||
+ | |||
+ | this.info = function (){ | ||
+ | console.log('Position: ('+that.x+','+that.y+')\nVelocity: ('+that.vx+','+that.vy+')\nAcceleration_y: ('+that.wy+')') | ||
+ | } | ||
+ | |||
+ | this.move=function(){ | ||
+ | |||
+ | } | ||
+ | |||
+ | this.draw = function(){ | ||
+ | ctx2.beginPath(); | ||
+ | ctx2.arc(that.x,that.y,rad,0,2*Math.PI); | ||
+ | ctx2.fillStyle = '#9999FF'; | ||
+ | ctx2.fill(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | if (za==1){ // создание частиц | ||
+ | var particles = []; | ||
+ | |||
+ | if (N%2==0){ | ||
+ | for(var i=0;i<N;i++){ | ||
+ | var fi= Math.PI/3; | ||
+ | var dy=0; | ||
+ | if (i<N/2) | ||
+ | dy = i*(L0-1)*Math.sin(fi); | ||
+ | else | ||
+ | dy = (N-i-1)*(L0-1)*Math.sin(fi); | ||
+ | particles.push( | ||
+ | new Particle( 400+i*(L0-1)*Math.cos(fi), 50+ dy, 0, 0, 0, 0, 0, 0) | ||
+ | ); | ||
+ | particles[i].draw(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (N%2!=0){ | ||
+ | for(var i=0;i<N;i++){ | ||
+ | var fi= Math.PI/4; | ||
+ | if (i<(N+1)/2) | ||
+ | var dy = i*(L0-1)*Math.sin(fi); | ||
+ | else | ||
+ | dy = (N-i-1)*(L0-1)*Math.sin(fi); | ||
+ | particles.push( | ||
+ | new Particle( 400+i*(L0-1)*Math.cos(fi), 50+ dy, 0, 0, 0, 0, 0, 0) | ||
+ | ); | ||
+ | particles[i].draw(); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | function phys(){ | ||
+ | t_max+=dt; | ||
+ | var Vmax=0; | ||
+ | for(var i=0;i<N;i++){ | ||
+ | //particles[i].move(); | ||
+ | |||
+ | if (i!=0 && i!=N-1){ | ||
+ | |||
+ | var rxl = particles[i].x-particles[i-1].x; | ||
+ | var ryl = particles[i].y-particles[i-1].y; | ||
+ | var rl = Math.sqrt(Math.pow(rxl,2)+Math.pow(ryl,2)); | ||
+ | |||
+ | |||
+ | var rxr = particles[i].x-particles[i+1].x; | ||
+ | var ryr = particles[i].y-particles[i+1].y; | ||
+ | var rr = Math.sqrt(Math.pow(rxr,2)+Math.pow(ryr,2)); | ||
+ | |||
+ | var Fx = -C*(rl-L0)*rxl/rl/L0 - C*(rr-L0)*rxr/rr/L0; | ||
+ | var Fy = -C*(rl-L0)*ryl/rl/L0 - C*(rr-L0)*ryr/rr/L0; | ||
+ | |||
+ | particles[i].wx = Fx/m - b* particles[i].vx/m; | ||
+ | particles[i].wy = Fy/m + g - b* particles[i].vy/m; | ||
+ | } | ||
+ | |||
+ | else if(i==N-1){ | ||
+ | if (padenie == 0) W.push (0); | ||
+ | if (padenie == 1){ | ||
+ | var rxl = particles[i].x-particles[i-1].x; | ||
+ | var ryl = particles[i].y-particles[i-1].y; | ||
+ | var rl = Math.sqrt(Math.pow(rxl,2)+Math.pow(ryl,2)); | ||
+ | |||
+ | var Fx = -C*(rl-L0)*rxl/rl/L0 ; | ||
+ | var Fy = -C*(rl-L0)*ryl/rl/L0 ; | ||
+ | |||
+ | particles[i].wx = Fx/m- b* particles[i].vx/m; | ||
+ | particles[i].wy = Fy/m + g- b* particles[i].vy/m; | ||
+ | |||
+ | W.push (Math.sqrt(Math.pow(particles[N-1].wx,2)+Math.pow(particles[N-1].wy,2))); | ||
+ | console.log(Math.sqrt(Math.pow(particles[N-1].wx,2)+Math.pow(particles[N-1].wy,2))) | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // явная схема интегрирования, Верле | ||
+ | for (var i=0;i<N;i++){ | ||
+ | particles[i].vx = particles[i].vx + particles[i].wx*dt; | ||
+ | particles[i].vy = particles[i].vy + particles[i].wy*dt; | ||
+ | particles[i].x = particles[i].x + particles[i].vx*dt; | ||
+ | particles[i].y = particles[i].y + particles[i].vy*dt; | ||
+ | var v = Math.sqrt(Math.pow(particles[i].vx,2)+Math.pow(particles[i].vy,2)); | ||
+ | if (v>Vmax) Vmax=v; | ||
+ | } | ||
+ | if (Vmax < eps){ padenie = 1; b=0.01} | ||
+ | //console.log(Vmax) | ||
+ | } | ||
+ | |||
+ | |||
+ | function draw(){ | ||
+ | ctx2.clearRect(0,0,800,800); | ||
+ | for(var i=0;i<N;i++){ | ||
+ | particles[i].draw(); | ||
+ | } | ||
+ | |||
+ | |||
+ | cplot.clearRect(0,0,width,height); | ||
+ | |||
+ | var W_scale =height/250; | ||
+ | var t_scale= width/t_max; | ||
+ | |||
+ | cplot.beginPath(); | ||
+ | for (var i =0; i<W.length-1; i++){ | ||
+ | cplot.moveTo(i*t_scale,height-W[i]*(W_scale)-50); | ||
+ | cplot.lineTo((i+1)*t_scale, height-W[i+1]*(W_scale)-50); | ||
+ | |||
+ | } | ||
+ | cplot.stroke(); | ||
+ | } | ||
+ | |||
+ | function control(){ | ||
+ | if (animation!=0){ | ||
+ | phys(); | ||
+ | draw(); | ||
+ | } | ||
+ | } | ||
+ | setInterval(control,1000*dt); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | '''HTML:''' <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | <!DOCTYPE html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <title>Class</title> | ||
+ | <script src='cepochka.js'></script> | ||
+ | <style> | ||
+ | input{ | ||
+ | width:100px; | ||
+ | height:30px; | ||
+ | } | ||
+ | button{ | ||
+ | width:100px; | ||
+ | height:30px; | ||
+ | } | ||
+ | div table{ | ||
+ | margin-left:auto; | ||
+ | margin-right:auto;} | ||
+ | table td{ | ||
+ | text-align:center; | ||
+ | width:180px; | ||
+ | height:30px; | ||
+ | } | ||
+ | </style> | ||
+ | </head> | ||
+ | <body> | ||
+ | <center> | ||
+ | <canvas id='canvasex2' width=800 height=800 background-color=#FF99CC style='border: 1px dashed #000000' ></canvas> | ||
+ | <canvas id='canvasex1' width=800 height=300 background-color=#FF99CC style='border: 1px dashed #000000' ></canvas> | ||
+ | |||
+ | <table> | ||
+ | <tr> | ||
+ | <td><input type="button" id="start" value="start" > </td> | ||
+ | <td> <input type="button" id="una" value="stop" width=40 height=20></td> | ||
+ | <td> <button onclick='window.location.reload(true)' style ='width=100 height=20'>clear</button></td> | ||
+ | <table> | ||
+ | <tr><th> | ||
+ | <input type="range" min="11" max="41" id="num" | ||
+ | oninput="main()" value="0"></th> | ||
+ | <th><div id="my">0</div></th></tr> | ||
+ | <tr><th> | ||
+ | <input type="number" id="b" name="b" value="0.1" | ||
+ | min="0" max="0.1" step="0.01" style='border: 1px dashed #000000'></th> | ||
+ | <th> <div> <h3><i> viscosity</i></div></th></tr> | ||
+ | <tr><th> | ||
+ | <input type="number" id="D" name="D" value="50000" | ||
+ | min="1000" max="50000" step="5000" style='border: 1px dashed #000000'></th> | ||
+ | <th> <div> <h3><i> spring rate</i></div></th></tr> | ||
+ | <tr><th> | ||
+ | <input type="number" id="mass" name="mass" value="1" | ||
+ | min="0" max="2" step="0.5" style='border: 1px dashed #000000'></th> | ||
+ | <th> <div> <h3><i> mass</i></div></th></tr> | ||
+ | </center> | ||
+ | </body> | ||
+ | </html> | ||
+ | </syntaxhighlight> | ||
+ | </div> |
Версия 14:50, 24 января 2023
Курсовой проект по Введению в механику дискретных сред
Исполнитель: Литвинова Ярослава Игоревна
Группа: 5030103/90101
Семестр: осень 2022
Постановка задачи
Данная работа посвящена визуализации статического провисания и падения цепочки. Цепочка состоит из частиц, соединенных упругими связями. Необходимо показать, как цепочка придет в положение равновесия под воздействем силы тяжести, и смоделировать движение цепочки при отпускании одного края, а также исследовать зависимость ускорения отпущенной крайней частицы от времени.
Математическая модель
где
- силы упругости действующие на -ую частицу со стороны и соответственно;
- сила тяжести;
Сила упругости, возникающая в пружине соединяющей частицу 1 и 2, вычисляется по следующей формуле:
, где - коэффициент жесткости пружины.
Обезразмеренное уравнение будет иметь вид:
Интегрирование по времени производится явной схемой интегрирования методом Верле.
Визуализация
Код программы
Код программы:
1 <br />
2 window.addEventListener('load',main,false)
3 function main(){
4
5 Num = document.getElementById("num").value;
6 my = document.getElementById("my");
7 my.innerHTML =Num + " numbers";
8 var animation = 0;
9 var za = 0;
10 var padenie = 0;
11 var ctx2 = canvasex2.getContext('2d');
12 var cplot = canvasex1.getContext('2d');
13 var width = canvasex1.width;
14 var height = canvasex1.height;
15
16 var t_max = 0;
17 var q = 0;
18 var W=[]; // массив
19 var V = []; // массив скоростей
20 var c=0;
21 una.onclick= function una(){animation = 0; }
22
23 start.onclick= function start(){
24
25 // Изменяемые параметры
26 var b = document.getElementById("b").value; // вязкость
27 var C = document.getElementById("D").value; // жесткость пружины
28 var N = document.getElementById("num").value; // количество элементов в цепочке
29 var m= document.getElementById("mass").value; // масса цепочки
30
31 animation=1;
32 za = za + 1;
33 // Неизменяемые параметры
34 //var N=41; var Mass = 50; var C = 50000; b=0.3;
35 var L0 = 10; //равновесное растояние
36 var Lenght = (N-1)*L0;
37 //var m = Mass/N;
38 var g = 9.81;
39 var rad = 5;
40 var eps = 0.9;
41 var voln = 0.1;
42 var dt=voln/Math.pow(C/m, 1/2);
43
44
45 function Particle(x,y,vx,vy,wx,wy,vxpred,vypred){
46 var that=this;
47 this.x=x;
48 this.y=y;
49 this.vx=vx;
50 this.vy=vy;
51 this.wx=wx;
52 this.wy=wy;
53 this.vxpred=vxpred;
54 this.vypred=vypred;
55
56 this.info = function (){
57 console.log('Position: ('+that.x+','+that.y+')\nVelocity: ('+that.vx+','+that.vy+')\nAcceleration_y: ('+that.wy+')')
58 }
59
60 this.move=function(){
61
62 }
63
64 this.draw = function(){
65 ctx2.beginPath();
66 ctx2.arc(that.x,that.y,rad,0,2*Math.PI);
67 ctx2.fillStyle = '#9999FF';
68 ctx2.fill();
69 }
70 }
71
72
73 if (za==1){ // создание частиц
74 var particles = [];
75
76 if (N%2==0){
77 for(var i=0;i<N;i++){
78 var fi= Math.PI/3;
79 var dy=0;
80 if (i<N/2)
81 dy = i*(L0-1)*Math.sin(fi);
82 else
83 dy = (N-i-1)*(L0-1)*Math.sin(fi);
84 particles.push(
85 new Particle( 400+i*(L0-1)*Math.cos(fi), 50+ dy, 0, 0, 0, 0, 0, 0)
86 );
87 particles[i].draw();
88 }
89 }
90
91 if (N%2!=0){
92 for(var i=0;i<N;i++){
93 var fi= Math.PI/4;
94 if (i<(N+1)/2)
95 var dy = i*(L0-1)*Math.sin(fi);
96 else
97 dy = (N-i-1)*(L0-1)*Math.sin(fi);
98 particles.push(
99 new Particle( 400+i*(L0-1)*Math.cos(fi), 50+ dy, 0, 0, 0, 0, 0, 0)
100 );
101 particles[i].draw();
102
103 }
104 }
105
106 }
107
108 function phys(){
109 t_max+=dt;
110 var Vmax=0;
111 for(var i=0;i<N;i++){
112 //particles[i].move();
113
114 if (i!=0 && i!=N-1){
115
116 var rxl = particles[i].x-particles[i-1].x;
117 var ryl = particles[i].y-particles[i-1].y;
118 var rl = Math.sqrt(Math.pow(rxl,2)+Math.pow(ryl,2));
119
120
121 var rxr = particles[i].x-particles[i+1].x;
122 var ryr = particles[i].y-particles[i+1].y;
123 var rr = Math.sqrt(Math.pow(rxr,2)+Math.pow(ryr,2));
124
125 var Fx = -C*(rl-L0)*rxl/rl/L0 - C*(rr-L0)*rxr/rr/L0;
126 var Fy = -C*(rl-L0)*ryl/rl/L0 - C*(rr-L0)*ryr/rr/L0;
127
128 particles[i].wx = Fx/m - b* particles[i].vx/m;
129 particles[i].wy = Fy/m + g - b* particles[i].vy/m;
130 }
131
132 else if(i==N-1){
133 if (padenie == 0) W.push (0);
134 if (padenie == 1){
135 var rxl = particles[i].x-particles[i-1].x;
136 var ryl = particles[i].y-particles[i-1].y;
137 var rl = Math.sqrt(Math.pow(rxl,2)+Math.pow(ryl,2));
138
139 var Fx = -C*(rl-L0)*rxl/rl/L0 ;
140 var Fy = -C*(rl-L0)*ryl/rl/L0 ;
141
142 particles[i].wx = Fx/m- b* particles[i].vx/m;
143 particles[i].wy = Fy/m + g- b* particles[i].vy/m;
144
145 W.push (Math.sqrt(Math.pow(particles[N-1].wx,2)+Math.pow(particles[N-1].wy,2)));
146 console.log(Math.sqrt(Math.pow(particles[N-1].wx,2)+Math.pow(particles[N-1].wy,2)))
147 }
148 }
149 }
150 // явная схема интегрирования, Верле
151 for (var i=0;i<N;i++){
152 particles[i].vx = particles[i].vx + particles[i].wx*dt;
153 particles[i].vy = particles[i].vy + particles[i].wy*dt;
154 particles[i].x = particles[i].x + particles[i].vx*dt;
155 particles[i].y = particles[i].y + particles[i].vy*dt;
156 var v = Math.sqrt(Math.pow(particles[i].vx,2)+Math.pow(particles[i].vy,2));
157 if (v>Vmax) Vmax=v;
158 }
159 if (Vmax < eps){ padenie = 1; b=0.01}
160 //console.log(Vmax)
161 }
162
163
164 function draw(){
165 ctx2.clearRect(0,0,800,800);
166 for(var i=0;i<N;i++){
167 particles[i].draw();
168 }
169
170
171 cplot.clearRect(0,0,width,height);
172
173 var W_scale =height/250;
174 var t_scale= width/t_max;
175
176 cplot.beginPath();
177 for (var i =0; i<W.length-1; i++){
178 cplot.moveTo(i*t_scale,height-W[i]*(W_scale)-50);
179 cplot.lineTo((i+1)*t_scale, height-W[i+1]*(W_scale)-50);
180
181 }
182 cplot.stroke();
183 }
184
185 function control(){
186 if (animation!=0){
187 phys();
188 draw();
189 }
190 }
191 setInterval(control,1000*dt);
192 }
193
194 }
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Class</title>
5 <script src='cepochka.js'></script>
6 <style>
7 input{
8 width:100px;
9 height:30px;
10 }
11 button{
12 width:100px;
13 height:30px;
14 }
15 div table{
16 margin-left:auto;
17 margin-right:auto;}
18 table td{
19 text-align:center;
20 width:180px;
21 height:30px;
22 }
23 </style>
24 </head>
25 <body>
26 <center>
27 <canvas id='canvasex2' width=800 height=800 background-color=#FF99CC style='border: 1px dashed #000000' ></canvas>
28 <canvas id='canvasex1' width=800 height=300 background-color=#FF99CC style='border: 1px dashed #000000' ></canvas>
29
30 <table>
31 <tr>
32 <td><input type="button" id="start" value="start" > </td>
33 <td> <input type="button" id="una" value="stop" width=40 height=20></td>
34 <td> <button onclick='window.location.reload(true)' style ='width=100 height=20'>clear</button></td>
35 <table>
36 <tr><th>
37 <input type="range" min="11" max="41" id="num"
38 oninput="main()" value="0"></th>
39 <th><div id="my">0</div></th></tr>
40 <tr><th>
41 <input type="number" id="b" name="b" value="0.1"
42 min="0" max="0.1" step="0.01" style='border: 1px dashed #000000'></th>
43 <th> <div> <h3><i> viscosity</i></div></th></tr>
44 <tr><th>
45 <input type="number" id="D" name="D" value="50000"
46 min="1000" max="50000" step="5000" style='border: 1px dashed #000000'></th>
47 <th> <div> <h3><i> spring rate</i></div></th></tr>
48 <tr><th>
49 <input type="number" id="mass" name="mass" value="1"
50 min="0" max="2" step="0.5" style='border: 1px dashed #000000'></th>
51 <th> <div> <h3><i> mass</i></div></th></tr>
52 </center>
53 </body>
54 </html>