def execute(self): ni = len(self.rotor_loads_cid) self.freq_factor = [] for factor in self.freq_factor_cid: if factor.freq_factor: self.freq_factor.append(factor.freq_factor) # rotor loads for name in self.rotor_loads.list_vars(): try: value = np.array([getattr(self.rotor_loads_cid[i], name)[-1] for i in range(ni)]) setattr(self.rotor_loads, name, value) except: pass # hub loads for name in self.hub_loads.list_vars(): try: value = np.array([getattr(self.hub_loads_cid[i], name)[-1] for i in range(ni)]) setattr(self.hub_loads, name, value) except: pass # operational data for name in self.oper.list_vars(): try: value = np.array([getattr(self.oper_cid[i], name)[-1] for i in range(ni)]) setattr(self.oper, name, value) except: pass # blade_loads self.blade_loads = DistributedLoadsArrayVT() for i, case in enumerate(self.blade_loads_cid): try: self.blade_loads.add('load%i'%i, VarTree(case.loads_array[-1], iotype='out')) self.blade_loads.loads_array.append('load%i'%i) except: self._logger.warning('failed setting blade_loads.load%i' % i) # blade_disps tip_pos = [] tip_rot = [] self.blade_disps = BeamDisplacementsArrayVT() for i, case in enumerate(self.blade_disps_cid): try: self.blade_disps.add('disp%i'%i, VarTree(case.disps_array[-1], iotype='out')) tip_pos.append(case.disps_array[-1].main_axis[-1, :]) tip_rot.append(case.tip_rot[-1]) except: self._logger.warning('failed setting blade_disps.disp%i' % i) self.blade_disps.tip_pos = np.array(tip_pos) self.blade_disps.tip_rot = np.array(tip_rot)
class AeroElasticSolverCaseIter(Component): """ Class that iterates over a list of cases computed using a AeroElasticSolverBase class """ wt = VarTree(AeroelasticHAWTVT(), iotype='in', desc='Turbine definition') inflow = VarTree(TurbineEnvironmentCaseListVT(), iotype='in', desc='Inflow conditions') oper = VarTree(RotorOperationalDataArray(), iotype='out', desc='Operational data') rotor_loads = VarTree(RotorLoadsArrayVT(), iotype='out', desc='Rotor torque, power, and thrust') blade_loads = VarTree(DistributedLoadsArrayVT(), iotype='out', desc='Spanwise load distributions') blade_disps = VarTree(BeamDisplacementsArrayVT(), iotype='out', desc='Blade deflections and rotations')
class H2SCIDPostProcess(Component): """ Component to gather the CID outputs from lists to the corresponding variabletree """ blade_loads_cid = List(iotype='in', desc='Blade distributed loads') blade_disps_cid = List(iotype='in', desc='Blade axis displacements') hub_loads_cid = List(iotype='in', desc='Hub Loads') rotor_loads_cid = List(iotype='in', desc='Rotor Loads') oper_cid = List(iotype='in', desc='Rotor Loads') freq_factor_cid = List(iotype='in') blade_loads = VarTree(DistributedLoadsArrayVT(), iotype='out', desc='Blade distributed loads') blade_disps = VarTree(BeamDisplacementsArrayVT(), iotype='out', desc='Blade axis displacements') rotor_loads = VarTree(RotorLoadsArrayVT(), iotype='out', desc='Rotor Loads') hub_loads = VarTree(PointLoadArray(), iotype='out', desc='Hub Loads') oper = VarTree(RotorOperationalDataArray(), iotype='out', desc='Rotor operational data') freq_factor = List(iotype='out') def execute(self): ni = len(self.rotor_loads_cid) self.freq_factor = [] for factor in self.freq_factor_cid: if factor.freq_factor: self.freq_factor.append(factor.freq_factor) # rotor loads for name in self.rotor_loads.list_vars(): try: value = np.array([getattr(self.rotor_loads_cid[i], name)[-1] for i in range(ni)]) setattr(self.rotor_loads, name, value) except: pass # hub loads for name in self.hub_loads.list_vars(): try: value = np.array([getattr(self.hub_loads_cid[i], name)[-1] for i in range(ni)]) setattr(self.hub_loads, name, value) except: pass # operational data for name in self.oper.list_vars(): try: value = np.array([getattr(self.oper_cid[i], name)[-1] for i in range(ni)]) setattr(self.oper, name, value) except: pass # blade_loads self.blade_loads = DistributedLoadsArrayVT() for i, case in enumerate(self.blade_loads_cid): try: self.blade_loads.add('load%i'%i, VarTree(case.loads_array[-1], iotype='out')) self.blade_loads.loads_array.append('load%i'%i) except: self._logger.warning('failed setting blade_loads.load%i' % i) # blade_disps tip_pos = [] tip_rot = [] self.blade_disps = BeamDisplacementsArrayVT() for i, case in enumerate(self.blade_disps_cid): try: self.blade_disps.add('disp%i'%i, VarTree(case.disps_array[-1], iotype='out')) tip_pos.append(case.disps_array[-1].main_axis[-1, :]) tip_rot.append(case.tip_rot[-1]) except: self._logger.warning('failed setting blade_disps.disp%i' % i) self.blade_disps.tip_pos = np.array(tip_pos) self.blade_disps.tip_rot = np.array(tip_rot)
class HAWC2SDistributed(Assembly): """ Assembly for running HAWC2S in parallel using a CaseIteratorDriver parameters ----------- wsp: array-like array of wind speeds. pitch and RPM will either be interpolated from the opt file or computed on the fly htc_master_file: string name of HAWC2S master file. For now the master file HAS TO be named hawc2s_master.htc !!! hawc2bin: string absolute path to HAWC2S executable optional parameters: -------------------- bladegeom: BladeGeometryVT IDOtools blade geometry VarTree beamprops: BeamStructureVT IDOtools blade beam structural properties radius: float blade length """ # For now the master file HAS TO be named hawc2s_master.htc !!! htc_master_file = Str(iotype='in') model_name = Str('hawc2s_model', iotype='in') hawc2bin = Str(iotype='in') designTSR = Float(7.5, iotype='in') vartrees_out = VarTree(HAWC2VarTrees(), iotype='out') controller = VarTree(DTUBasicControllerVT(), iotype='in') wt = VarTree(AeroelasticHAWTVT(), iotype='in', desc='Turbine definition') inflow = VarTree(TurbineEnvironmentCaseListVT(), iotype='in', desc='Inflow conditions') case_list = Dict(iotype='in', desc='Dictionary of TurbineEnvironmentVT case inputs') oper = VarTree(RotorOperationalDataArray(), iotype='out', desc='Operational data') rotor_loads = VarTree(RotorLoadsArrayVT(), iotype='out', desc='Rotor torque, power, and thrust') blade_loads = VarTree(DistributedLoadsArrayVT(), iotype='out', desc='Spanwise load distributions') blade_disps = VarTree(BeamDisplacementsArrayVT(), iotype='out', desc='Blade deflections and rotations') def configure_hawc2s(self, htc_master_file=''): # Generate simple CID cases self.add('casegen', MakeCases()) self.driver.workflow.add('casegen') self.create_passthrough('casegen.user_cases') self.htc_master_file = htc_master_file if not self.htc_master_file == '': # Read Input file for data initialization self.reader = HAWC2InputReader() self.reader.htc_master_file = self.htc_master_file self.reader.execute() self.casegen.vartrees = self.reader.vartrees.copy() self.vartrees_out = self.reader.vartrees.copy() # connect FUSED-Wind inflow variables used by HAWC2S self.connect('inflow.vhub', 'casegen.wsp') self.connect('inflow.density[0]', 'casegen.vartrees.wind.density') self.connect('designTSR', 'casegen.vartrees.dlls.risoe_controller.dll_init.designTSR') self.connect('designTSR', 'vartrees_out.dlls.risoe_controller.dll_init.designTSR') # add case iterator with HAWC2 wrapper self.add('h2', HAWC2SCaseIter()) self.driver.workflow.add('h2') self.connect('model_name', 'h2.model_name') self.connect('hawc2bin', 'h2.hawc2bin') self.connect('casegen.cases', 'h2.vartrees') self.connect('casegen.case_ids', 'h2.case_ids') self.create_passthrough('h2.sequential') self.create_passthrough('h2.set_tsr_flag') self.h2.output.commands = self.reader.vartrees.h2s.commands # postprocess CID cases self.add('h2post', H2SCIDPostProcess()) self.driver.workflow.add('h2post') self.connect('h2.rotor_loads', 'h2post.rotor_loads_cid') self.connect('h2.blade_loads', 'h2post.blade_loads_cid') self.connect('h2.hub_loads', 'h2post.hub_loads_cid') self.connect('h2.blade_disps', 'h2post.blade_disps_cid') self.connect('h2.oper', 'h2post.oper_cid') self.connect('h2post.rotor_loads', 'rotor_loads') self.connect('h2post.blade_loads', 'blade_loads') self.connect('h2post.blade_disps', 'blade_disps') self.connect('h2post.oper', 'oper') self.create_passthrough('h2post.hub_loads') # taken out for now ... # self.add('h2interp', H2SResInterp()) # self.driver.workflow.add('h2interp') # self.connect('h2post.rotor_loads', 'h2interp.rotor_loads') # self.connect('h2post.blade_loads', 'h2interp.blade_loads') # self.connect('h2post.hub_loads', 'h2interp.hub_loads') # self.connect('h2post.blade_disps', 'h2interp.blade_disps') # self.connect('h2post.oper', 'h2interp.oper') # self.create_passthrough('h2interp.rotor_loads_i') # self.create_passthrough('h2interp.blade_loads_i') # self.create_passthrough('h2interp.hub_loads_i') # self.create_passthrough('h2interp.blade_disps_i') # self.create_passthrough('h2interp.oper_i') self.log_level = logging.DEBUG def configure_geometry(self): self.add('geom', HAWC2GeometryBuilder()) self.driver.workflow.add('geom') self.create_passthrough('geom.bladegeom', alias='pfIn') # self.create_passthrough('geom.blade_length') self.connect('wt.blade_length', 'geom.blade_length') self.create_passthrough('geom.interp_from_htc', alias='planform_interp_from_htc') self.create_passthrough('geom.blade_ni_span') self.connect('geom.blade_ae', 'casegen.vartrees.blade_ae') self.connect('geom.blade_ae', 'vartrees_out.blade_ae') # this should be changed self.geom.c12axis_init = self.reader.vartrees.blade_ae.c12axis.copy() def configure_freq_placement(self, freq_type='ae'): self.h2.configure_freq_placement_cid(freq_type=freq_type) self.connect('h2.freq_factor', 'h2post.freq_factor_cid') self.create_passthrough('h2post.freq_factor') self.create_passthrough('h2.mode_freq') self.create_passthrough('h2.mode_damp') self.create_passthrough('h2.mode_target_freq') self.create_passthrough('h2.mode_target_damp') def configure_controller_tuning(self): self.controller = self.reader.vartrees.dlls.risoe_controller.dll_init.copy() for att in self.controller.list_vars(): if att == 'designTSR': continue self.connect('controller.'+att, 'casegen.vartrees.dlls.risoe_controller.dll_init.'+att) self.connect('controller.'+att, 'vartrees_out.dlls.risoe_controller.dll_init.'+att) def configure_structure(self): self.add('beam_st', HAWC2BeamStructureIDO()) self.driver.workflow.add('beam_st') self.connect('wt.blade1.beam_structure', 'beam_st.beam_structure') self.connect('beam_st.h2beam_structure', 'casegen.vartrees.blade_structure') self.connect('beam_st.h2beam_structure', 'vartrees_out.blade_structure') def _pre_execute(self): super(HAWC2SDistributed, self)._pre_execute() self.tt = time.time() def _post_execute(self): super(HAWC2SDistributed, self)._post_execute() t = time.time() - self.tt self._logger.info('HAWC2S time: %f' % t)