Browse Source

A 'working' transient model

Also, an AlternativeModels.js file contain some of the other models not used. Lumped sum, etc.
formula
Scott Mobley 11 years ago
parent
commit
40b2667779
  1. 89
      js/AlternativeModels.js
  2. 187
      js/CookingFormula.js

89
js/AlternativeModels.js

@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
function findClosest(value,array) {
closestDiff = null;
closestPosition = null;
for (var i=0;i<array.length;i++) {
diff = Math.abs(value-array[i])
if (diff<closestDiff || closestDiff == null) {
closestPosition=i;
closestDiff = diff;
}
}
return ([closestPosition,array[closestPosition]])
}
function biotSphereCoefficients (Biot) {
Bi = [0.01, 0.02, 0.04, 0.06, 0.08, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 10000]
lambdaOne = [0.1730, 0.2445, 0.3450, 0.4217, 0.4860, 0.5423, 0.7593, 0.9208, 1.0528, 1.1656, 1.2644, 1.3525, 1.4320, 1.5044, 1.5708, 2.0288, 2.2889, 2.4556, 2.5704, 2.6537, 2.7165, 2.7654, 2.8044, 2.8363, 2.9857, 3.3072, 3.0632, 3.0788, 3.1102, 3.1416]
alphaOne = [ 1.0030, 1.0060, 1.0120, 1.0179, 1.0239, 1.0298, 1.0592, 1.0880, 1.1164, 1.1441, 1.1713, 1.1978, 1.2236, 1.2488, 1.2732, 1.4793, 1.6227, 1.7202, 1.7870, 1.8338, 1.8673, 1.8920, 1.9106, 1.9249, 1.9781, 1.9898, 1.9942, 1.9962, 1.9990, 2 ]
position = findClosest(Biot,Bi)[0]
return([lambdaOne[position], alphaOne[position]])
}
function lumpedCapacitance (outerRadius,radiusInner,tempInitial,tempInfini,heatConvectionTerm,t) {
volume = (4/3)*Math.PI*Math.pow(outerRadius,3) - (4/3)*Math.PI*Math.pow(radiusInner,3); //3D Sphere
surfaceArea = 4*Math.PI*Math.pow(outerRadius,2); //3D Sphere
mass = density * volume;
charLength = volume/surfaceArea ;
biotNum = heatConvectionTerm * charLength/thermalConduct
console.log("The Biot Value is " + biotNum)
b=(heatConvectionTerm)/(density*charLength*cp)
console.log("The time constant b is "+ b)
tempAtTime = Math.exp(-b*t)*(tempInitial-tempInfini)+tempInfini;
console.log("The Temperature at time " + t +" seconds is " + tempAtTime)
qDot = -1*heatConvectionTerm*surfaceArea*(tempAtTime-tempInfini) //Heat Transfer Rate Useful for water Loss
console.log("The Heat Flux is " + qDot )
return([tempAtTime,qDot])
}
function transientSphereOneTerm (rPosition,rTotal,tempInitial,tempInfini,t) {
alpha = thermalConduct/(density*cp)
console.log("Alpha is " + alpha)
Fourier = (alpha*t)/Math.pow(rTotal,2)
console.log("Fourier is " + Fourier)
biotNum = heatConvection * rTotal/thermalConduct
console.log("The Biot Value is " + biotNum)
temp=biotSphereCoefficients(biotNum)
lambdaOne=temp[0];
alphaOne=temp[1];
console.log("lambda1 is " + lambdaOne)
console.log("A1 is " + alphaOne)
//This is only valid for Fourier greater than 0.2
sinPortion= Math.sin(lambdaOne*rPosition/rTotal)/(lambdaOne*rPosition/rTotal);
expotentialPortion = alphaOne*(1/Math.exp(Math.pow(lambdaOne,2)*Fourier))
tempAtTimeAndRadius=(sinPortion*expotentialPortion*(tempInitial-tempInfini))+tempInfini
console.log("The Temperature at radius " + rPosition + " m and time " + t + " seconds is " + tempAtTimeAndRadius + " C or " + celsiusToFarenheit(tempAtTimeAndRadius) + " F");
}
function lumpedCapacitanceMethod (outerRadius,radiusInner,tempInitial,tempInfini, t) {
volume = (4/3)*Math.PI*Math.pow(outerRadius,3) - (4/3)*Math.PI*Math.pow(radiusInner,3); //3D Sphere
surfaceArea = 4*Math.PI*Math.pow(outerRadius,2); //3D Sphere
mass = density * volume;
charLength = volume/surfaceArea ;
biotNum = heatConvection * charLength/thermalConduct
console.log("The Biot Value is " + biotNum)
b=(heatConvection)/(density*charLength*cp)
console.log("The time constant b is "+ b)
tempAtTime = Math.exp(-b*t)*(tempInitial-tempInfini)+tempInfini;
console.log("The Temperature at time " + t +" seconds is " + tempAtTime)
Qdot = -1*heatConvection*surfaceArea*(tempAtTime-tempInfini) //Heat Transfer Rate Useful for water Loss
console.log("The Heat Flux is " + Qdot )
return(tempAtTime)
}
function findAllRoots (Biot) {
limit = 50; //Terms to Compute too
storage = [];
for (var k=0; k<=limit; k++) {
minK = (k+0.5)*Math.PI;
maxK = (k+1)*Math.PI;
answer = bisectionMethod(minK,maxK,Biot);
if (answer !=undefined) {
storage.push(answer);
}
}
//console.log(storage)
return(storage)
}

187
js/CookingFormula.js

@ -7,40 +7,24 @@ @@ -7,40 +7,24 @@
density = 996; // kg/m3 Assuming Density of Water 1000 kg/m3
cp = 2810 // J/kg K for Turkey
heatConvection = 5; // W/m2 K Some Reasonable estimate for natural Convection. Change as needed. 5-25
thermalConduct = 0.412 // W/m K
thermalConduct = 0.412 // W/m K // Chicken
globalTime = 1;
function celsiusToFarenheit(celsius) {
farenheit = (celsius*(9/5)) + 32;
return(farenheit)
}
function farenheitToCelsius (farenheit) {
celsius = (farenheit*(9/5)) + 32;
return(celsius)
}
function poundsToKilograms(pounds) {
kilograms = (pounds * 0.453592);
return(kilograms)
}
function findClosest(value,array) {
closestDiff = null;
closestPosition = null;
for (var i=0;i<array.length;i++) {
diff = Math.abs(value-array[i])
if (diff<closestDiff || closestDiff == null) {
closestPosition=i;
closestDiff = diff;
}
}
return ([closestPosition,array[closestPosition]])
}
function biotSphereCoefficients (Biot) {
Bi = [0.01, 0.02, 0.04, 0.06, 0.08, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 10000]
lambdaOne = [0.1730, 0.2445, 0.3450, 0.4217, 0.4860, 0.5423, 0.7593, 0.9208, 1.0528, 1.1656, 1.2644, 1.3525, 1.4320, 1.5044, 1.5708, 2.0288, 2.2889, 2.4556, 2.5704, 2.6537, 2.7165, 2.7654, 2.8044, 2.8363, 2.9857, 3.3072, 3.0632, 3.0788, 3.1102, 3.1416]
alphaOne = [ 1.0030, 1.0060, 1.0120, 1.0179, 1.0239, 1.0298, 1.0592, 1.0880, 1.1164, 1.1441, 1.1713, 1.1978, 1.2236, 1.2488, 1.2732, 1.4793, 1.6227, 1.7202, 1.7870, 1.8338, 1.8673, 1.8920, 1.9106, 1.9249, 1.9781, 1.9898, 1.9942, 1.9962, 1.9990, 2 ]
position = findClosest(Biot,Bi)[0]
return([lambdaOne[position], alphaOne[position]])
}
function calculateRadius(weight) {
//Using Ratios for a rectangular Box Turkey
ratioLvG=1.4; //1.4, Turkey length vs shoulder girth
@ -59,79 +43,8 @@ console.log("Complex Radius " + complexRadius + " Meters") @@ -59,79 +43,8 @@ console.log("Complex Radius " + complexRadius + " Meters")
return(complexRadius)
}
function lumpedCapacitance (outerRadius,radiusInner,tempInitial,tempInfini,heatConvectionTerm,t) {
volume = (4/3)*Math.PI*Math.pow(outerRadius,3) - (4/3)*Math.PI*Math.pow(radiusInner,3); //3D Sphere
surfaceArea = 4*Math.PI*Math.pow(outerRadius,2); //3D Sphere
mass = density * volume;
charLength = volume/surfaceArea ;
biotNum = heatConvectionTerm * charLength/thermalConduct
console.log("The Biot Value is " + biotNum)
b=(heatConvectionTerm)/(density*charLength*cp)
console.log("The time constant b is "+ b)
tempAtTime = Math.exp(-b*t)*(tempInitial-tempInfini)+tempInfini;
console.log("The Temperature at time " + t +" seconds is " + tempAtTime)
qDot = -1*heatConvectionTerm*surfaceArea*(tempAtTime-tempInfini) //Heat Transfer Rate Useful for water Loss
console.log("The Heat Flux is " + qDot )
return([tempAtTime,qDot])
}
function lumpedCapacitanceMethod (outerRadius,radiusInner,tempInitial,tempInfini, t) {
volume = (4/3)*Math.PI*Math.pow(outerRadius,3) - (4/3)*Math.PI*Math.pow(radiusInner,3); //3D Sphere
surfaceArea = 4*Math.PI*Math.pow(outerRadius,2); //3D Sphere
mass = density * volume;
charLength = volume/surfaceArea ;
biotNum = heatConvection * charLength/thermalConduct
console.log("The Biot Value is " + biotNum)
b=(heatConvection)/(density*charLength*cp)
console.log("The time constant b is "+ b)
tempAtTime = Math.exp(-b*t)*(tempInitial-tempInfini)+tempInfini;
console.log("The Temperature at time " + t +" seconds is " + tempAtTime)
Qdot = -1*heatConvection*surfaceArea*(tempAtTime-tempInfini) //Heat Transfer Rate Useful for water Loss
console.log("The Heat Flux is " + Qdot )
return(tempAtTime)
}
function transientSphereOneTerm (rPosition,rTotal,tempInitial,tempInfini,t) {
alpha = thermalConduct/(density*cp)
console.log("Alpha is " + alpha)
Fourier = (alpha*t)/Math.pow(rTotal,2)
console.log("Fourier is " + Fourier)
biotNum = heatConvection * rTotal/thermalConduct
console.log("The Biot Value is " + biotNum)
temp=biotSphereCoefficients(biotNum)
lambdaOne=temp[0];
alphaOne=temp[1];
console.log("lambda1 is " + lambdaOne)
console.log("A1 is " + alphaOne)
//This is only valid for Fourier greater than 0.2
sinPortion= Math.sin(lambdaOne*rPosition/rTotal)/(lambdaOne*rPosition/rTotal);
expotentialPortion = alphaOne*(1/Math.exp(Math.pow(lambdaOne,2)*Fourier))
tempAtTimeAndRadius=(sinPortion*expotentialPortion*(tempInitial-tempInfini))+tempInfini
console.log("The Temperature at radius " + rPosition + " m and time " + t + " seconds is " + tempAtTimeAndRadius + " C or " + celsiusToFarenheit(tempAtTimeAndRadius) + " F");
}
function findAllRoots (Biot) {
limit = 50; //Terms to Compute too
storage = [];
for (var k=0; k<=limit; k++) {
minK = (k+0.5)*Math.PI;
maxK = (k+1)*Math.PI;
answer = bisectionMethod(minK,maxK,Biot);
if (answer !=undefined) {
storage.push(answer);
}
}
//console.log(storage)
return(storage)
}
function findAllRootsAlternative (min,max,splitsNum,Biot) {
function findAllRoots(min,max,splitsNum,Biot) {
var step = ( max - min ) / ( splitsNum - 1 );
var storage = [];
for (var i = step; i < max; i=i+step ) {
@ -186,10 +99,10 @@ return(result) @@ -186,10 +99,10 @@ return(result)
}
function oven() {
this.tempInfini=0; //C
this.setTemp = 0;
var proportional = 0.01; // This value is arbitrary to how fast you want the temperatures to converge. (Or oscillate, which could be realistic as well)
var errorTolerance = 1; //Stove is accurate to 1 degree Celcius Should hopefully oscillate below that value.
this.tempInfini=20; //C
this.setTemp = 20;
var proportional = 0.1; // This value is arbitrary to how fast you want the temperatures to converge. (Or oscillate, which could be realistic as well)
var errorTolerance = 5; //Stove is accurate to 1 degree Celcius Should hopefully oscillate below that value.
this.changeTemp = function(setTemp) {
this.setTemp = setTemp;
@ -208,59 +121,85 @@ var errorTolerance = 1; //Stove is accurate to 1 degree Celcius Should hopefully @@ -208,59 +121,85 @@ var errorTolerance = 1; //Stove is accurate to 1 degree Celcius Should hopefully
}
}
}
ovenObject = new oven ();
function Turkey(weight,time) {
totalRadius = calculateRadius(weight)
function Layer(name) {
this.name = name
this.temperature = 20;
this.waterContent =100;
function layerModel(name,radiusPercent) {
this.name = name;
this.radiusPercent=radiusPercent;
this.initialTemp = 20;
this.waterContent =100000;
this.Qdot = 0;
this.finalTemperature = 20;
}
skin= new Layer("Skin")
body = new Layer("Body")
core = new Layer("Core")
skin.temperature = lumpedCapacitance(totalRadius,totalRadius*0.85,skin.temperature,ovenTemp,airConvection,time)[0]
body.temperature = lumpedCapacitance(totalRadius*0.85,totalRadius*0.30,body.temperature,skin.temperature,airConvection*1000,time)[0]
core.temperature = lumpedCapacitance(totalRadius*0.30,0,core.temperature,body.temperature,airConvection*1000,time)[0]
}
function turkeyModel(weight) {
this.totalRadius = calculateRadius(weight)
this.skin = new layerModel("Skin",0.85)
this.body = new layerModel("Body",0.45)
this.core = new layerModel("Core",0.01)
this.updateLayerTemps = function() {
this.skin.finalTemperature = transientSphereSeries (this.skin.radiusPercent*this.totalRadius,this.totalRadius,this.skin.initialTemp,ovenObject.tempInfini,globalTime)
this.skin.initialTemp = this.skin.finalTemperature;
this.body.finalTemperature = transientSphereSeries (this.body.radiusPercent*this.totalRadius,this.totalRadius,this.body.initialTemp,ovenObject.tempInfini,globalTime)
this.body.initialTemp = this.body.finalTemperature;
this.core.finalTemperature = transientSphereSeries (this.core.radiusPercent*this.totalRadius,this.totalRadius,this.core.initialTemp,ovenObject.tempInfini,globalTime)
this.core.initialTemp = this.core.finalTemperature;
}
}
var oldBiot=null;
function transientSphereSeries (rPosition,rTotal,tempInitial,tempInfini,t) {
var min = 0;
var max = 1000; // This are for setting Lambda boundries and nothing else
var sum=0;
var alpha = thermalConduct/(density*cp)
console.log("Alpha is " + alpha)
//console.log("Alpha is " + alpha)
var Fourier = (alpha*t)/Math.pow(rTotal,2)
console.log("Fourier is " + Fourier)
//console.log("Fourier is " + Fourier)
var biotNum = heatConvection * rTotal/thermalConduct
console.log("The Biot Value is " + biotNum)
var min = 0;
var max = 1000;
if (biotNum != oldBiot) {
console.log("Recalculating Lambda Terms")
lambdaTerms = findAllRoots(min,max,max*Math.PI*10,biotNum)
oldBiot = biotNum;
}
//console.log("The Biot Value is " + biotNum)
lambdaTerms=findAllRootsAlternative (min,max,max*Math.PI*10,biotNum)
for (var i = 0; i<lambdaTerms.length; i++) {
lambdaN = lambdaTerms[i]
sinPortion= Math.sin(lambdaN*rPosition/rTotal)/(lambdaN*rPosition/rTotal);
exponentialPortion = (1/Math.exp(Math.pow(lambdaN,2)*Fourier))
frontCoefficientPortion = 4*(Math.sin(lambdaN)-(lambdaN*Math.cos(lambdaN)))/ (2*lambdaN-Math.sin(2*lambdaN))
sum = frontCoefficientPortion*exponentialPortion*sinPortion + sum
}
tempAtTimeAndRadius=(sum*(tempInitial-tempInfini))+tempInfini
console.log("The Temperature at radius " + rPosition + " m and time " + t + " seconds is " + tempAtTimeAndRadius + " C or " + celsiusToFarenheit(tempAtTimeAndRadius) + " F");
return(tempAtTimeAndRadius)
}
setInterval(function(){time()},1000);
//Running the Program Stuff
function time() {
ovenObject.equalizeTemp();
ovenObject = new oven ();
turkey = new turkeyModel(8);
setInterval(function(){time()},20);
function time() {
console.clear()
if (ovenObject.equalizeTemp() ) {
globalTime = 0; //Reset the model's time calculation if there are major changes in the tolerance of the temperature
}
else {globalTime = globalTime +60 }
console.log(ovenObject.tempInfini)
turkey.updateLayerTemps();
}
Loading…
Cancel
Save