Моделирование нестационарного распределения тепла

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск

Описание[править]

Моделирование процесса распределения тепла в прямоугольному образце Исполнители: Алексеенко Егор, Тюнин Павел

Математическая модель[править]

Основные допущения[править]

При моделировании образца были сделаны следующие допущения:

  • Не учитываются воздействия среды

Входные данные[править]

Перед началом моделирования задаются следующие данные:

  1. Источники тепла
  2. Граничные условия

Управление[править]

  • Левая кнопка мыши - увеличение температуры;
  • Правая кнопка мыши - уменьшение температуры;

Визуализация[править]

Код программы[править]

Текст программы на языке JavaScript:
  1    // канвас
  2     var ctx = canvasEx.getContext("2d");
  3     var w = canvasEx.width;
  4     var h = canvasEx.height;
  5     var clr = colorbar.getContext("2d");
  6     var wc = colorbar.width;
  7     var hc = colorbar.height;
  8     // константы
  9     var isStarted = 0;
 10     var isPaused = 0;
 11     var t = 0;
 12     var dt = 0.01;
 13     var fps = 1/dt;
 14     var L = 10;
 15     var Nx = 22;
 16     var Ny = 22;
 17     var dx = L/(Nx-2);
 18     var dy = L/(Ny-2);
 19     var T0 = 15;
 20     var DT = 10;
 21     var a = 0.1; // Коэффициент температуропроводности
 22     var TMax = 100;
 23     var TMin = 0;
 24     var TAv = (TMax-TMin)/2;
 25     var xscale = w / L;
 26     var yscale = h / L;
 27     var fx = 1;
 28     var fy = 1;
 29     // задание начальных условий
 30     var T = new Array(Ny);
 31     for (var i = 0; i < Ny; i++)
 32     {
 33         T[i] = new Array(Nx);
 34     }
 35     for (var i = 0; i < Ny; i++)
 36     {
 37         for (j = 0; j < Nx; j++)
 38         {
 39             T[i][j] = T0;
 40         }
 41     }
 42     T[1][1] = 50;
 43     //
 44     var cyan = {
 45         r: 0,
 46         g: 1,
 47         b: 1,
 48     }
 49     var yellow = {
 50         r: 1,
 51         g: 1,
 52         b: 0,
 53     }
 54     var green = {
 55         r: 0,
 56         g: 1,
 57         b: 0,
 58     }
 59     var brown = {
 60         r: 110/255,
 61         g: 67/255,
 62         b: 6/255,
 63     }
 64     var blue = {
 65         r: 0,
 66         g: 0,
 67         b: 1,
 68     }
 69     var red = {
 70         r: 1,
 71         g: 0,
 72         b: 0,
 73     }
 74     var N = 5+5*4;
 75     for (var i=0; i<N; i++) {
 76         clr.fillStyle = gradient([blue, cyan, green, yellow, red], i/(N-1));
 77         clr.fillRect(wc/N*i, 0, wc/N, hc);
 78     }
 79     function gradient(colors, a) {
 80         var n = colors.length-1;
 81         if (Math.floor(a*n)==n) {
 82             let i = n-1;
 83             let j = n;
 84             var color1 = colors[i];
 85             var color2 = colors[j];
 86             var a = 1;
 87         } else {
 88             let i = Math.floor(a*n)==n ? n-1 : Math.floor(a*n);
 89             let j = i+1;
 90             var color1 = colors[i];
 91             var color2 = colors[j];
 92             var a = a*n - Math.floor(a*n);
 93         }
 94         return 'rgb('+Math.floor(255*(color1.r+(color2.r-color1.r)*a))+', '+Math.floor(255*(color1.g+(color2.g-color1.g)*a))+', '+Math.floor(255*(color1.b+(color2.b-color1.b)*a))+')';
 95     }
 96     // функция просчитывания температурного поля
 97     function phys()
 98     {
 99         for (var i = 1+fy; i < Ny-1-fy; i++)
100         {
101             for (var j = 1+fx; j < Nx-1-fx; j++)
102             {
103                 T[i][j] = T[i][j] + a*dt*((T[i+1][j] + T[i-1][j] -2*T[i][j])/(dx*dx) + (T[i][j+1] + T[i][j-1] -2*T[i][j])/(dy*dy));
104             }
105         }
106       if (c2.checked)
107       {
108          for (var i = 1; i<20; i++)
109          {  
110             T[i][0] = T[i][20];
111             T[i][21] = T[i][1];
112          }
113       }
114       if (c1.checked)
115       {
116             for (j=1; j<20; j++)
117          {
118             T[21][j]=T[1][j];
119             T[0][j]=T[20][j];
120          }
121       }
122       if ((c1.checked) && (c2.checked))
123       {
124          for (var i = 1; i<20; i++)
125          {  
126             T[i][0] = T[i][20];
127             T[i][21] = T[i][1];
128          }
129          for (j=1; j<20; j++)
130          {
131             T[21][j]=T[1][j];
132             T[0][j]=T[20][j];
133          }
134       }      
135     }
136     // отрисовка температурного поля
137      function draw()
138     {
139         ctx.clearRect(0,0,w,h);
140         for (var i = 1; i < Ny-1; i++)
141         {
142             for (var j = 1; j < Nx-1; j++)
143             {
144                 var imageData = clr.getImageData(wc*(T[i][j]/TMax)-1,1, 1,1).data;
145                 ctx.fillStyle = "rgb("+imageData[0]+","+imageData[1]+","+imageData[2]+")";
146                 ctx.fillRect((j-1)*dx*xscale, (i-1)*dy*yscale, (j)*dx*xscale,(i)*dy*yscale);
147             }
148         }
149     }
150     function control()
151     {
152         phys();
153         draw();
154     }
155     // функция старта
156     start.onclick = function ()
157     {
158         if (isStarted == 0 || isPaused == 1)
159         {
160               t = setInterval(control,1/fps);
161               isStarted = 1;
162               isPaused = 0;
163             document.getElementById("c1").setAttribute("disabled", "true");
164             document.getElementById("c2").setAttribute("disabled", "true");
165               if (c2.checked)
166               {
167                   fx = 0;
168               }
169               else fx = 1;
170               if (c1.checked)
171               {
172                   fy = 0;
173               }
174               else fy = 1;
175         }
176     };
177     // функция паузы
178     pause.onclick = function()
179     {
180         if (isPaused == 0)
181         {
182             clearTimeout(t);
183             isPaused = 1;
184         }
185     };
186     // получение координат курсора, с пересчетом в координаты ячейки
187     function getMouseCoords(e)
188     {
189         let m = {};
190         let rect = canvasEx.getBoundingClientRect();
191         m.x = Math.floor((e.clientX - rect.left)/(dx*xscale))+1;
192         m.y = Math.floor((e.clientY - rect.top)/(dy*xscale))+1;
193         return m;
194     }
195     // функция добавления моментальных источников тепла
196     canvasEx.onclick = function(e)
197     {
198         if (isStarted == 0)
199         {
200             var m = getMouseCoords(e);
201             if (T[m.y][m.x] + DT <= TMax)
202             {
203                 T[m.y][m.x] += DT;
204                 draw();
205             }
206         }
207     };
208     //функция моментального охлаждения
209     canvasEx.oncontextmenu = function(e)
210     {
211         if (isStarted == 0)
212         {
213             var m = getMouseCoords(e);
214             if (T[m.y][m.x] - DT >= TMin)
215             {
216                 T[m.y][m.x] -= DT;
217                 draw();
218             }
219         }
220     };
221     //функция отключения контекстного меню
222     document.body.oncontextmenu = function (e) {
223         return false;
224     };
225     // функция сброса состояния
226     reset.onclick = function()
227     {
228         document.getElementById('c1').removeAttribute("disabled");
229         document.getElementById('c2').removeAttribute("disabled");
230         isPaused = 0;
231         isStarted = 0;
232         clearTimeout(t);
233         var fx = 1;
234         var fy = 1;
235         for (var i = 0; i < Ny; i++)
236         {
237             for (j = 0; j < Nx; j++)
238             {
239                 T[i][j] = T0;
240             }
241         }
242         draw();
243      };
244  draw();