# Edit in JSFiddle

```// Global variables. Yeah yeah I know. Just felt like making this one as a procedural program rather than OOP.
var width = 10,
cells = [],
cellWidth = 0.01, // 10 centimeters
cellDepth = 0.01, // 10 millimeter
cellEdgeArea = cellWidth*cellDepth,
materialConductivities = {copper: 400, aluminum: 215, brick: 1.3, iron: 80}, // Assume constant. (W / m K)
materialSpecificHeats = {copper: 390, aluminum: 910, brick: 900, iron: 450}, // Assume constant. (J / kg K)
materialDensities = {copper: 8940, aluminum: 2712, brick: 2000, iron: 7850}, // Assume constant. (kg / m^3)
convectionCoefficient = 30, // (W / m^2)
currentMaterial = 'copper',
inputHeat = 800, // Watts
heatAppliedTo = 40, // Cell id#
initialTemp = 295, // Room temperature. (K)
lastTimestamp = null
;
var createCells = function() {
var table = \$("#plate");
var index = 0;
for (var row = 0; row < width; row += 1) {
var tr = \$("<tr>");
for (var col = 0; col < width; col += 1) {
var td = \$("<td>").attr("id", index);
tr.append(td);
cells[index] = initialTemp;
index++;
}
table.append(tr);
}
};

var keyForNeighbor = function(myKey, whichNeighbor) {
// whichNeighbor: 0 = north, 1 = east, 2 = south, 3 = west (clockwise)
if (whichNeighbor === 0 && myKey >= width)
return myKey - width;

if (whichNeighbor === 1 && ( (myKey + 1) % width !== 0 ) )
return myKey + 1;

if (whichNeighbor === 2 && myKey < (width*width - width) )
return myKey + width;

if (whichNeighbor === 3 && myKey % width !== 0)
return myKey - 1;

return null;
};

var _ = function(id) {
return \$("#" + id);
};

var cellMass = function() {
return cellWidth * cellWidth * cellDepth * materialDensities[currentMaterial];
};

var energyTransfer = function(myTemp, yourTemp, dTime) {
var J = cellWidth * (yourTemp - myTemp) * materialConductivities[currentMaterial] * dTime;
return J;
// This is the heat transfer INTO the cell, though general convention is to measure transfer out.
// Returns the number of Joules transfered into the cell in dTime seconds.
};

var temperatureChange = function(energyIn) {
var heatCapacity = cellMass() * materialSpecificHeats[currentMaterial];
return energyIn / heatCapacity;
// Returns change of temp in K
};

var updateCell = function(id, newTemp) {
cells[id] = newTemp;
//_(id).text(Math.round(newTemp));
};

var colorCells = function() {
for (var i = 0, len = cells.length; i < len; i+=1) {
var opacity = (cells[i] - initialTemp) / 2000;
if (opacity > 1) opacity = 1;
if (opacity < 0) opacity = 0;
_(i).css("background", "rgba(255,0,0,"+opacity+")");
};
};

var loop = function() {
var now = new Date().getTime();
var dTime = (now - lastTimestamp) / 1000;
lastTimestamp = now;

var cellCache = [];
for (var i = 0, len = cells.length; i < len; i += 1)
cellCache[i] = cells[i];

for (var i = 0, len = cells.length; i < len; i += 1) {
var energyIn = 0;
var myTemp = cellCache[i];
for (var n = 0; n < 4; n += 1) {
var neighborKey = keyForNeighbor(i, n);
if (neighborKey === null)
continue;
var neighborTemp = cellCache[neighborKey];
energyIn += energyTransfer(myTemp, neighborTemp, dTime);
};

energyIn -= convectionCoefficient * cellWidth * cellWidth * 2 * (myTemp - initialTemp);

if (i === heatAppliedTo)
energyIn += inputHeat;

updateCell(i, myTemp + temperatureChange(energyIn) );
};
colorCells();
};

lastTimestamp = new Date().getTime();
createCells();
\$("td").click(function() {
heatAppliedTo = parseInt(\$(this).attr("id"));
});
setInterval(loop, 20);

});```
```<table id="plate">
</table>```
```#plate {
border-collapse:collapse;
margin:20px auto;
font-family:"Verdana", "Arial";
font-size:8px;
text-align:center;
color:#CCC;
border: 1px solid #DDD;
}
#plate td {
/*border:1px solid #DDD;*/
width:20px;
height:20px;
overflow:hidden;
}```