';
html += '' + fmt(result.density * 100, 0) + '%Air densityTemperature correction from exhaust air temperature.
';
html += '' + fmt(result.eqLength, 0) + 'Equivalent ftDuct length plus fittings and accessories.
';
html += '' + fmt(data.material.factor, 2) + 'xDuct drag' + data.material.name + '
';
html += '' + fmt(result.frictionFactor, 3) + 'Friction factorReynolds ' + fmt0(result.reynolds) + '
';
html += '' + fmt(result.filterLoss, 2) + 'Filter in w.g.' + data.filter.name + '
';
html += '' + fmt(result.capLoss + result.louverLoss, 2) + 'Outlet in w.g.' + data.cap.name + '
';
setHtml('espSpecGrid816', html);
}
function renderResults(data, result) {
var breakdown = '';
setHtml('espLead816', 'Design exhaust is ' + cfmToDisplay(data.cfm) + ' through ' + data.geom.label + ' duct using ' + data.material.name.toLowerCase() + '.');
setText('espBadge816', result.badge);
setText('espTotal816', unitSystem === 'metric' ? fmt0(result.total * INWG_TO_PA) : fmt(result.total, 3));
setText('espTotalUnit816', pressureUnitText('total'));
setText('espFanAvailable816', unitSystem === 'metric' ? fmt0(result.fanSp * INWG_TO_PA) : fmt(result.fanSp, 3));
setText('espFanAvailableUnit816', pressureUnitText('available'));
setText('espMargin816', unitSystem === 'metric' ? fmt0(result.margin * INWG_TO_PA) : fmt(result.margin, 3));
setText('espMarginUnit816', pressureUnitText('after reserve'));
setText('espVelocity816', velocityToDisplay(result.velocity));
setText('espVelocityUnit816', velocityUnitText());
setText('espDuctLoss816', unitSystem === 'metric' ? fmt0(result.ductLoss * INWG_TO_PA) : fmt(result.ductLoss, 3));
setText('espDuctLossUnit816', pressureUnitText('duct/fittings'));
setText('espDelivered816', unitSystem === 'metric' ? fmt0(result.delivered * CFM_TO_M3H) : fmt0(result.delivered));
setText('espDeliveredUnit816', unitSystem === 'metric' ? 'm3/h if fan is short' : 'CFM if fan is short');
setHtml('espStatus816', result.status);
breakdown += row('Airflow and duct geometry', cfmToDisplay(data.cfm) + ' through ' + data.geom.label + ', area ' + fmt(data.geom.areaFt2, 3) + ' sq ft');
breakdown += row('Temperature density correction', fmt(data.tempF, 0) + ' deg F gives ' + fmt(result.density * 100, 1) + '% of standard air density');
breakdown += row('Velocity pressure', 'Velocity ' + fmt0(result.velocity) + ' FPM, VP = (V / 4005)^2 x density = ' + pressureToDisplay(result.vp));
breakdown += row('Straight duct and fittings', lengthToDisplay(data.lengthFt) + ' straight, 90s ' + lengthToDisplay(result.eq90) + ', 45s ' + lengthToDisplay(result.eq45) + ', transitions ' + lengthToDisplay(result.eqTrans));
breakdown += row('Accessory equivalent length', 'Hood, damper, cap, and louver add ' + lengthToDisplay(result.eqAccessory) + '; total equivalent length ' + lengthToDisplay(result.eqLength));
breakdown += row('Duct friction', 'Darcy loss with material factor ' + fmt(data.material.factor, 2) + ' = ' + pressureToDisplay(result.ductLoss));
breakdown += row('Hood or inlet loss', data.hood.name + ' = ' + pressureToDisplay(result.inletLoss));
breakdown += row('Backdraft damper loss', data.damper.name + ' = ' + pressureToDisplay(result.damperLoss));
breakdown += row('Wall or roof cap loss', data.cap.name + ' = ' + pressureToDisplay(result.capLoss));
breakdown += row('Louver or screen loss', data.louver.name + ' = ' + pressureToDisplay(result.louverLoss));
breakdown += row('Filter or media loss', data.filter.name + ' at rated ' + cfmToDisplay(data.filterFlow) + ' = ' + pressureToDisplay(result.filterLoss));
breakdown += row('Component subtotal', 'Inlet + damper + cap + louver + filter = ' + pressureToDisplay(result.componentLoss));
breakdown += row('Total static pressure', 'Duct loss + component subtotal = ' + pressureToDisplay(result.total));
breakdown += row('Reserve requirement', 'Total x ' + fmt(1 + data.reserve, 2) + ' = ' + pressureToDisplay(result.withReserve));
breakdown += row('Fan curve check', pressureToDisplay(result.fanSp) + ' available, reserve margin ' + pressureToDisplay(result.margin));
setHtml('espBreakdown816', breakdown);
renderSpecGrid(data, result);
byId('espResults816').className = 'esp-section esp-results active';
}
function setLabels() {
if (unitSystem === 'metric') {
setText('espCfmLabel816', 'Exhaust airflow (m3/h)');
setText('espDiameterLabel816', 'Round duct diameter (mm)');
setText('espWidthLabel816', 'Rectangular duct width (mm)');
setText('espHeightLabel816', 'Rectangular duct height (mm)');
setText('espLengthLabel816', 'Straight duct length (m)');
setText('espFilterFlowLabel816', 'Filter rated airflow (m3/h)');
setText('espCustomFilterLabel816', 'Custom filter pressure (Pa)');
setText('espCustomInletLabel816', 'Custom inlet pressure (Pa)');
setText('espTemperatureLabel816', 'Exhaust air temperature (deg C)');
setText('espFanStaticLabel816', 'Custom fan static rating (Pa)');
byId('espUnitMetric816').className = 'esp-unit-btn active';
byId('espUnitImperial816').className = 'esp-unit-btn';
} else {
setText('espCfmLabel816', 'Exhaust airflow (CFM)');
setText('espDiameterLabel816', 'Round duct diameter (in)');
setText('espWidthLabel816', 'Rectangular duct width (in)');
setText('espHeightLabel816', 'Rectangular duct height (in)');
setText('espLengthLabel816', 'Straight duct length (ft)');
setText('espFilterFlowLabel816', 'Filter rated airflow (CFM)');
setText('espCustomFilterLabel816', 'Custom filter pressure (in w.g.)');
setText('espCustomInletLabel816', 'Custom inlet pressure (in w.g.)');
setText('espTemperatureLabel816', 'Exhaust air temperature (deg F)');
setText('espFanStaticLabel816', 'Custom fan static rating (in w.g.)');
byId('espUnitImperial816').className = 'esp-unit-btn active';
byId('espUnitMetric816').className = 'esp-unit-btn';
}
}
function convertFields(nextUnit) {
var cfm = readCfm();
var filterFlow = readFilterFlow();
var dia = readInches('espDiameter816', 6);
var width = readInches('espWidth816', 12);
var height = readInches('espHeight816', 8);
var length = readFeet('espLength816', 30);
var customFilter = readPressure('espCustomFilter816', 0.2);
var customInlet = readPressure('espCustomInlet816', 0.08);
var fanStatic = readPressure('espFanStatic816', 0.75);
var tempF = readTempF();
if (nextUnit === 'metric') {
setValue('espCfm816', fmt0(cfm * CFM_TO_M3H).replace(/,/g, ''));
setValue('espFilterFlow816', fmt0(filterFlow * CFM_TO_M3H).replace(/,/g, ''));
setValue('espDiameter816', fmt(dia * IN_TO_MM, 0).replace(/,/g, ''));
setValue('espWidth816', fmt(width * IN_TO_MM, 0).replace(/,/g, ''));
setValue('espHeight816', fmt(height * IN_TO_MM, 0).replace(/,/g, ''));
setValue('espLength816', fmt(length * FT_TO_M, 1).replace(/,/g, ''));
setValue('espCustomFilter816', fmt0(customFilter * INWG_TO_PA).replace(/,/g, ''));
setValue('espCustomInlet816', fmt0(customInlet * INWG_TO_PA).replace(/,/g, ''));
setValue('espFanStatic816', fmt0(fanStatic * INWG_TO_PA).replace(/,/g, ''));
setValue('espTemperature816', fmt((tempF - 32) * 5 / 9, 0).replace(/,/g, ''));
} else {
setValue('espCfm816', fmt0(cfm).replace(/,/g, ''));
setValue('espFilterFlow816', fmt0(filterFlow).replace(/,/g, ''));
setValue('espDiameter816', fmt(dia, 1).replace(/,/g, ''));
setValue('espWidth816', fmt(width, 1).replace(/,/g, ''));
setValue('espHeight816', fmt(height, 1).replace(/,/g, ''));
setValue('espLength816', fmt(length, 1).replace(/,/g, ''));
setValue('espCustomFilter816', fmt(customFilter, 2).replace(/,/g, ''));
setValue('espCustomInlet816', fmt(customInlet, 2).replace(/,/g, ''));
setValue('espFanStatic816', fmt(fanStatic, 2).replace(/,/g, ''));
setValue('espTemperature816', fmt(tempF, 0).replace(/,/g, ''));
}
}
window.espToggleShape816 = function() {
var shape = byId('espShape816').value;
byId('espRoundField816').style.display = shape === 'round' ? 'block' : 'none';
byId('espWidthField816').style.display = shape === 'rect' ? 'block' : 'none';
byId('espHeightField816').style.display = shape === 'rect' ? 'block' : 'none';
window.espCalculate816();
};
window.espSetUnits816 = function(nextUnit) {
if (nextUnit === unitSystem) {
return;
}
convertFields(nextUnit);
unitSystem = nextUnit;
setLabels();
window.espCalculate816();
};
window.espApplyPreset816 = function(key) {
var p = presets[key] || presets.shopFume;
unitSystem = 'imperial';
setLabels();
setValue('espFanPreset816', p.fan);
setValue('espCfm816', p.cfm);
setValue('espShape816', p.shape);
setValue('espDiameter816', p.dia);
setValue('espWidth816', p.width);
setValue('espHeight816', p.height);
setValue('espDuctMaterial816', p.material);
setValue('espLength816', p.length);
setValue('espElbows90816', p.e90);
setValue('espElbows45816', p.e45);
setValue('espTransitions816', p.trans);
setValue('espHood816', p.hood);
setValue('espDamper816', p.damper);
setValue('espCap816', p.cap);
setValue('espLouver816', p.louver);
setValue('espFilter816', p.filter);
setValue('espFilterFlow816', p.filterFlow);
setValue('espCustomFilter816', p.customFilter);
setValue('espCustomInlet816', p.customInlet);
setValue('espTemperature816', p.temp);
setValue('espFanStatic816', p.fanStatic);
setValue('espReserve816', p.reserve);
window.espToggleShape816();
window.espCalculate816();
};
window.espCalculate816 = function() {
var data = collect();
var result = solve(data);
renderResults(data, result);
};
function attachEvents() {
var ids = ['espCfm816','espFanPreset816','espShape816','espDiameter816','espWidth816','espHeight816','espDuctMaterial816','espLength816','espElbows90816','espElbows45816','espTransitions816','espHood816','espDamper816','espCap816','espLouver816','espFilter816','espFilterFlow816','espCustomFilter816','espCustomInlet816','espTemperature816','espFanStatic816','espReserve816'];
var i;
for (i = 0; i < ids.length; i++) {
if (byId(ids[i])) {
byId(ids[i]).addEventListener('input', function() { window.espCalculate816(); });
byId(ids[i]).addEventListener('change', function() { window.espCalculate816(); });
}
}
}
attachEvents();
setLabels();
window.espToggleShape816();
window.espApplyPreset816('shopFume');
})();
At zero resistance in perfect conditions, fans are rated for how much air they can move. In the real world there is resistance, resistance from everything working against the air flow. The filter resists. The bend resists. The roof cap resists. And all these forces combine to cut down on the amount of air that actualy moves into the outside. Once the combined static pressure overwhelms the capacity of the fan, the amount of air flowing will be far lower.
The system includes all of these components. For a correct reading you need to include them all. Friction is created by straight duct based off its size (diameter), length and smoothness of material. Rigid metal duct is less restrictive than flexible duct. Any sag in flexible duct make it even more restrictive. Transitions, elbows and other fittings adds equal length to the run. Inlets and hoods produce entrance losses. Louvers and roof caps create exit losses. Summing up these gives you the total pressure that the fan must overcome.
Understanding Fan Resistance
The resistance of filters changes as they get dirty. The cleaner the filter, the lower its resistance. The dirtier the filter, the higher its resistance. When sizing your system, assume it will be operating at max resistance. That way, the fan still operates with a full filter. Resistance also depends on temperature. Hot air is less dense than cold air, so the systems resistance drops a bit. If you input the exhaust temperature, the calculator applies the correction automatically.
As static pressure increases, most fans give up airflow. Fan performance curves show this inverse relationship clearly. Choose the right fan for your systems pressure demands using the reference tables as a guide. Higher pressure systems require inline fans versus simple wall fans. A propeller fan becomes very inefficient under high pressure conditions. Choose a fan with enough spare capacity to handle the calculated pressure and still deliver the airflow you need.
These mistakes lead to poor performance. Homeowners pick a fan purely on sound level, while ignoring the impact of fittings and length of ducts. Result: Moisture issues and poor ventilation. Commercial guys might oversize fans for there applications. But each fitting adds resistance, which lowers air flow. With this calculator, youll see the loss of air before installation.
To reduce resistance (static pressure), you can improve the duct design. Increasing duct diameter often drops resistance more then removing a fitting. The smoother the material, the less turbulent it is. Reducing bends in the ducts minimizes losses at fittings. Tightening up loose flexible ducts can reduce internal friction. Lighter dampers on ducted systems replace heavier dampers that adds to resistance. Making these changes can recover lost airflow without needing to replace the fan.

-
Hi, I am Thomas Martinez, the owner of ToolCroze.com! As a passionate DIY enthusiast and a firm believer in the power of quality tools, I created this platform to share my knowledge and experiences with fellow craftsmen and handywomen alike.
View all posts