def __init__(self, name, becas_hash, config, input_folder, s): """ parameters ---------- config: dict dictionary with inputs to BECASWrapper input_folder: list list with becas input folders s: array spanwise location of the cross-section """ super(BECASCSStructureKM, self).__init__() self.basedir = os.getcwd() self.becas_hash = becas_hash # add outputs self.add_output('%s:k_matrix' % name, shape=(6, 6)) self.add_output('%s:m_matrix' % name, shape=(6, 6)) self.workdir = 'becas_%s_%i' % (name, self.becas_hash) # not so nice hack to ensure unique directory names when # running parallel FD # the hash is passed to downstream BECASStressRecovery class self.add_output(name + ':hash', float(self.becas_hash)) config['BECASWrapper']['path_input'] = os.path.join( self.basedir, input_folder) self.becas = BECASWrapper(s, **config['BECASWrapper']) self.s = s
def becas_configure_stress_recovery(kls): # uncomment to keep Sim-* directories # import os # os.environ['OPENMDAO_KEEPDIRS'] = '1' kls.add('blade_strength', BECASStressRecovery()) kls.driver.workflow.add('blade_strength') cls = kls.blade_strength cls.add('cid', CaseIteratorDriver()) cls.driver.workflow.add('cid') cls.create_passthrough('cid.sequential') cls.sequential = False # add becas cls.add('becas', BECASWrapper()) cls.cid.workflow.add('becas') cls.becas.exec_mode = 'octave' cls.becas.analysis_mode = 'stress_recovery' cls.create_passthrough('becas.path_becas') # add parameters and responses cls.cid.add_parameter('becas.load_cases') cls.cid.add_response('becas.max_failure') cls.cid.add_response('becas.max_failure_ks') cls.connect('load_cases', 'cid.case_inputs.becas.load_cases') # cls.create_passthrough('cid.case_inputs.becas.load_cases') # cls.cid.add_response('becas.stress') # cls.cid.add_response('becas.strain') # add postprocessing components cls.add('process_failure', ProcessFailures()) cls.add('process_failure_ks', ProcessFailures()) cls.driver.workflow.add(['process_failure', 'process_failure_ks']) cls.connect('cid.case_outputs.becas.max_failure', 'process_failure.failureIn') cls.connect('cid.case_outputs.becas.max_failure_ks', 'process_failure_ks.failureIn') cls.connect('process_failure.max_failure', 'failure') cls.create_passthrough('process_failure_ks.max_failure', alias='failure_ks') cls.log_level = logging.DEBUG cls.becas.log_level = logging.DEBUG
def __init__(self, name, config, s, ncases): super(BECASCSStressRecovery, self).__init__() self.name = name self.s = s self.basedir = os.getcwd() # not so nice hack to ensure unique directory names when # running parallel FD # the hash is generated in the upstream BECASBeamStructure class self.add_param(name + ':hash', 0.) self.add_param('load_cases_%s' % name, np.zeros((ncases, 6))) self.add_output('blade_failure_index_%s' % name, np.zeros(ncases)) self.becas = BECASWrapper(s, **config['BECASWrapper']) self.becas.analysis_mode = 'stress_recovery'
def becas_configure_stiffness_calc(kls): # uncomment to keep Sim-* directories # import os # os.environ['OPENMDAO_KEEPDIRS'] = '1' kls.add('blade_beam_st', BECASBeamStructure()) kls.driver.workflow.add('blade_beam_st') cls = kls.blade_beam_st cls.add('cid', CaseIteratorDriver()) cls.driver.workflow.add('cid') cls.create_passthrough('cid.sequential') cls.sequential = False cls.add('a2b', CS2DtoBECAS()) cls.cid.workflow.add('a2b') cls.create_passthrough('a2b.path_shellexpander') cls.connect('becas_inputs', 'a2b.becas_inputs') cls.connect('section_name', 'a2b.section_name') # add BECAS mesh parameters cls.create_passthrough('a2b.total_points') cls.create_passthrough('a2b.max_layers') # add the CrossSectionStructureVT as parameter to the cid cls.cid.add_parameter('a2b.cs2d') # the parent assembly will connect to this with a list of cases # for each radial position cls.connect('cs2d', 'cid.case_inputs.a2b.cs2d') # declare outputs cls.cid.add_response('a2b.te_ratio') cls.create_passthrough('cid.case_outputs.a2b.te_ratio') # add becas cls.add('becas', BECASWrapper()) cls.cid.workflow.add('becas') cls.becas.exec_mode = 'octave' cls.becas.analysis_mode = 'stiffness' # connect path_input constructed by a2b to becas cls.connect('a2b.path_input', 'becas.path_input') cls.connect('a2b.cs2d.s/pf.blade_length', 'becas.spanpos') # path_becas needs to be set at runtime cls.create_passthrough('becas.path_becas') # declare outputs cls.cid.add_response('becas.hawc2_crossVT') cls.create_passthrough('cid.case_outputs.becas.hawc2_crossVT') # postprocess each case to generate the BeamStructureVT output # moved to parent assembly to avoid pickling error cls.add('postpro', ComputeHAWC2BeamProps()) cls.driver.workflow.add('postpro') cls.connect('pf', 'postpro.pf') cls.connect('cid.case_outputs.becas.hawc2_crossVT', 'postpro.cs2d_cases') cls.connect('postpro.beam_structure', 'beam_structure') cls.create_passthrough('postpro.mass') cls.create_passthrough('postpro.mass_moment') cls.create_passthrough('postpro.hub_radius') # uncomment to get full debug output cls.log_level = logging.DEBUG cls.a2b.log_level = logging.DEBUG cls.becas.log_level = logging.DEBUG
def __init__(self, name, becas_hash, config, st3d, s, ni_chord, cs_size, cs_size_ref): """ parameters ---------- config: dict dictionary with inputs to CS2DtoBECAS and BECASWrapper st3d: dict dictionary with blade structural definition s: array spanwise location of the cross-section ni_chord: int number of points definiting the cross-section shape cs_size: int size of blade_beam_structure array (19 or 30) cs_size_ref: int size of blade_beam_csprops_ref array (18) """ super(BECASCSStructure, self).__init__() self.basedir = os.getcwd() self.becas_hash = becas_hash self.nr = len(st3d['regions']) self.ni_chord = ni_chord # fix mesh distribution function after first run # defaults to True try: self.fix_mesh_distribution = config['fix_mesh_distribution'] except: self.fix_mesh_distribution = True # add materials properties array ((10, nmat)) self.add_param('matprops', st3d['matprops']) # add materials strength properties array ((18, nmat)) self.add_param('failmat', st3d['failmat']) # add DPs array self.add_param('%s:DPs' % name, np.zeros(self.nr + 1)) # add coords coords self._varnames = [] self.add_param('%s:coords' % name, np.zeros((ni_chord, 3))) self.cs2di = {} self.cs2di['materials'] = st3d['materials'] self.cs2di['matprops'] = st3d['matprops'] self.cs2di['failcrit'] = st3d['failcrit'] self.cs2di['failmat'] = st3d['failmat'] self.cs2di['web_def'] = st3d['web_def'] self.cs2di['s'] = s self.cs2di['DPs'] = np.zeros(self.nr + 1) self.cs2di['regions'] = [] self.cs2di['webs'] = [] for ireg, reg in enumerate(st3d['regions']): r = {} r['layers'] = reg['layers'] nl = len(reg['layers']) r['thicknesses'] = np.zeros(nl) r['angles'] = np.zeros(nl) self.cs2di['regions'].append(r) for i, lname in enumerate(reg['layers']): varname = '%s:r%02d%s' % (name, ireg, lname) self._varnames.append(varname) for ireg, reg in enumerate(st3d['webs']): r = {} r['layers'] = reg['layers'] nl = len(reg['layers']) r['thicknesses'] = np.zeros(nl) r['angles'] = np.zeros(nl) self.cs2di['webs'].append(r) for i, lname in enumerate(reg['layers']): varname = '%s:w%02d%s' % (name, ireg, lname) self._varnames.append(varname) self.add_param(name + ':tvec', np.zeros(len(self._varnames) * 2)) # add outputs self.add_output('%s:cs_props' % name, np.zeros(cs_size)) self.add_output('%s:csprops_ref' % name, np.zeros(cs_size_ref)) self.add_output('%s:k_matrix' % name, shape=(6, 6)) self.add_output('%s:m_matrix' % name, shape=(6, 6)) self.cs_props_m1 = np.zeros(cs_size) self.csprops_ref_m1 = np.zeros(cs_size_ref) self.k_matrix_m1 = np.zeros((6, 6)) self.m_matrix_m1 = np.zeros((6, 6)) self.add_output('%s:DPcoords' % name, np.zeros((self.nr + 1, 3))) self.workdir = 'becas_%s_%i' % (name, self.becas_hash) # not so nice hack to ensure unique directory names when # running parallel FD # the hash is passed to downstream BECASStressRecovery class self.add_output(name + ':hash', float(self.becas_hash)) self.mesher = CS2DtoBECAS(self.cs2di, **config['CS2DtoBECAS']) self.becas = BECASWrapper(self.cs2di['s'], **config['BECASWrapper']) self.redistribute_flag = True