diff --git a/bifacial_radiance/module.py b/bifacial_radiance/module.py index 32fccfa9..b15a9689 100644 --- a/bifacial_radiance/module.py +++ b/bifacial_radiance/module.py @@ -29,10 +29,11 @@ class ModuleObj(SuperClass): def __repr__(self): return str(type(self)) + ' : ' + str(self.getDataDict()) - def __init__(self, name=None, x=None, y=None, z=None, bifi=1, modulefile=None, - text=None, customtext='', xgap=0.01, ygap=0.0, zgap=0.1, - numpanels=1, rewriteModulefile=True, cellModule=None, - glass=False, modulematerial='black', tubeParams=None, + def __init__(self, name=None, x=None, y=None, z=None, bifi=1, + modulefile=None, text=None, customtext='', xgap=0.01, + ygap=0.0, zgap=0.1, numpanels=1, rewriteModulefile=True, + cellModule=None, glass=False, glassEdge=0.01, + modulematerial='black', tubeParams=None, frameParams=None, omegaParams=None, hpc=False): """ Add module details to the .JSON module config file module.json @@ -40,7 +41,7 @@ def __init__(self, name=None, x=None, y=None, z=None, bifi=1, modulefile=None, Module definitions assume that the module .rad file is defined with zero tilt, centered along the x-axis and y-axis for the center of rotation of the module (+X/2, -X/2, +Y/2, -Y/2 on each side). - Tip: to define a module that is in 'portrait' mode, y > x. + Tip: to define a module that is in 'portrait' mode, y > x. Parameters ------------ @@ -50,11 +51,16 @@ def __init__(self, name=None, x=None, y=None, z=None, bifi=1, modulefile=None, Width of module along the axis of the torque tube or rack. (meters) y : numeric Length of module (meters) + z : numeric + Thickness of the module (meters), or of the glass if glass = True, + in which case absorber thickness will be 0.001 and glass whatever + thickness is given, with absorber in the middle of the glass. bifi : numeric - Bifaciality of the panel (not currently used). Between 0 (monofacial) - and 1, default 1. + Bifaciality of the panel (not currently used). Between 0 + (monofacial) and 1, default 1. modulefile : str - Existing radfile location in \objects. Otherwise a default value is used + Existing radfile location in \\objects. Otherwise a default value + is used text : str Text used in the radfile to generate the module. Manually passing this value will overwrite module definition @@ -66,41 +72,47 @@ def __init__(self, name=None, x=None, y=None, z=None, bifi=1, modulefile=None, Default True. Will rewrite module file each time makeModule is run. numpanels : int Number of modules arrayed in the Y-direction. e.g. - 1-up or 2-up, etc. (supports any number for carport/Mesa simulations) + 1-up or 2-up, etc. (supports any number for carport/Mesa + simulations) xgap : float Panel space in X direction. Separation between modules in a row. ygap : float Gap between modules arrayed in the Y-direction if any. zgap : float - Distance behind the modules in the z-direction to the edge of the tube (m) + Distance behind the modules in the z-direction to the edge of the + torquetube (m) glass : bool Add 5mm front and back glass to the module (glass/glass). Warning: glass increases the analysis variability. Recommend setting accuracy='high' in AnalysisObj.analysis() + glassEdge: float + Difference in space between module size and absorber part of the + module (or if cell-level module, full cell-level module size; + value will be applied as extra glass 1/2 to each side on x and y. cellModule : dict Dictionary with input parameters for creating a cell-level module. Shortcut for ModuleObj.addCellModule() tubeParams : dict - Dictionary with input parameters for creating a torque tube as part of the - module. Shortcut for ModuleObj.addTorquetube() + Dictionary with input parameters for creating a torque tube as + part of the module. Shortcut for ModuleObj.addTorquetube() frameParams : dict - Dictionary with input parameters for creating a frame as part of the module. - Shortcut for ModuleObj.addFrame() + Dictionary with input parameters for creating a frame as part of + the module. Shortcut for ModuleObj.addFrame() omegaParams : dict - Dictionary with input parameters for creating a omega or module support - structure. Shortcut for ModuleObj.addOmega() + Dictionary with input parameters for creating a omega or module + support structure. Shortcut for ModuleObj.addOmega() hpc : bool (default False) - Set up module in HPC mode. Namely turn off read/write to module.json - and just pass along the details in the module object. Note that - calling e.g. addTorquetube() after this will tend to write to the - module.json so pass all geometry parameters at once in to makeModule - for best response. - - + Set up module in HPC mode. Namely turn off read/write to + module.json and just pass along the details in the module object. + Note that calling e.g. addTorquetube() after this will tend to + write to the module.json so pass all geometry parameters at once + in to makeModule for best response. + + '""" - self.keys = ['x', 'y', 'z', 'modulematerial', 'scenex','sceney', - 'scenez','numpanels','bifi','text','modulefile', 'glass', - 'offsetfromaxis','xgap','ygap','zgap' ] + self.keys = ['x', 'y', 'z', 'modulematerial', 'scenex', 'sceney', + 'scenez', 'numpanels', 'bifi', 'text', 'modulefile', 'glass', + 'glassEdge', 'offsetfromaxis', 'xgap', 'ygap', 'zgap' ] #replace whitespace with underlines. what about \n and other weird characters? # TODO: Address above comment? @@ -230,6 +242,8 @@ def readModule(self, name=None): moduleDict['modulematerial'] = 'black' if not 'glass' in moduleDict: moduleDict['glass'] = False + if not 'glassEdge' in moduleDict: + moduleDict['glassEdge'] = 0.01 if not 'z' in moduleDict: moduleDict['z'] = 0.02 # set ModuleObj attributes from moduleDict @@ -516,34 +530,21 @@ def _makeModuleFromDict(self, x=None, y=None, z=None, xgap=None, ygap=None, self.offsetfromaxis = np.round(zgap + diam/2.0,8) if hasattr(self, 'frame'): self.offsetfromaxis = self.offsetfromaxis + self.frame.frame_z - # TODO: make sure the above is consistent with old version below - """ - if torquetube: - diam = torquetube['diameter'] - torquetube_bool = torquetube['bool'] - else: - diam=0 - torquetube_bool = False - if self.axisofrotationTorqueTube == True: - if torquetube_bool == True: - self.offsetfromaxis = np.round(zgap + diam/2.0,8) - else: - self.offsetfromaxis = zgap - if hasattr(self, 'frame'): - self.offsetfromaxis = self.offsetfromaxis + self.frame.frame_z - """ + # Adding the option to replace the module thickess if self.glass: - zglass = 0.01 print("\nWarning: module glass increases analysis variability. " "Recommend setting `accuracy='high'` in AnalysisObj.analysis().\n") - else: - zglass = 0.0 - - if z is None: - if self.glass: + if z is None: + zglass = 0.01 z = 0.001 else: + zglass = z + z = 0.001 + + else: # no glass + zglass = 0.0 + if z is None: z = 0.020 self.z = z @@ -600,31 +601,9 @@ def _makeModuleFromDict(self, x=None, y=None, z=None, xgap=None, ygap=None, offsetfromaxis=self.offsetfromaxis) if omega2omega_x > self.scenex: self.scenex = omega2omega_x - - # TODO: is the above line better than below? - # I think this causes it's own set of problems, need to check. - """ - if self.scenex