Source code for enex_analysis.components.fan

from dataclasses import dataclass

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

try:
    import dartwork_mpl as dm
except ImportError:
    dm = None

from .. import calc_util as cu
from ..enex_functions import cubic_function, quartic_function


[docs] @dataclass class Fan: def __post_init__(self): # Fan reference: https://www.krugerfan.com/public/uploads/KATCAT006.pdf self.fan1 = { "flow rate": [ 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, ], # [m3/s] "pressure": [ 140, 136, 137, 147, 163, 178, 182, 190, 198, 181, ], # [Pa] "efficiency": [ 0.43, 0.48, 0.52, 0.55, 0.60, 0.65, 0.68, 0.66, 0.63, 0.52, ], # [-] "fan type": "centrifugal", } # self.fan2 = { # 'flow rate' : [0.5, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0], # [m3/s] # 'pressure' : [137, 138, 143, 168, 182, 191, 198, 200, 201, 170, 160], # [Pa] # 'efficiency' : [0.45, 0.49, 0.57, 0.62, 0.67, 0.69, 0.68, 0.67, 0.63, 0.40, 0.48], # [-] # 'fan type' : 'centrifugal', # } self.fan2 = { "flow rate": [ 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, ], # [m3/s] "pressure": [ 244, 241, 239, 242, 260, 290, 305, 340, 345, 350, 320, 230, ], # [Pa] "efficiency": [ 0.44, 0.47, 0.50, 0.52, 0.56, 0.58, 0.63, 0.67, 0.65, 0.60, 0.55, 0.31, ], # [-] "fan type": "centrifugal", } self.fan3 = { # https://ventilatorry.ru/downloads/ebmpapst/datasheet/w3g710-go81-01-en-datasheet-ebmpapst.pdf "flow rate": [ 0 / cu.h2s, 6245 / cu.h2s, 8330 / cu.h2s, 10410 / cu.h2s, 12610 / cu.h2s, ], # [m3/s] "power": [0, 100, 238, 465, 827], # [-] "fan type": "axial", } self.fan_list = [self.fan1, self.fan2, self.fan3]
[docs] def get_efficiency(self, fan, dV_fan): if "efficiency" not in fan: raise ValueError("Selected fan does not have efficiency data.") self.efficiency_coeffs, _ = curve_fit( cubic_function, fan["flow rate"], fan["efficiency"] ) eff = cubic_function(dV_fan, *self.efficiency_coeffs) return eff
[docs] def get_pressure(self, fan, dV_fan): if "pressure" not in fan: raise ValueError("Selected fan does not have pressure data.") self.pressure_coeffs, _ = curve_fit( cubic_function, fan["flow rate"], fan["pressure"] ) pressure = cubic_function(dV_fan, *self.pressure_coeffs) return pressure
[docs] def get_power(self, fan, dV_fan): if "efficiency" in fan and "pressure" in fan: eff = self.get_efficiency(fan, dV_fan) pressure = self.get_pressure(fan, dV_fan) power = pressure * dV_fan / eff elif "power" in fan: self.power_coeffs, _ = curve_fit( quartic_function, fan["flow rate"], fan["power"] ) power = quartic_function(dV_fan, *self.power_coeffs) else: raise ValueError( "Fan must have either ('efficiency' + 'pressure') " "or 'power' data to compute power." ) return power
[docs] def show_graph(self): """Plot flow-rate vs pressure and efficiency curves for all fans. Raw datapoints are shown as dots; cubic curve fits as lines. Raises ------ ImportError If ``dartwork_mpl`` is not installed. """ if dm is None: raise ImportError( "dartwork_mpl is required for show_graph(). " "Install it with: pip install dartwork-mpl" ) fig, axes = plt.subplots(1, 2, figsize=(dm.cm2in(15), dm.cm2in(5))) # 그래프 색상 설정 scatter_colors = ["dm.red3", "dm.blue3", "dm.green3", "dm.orange3"] plot_colors = ["dm.red6", "dm.blue6", "dm.green6", "dm.orange6"] data_pairs = [ ("pressure", "Pressure [Pa]", "Flow Rate vs Pressure"), ("efficiency", "Efficiency [-]", "Flow Rate vs Efficiency"), ] for ax, (key, ylabel, title) in zip(axes, data_pairs, strict=False): print(f"\n{'=' * 10} {title} {'=' * 10}") for i, fan in enumerate(self.fan_list): # 원본 데이터 (dot 형태) ax.scatter( fan["flow rate"], fan[key], label=f"Fan {i + 1} Data", color=scatter_colors[i], s=2, ) # 곡선 피팅 수행 coeffs, _ = curve_fit( cubic_function, fan["flow rate"], fan[key] ) flow_range = np.linspace( min(fan["flow rate"]), max(fan["flow rate"]), 100 ) fitted_values = cubic_function(flow_range, *coeffs) # 피팅된 곡선 (line 형태) ax.plot( flow_range, fitted_values, label=f"Fan {i + 1} Fit", color=plot_colors[i], linestyle="-", ) a, b, c, d = coeffs print( f"fan {i + 1}: {a:.4f}x³ + {b:.4f}x² + {c:.4f}x + {d:.4f}" ) ax.set_xlabel("Flow Rate [m$^3$/s]", fontsize=dm.fs(0.5)) ax.set_ylabel(ylabel, fontsize=dm.fs(0.5)) ax.set_title(title, fontsize=dm.fs(0.5)) ax.legend() plt.subplots_adjust(wspace=0.3) dm.simple_layout( fig, margins=(0.05, 0.05, 0.05, 0.05), bbox=(0, 1, 0, 1), verbose=False, ) dm.save_and_show(fig)