Испытания на разрыв и сжатие плоского тела — различия между версиями
George (обсуждение | вклад) м (→Результат) |
George (обсуждение | вклад) м |
||
Строка 10: | Строка 10: | ||
− | == | + | == Описание == |
+ | Проводятся эксперименты сжатия и растяжения плоского тела на примере [https://ru.wikipedia.org/wiki/Поликристалл поликристалла]. Поликристалл моделируется множеством материальных точек, разделённых на области с разной жёсткостью связи (используется потенциал Леннард-Джонса с конечным радиусом обрезания). На плоскости строится [https://ru.wikipedia.org/wiki/Диаграмма_Вороного диаграмма Вороного], каждая точка тела попадает в одну из областей и получает соответствующий коэффициент (различный для разных областей). При расчёте силы взаимодействия между двумя точками их коэффициенты складываются, получившиеся значение есть жёсткость связи в потенциале. Диаграмма напряжений строится вплоть до момента потери устойчивости. | ||
− | + | В рамках эксперимента скорость деформации постоянна. Используется метод интегрирования Верле. | |
− | |||
+ | Решение задачи и визуализация написаны нa JavaScript, диаграмма Вороного получается POST запросом к серверу (расчёты производятся программой на C++ с помощью алгоритма Форчуна, парсер написан на PHP). | ||
== Результат == | == Результат == | ||
Строка 23: | Строка 24: | ||
<big>[//ailurus.ru/stands/cern/ Страница полного решения]</big> | <big>[//ailurus.ru/stands/cern/ Страница полного решения]</big> | ||
</center> | </center> | ||
+ | |||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | '''Исходный код для одной из конфиграций [JavaScript]:''' <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | var points = [{'x': 591, 'y':474}, | ||
+ | {'x': 94, 'y':587}, | ||
+ | {'x': 200, 'y':540}, | ||
+ | {'x': 577, 'y':71}, | ||
+ | {'x': 415, 'y':584}, | ||
+ | {'x': 225, 'y':302}, | ||
+ | {'x': 93, 'y':154}, | ||
+ | {'x': 127, 'y':123}, | ||
+ | {'x': 209, 'y':313}, | ||
+ | {'x': 32, 'y':290}]; | ||
+ | var pressureSign = 1; | ||
+ | var fragmentation = false; | ||
+ | var animationSpeed = 40; | ||
+ | var strainRate = 10; | ||
+ | |||
+ | var integrator = VerletIntegrator; | ||
+ | var t = 0; | ||
+ | var dt = 0.005; | ||
+ | var timeValue = document.getElementById('timeValue'); | ||
+ | |||
+ | var particleRadius = 6; | ||
+ | var numberOfColumns = 29; | ||
+ | var numberOfRows = 29; | ||
+ | var cm = [ 0.754335746098413, | ||
+ | 0.8107304103877537, | ||
+ | 0.9306594025241637, | ||
+ | 0.9667586023289361, | ||
+ | 0.7504112576761824, | ||
+ | 0.828054551661692, | ||
+ | 0.9496843639510728, | ||
+ | 0.9562931712096583, | ||
+ | 0.8953204544716538, | ||
+ | 0.7549681403247804, | ||
+ | 0.892707460881279, | ||
+ | 0.7946054751314912, | ||
+ | 0.9651534693380119, | ||
+ | 0.9753409489560376, | ||
+ | 0.828824739204054, | ||
+ | 0.7564226662369037, | ||
+ | 0.8476944814390296]; | ||
+ | |||
+ | var colors = ["Turquoise", | ||
+ | "Yellow", | ||
+ | "YellowGreen", | ||
+ | "Teal", | ||
+ | "White", | ||
+ | "BlueViolet", | ||
+ | "Tomato", | ||
+ | "Silver", | ||
+ | "Gray", | ||
+ | "Orange", | ||
+ | "SpringGreen", | ||
+ | "WhiteSmoke", | ||
+ | "Linen", | ||
+ | "PaleGreen", | ||
+ | "FireBrick", | ||
+ | "SlateGray", | ||
+ | "Bisque"]; | ||
+ | |||
+ | function indexOfTheNearestPoint(x, y){ | ||
+ | var squareLength = []; | ||
+ | for(var i = 0; i < points.length; ++i){ | ||
+ | squareLength[i] = Math.pow(points[i].x - x, 2) + Math.pow(points[i].y - y, 2); | ||
+ | } | ||
+ | return squareLength.indexOf(Math.min.apply(null, squareLength)); | ||
+ | } | ||
+ | var particles = []; | ||
+ | |||
+ | var stepBetweenColumns = (canvas.width / numberOfColumns); | ||
+ | var stepBetweenRows = stepBetweenColumns * Math.sin(Math.PI/3); | ||
+ | numberOfRows = Math.ceil(canvas.width / stepBetweenRows); | ||
+ | if(!(numberOfRows % 2)){ | ||
+ | --numberOfRows; | ||
+ | } | ||
+ | canvas.height = numberOfRows * stepBetweenRows; | ||
+ | var halfOfStepBetweenColumns = 0.5 * stepBetweenColumns; | ||
+ | var halfOfStepBetweenRows = 0.5 * stepBetweenRows; | ||
+ | |||
+ | for(var k = 0, l = 0; k < numberOfRows; ++k){ | ||
+ | if(k % 2){ | ||
+ | for(var i = 0, j = halfOfStepBetweenColumns; i < numberOfColumns - 1; ++i){ | ||
+ | var x = halfOfStepBetweenColumns + j; | ||
+ | var y = halfOfStepBetweenRows + l; | ||
+ | j += stepBetweenColumns; | ||
+ | |||
+ | var index = indexOfTheNearestPoint(x, y); | ||
+ | var particle = createVerletElement([x, y], null, 1, 'circle', [particleRadius], colors[index]); | ||
+ | particle.c = cm[index]; | ||
+ | particles.push(particle); | ||
+ | } | ||
+ | }else{ | ||
+ | for(var i = 0, j = 0; i < numberOfColumns; ++i){ | ||
+ | var x = halfOfStepBetweenColumns + j; | ||
+ | var y = halfOfStepBetweenRows + l; | ||
+ | j += stepBetweenColumns; | ||
+ | |||
+ | var index = indexOfTheNearestPoint(x, y); | ||
+ | var particle = createVerletElement([x, y], null, 1, 'circle', [particleRadius], colors[index]); | ||
+ | particle.c = cm[index]; | ||
+ | particles.push(particle); | ||
+ | } | ||
+ | } | ||
+ | l += stepBetweenRows; | ||
+ | } | ||
+ | var helper2 = []; | ||
+ | for(var i = 0; i < particles.length; i += 2 * numberOfColumns - 1){ | ||
+ | helper2.push(i); | ||
+ | helper2.push(i - 1 + numberOfColumns); | ||
+ | helper2.push(i + numberOfColumns); | ||
+ | helper2.push(i - 2 + 2 * numberOfColumns); | ||
+ | } | ||
+ | for(var i = 0; i < particles.length; ++i){ | ||
+ | if(helper2.indexOf(i) >= 0){ | ||
+ | particles[i].color = 'rgb(255, 200, 40)'; | ||
+ | } | ||
+ | } | ||
+ | function applyInitionalConditions(){ | ||
+ | for(var i = 0; i < numberOfColumns; ++i){ | ||
+ | particles[i].previousPosition.y = particles[i].position.y - strainRate * dt * pressureSign; | ||
+ | particles[particles.length - i - 1].previousPosition.y = particles[particles.length - i - 1].position.y + strainRate * dt * pressureSign; | ||
+ | particles[i].color = 'crimson'; | ||
+ | particles[particles.length - i - 1].color = 'crimson'; | ||
+ | } | ||
+ | } | ||
+ | applyInitionalConditions(); | ||
+ | draw(); | ||
+ | drawLine(460.258514, 276.798706, 600.000000, 271.944183,4, 'dodgerblue'); | ||
+ | drawLine(410.950745, 381.721161, 547.375000, 600.000000,4, 'dodgerblue'); | ||
+ | drawLine(254.635513, 600.000000, 254.635513, 600.000000,4, 'dodgerblue'); | ||
+ | drawLine(0.000000, 451.651520, 89.154579, 433.040131,4, 'dodgerblue'); | ||
+ | drawLine(0.000000, 193.966919, 127.067291, 250.960342,4, 'dodgerblue'); | ||
+ | drawLine(0.000000, 17.854839, 176.980927, 211.962967,4, 'dodgerblue'); | ||
+ | drawLine(340.791107, 0.000000, 354.080383, 115.003471,4, 'dodgerblue'); | ||
+ | drawLine(333.749329, 433.736267, 299.723267, 600.000000,4, 'dodgerblue'); | ||
+ | drawLine(89.154556, 433.040070, 163.183975, 600.000000,4, 'dodgerblue'); | ||
+ | drawLine(333.749329, 433.736267, 410.950745, 381.721130,4, 'dodgerblue'); | ||
+ | drawLine(301.455261, 430.344025, 333.749329, 433.736267,4, 'dodgerblue'); | ||
+ | drawLine(89.154579, 433.040131, 104.770851, 422.545990,4, 'dodgerblue'); | ||
+ | drawLine(460.258545, 276.798706, 410.950745, 381.721161,4, 'dodgerblue'); | ||
+ | drawLine(161.072784, 226.151321, 301.455261, 430.344025,4, 'dodgerblue'); | ||
+ | drawLine(104.770851, 422.545959, 301.455261, 430.344025,4, 'dodgerblue'); | ||
+ | drawLine(127.067291, 250.960342, 104.770859, 422.545959,4, 'dodgerblue'); | ||
+ | drawLine(354.080414, 115.003471, 460.258545, 276.798706,4, 'dodgerblue'); | ||
+ | drawLine(127.067291, 250.960327, 161.072784, 226.151306,4, 'dodgerblue'); | ||
+ | drawLine(176.980927, 211.962967, 354.080383, 115.003494,4, 'dodgerblue'); | ||
+ | drawLine(161.072784, 226.151306, 176.980927, 211.962967,4, 'dodgerblue'); | ||
+ | var textColor = 'rgb(255, 255, 255)';var D = 100; | ||
+ | if(-1 == pressureSign){ | ||
+ | D *= 100; | ||
+ | } | ||
+ | var a = stepBetweenColumns;//23.131737698273685;// 1*32; | ||
+ | var cutLength = 1.5 * canvas.height;//Math.sqrt(2130); | ||
+ | |||
+ | var squareA = Math.pow(a, 2); | ||
+ | var squareCutLength = Math.pow(cutLength, 2); | ||
+ | |||
+ | var diagramData = {'x': [], 'y': []}; | ||
+ | var diagramCanvas = document.getElementById('diagram'); | ||
+ | var stepFromBoard = 7; | ||
+ | var step = 0; | ||
+ | |||
+ | function applyPhysics(){ | ||
+ | var forces = []; | ||
+ | for(var j = 0; j < particles.length; ++j){ | ||
+ | var forceX = 0; | ||
+ | var forceY = 0; | ||
+ | for(var i = 0; i < particles.length; ++i){ | ||
+ | if(i == j){ | ||
+ | continue; | ||
+ | } | ||
+ | var diffX = particles[j].position.x - particles[i].position.x; | ||
+ | var diffY = particles[j].position.y - particles[i].position.y; | ||
+ | var squareDiff = Math.pow(diffX, 2) + Math.pow(diffY, 2); | ||
+ | if(squareDiff > squareCutLength){ | ||
+ | fragmentation = true; | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | var tmp = squareA / squareDiff; | ||
+ | var force = 0.5 * (particles[j].c + particles[i].c) * (12 * D / squareA) * (Math.pow(tmp, 7) - Math.pow(tmp, 4)); | ||
+ | //-(particles[j].c + particles[i].c) * D * squareDiff / 100000; | ||
+ | forceX += force * diffX; | ||
+ | forceY += force * diffY; | ||
+ | } | ||
+ | forces[j] = {'x': 0, 'y': forceY}; | ||
+ | } | ||
+ | var sigma = 0; | ||
+ | for(var i = 0; i < numberOfColumns; ++i){ | ||
+ | sigma -= forces[i].y;// + forces[particles.length - i - 1].y; | ||
+ | forces[i] = {'x': 0, 'y': 0}; | ||
+ | forces[particles.length - i - 1] = {'x': 0, 'y': 0}; | ||
+ | } | ||
+ | if(!fragmentation){ | ||
+ | var epsilon = pressureSign * (particles[1].position.y - halfOfStepBetweenRows) / (canvas.height - 2 * halfOfStepBetweenRows); | ||
+ | diagramData.x.push(epsilon); | ||
+ | diagramData.y.push(sigma / (numberOfColumns * 1)); | ||
+ | plotFromData(diagramCanvas, diagramData, 'Stress-deformation diagram', 'rgb(56, 195, 237)', 2, textColor); | ||
+ | } | ||
+ | for(var j = 0; j < particles.length; ++ j){ | ||
+ | integrator(particles[j], forces[j], dt); | ||
+ | } | ||
+ | timeValue.textContent = t.toFixed(2); | ||
+ | ++step; | ||
+ | } | ||
+ | function draw(){ | ||
+ | ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
+ | for(var i = 0; i < particles.length; ++i){ | ||
+ | particles[i].draw(); | ||
+ | } | ||
+ | } | ||
+ | document.getElementById('play').onclick = function(){ | ||
+ | this.className = 'inprogress'; | ||
+ | document.getElementById('conditions').className = 'hide'; | ||
+ | document.getElementById('diagram').className = ''; | ||
+ | animate(animationSpeed); | ||
+ | } | ||
+ | document.getElementById('strainRate').onchange = function(){ | ||
+ | document.getElementById('strainRateValue').textContent = (+this.value).toFixed(1); | ||
+ | strainRate = (+this.value).toFixed(1); | ||
+ | applyInitionalConditions(); | ||
+ | } | ||
+ | document.getElementById('animationSpeed').onchange = function(){ | ||
+ | document.getElementById('animationSpeedValue').textContent = (+this.value).toFixed(0); | ||
+ | animationSpeed = (+this.value).toFixed(0); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | </div> |
Версия 23:27, 9 мая 2017
Курсовые работы 2016-2017 учебного года > Испытания на разрыв и сжатие плоского телаКурсовой проект по Механике дискретных сред
Исполнитель: Старобинский Егор
Группа: 09 (43604/1)
Семестр: осень 2016
Описание
Проводятся эксперименты сжатия и растяжения плоского тела на примере поликристалла. Поликристалл моделируется множеством материальных точек, разделённых на области с разной жёсткостью связи (используется потенциал Леннард-Джонса с конечным радиусом обрезания). На плоскости строится диаграмма Вороного, каждая точка тела попадает в одну из областей и получает соответствующий коэффициент (различный для разных областей). При расчёте силы взаимодействия между двумя точками их коэффициенты складываются, получившиеся значение есть жёсткость связи в потенциале. Диаграмма напряжений строится вплоть до момента потери устойчивости.
В рамках эксперимента скорость деформации постоянна. Используется метод интегрирования Верле.
Решение задачи и визуализация написаны нa JavaScript, диаграмма Вороного получается POST запросом к серверу (расчёты производятся программой на C++ с помощью алгоритма Форчуна, парсер написан на PHP).
Результат
1 var points = [{'x': 591, 'y':474},
2 {'x': 94, 'y':587},
3 {'x': 200, 'y':540},
4 {'x': 577, 'y':71},
5 {'x': 415, 'y':584},
6 {'x': 225, 'y':302},
7 {'x': 93, 'y':154},
8 {'x': 127, 'y':123},
9 {'x': 209, 'y':313},
10 {'x': 32, 'y':290}];
11 var pressureSign = 1;
12 var fragmentation = false;
13 var animationSpeed = 40;
14 var strainRate = 10;
15
16 var integrator = VerletIntegrator;
17 var t = 0;
18 var dt = 0.005;
19 var timeValue = document.getElementById('timeValue');
20
21 var particleRadius = 6;
22 var numberOfColumns = 29;
23 var numberOfRows = 29;
24 var cm = [ 0.754335746098413,
25 0.8107304103877537,
26 0.9306594025241637,
27 0.9667586023289361,
28 0.7504112576761824,
29 0.828054551661692,
30 0.9496843639510728,
31 0.9562931712096583,
32 0.8953204544716538,
33 0.7549681403247804,
34 0.892707460881279,
35 0.7946054751314912,
36 0.9651534693380119,
37 0.9753409489560376,
38 0.828824739204054,
39 0.7564226662369037,
40 0.8476944814390296];
41
42 var colors = ["Turquoise",
43 "Yellow",
44 "YellowGreen",
45 "Teal",
46 "White",
47 "BlueViolet",
48 "Tomato",
49 "Silver",
50 "Gray",
51 "Orange",
52 "SpringGreen",
53 "WhiteSmoke",
54 "Linen",
55 "PaleGreen",
56 "FireBrick",
57 "SlateGray",
58 "Bisque"];
59
60 function indexOfTheNearestPoint(x, y){
61 var squareLength = [];
62 for(var i = 0; i < points.length; ++i){
63 squareLength[i] = Math.pow(points[i].x - x, 2) + Math.pow(points[i].y - y, 2);
64 }
65 return squareLength.indexOf(Math.min.apply(null, squareLength));
66 }
67 var particles = [];
68
69 var stepBetweenColumns = (canvas.width / numberOfColumns);
70 var stepBetweenRows = stepBetweenColumns * Math.sin(Math.PI/3);
71 numberOfRows = Math.ceil(canvas.width / stepBetweenRows);
72 if(!(numberOfRows % 2)){
73 --numberOfRows;
74 }
75 canvas.height = numberOfRows * stepBetweenRows;
76 var halfOfStepBetweenColumns = 0.5 * stepBetweenColumns;
77 var halfOfStepBetweenRows = 0.5 * stepBetweenRows;
78
79 for(var k = 0, l = 0; k < numberOfRows; ++k){
80 if(k % 2){
81 for(var i = 0, j = halfOfStepBetweenColumns; i < numberOfColumns - 1; ++i){
82 var x = halfOfStepBetweenColumns + j;
83 var y = halfOfStepBetweenRows + l;
84 j += stepBetweenColumns;
85
86 var index = indexOfTheNearestPoint(x, y);
87 var particle = createVerletElement([x, y], null, 1, 'circle', [particleRadius], colors[index]);
88 particle.c = cm[index];
89 particles.push(particle);
90 }
91 }else{
92 for(var i = 0, j = 0; i < numberOfColumns; ++i){
93 var x = halfOfStepBetweenColumns + j;
94 var y = halfOfStepBetweenRows + l;
95 j += stepBetweenColumns;
96
97 var index = indexOfTheNearestPoint(x, y);
98 var particle = createVerletElement([x, y], null, 1, 'circle', [particleRadius], colors[index]);
99 particle.c = cm[index];
100 particles.push(particle);
101 }
102 }
103 l += stepBetweenRows;
104 }
105 var helper2 = [];
106 for(var i = 0; i < particles.length; i += 2 * numberOfColumns - 1){
107 helper2.push(i);
108 helper2.push(i - 1 + numberOfColumns);
109 helper2.push(i + numberOfColumns);
110 helper2.push(i - 2 + 2 * numberOfColumns);
111 }
112 for(var i = 0; i < particles.length; ++i){
113 if(helper2.indexOf(i) >= 0){
114 particles[i].color = 'rgb(255, 200, 40)';
115 }
116 }
117 function applyInitionalConditions(){
118 for(var i = 0; i < numberOfColumns; ++i){
119 particles[i].previousPosition.y = particles[i].position.y - strainRate * dt * pressureSign;
120 particles[particles.length - i - 1].previousPosition.y = particles[particles.length - i - 1].position.y + strainRate * dt * pressureSign;
121 particles[i].color = 'crimson';
122 particles[particles.length - i - 1].color = 'crimson';
123 }
124 }
125 applyInitionalConditions();
126 draw();
127 drawLine(460.258514, 276.798706, 600.000000, 271.944183,4, 'dodgerblue');
128 drawLine(410.950745, 381.721161, 547.375000, 600.000000,4, 'dodgerblue');
129 drawLine(254.635513, 600.000000, 254.635513, 600.000000,4, 'dodgerblue');
130 drawLine(0.000000, 451.651520, 89.154579, 433.040131,4, 'dodgerblue');
131 drawLine(0.000000, 193.966919, 127.067291, 250.960342,4, 'dodgerblue');
132 drawLine(0.000000, 17.854839, 176.980927, 211.962967,4, 'dodgerblue');
133 drawLine(340.791107, 0.000000, 354.080383, 115.003471,4, 'dodgerblue');
134 drawLine(333.749329, 433.736267, 299.723267, 600.000000,4, 'dodgerblue');
135 drawLine(89.154556, 433.040070, 163.183975, 600.000000,4, 'dodgerblue');
136 drawLine(333.749329, 433.736267, 410.950745, 381.721130,4, 'dodgerblue');
137 drawLine(301.455261, 430.344025, 333.749329, 433.736267,4, 'dodgerblue');
138 drawLine(89.154579, 433.040131, 104.770851, 422.545990,4, 'dodgerblue');
139 drawLine(460.258545, 276.798706, 410.950745, 381.721161,4, 'dodgerblue');
140 drawLine(161.072784, 226.151321, 301.455261, 430.344025,4, 'dodgerblue');
141 drawLine(104.770851, 422.545959, 301.455261, 430.344025,4, 'dodgerblue');
142 drawLine(127.067291, 250.960342, 104.770859, 422.545959,4, 'dodgerblue');
143 drawLine(354.080414, 115.003471, 460.258545, 276.798706,4, 'dodgerblue');
144 drawLine(127.067291, 250.960327, 161.072784, 226.151306,4, 'dodgerblue');
145 drawLine(176.980927, 211.962967, 354.080383, 115.003494,4, 'dodgerblue');
146 drawLine(161.072784, 226.151306, 176.980927, 211.962967,4, 'dodgerblue');
147 var textColor = 'rgb(255, 255, 255)';var D = 100;
148 if(-1 == pressureSign){
149 D *= 100;
150 }
151 var a = stepBetweenColumns;//23.131737698273685;// 1*32;
152 var cutLength = 1.5 * canvas.height;//Math.sqrt(2130);
153
154 var squareA = Math.pow(a, 2);
155 var squareCutLength = Math.pow(cutLength, 2);
156
157 var diagramData = {'x': [], 'y': []};
158 var diagramCanvas = document.getElementById('diagram');
159 var stepFromBoard = 7;
160 var step = 0;
161
162 function applyPhysics(){
163 var forces = [];
164 for(var j = 0; j < particles.length; ++j){
165 var forceX = 0;
166 var forceY = 0;
167 for(var i = 0; i < particles.length; ++i){
168 if(i == j){
169 continue;
170 }
171 var diffX = particles[j].position.x - particles[i].position.x;
172 var diffY = particles[j].position.y - particles[i].position.y;
173 var squareDiff = Math.pow(diffX, 2) + Math.pow(diffY, 2);
174 if(squareDiff > squareCutLength){
175 fragmentation = true;
176 continue;
177 }
178
179 var tmp = squareA / squareDiff;
180 var force = 0.5 * (particles[j].c + particles[i].c) * (12 * D / squareA) * (Math.pow(tmp, 7) - Math.pow(tmp, 4));
181 //-(particles[j].c + particles[i].c) * D * squareDiff / 100000;
182 forceX += force * diffX;
183 forceY += force * diffY;
184 }
185 forces[j] = {'x': 0, 'y': forceY};
186 }
187 var sigma = 0;
188 for(var i = 0; i < numberOfColumns; ++i){
189 sigma -= forces[i].y;// + forces[particles.length - i - 1].y;
190 forces[i] = {'x': 0, 'y': 0};
191 forces[particles.length - i - 1] = {'x': 0, 'y': 0};
192 }
193 if(!fragmentation){
194 var epsilon = pressureSign * (particles[1].position.y - halfOfStepBetweenRows) / (canvas.height - 2 * halfOfStepBetweenRows);
195 diagramData.x.push(epsilon);
196 diagramData.y.push(sigma / (numberOfColumns * 1));
197 plotFromData(diagramCanvas, diagramData, 'Stress-deformation diagram', 'rgb(56, 195, 237)', 2, textColor);
198 }
199 for(var j = 0; j < particles.length; ++ j){
200 integrator(particles[j], forces[j], dt);
201 }
202 timeValue.textContent = t.toFixed(2);
203 ++step;
204 }
205 function draw(){
206 ctx.clearRect(0, 0, canvas.width, canvas.height);
207 for(var i = 0; i < particles.length; ++i){
208 particles[i].draw();
209 }
210 }
211 document.getElementById('play').onclick = function(){
212 this.className = 'inprogress';
213 document.getElementById('conditions').className = 'hide';
214 document.getElementById('diagram').className = '';
215 animate(animationSpeed);
216 }
217 document.getElementById('strainRate').onchange = function(){
218 document.getElementById('strainRateValue').textContent = (+this.value).toFixed(1);
219 strainRate = (+this.value).toFixed(1);
220 applyInitionalConditions();
221 }
222 document.getElementById('animationSpeed').onchange = function(){
223 document.getElementById('animationSpeedValue').textContent = (+this.value).toFixed(0);
224 animationSpeed = (+this.value).toFixed(0);
225 }