first commit
This commit is contained in:
93
helix/calculators/pressure_coefficient_calculator.py
Normal file
93
helix/calculators/pressure_coefficient_calculator.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from math import sqrt, log
|
||||
import math
|
||||
|
||||
from helix.constants.global_constants import parapet_coefficients, parapet_factor_max
|
||||
from numpy import array
|
||||
from numpy.ma import maximum
|
||||
|
||||
from helix.constants.panel_type import PanelType
|
||||
|
||||
|
||||
class PressureCoefficientCalculator(object):
|
||||
def __init__(self, user_values):
|
||||
self.values = user_values
|
||||
self.system_constants = self.values.system_type().system_constants()
|
||||
self.module_constants = self.values.module_system_constants()
|
||||
|
||||
def c_p_matrix(self, L_B):
|
||||
parapet = self.parapet_factor()
|
||||
return self.compute_c_p_matrix(L_B, parapet)
|
||||
|
||||
def L_B(self):
|
||||
""" Building scaling factor """
|
||||
height = max(15, self.values.building_height())
|
||||
|
||||
length = self.values.building_length()
|
||||
width = self.values.building_width()
|
||||
|
||||
longest_side = max(width, length)
|
||||
|
||||
return min(height, 0.4 * sqrt(height * max(1, longest_side)))
|
||||
|
||||
def minimum_array_size(self, L_B):
|
||||
panel_area = self.module_constants.panel_area
|
||||
module_count = self.system_constants.module_count
|
||||
minimum_array_size = []
|
||||
for minimum_A_n in self.minimum_A_n(L_B):
|
||||
if minimum_A_n is None:
|
||||
value = 6
|
||||
else:
|
||||
value = int(math.ceil((minimum_A_n * L_B ** 2) / (panel_area * 1000) / module_count))
|
||||
minimum_array_size.append(value)
|
||||
return minimum_array_size
|
||||
|
||||
# Normalized area, scales the tributary area by the building scaling factor and panel area
|
||||
def A_n(self, L_B):
|
||||
return self.module_constants.tributary_area * (self.module_constants.panel_area * 1000. / L_B ** 2)
|
||||
|
||||
def compute_c_p_matrix(self, L_B, parapet):
|
||||
A_n = self.A_n(L_B)
|
||||
wind_zones = self.system_constants.wind_zones
|
||||
return array([self.c_p_row(A_n, wind_zone, parapet) for wind_zone in wind_zones])
|
||||
|
||||
def c_p_row(self, A_n_row, wind_zone, parapet_factor):
|
||||
c_p_lower_bound = self.module_constants.c_p_lower_bound()
|
||||
|
||||
if wind_zone == self.system_constants.wind_zones[-1]:
|
||||
return c_p_lower_bound
|
||||
computed_row = []
|
||||
for index, A_n in enumerate(A_n_row):
|
||||
edge_factor = self.module_constants.edge_factor(wind_zone, PanelType.from_index(index))
|
||||
computed_row.append(self.c_p(A_n, wind_zone, parapet_factor, edge_factor))
|
||||
|
||||
return maximum(array(computed_row), c_p_lower_bound)
|
||||
|
||||
def c_p(self, A_n, wind_zone, parapet_factor, edge_factor):
|
||||
c0, c1 = self.module_constants.c_p_constants(A_n, wind_zone)
|
||||
return max(0., c0 * log(A_n) + c1) * parapet_factor * edge_factor
|
||||
|
||||
def parapet_factor(self):
|
||||
height = max(15, self.values.building_height())
|
||||
parapet_height = max(0, self.values.building_parapet_height())
|
||||
|
||||
factor = parapet_height / height
|
||||
c0, c1 = parapet_coefficients
|
||||
return min(parapet_factor_max, c0 + c1 * factor)
|
||||
|
||||
def ideal_subarray_average_uplift_c_p(self, L_B):
|
||||
c_p_matrix = self.compute_c_p_matrix(L_B, 1)
|
||||
return [self.module_constants.weighted_average_c_p(c, n, e, m) for c, n, e, m in c_p_matrix]
|
||||
|
||||
def minimum_A_n(self, L_B):
|
||||
uplift_c_p = self.ideal_subarray_average_uplift_c_p(L_B)
|
||||
minimum_A_n = []
|
||||
for idx, wind_zone in enumerate(self.system_constants.wind_zones):
|
||||
wind_zone_uplift = uplift_c_p[idx]
|
||||
coefficients = self.module_constants.minimum_a_n_coefficients(wind_zone_uplift, wind_zone)
|
||||
if not coefficients:
|
||||
minimum_A_n.append(None)
|
||||
continue
|
||||
|
||||
value = math.exp((coefficients[0] - wind_zone_uplift) / coefficients[1])
|
||||
minimum_A_n.append(value)
|
||||
return minimum_A_n
|
||||
Reference in New Issue
Block a user