-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathobjects.js
120 lines (112 loc) · 4.92 KB
/
objects.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// this file contains the objects used for identifying solutions
// for a given room, set of candidate fans, and range of acceptable conditions
// defined by a addUser
//
// all objects store data in SI units (without prefixes)
/* object to represent the dimensions of a cuboid room */
function Room(ceilingHeight, sizeX, sizeY) {
this.ceilingHeight = ceilingHeight;
this.sizeX = sizeX;
this.sizeY = sizeY;
this.area = function() {
return this.sizeX * this.sizeY;
}
};
/* object to represent a candidate fan type */
function Fan(type, diameter, airflow, ul507, percentFanSpeed) {
this.type = type;
this.diameter = diameter;
this.airflow = airflow;
this.ul507 = ul507;
this.maxFanAirSpeed = this.airflow/(Math.PI * Math.pow(this.diameter,2)/4);
};
/* Layout object represents a potential design layout
including the room characteristics and the number of fans */
function Layout(numFansX, numFansY, room){
this.numFansX = numFansX;
this.numFansY = numFansY;
this.room = room;
this.cellSizeX = this.room.sizeX / this.numFansX;
this.cellSizeY = this.room.sizeY / this.numFansY;
this.cellArea = this.cellSizeX * this.cellSizeY;
this.cellVolume = this.cellArea * this.room.ceilingHeight;
this.r = Math.sqrt(this.cellArea);
// TODO redefine throughout to always > 1
this.aspectRatio = Math.max(this.cellSizeX/this.cellSizeY, this.cellSizeY/this.cellSizeX);
this.numFans = function(){
return parseInt(this.numFansX * this.numFansY, 10);
};
}
/* Solution object represents a potential design solution
including the room, layout and fan characteristics */
function Solution(layout, fan, percentFanSpeed, bladeHeight, mdMin){
this.layout = layout;
this.fan = fan;
this.percentFanSpeed = percentFanSpeed;
this.dr = this.fan.diameter/this.layout.r;
this.cd = this.layout.room.ceilingHeight/this.fan.diameter;
this.do = this.fan.diameter/1.7;
this.density = (Math.PI * Math.pow(this.fan.diameter,2)/4)/this.layout.cellArea;
this.bladeHeightRange = bladeHeight;
// this.isBladeLowest = isBladeLowest;
this.mdMin = mdMin;
this.clearanceX = function(){
return (this.layout.cellSizeX - this.fan.diameter) / 2;
}
this.clearanceY = function(){
return (this.layout.cellSizeY - this.fan.diameter) / 2;
}
this.calcBladeHeightRange = function(){
// constrain min blade height based on UL507 requirement
this.fan.ul507 == "Yes" ? min = 3.048 : min = 2.1336;
constraintUL507 = min;
// constrain max blade height based on mount distance (avoiding starvation)
max = this.layout.room.ceilingHeight - (this.mdMin * this.fan.diameter);
constraintMount = max;
// constrain min/max blade height based on user input ranges
if (this.bladeHeightRange[0] > min ) min = this.bladeHeightRange[0];
if (max > this.bladeHeightRange[1]) max = this.bladeHeightRange[1];
mean = (min+max)/2
return {'pass': (max-min) >= 0, 'min': min, 'max' : max, 'mean' : mean, 'constraintMount' : constraintMount, 'constraintUL507': constraintUL507};
}
this.validBladeHeightRange = this.calcBladeHeightRange();
this.hd = this.validBladeHeightRange['mean']/this.fan.diameter;
this.fanAirSpeed = this.fan.maxFanAirSpeed * this.percentFanSpeed /100;
this.airTurnoversPerHour = this.fan.airflow*this.percentFanSpeed*36/this.layout.cellVolume; // * 3600 to convert m3/s to m3/hour, /100 to convert percent
this.calcAirspeeds = function(){
lowest = this.fanAirSpeed *
(0.9 * this.dr - 0.017 * this.cd +0.11 * this.do + p.isSeated*0.024 + 0.047)/this.layout.aspectRatio;
areaWeightedAverage = this.fanAirSpeed * (0.99 * this.dr - 0.06 * this.cd + 0.11 * this.do + p.isSeated*0.024 + 0.25);
highest = this.fanAirSpeed *
(-0.18 * this.hd - p.isSeated*0.1 + 1.3);
return [lowest,areaWeightedAverage,highest];
}
this.airspeeds = this.calcAirspeeds();
this.uniformity = 1 - ((this.airspeeds[2]-this.airspeeds[0])/this.airspeeds[2]);
this.tempDiffs = this.airspeeds.map(airspeedToTempDiff);
}
function airspeedToTempDiff(airspeed){
// difference in operative temp (air temp = mean radiant temp)
// to maintain the same SET at standard conditions
// as air speed increases (and no other variables change).
// see R script in repo for more information
// Call:
// lm(formula = eqn_data$delta_ta_c ~ log(eqn_data$vel_mps))
//
// Residuals:
// Min 1Q Median 3Q Max
// -0.26870 -0.05399 0.01651 0.06621 0.08706
//
// Coefficients:
// Estimate Std. Error t value Pr(>|t|)
// (Intercept) 3.083109 0.005652 545.5 <2e-16 ***
// log(eqn_data$vel_mps) 1.551196 0.008971 172.9 <2e-16 ***
// ---
// Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
//
// Residual standard error: 0.07604 on 182 degrees of freedom
// Multiple R-squared: 0.9939, Adjusted R-squared: 0.9939
// F-statistic: 2.99e+04 on 1 and 182 DF, p-value: < 2.2e-16
//
return 3.083109 + 1.551196 * Math.log(airspeed);
}