Испытания на разрыв и сжатие плоского тела

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Курсовые работы 2016-2017 учебного года > Испытания на разрыв и сжатие плоского тела

Курсовой проект по Механике дискретных сред

Исполнитель: Старобинский Егор

Группа: 09 (43604/1)

Семестр: осень 2016


Описание

Проводятся эксперименты сжатия и растяжения плоского тела на примере поликристалла. Поликристалл моделируется множеством материальных точек, разделённых на области с разной жёсткостью связи (используется потенциал Леннард-Джонса с конечным радиусом обрезания). На плоскости строится диаграмма Вороного, каждая точка тела попадает в одну из областей и получает соответствующий коэффициент (различный для разных областей). При расчёте силы взаимодействия между двумя точками их коэффициенты складываются, получившиеся значение есть жёсткость связи в потенциале. Диаграмма напряжений строится вплоть до момента потери устойчивости.

В рамках эксперимента скорость деформации и ширина образца постоянны. Поликристалл может содержать до 17 областей. Уравнения динамики решаются с помощью метода интегрирования Верле.

Решение задачи и визуализация написаны нa JavaScript, диаграмма Вороного получается POST запросом к серверу (расчёты производятся программой на C++ с помощью алгоритма Форчуна, парсер написан на PHP).

Результат

Страница полного решения


Исходный код для одной из конфиграций [JavaScript]:
  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 }