class Dummy(Component): x = Float(0.0, low=-10, high=10, iotype='in') y = Float(0.0, low=0, high=10, iotype='in') lst = List([1, 2, 3, 4, 5], iotype='in') i = Int(0, low=-10, high=10, iotype='in') j = Int(0, low=0, high=10, iotype='in') enum_i = Enum(values=(1, 5, 8), iotype='in') enum_f = Enum(values=(1.1, 5.5, 8.8), iotype='in')
class HAWC2Constraint(VariableTree): con_name = Str() con_type = Enum('free', ('fixed', 'fixed_to_body', 'free', 'prescribed_angle'), desc='Constraint type') body1 = Str(desc='Main body name to which the body is attached') DOF = Array(np.zeros(6), desc='Degrees of freedom')
class HAWC2Aero(VariableTree): nblades = Int(3, desc='Number of blades') hub_vec_mbdy_name = Str('shaft') hub_vec_coo = Int(-3) links = List() induction_method = Enum(1, (0, 1), desc='BEM induction method, 0=none, 1=normal') aerocalc_method = Enum(1, (0, 1), desc='BEM aero method, 0=none, 1=normal') aerosections = Int(30, desc='Number of BEM aerodynamic sections') tiploss_method = Enum(1, (0, 1), desc='BEM induction method, 0=none, 1=prandtl') dynstall_method = Enum( 2, (0, 1, 2), desc='BEM induction method, 0=none, 1=stig oeye method,2=mhh method') ae_sets = List([1, 1, 1]) ae_filename = Str() pc_filename = Str()
class SomeComp(Component): """Arbitrary component with a few variables, but which does not really do any calculations""" w = Float(0.0, low=-10, high=0.0, iotype="in") x = Float(0.0, low=0.0, high=100.0, iotype="in") y = Int(10, low=10, high=100, iotype="in") z = Enum([-10, -5, 0, 7], iotype="in")
class Dummy(Component): a = Float(iotype="in") b = Float(iotype="in") x = Float(iotype="out") y = Float(iotype="out") i = Int(iotype="in") j = Int(iotype="out") farr = Array([1.1, 2.2, 3.3]) iarr = Array([1, 2, 3]) en = Enum(values=['foo', 'bar', 'baz'], iotype='in')
class TurbineEnvironmentVT(VariableTree): vhub = Float(desc='Hub-height velocity') direction = Float(desc='Incident wind direction') density = Float(1.225, desc='air density') viscosity = Float(1.78405e-5, desc='air viscosity') ti = Float(0., desc='Turbulence intensity in percent') inflow_type = Enum('constant', ('constant','log','powerlaw','linear','user'), desc='shear type') shear_exp = Float(0., iotype='in', desc='Shear exponent (when applicaple)') kappa = Float(0.4, iotype='in', desc='Von Karman constant') z0 = Float(0.111, iotype='in', desc='Roughness length')
class MainBody(VariableTree): body_name = Str('body') subsystem = Enum('Tower', ('Rotor', 'Nacelle', 'Tower', 'Foundation')) beam_structure = VarTree(BeamStructureVT(), desc='Structural beam properties of the body') geom = VarTree(BeamGeometryVT(), desc='Beam geometry') mass = Float(desc='mass of the body') damping_posdef = Array(np.zeros(6)) concentrated_mass = List(Array())
class Connectable(Component): b_in = Bool(iotype='in') e_in = Enum(values=(1, 2, 3), iotype='in') f_in = Float(iotype='in') i_in = Int(iotype='in') s_in = Str(iotype='in') b_out = Bool(iotype='out') e_out = Enum(values=(1, 2, 3), iotype='out') f_out = Float(iotype='out') i_out = Int(iotype='out') s_out = Str(iotype='out') def execute(self): self.b_out = self.b_in self.e_out = self.e_in self.f_out = self.f_in self.i_out = self.i_in self.s_out = self.s_in
class HAWC2Wind(VariableTree): density = Float(1.225, desc='Density') wsp = Float(desc='Hub height wind speed') tint = Float(desc='Turbulence intensity') horizontal_input = Enum(1, (0, 1), desc='0=meteorological default, 1=horizontal') center_pos0 = Array( np.zeros(3), desc='Turbulence box center start point in global coordinates.') windfield_rotations = Array( np.zeros(3), desc='Orientation of the wind field, yaw, tilt, rotation.') shear_type = Enum(1, (0, 1, 2, 3, 4), desc='Definition of the mean wind shear:' '0=None,1=constant,2=logarithmic,3=power law,4=linear') shear_factor = Float(0., desc='Shear parameter - depends on the shear type') turb_format = Enum(0, (0, 1, 2), desc='Turbulence format (0=none, 1=mann, 2=flex)') tower_shadow_method = Enum( 0, (0, 1, 2, 3), desc='Tower shadow model' '(0=none, 1=potential flow - default, 2=jet model, 3=potential_2') scale_time_start = Float(desc='Starting time for turbulence scaling') wind_ramp_t0 = Float(0., desc='Start time for wind ramp') wind_ramp_t1 = Float(desc='End time for wind ramp') wind_ramp_factor0 = Float(0., desc='Start factor for wind ramp') wind_ramp_factor1 = Float(1., desc='End factor for wind ramp') wind_ramp_abs = List() iec_gust = Bool(False, desc='Flag for specifying an IEC gust') iec_gust_type = Enum('eog', ('eog', 'edc', 'ecd', 'ews'), desc='IEC gust types') G_A = Float() G_phi0 = Float() G_t0 = Float() G_T = Float() mann = VarTree(HAWC2Mann())
class OptLatinHypercube(HasTraits): """IDOEgenerator which provides a Latin hypercube DOE sample set. The Morris-Mitchell sampling criterion of the DOE is optimzied using an evolutionary algorithm. """ implements(IDOEgenerator) num_sample_points = Int( 20, desc="Number of sample points in the DOE sample set.") num_parameters = Int( 2, desc="Number of parameters, or dimensions, for the DOE.") population = Int( 20, desc="Size of the population used in the evolutionary optimization.") generations = Int( 2, desc="Number of generations the optimization will evolve over.") norm_method = Enum( ["1-norm", "2-norm"], desc= "Vector norm calculation method. '1-norm' is faster, but less accurate." ) def __init__(self, num_samples=None, population=None, generations=None): super(OptLatinHypercube, self).__init__() self.qs = [1, 2, 5, 10, 20, 50, 100] #list of qs to try for Phi_q optimization if num_samples is not None: self.num_sample_points = num_samples if population is not None: self.population = population if generations is not None: self.generations = generations def __iter__(self): """Return an iterator over our sets of input values.""" return self._get_input_values() def _get_input_values(self): rand_doe = rand_latin_hypercube(self.num_sample_points, self.num_parameters) best_lhc = LatinHypercube(rand_doe, q=1, p=_norm_map[self.norm_method]) for q in self.qs: lh = LatinHypercube(rand_doe, q, _norm_map[self.norm_method]) lh_opt = _mmlhs(lh, self.population, self.generations) if lh_opt.mmphi() < best_lhc.mmphi(): best_lhc = lh_opt for row in best_lhc: yield row
class SphereFunction(Component): total = Float(0., iotype='out') x = Float(0, low=-5.12, high=5.13, iotype="in") y = Enum([-10, 0, 1, 2, 3, 4, 5], iotype="in") z = Int(0, low=-5, high=5, iotype="in") def __init__(self): super(SphereFunction, self).__init__() def execute(self): """ calculate the sume of the squares for the list of numbers """ self.total = self.x**2 + self.y**2 + self.z**2
class FASTInitialConditions(VariableTree): # Initial Conditions WSPtmfPitch = Array(array([0, 4, 12, 15, 22]), dtype=float, desc="Wind speeds used for ptfm pitch interp [m/s]", iotype='in') PtfmPitch = Array(array([0, .5, 6, 4, 2.8]), dtype=float, desc="Pitch points used for ptfm pitch interp [degrees]", iotype='in') WSPtfmSurge = Array(array([0, 4, 12.1, 14, 22]), dtype=float, desc="Wind speeds used for ptfm surge interp [m/s]", iotype='in') PtfmSurge = Array(array([0, 1.6, 12.3, 9.3, 5.9]), dtype=float, desc="Surge points used for pftm surge interp [m]", iotype='in') WSPitch = Array(array([0, 12, 14, 22]), dtype=float, desc="Wind speeds used for blade pitch interp [m/s]", iotype='in') Pitch = Array(array([0, 0, 6.2, 18.9]), dtype=float, desc="Pitch points used for blade pitch interp [degrees]", iotype='in') WSRpm = Array(array([0, 4, 9, 12]), dtype=float, desc="Wind speeds used for rotor speed interp [m/s]", iotype='in') Rpm = Array(array([0, 7, 14.2, 16]), dtype=float, desc="Rotor speeds used for rotor speed interp [rpm]", iotype='in') # May move the following variables if there is a better place for them DLC = Float(1.1, desc="DLC Number", iotype='in') IEC_WindType = List(Enum('NTM', ('NTM', '1ETM', 'ECD', 'EWSH+', 'EWSH-', 'EWSV+', 'EWSV-', 'EOG', '1EWM50', '1EWM1')), desc='IEC wind type') RefHt = Float(180, desc='Reference height') def __init__(self, pitch_array): super(FASTInitialConditions, self).__init__() self.add( 'Pitch', Array(pitch_array, dtype=float, desc="Pitch points used for blade pitch interp [degrees]", iotype='in'))
class dummy_comp(Component): x = Float(0.0, iotype='in') e = Enum(0, [0,1,2,3], iotype = 'in') d = Dict(value = {'e':2.71, "pi": 3.14159}, value_trait = Float, key_trait = Str, iotype = 'in') X = Array([0,1,2,3], iotype = 'in') Y = Array([[0,1],[2,3]], iotype = 'in') Y2 = Array([[5],[8]], iotype = 'in') Y3 = Array([[1]], iotype = 'in') Z = List([1,2,3,4], iotype='in') def execute(self): return
class BasicTurbineVT(VariableTree): turbine_name = Str('FUSED-Wind turbine', desc='Wind turbine name') docs = Str(desc='Human readable description of wind turbine') nblades = Int(3, desc='number of blades') orientation = Str('upwind') rotor_diameter = Float(units='m', desc='Rotor Diameter') hub_height = Float(units='m', desc='Hub height') drivetrain_config = Enum(1, (1, 2, 3, 4, 'x'), desc='Drive train configuration') iec_class = Str(desc='Primary IEC classification of the turbine') controls = VarTree(ControlsVT(), desc='control specifications VT')
def __init__(self, iotype, client, rpath, typ, valstrs): ProxyMixin.__init__(self, client, rpath) om_units = None if typ == 'PHXDouble': self._from_string = float self._to_string = _float2str as_units = client.get(rpath+'.units') if as_units: om_units = get_translation(as_units) elif typ == 'PHXLong': self._from_string = int self._to_string = str elif typ == 'PHXString': self._from_string = self._null self._to_string = self._null else: raise NotImplementedError('EnumProxy for %r' % typ) default = self._from_string(self._valstr) desc = client.get(rpath+'.description') enum_values = [] for valstr in valstrs.split(','): enum_values.append(self._from_string(valstr.strip(' "'))) enum_aliases = [] aliases = self._client.get(rpath+'.enumAliases') if aliases: for alias in aliases.split(','): enum_aliases.append(alias.strip(' "')) if enum_aliases: if len(enum_aliases) != len(enum_values): raise ValueError("Aliases %r don't match values %r" % (enum_aliases, enum_values)) Enum.__init__(self, default_value=default, iotype=iotype, desc=desc, values=enum_values, aliases=enum_aliases, units=om_units)
class Oneinp(Component): """ A simple input component """ ratio1 = Float(2., iotype='in', desc='Float Variable') ratio2 = Int(2, iotype='in', desc='Int Variable') ratio3 = Bool(False, iotype='in', desc='Float Variable') ratio4 = Float(1.03, iotype='in', desc='Float variable ', units='ft') ratio5 = Str('01234', iotype='in', desc='string variable') ratio6 = Enum(0, (0, 3, 11, 27), iotype='in', desc='some enum') unit = Float(0.0, units='ft', iotype='in') no_unit = Float(0.0, iotype='in') def execute(self): """
class ExternalParms(XMLContainer): """ XML parameters specific to an 'external'. """ XMLTAG = 'External_Parms' external_type = Enum(_MISSLE_TYPE, iotype='in', xmltag='External_Type', values=(_BOMB_TYPE, _MISSLE_TYPE, _TANK_TYPE, _FIXED_TANK_TYPE), aliases=('Bomb', 'Missile', 'Tank', 'Fixed Tank'), desc='Type of external store.') length = Float(6.5, low=0.1, high=100., iotype='in', xmltag='Length', desc='Store length.') fine_ratio = Float(15.0, low=2., high=50., iotype='in', xmltag='Finess_Ratio', desc='') drag = Float(0.01, low=0., high=100., iotype='in', xmltag='Drag', desc='Equivalent flat plate drag of store.') pylon = Bool(True, iotype='in', xmltag='Pylon_Flag', desc='If True, include pylon.') pylon_height = Float(0.35, low=0.001, high=20., iotype='in', xmltag='Pylon_Height', desc='Height of pylon.') pylon_drag = Float(0.01, low=0., high=100., iotype='in', xmltag='Pylon_Drag', desc='Equivalent flat plat drag of pylon.') def __init__(self): super(ExternalParms, self).__init__(self.XMLTAG)
class Oneout(Component): """ A simple output component """ ratio1 = Float(3.54, iotype='out', desc='Float Variable') ratio2 = Int(9, iotype='out', desc='Integer variable') ratio3 = Bool(True, iotype='out', desc='Boolean Variable') ratio4 = Float(1.03, iotype='out', desc='Float variable ', units='cm') ratio5 = Str('05678', iotype='out', desc='string variable') ratio6 = Enum(27, (0, 3, 9, 27), iotype='out', desc='some enum') unit = Float(12.0, units='inch', iotype='out') no_unit = Float(12.0, iotype='out') def execute(self): """
class MaterialProps(VariableTree): """ Material properties """ materialname = Str(desc='Material name') E1 = Float(units='GPa', desc='Youngs modulus in the radial direction') E2 = Float(units='GPa', desc='Youngs modulus in the tangential direction') E3 = Float(units='GPa', desc='Youngs modulus in the axial direction') nu12 = Float(desc='Poissons ratio in the radial-tangential direction') nu13 = Float(desc='Poissons ratio in the radial-axial direction') nu23 = Float(desc='Poissons ratio in the tangential-axial direction') G12 = Float(units='GPa', desc='Shear modulus in radial-tangential direction') G13 = Float(units='GPa', desc='Shear modulus in radial-axial direction') G23 = Float(units='GPa', desc='Shear modulus in tangential-axial direction') rho = Float(units='kg/m**3', desc='Mass density') failure_criterium = Enum('maximum_strain', ('maximum_strain', 'maximum_stress', 'tsai_wu')) s11_t = Float(1e6, desc='tensile strength in the 1 direction') s22_t = Float(1e6, desc='tensile strength in the 2 direction') s33_t = Float(1e6, desc='tensile strength in the 3 direction') s11_c = Float(1e6, desc='compressive strength in the 1 direction') s22_c = Float(1e6, desc='compressive strength in the 2 direction') s33_c = Float(1e6, desc='compressive strength in the 3 direction') t12 = Float(1e6, desc='shear strength in the 12 plane') t13 = Float(1e6, desc='shear strength in the 13 plane') t23 = Float(1e6, desc='shear strength in the 23 plane') e11_c = Float(1e6, desc='maximum tensile strain in the 1 direction') e22_c = Float(1e6, desc='maximum tensile strain in the 2 direction') e33_c = Float(1e6, desc='maximum tensile strain in the 3 direction') e11_t = Float(1e6, desc='maximum compressive strain in the 1 direction') e22_t = Float(1e6, desc='maximum compressive strain in the 2 direction') e33_t = Float(1e6, desc='maximum compressive strain in the 3 direction') g12 = Float(1e6, desc='maximum shear strain in the 12 plane ') g13 = Float(1e6, desc='maximum shear strain in the 13 plane') g23 = Float(1e6, desc='maximum shear strain in the 23 plane') # Reduction factors for the material safety factor # computed as gMa = gM0 * sum(Cia) # gMa defaults to 1 so partials can be used directly in above material strengths gM0 = Float(0.25, desc='Material safety factor') C1a = Float(1., desc='influence of ageing') C2a = Float(1., desc='influence of temperature') C3a = Float(1., desc='influence of manufacturing technique') C4a = Float(1., desc='influence of curing technique')
class DREA_HSRnoise(Assembly): """Assembly to execute on DREA followed by HSRnoise.""" geo = Slot(Geometry, iotype='in') alt = Float(0.0, iotype='in', units='ft', desc='Altitude') point = Enum(1, [1,2,3], iotype='in', desc='Certification observer point') def __init__(self): """Creates an Assembly to run DREA and HSRnoise.""" super(DREA_HSRnoise, self).__init__() FO1 = Case(inputs=[('point', 1),('dreaprep.Mach',0.28),('alt',2000.0),('dreaprep.PC',100.0),('hsrnoise.phi', 0.0)], outputs=[('drea.CFG',0.0),('hsrnoise.thetas',0.0),('hsrnoise.Freq',0.0),('hsrnoise.SPL_corr',0),('hsrnoise.OASPL30',0.0),('hsrnoise.OASPL60',0.0),('hsrnoise.OASPL90',0.0),('hsrnoise.OASPL120',0.0),('hsrnoise.OASPL150',0.0)]) FO2 = Case(inputs=[('point', 1),('dreaprep.Mach',0.28),('alt',2000.0),('dreaprep.PC', 65.0),('hsrnoise.phi', 0.0)], outputs=[('drea.CFG',0.0),('hsrnoise.thetas',0.0),('hsrnoise.Freq',0.0),('hsrnoise.SPL_corr',0),('hsrnoise.OASPL30',0.0),('hsrnoise.OASPL60',0.0),('hsrnoise.OASPL90',0.0),('hsrnoise.OASPL120',0.0),('hsrnoise.OASPL150',0.0)]) App = Case(inputs=[('point', 2),('dreaprep.Mach',0.20),('alt', 394.0),('dreaprep.PC', 30.0),('hsrnoise.phi', 0.0)], outputs=[('drea.CFG',0.0),('hsrnoise.thetas',0.0),('hsrnoise.Freq',0.0),('hsrnoise.SPL_corr',0),('hsrnoise.OASPL30',0.0),('hsrnoise.OASPL60',0.0),('hsrnoise.OASPL90',0.0),('hsrnoise.OASPL120',0.0),('hsrnoise.OASPL150',0.0)]) SL1 = Case(inputs=[('point', 3),('dreaprep.Mach',0.25),('alt',1000.0),('dreaprep.PC',100.0),('hsrnoise.phi', 0.0)], outputs=[('drea.CFG',0.0),('hsrnoise.thetas',0.0),('hsrnoise.Freq',0.0),('hsrnoise.SPL_corr',0),('hsrnoise.OASPL30',0.0),('hsrnoise.OASPL60',0.0),('hsrnoise.OASPL90',0.0),('hsrnoise.OASPL120',0.0),('hsrnoise.OASPL150',0.0)]) SL2 = Case(inputs=[('point', 3),('dreaprep.Mach',0.25),('alt',1000.0),('dreaprep.PC',100.0),('hsrnoise.phi',30.0)], outputs=[('drea.CFG',0.0),('hsrnoise.thetas',0.0),('hsrnoise.Freq',0.0),('hsrnoise.SPL_corr',0),('hsrnoise.OASPL30',0.0),('hsrnoise.OASPL60',0.0),('hsrnoise.OASPL90',0.0),('hsrnoise.OASPL120',0.0),('hsrnoise.OASPL150',0.0)]) SL3 = Case(inputs=[('point', 3),('dreaprep.Mach',0.25),('alt',1000.0),('dreaprep.PC',100.0),('hsrnoise.phi',60.0)], outputs=[('drea.CFG',0.0),('hsrnoise.thetas',0.0),('hsrnoise.Freq',0.0),('hsrnoise.SPL_corr',0),('hsrnoise.OASPL30',0.0),('hsrnoise.OASPL60',0.0),('hsrnoise.OASPL90',0.0),('hsrnoise.OASPL120',0.0),('hsrnoise.OASPL150',0.0)]) SL4 = Case(inputs=[('point', 3),('dreaprep.Mach',0.25),('alt',1000.0),('dreaprep.PC',100.0),('hsrnoise.phi',90.0)], outputs=[('drea.CFG',0.0),('hsrnoise.thetas',0.0),('hsrnoise.Freq',0.0),('hsrnoise.SPL_corr',0),('hsrnoise.OASPL30',0.0),('hsrnoise.OASPL60',0.0),('hsrnoise.OASPL90',0.0),('hsrnoise.OASPL120',0.0),('hsrnoise.OASPL150',0.0)]) cases = ListCaseIterator([FO1,FO2,App,SL1,SL2,SL3,SL4]) db_recorder = DBCaseRecorder() self.add('geo', Geometry()) self.add('dreaprep', DREAprep()) self.add('drea', DREA()) self.add('hsrnoise', HSRNOISE()) self.add('ACDgen', ACDgen()) self.add('analysis',CaseIteratorDriver()) self.analysis.iterator = cases self.analysis.recorders = [db_recorder] self.ACDgen.case_data = db_recorder.get_iterator() # Set up the workflows #--------------------------- #self.analysis.workflow.add(['dreaprep', 'drea', 'hsrnoise']) #self.driver.workflow.add(['analysis','ACDgen']) self.driver.workflow.add(['dreaprep', 'drea', 'hsrnoise']) # Connections #--------------------------- self.connect('geo',['drea.geo_in','hsrnoise.geo_in']) self.connect('alt',['dreaprep.alt','hsrnoise.ALTEVO']) self.connect('dreaprep.flow_out','drea.flow_in') self.connect('drea.flow_out','hsrnoise.flow_in') self.connect('drea.CFG','hsrnoise.CFG')
class CentralComposite(Container): """ DOEgenerator that performs a central composite Design of Experiments. Plugs into the DOEgenerator socket on a DOEdriver.""" implements(IDOEgenerator) # pylint: disable-msg=E1101 num_parameters = Int(0, iotype="in", desc="Number of independent parameters in the DOE.") type = Enum("Face-Centered", ["Face-Centered", "Inscribed"], iotype="in", desc="Type of central composite design") def __init__(self, type="Face-Centered", *args, **kwargs): super(CentralComposite, self).__init__(*args, **kwargs) self.type = type def __iter__(self): """Return an iterator over our sets of input values.""" # Set the number of center points and the alpha parameter based on the type of central composite design num_center_points = 1 if self.type == "Face-Centered": alpha = 1.0 if self.type == "Inscribed": alpha = self.num_parameters**0.5 # Based on recommendation from "Response Surface Methodology" by R.H. Myers and D.C. Montgomery # Form the iterator for the corner points using a 2 level full factorial low_corner_val = 0.5 - 0.5 / alpha high_corner_val = 0.5 + 0.5 / alpha corner_points = product(*[[low_corner_val, high_corner_val] for i in range(self.num_parameters)]) # Form iterators for the face centered points (one for low value faces, one for high value faces) center_list = (self.num_parameters - 1) * [0.5] low_face_points = set(permutations([0.0] + center_list)) high_face_points = set(permutations([1.0] + center_list)) # Form iterator for center point(s) center_points = num_center_points * [self.num_parameters * [0.5]] # Chain case lists together to get complete iterator return chain(corner_points, low_face_points, high_face_points, center_points)
class FuseParms(XMLContainer): """ XML parameters specific to a fuselage2. """ XMLTAG = 'Fuse_Parms' fuse_length = Float(30., low=0.001, high=1000., iotype='in', xmltag='Fuse_Length', desc='') space_type = Enum(_PNT_SPACE_UNIFORM, iotype='in', xmltag='Space_Type', values=(_PNT_SPACE_PER_XSEC, _PNT_SPACE_FIXED, _PNT_SPACE_UNIFORM), aliases=('Per XSec', 'Fixed', 'Uniform'), desc='') def __init__(self): super(FuseParms, self).__init__(self.XMLTAG)
class Flags(VariableTree): Opt = Int(1, desc='0 - single run, 1 - optimization') ConFail = Int(0, desc='1 - use structural failure as a constraint on optimization') ConWireCont = Int(0, desc='1 - use wire length continuity as a constraint to set appropriate wire forces in multi-point optimizations') ConJigCont = Int(0, desc='1 - use jig continuity') ConDef = Int(0, desc='1 - constraints on maximum deformation of the rotor') MultiPoint = Int(4, desc='0 - single point optimization, 1 - 4 point optimization (h=0.5, h=3, wind case, gravity load)') Quad = Int(1, desc='0 - prop drive, 1 - quad rotor') FreeWake = Int(1, desc='0 - momentum theory, 1 - free vortex ring wake') PlotWake = Int(0, desc='0 - dont plot wake, 1 - plot wake ') DynamicClimb = Int(0, desc='0 - vc imposes downward velocity, 1 - vc represents climb (final altitude depends on Nw)') Cover = Int(0, desc='0 - no cover over root rotor blades, 1 - cover') Load = Int(0, desc='0 - normal run, 1 - gravity forces only, 2 - prescribed load from pLoad') Cdfit = Int(1, desc='0 - analytic model for drag coefficient, 1 - curve fit on BE airfoils') GWing = Int(1, desc='0 - Daedalus style wing, 1 - Gossamer style wing (changes amount of laminar flow)') AeroStr = Int(1, desc='0 - Assume flat wing, 1 - take deformation into account') Movie = Int(0, desc='0 - dont save animation, 1 - save animation') wingWarp = Int(0, desc='0 - no twist constraint, >0 - twist constraint at wingWarp') CFRPType = Str('NCT301-1X HS40 G150 33 +/-2%RW', desc='type of carbon fibre reinforced polymer') WireType = Enum('Pianowire', ('Pianowire', 'Vectran'), desc='Material to be used for lift wire')
class MultiObjExpectedImprovement(Component): best_cases = Slot( CaseSet, iotype="in", desc="CaseIterator which contains only Pareto optimal cases \ according to criteria.") criteria = Array( iotype="in", desc="Names of responses to maximize expected improvement around. \ Must be NormalDistribution type.") predicted_values = Array( [0, 0], iotype="in", dtype=NormalDistribution, desc="CaseIterator which contains NormalDistributions for each \ response at a location where you wish to calculate EI." ) n = Int(1000, iotype="in", desc="Number of Monte Carlo Samples with \ which to calculate probability of improvement.") calc_switch = Enum("PI", ["PI", "EI"], iotype="in", desc="Switch to use either \ probability (PI) or expected (EI) improvement.") PI = Float(0.0, iotype="out", desc="The probability of improvement of the next_case.") EI = Float(0.0, iotype="out", desc="The expected improvement of the next_case.") reset_y_star = Event(desc='Reset Y* on next execution') def __init__(self): super(MultiObjExpectedImprovement, self).__init__() self.y_star = None def _reset_y_star_fired(self): self.y_star = None def get_y_star(self): criteria_count = len(self.criteria) flat_crit = self.criteria.ravel() try: y_star = zip(*[self.best_cases[crit] for crit in self.criteria]) except KeyError: self.raise_exception( 'no cases in the provided case_set had output ' 'matching the provided criteria, %s' % self.criteria, ValueError) #sort list on first objective y_star = array(y_star)[array([i[0] for i in y_star]).argsort()] return y_star def _2obj_PI(self, mu, sigma): """Calculates the multi-objective probability of improvement for a new point with two responses. Takes as input a pareto frontier, mean and sigma of new point.""" y_star = self.y_star PI1 = (0.5 + 0.5 * erf( (1 / (2**0.5)) * ((y_star[0][0] - mu[0]) / sigma[0]))) PI3 = (1-(0.5+0.5*erf((1/(2**0.5))*((y_star[-1][0]-mu[0])/sigma[0]))))\ *(0.5+0.5*erf((1/(2**0.5))*((y_star[-1][1]-mu[1])/sigma[1]))) PI2 = 0 if len(y_star) > 1: for i in range(len(y_star) - 1): PI2=PI2+((0.5+0.5*erf((1/(2**0.5))*((y_star[i+1][0]-mu[0])/sigma[0])))\ -(0.5+0.5*erf((1/(2**0.5))*((y_star[i][0]-mu[0])/sigma[0]))))\ *(0.5+0.5*erf((1/(2**0.5))*((y_star[i+1][1]-mu[1])/sigma[1]))) mcpi = PI1 + PI2 + PI3 return mcpi def _2obj_EI(self, mu, sigma): """Calculates the multi-criteria expected improvement for a new point with two responses. Takes as input a pareto frontier, mean and sigma of new point.""" y_star = self.y_star ybar11 = mu[0]*(0.5+0.5*erf((1/(2**0.5))*((y_star[0][0]-mu[0])/sigma[0])))\ -sigma[0]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[0][0]-mu[0])**2/sigma[0]**2)) ybar13 = (mu[0]*(0.5+0.5*erf((1/(2**0.5))*((y_star[-1][0]-mu[0])/sigma[0])))\ -sigma[0]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[-1][0]-mu[0])**2/sigma[0]**2)))\ *(0.5+0.5*erf((1/(2**0.5))*((y_star[-1][1]-mu[1])/sigma[1]))) ybar12 = 0 if len(y_star) > 1: for i in range(len(y_star) - 1): ybar12 = ybar12+((mu[0]*(0.5+0.5*erf((1/(2**0.5))*((y_star[i+1][0]-mu[0])/sigma[0])))\ -sigma[0]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[i+1][0]-mu[0])**2/sigma[0]**2)))\ -(mu[0]*(0.5+0.5*erf((1/(2**0.5))*((y_star[i][0]-mu[0])/sigma[0])))\ -sigma[0]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[i][0]-mu[0])**2/sigma[0]**2))))\ *(0.5+0.5*erf((1/(2**0.5))*((y_star[i+1][1]-mu[1])/sigma[1]))) ybar1 = (ybar11 + ybar12 + ybar13) / self.PI ybar21 = mu[1]*(0.5+0.5*erf((1/(2**0.5))*((y_star[0][1]-mu[1])/sigma[1])))\ -sigma[1]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[0][1]-mu[1])**2/sigma[1]**2)) ybar23 = (mu[1]*(0.5+0.5*erf((1/(2**0.5))*((y_star[-1][1]-mu[1])/sigma[1])))\ -sigma[1]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[-1][1]-mu[1])**2/sigma[1]**2)))\ *(0.5+0.5*erf((1/(2**0.5))*((y_star[-1][0]-mu[0])/sigma[0]))) ybar22 = 0 if len(y_star) > 1: for i in range(len(y_star) - 1): ybar22 = ybar22+((mu[1]*(0.5+0.5*erf((1/(2**0.5))*((y_star[i+1][1]-mu[1])/sigma[1])))\ -sigma[1]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[i+1][1]-mu[1])**2/sigma[1]**2)))\ -(mu[1]*(0.5+0.5*erf((1/(2**0.5))*((y_star[i][1]-mu[1])/sigma[1])))\ -sigma[1]*(1/((2*pi)**0.5))*exp(-0.5*((y_star[i][1]-mu[1])**2/sigma[1]**2))))\ *(0.5+0.5*erf((1/(2**0.5))*((y_star[i+1][0]-mu[0])/sigma[0]))) ybar2 = (ybar21 + ybar22 + ybar23) / self.PI dists = [((ybar1 - point[0])**2 + (ybar2 - point[1])**2)**0.5 for point in y_star] mcei = self.PI * min(dists) if isnan(mcei): mcei = 0 return mcei def _dom(self, a, b): """determines if a completely dominates b returns True is if does """ comp = [c1 < c2 for c1, c2 in zip(a, b)] if sum(comp) == len(self.criteria): return True return False def _nobj_PI(self, mu, sigma): cov = diag(array(sigma)**2) rands = random.multivariate_normal(mu, cov, self.n) num = 0 # number of cases that dominate the current Pareto set for random_sample in rands: for par_point in self.y_star: #par_point = [p[2] for p in par_point.outputs] if self._dom(par_point, random_sample): num = num + 1 break pi = (self.n - num) / float(self.n) return pi def execute(self): """ Calculates the expected improvement or probability of improvement of a candidate point given by a normal distribution. """ mu = [objective.mu for objective in self.predicted_values] sig = [objective.sigma for objective in self.predicted_values] if self.y_star == None: self.y_star = self.get_y_star() n_objs = len(self.criteria) if n_objs == 2: """biobjective optimization""" self.PI = self._2obj_PI(mu, sig) if self.calc_switch == 'EI': """execute EI calculations""" self.EI = self._2obj_EI(mu, sig) if n_objs > 2: """n objective optimization""" self.PI = self._nobj_PI(mu, sig) if self.calc_switch == 'EI': """execute EI calculations""" self.raise_exception( "EI calculations not supported" " for more than 2 objectives", ValueError)
class BroydenSolver(Driver): """ :term:`MIMO` Newton-Raphson Solver with Broyden approximation to the Jacobian. Algorithms are based on those found in ``scipy.optimize``. Nonlinear solvers These solvers find x for which F(x)=0. Both x and F are multidimensional. All solvers have the parameter *iter* (the number of iterations to compute); some of them have other parameters of the solver. See the particular solver for details. A collection of general-purpose nonlinear multidimensional solvers. - ``broyden2``: Broyden's second method -- the same as ``broyden1`` but updates the inverse Jacobian directly - ``broyden3``: Broyden's second method -- the same as ``broyden2`` but instead of directly computing the inverse Jacobian, it remembers how to construct it using vectors. When computing ``inv(J)*F``, it uses those vectors to compute this product, thus avoiding the expensive NxN matrix multiplication. - ``excitingmixing``: The excitingmixing algorithm. ``J=-1/alpha`` The ``broyden2`` is the best. For large systems, use ``broyden3``; excitingmixing is also very effective. The remaining nonlinear solvers from SciPy are, in their own words, of "mediocre quality," so they were not implemented. """ implements(IHasParameters, IHasEqConstraints, ISolver) # pylint: disable-msg=E1101 algorithm = Enum('broyden2', ['broyden2', 'broyden3', 'excitingmixing'], iotype = 'in', desc='Algorithm to use. Choose from ' 'broyden2, broyden3, and excitingmixing.') itmax = Int(10, iotype='in', desc='Maximum number of iterations before ' 'termination.') alpha = Float(0.4, iotype='in', desc='Mixing Coefficient.') alphamax = Float(1.0, iotype='in', desc='Maximum Mixing Coefficient (only ' 'used with excitingmixing.)') tol = Float(0.00001, iotype='in', desc='Convergence tolerance. If the norm of the independent ' 'vector is lower than this, then terminate successfully.') def __init__(self): super(BroydenSolver, self).__init__() self.xin = numpy.zeros(0,'d') self.F = numpy.zeros(0,'d') def execute(self): """Solver execution.""" # get the initial values of the independents independents = self.get_parameters().values() self.xin = numpy.zeros(len(independents),'d') for i, val in enumerate(independents): self.xin[i] = val.evaluate(self.parent) # perform an initial run for self-consistency self.pre_iteration() self.run_iteration() self.post_iteration() # get initial dependents dependents = self.get_eq_constraints().values() self.F = numpy.zeros(len(dependents),'d') for i, val in enumerate(dependents): term = val.evaluate(self.parent) self.F[i] = term[0] - term[1] # pick solver algorithm if self.algorithm == 'broyden2': self.execute_broyden2() elif self.algorithm == 'broyden3': self.execute_broyden3() elif self.algorithm == 'excitingmixing': self.execute_excitingmixing() def execute_broyden2(self): """From SciPy, Broyden's second method. Updates inverse Jacobian by an optimal formula. There is NxN matrix multiplication in every iteration. The best norm(F(x))=0.003 achieved in ~20 iterations. """ xm = self.xin.T Fxm = numpy.matrix(self.F).T Gm = -self.alpha*numpy.matrix(numpy.identity(len(self.xin))) for n in range(self.itmax): if self._stop: self.raise_exception('Stop requested', RunStopped) deltaxm = -Gm*Fxm xm = xm + deltaxm.T # update the new independents in the model self.set_parameters(xm.flat) # run the model self.pre_iteration() self.run_iteration() self.post_iteration() # get dependents for i, val in enumerate(self.get_eq_constraints().values()): term = val.evaluate(self.parent) self.F[i] = term[0] - term[1] self.record_case() # successful termination if independents are below tolerance if norm(self.F) < self.tol: return Fxm1 = numpy.matrix(self.F).T deltaFxm = Fxm1 - Fxm if norm(deltaFxm) == 0: msg = "Broyden iteration has stopped converging. Change in " + \ "input has produced no change in output. This could " + \ "indicate a problem with your component connections. " + \ "It could also mean that this solver method is " + \ "inadequate for your problem." raise RuntimeError(msg) Fxm = Fxm1.copy() Gm = Gm + (deltaxm-Gm*deltaFxm)*deltaFxm.T/norm(deltaFxm)**2 def execute_broyden3(self): """from scipy, Broyden's second (sic) method. Updates inverse Jacobian by an optimal formula. The NxN matrix multiplication is avoided. The best norm(F(x))=0.003 achieved in ~20 iterations. """ zy = [] def updateG(z, y): """G:=G+z*y.T'""" zy.append((z, y)) def Gmul(f): """G=-alpha*1+z*y.T+z*y.T ...""" s = -self.alpha*f for z, y in zy: s = s + z*(y.T*f) return s xm = self.xin.T Fxm = numpy.matrix(self.F).T for n in range(self.itmax): if self._stop: self.raise_exception('Stop requested', RunStopped) deltaxm = Gmul(-Fxm) xm = xm + deltaxm.T # update the new independents in the model self.set_parameters(xm.flat) # run the model self.pre_iteration() self.run_iteration() self.post_iteration() # get dependents for i, val in enumerate(self.get_eq_constraints().values()): term = val.evaluate(self.parent) self.F[i] = term[0] - term[1] self.record_case() # successful termination if independents are below tolerance if norm(self.F) < self.tol: return Fxm1 = numpy.matrix(self.F).T deltaFxm = Fxm1 - Fxm if norm(deltaFxm) == 0: msg = "Broyden iteration has stopped converging. Change in " + \ "input has produced no change in output. This could " + \ "indicate a problem with your component connections. " + \ "It could also mean that this solver method is " + \ "inadequate for your problem." raise RuntimeError(msg) Fxm = Fxm1.copy() updateG(deltaxm - Gmul(deltaFxm), deltaFxm/norm(deltaFxm)**2) def execute_excitingmixing(self): """from scipy, The excitingmixing method. J=-1/alpha The best norm(F(x))=0.005 achieved in ~140 iterations. Note: SciPy uses 0.1 as the default value for alpha for this algorithm. Ours is set at 0.4, which is appropriate for ``Broyden2`` and ``Broyden3``, so adjust it accordingly if there are problems. """ xm = self.xin.copy() beta = numpy.array([self.alpha]*len(xm)) Fxm = self.F.T.copy() for n in range(self.itmax): if self._stop: self.raise_exception('Stop requested', RunStopped) deltaxm = beta*Fxm xm = xm + deltaxm # update the new independents in the model self.set_parameters(xm.flat) # run the model self.pre_iteration() self.run_iteration() self.post_iteration() # get dependents for i, val in enumerate(self.get_eq_constraints().values()): term = val.evaluate(self.parent) self.F[i] = term[0] - term[1] self.record_case() # successful termination if independents are below tolerance if norm(self.F) < self.tol: return Fxm1 = self.F.T for i in range(len(xm)): if Fxm1[i]*Fxm[i] > 0: beta[i] = beta[i] + self.alpha if beta[i] > self.alphamax: beta[i] = self.alphamax else: beta[i] = self.alpha Fxm = Fxm1.copy()
class DTUBasicControllerVT(HAWC2Type2DLLinit): """ Variable tree for DTU Basic Controller inputs """ Vin = Float(4., units='m/s') Vout = Float(25., units='m/s') nV = Int(22) ratedPower = Float(units='W') ratedAeroPower = Float(units='W') minRPM = Float(units='rpm') maxRPM = Float(units='rpm') gearRatio = Float(units=None) designTSR = Float(7.5) active = Bool(True) FixedPitch = Bool(False) maxTorque = Float(15.6e6, desc='Maximum allowable generator torque', units='N*m') minPitch = Float(100, desc='minimum pitch angle', units='deg') maxPitch = Float(90, desc='maximum pith angle', units='deg') maxPitchSpeed = Float(10, desc='Maximum pitch velocity operation', units='deg/s') maxPitchAcc = Float(8) generatorFreq = Float(0.2, desc='Frequency of generator speed filter', units='Hz') generatorDamping = Float(0.7, desc='Damping ratio of speed filter') ffFreq = Float(1.85, desc='Frequency of free-free DT torsion mode', units='Hz') Qg = Float(0.100131E+08, desc='Optimal Cp tracking K factor', units='kN*m/(rad/s)**2') pgTorque = Float(0.683456E+08, desc='Proportional gain of torque controller', units='N*m/(rad/s)') igTorque = Float(0.153367E+08, desc='Integral gain of torque controller', units='N*m/rad') dgTorque = Float(0., desc='Differential gain of torque controller', units='N*m/(rad/s**2)') pgPitch = Float(0.524485E+00, desc='Proportional gain of torque controller', units='N*m/(rad/s)') igPitch = Float(0.141233E+00, desc='Integral gain of torque controller', units='N*m/rad') dgPitch = Float(0., desc='Differential gain of torque controller', units='N*m/(rad/s**2)') prPowerGain = Float(0.4e-8, desc='Proportional power error gain') intPowerGain = Float(0.4e-8, desc='Proportional power error gain') generatorSwitch = Int( 1, desc='Generator control switch [1=constant power, 2=constant torque]') KK1 = Float( 198.32888, desc='Coefficient of linear term in aerodynamic gain scheduling') KK2 = Float( 693.22213, desc='Coefficient of quadratic term in aerodynamic gain scheduling') nlGainSpeed = Float(1.3, desc='Relative speed for double nonlinear gain') softDelay = Float(4., desc='Time delay for soft start of torque') cutin_t0 = Float(0.1) stop_t0 = Float(860.) TorqCutOff = Float(5) PitchDelay1 = Float(1) PitchVel1 = Float(1.5) PitchDelay2 = Float(1.) PitchVel2 = Float(2.04) generatorEfficiency = Float(0.94) overspeed_limit = Float(1500) minServoPitch = Float(0, desc='maximum pith angle', units='deg') maxServoPitchSpeed = Float(30, desc='Maximum pitch velocity operation', units='deg/s') maxServoPitchAcc = Float(8) poleFreqTorque = Float(0.05) poleDampTorque = Float(0.7) poleFreqPitch = Float(0.1) poleDampPitch = Float(0.7) gainScheduling = Enum(2, (1, 2), desc='Gain scheduling [1: linear, 2: quadratic]') prvs_turbine = Enum(0, (0, 1), desc='[0: pitch regulated, 1: stall regulated]') rotorspeed_gs = Enum(0, (0, 1), desc='Gain scheduling [0:standard, 1:with damping]') Kp2 = Float(0.0, desc='Additional gain-scheduling param. kp_speed') Ko1 = Float(1.0, desc='Additional gain-scheduling param. invkk1_speed') Ko2 = Float(0.0, desc='Additional gain-scheduling param. invkk2_speed') def set_constants(self, constants): for i, c in enumerate(constants): if c.val[0] == 1: self.ratedPower = c.val[1] * 1.e3 elif c.val[0] == 2: self.minRPM = c.val[1] * 60. / (2 * np.pi) elif c.val[0] == 3: self.maxRPM = c.val[1] * 60. / (2 * np.pi) elif c.val[0] == 4: self.maxTorque = c.val[1] elif c.val[0] == 5: self.minPitch = c.val[1] elif c.val[0] == 6: self.maxPitch = c.val[1] elif c.val[0] == 7: self.maxPitchSpeed = c.val[1] elif c.val[0] == 8: self.generatorFreq = c.val[1] elif c.val[0] == 9: self.generatorDamping = c.val[1] elif c.val[0] == 10: self.ffFreq = c.val[1] elif c.val[0] == 11: self.Qg = c.val[1] elif c.val[0] == 12: self.pgTorque = c.val[1] elif c.val[0] == 13: self.igTorque = c.val[1] elif c.val[0] == 14: self.dgTorque = c.val[1] elif c.val[0] == 15: self.generatorSwitch = c.val[1] elif c.val[0] == 16: self.pgPitch = c.val[1] elif c.val[0] == 17: self.igPitch = c.val[1] elif c.val[0] == 18: self.dgPitch = c.val[1] elif c.val[0] == 19: self.prPowerGain = c.val[1] elif c.val[0] == 20: self.intPowerGain = c.val[1] elif c.val[0] == 21: self.KK1 = c.val[1] elif c.val[0] == 22: self.KK2 = c.val[1] elif c.val[0] == 23: self.nlGainSpeed = c.val[1] elif c.val[0] == 24: self.cutin_t0 = c.val[1] elif c.val[0] == 25: self.softDelay = c.val[1] elif c.val[0] == 26: self.stop_t0 = c.val[1] elif c.val[0] == 27: self.TorqCutOff = c.val[1] elif c.val[0] == 29: self.PitchDelay1 = c.val[1] elif c.val[0] == 30: self.PitchVel1 = c.val[1] elif c.val[0] == 31: self.PitchDelay2 = c.val[1] elif c.val[0] == 32: self.PitchVel2 = c.val[1] elif c.val[0] == 39: self.overspeed_limit = c.val[1] # pick up the rest of the controller constants in generic variables else: self.add( 'constant%i' % (i + 1), Float(c.val[1], desc='Constant %i of type2_dll %s' % ((i + 1), self.name)))
class PdcylComp(ExternalCode): """ OpenMDAO component wrapper for PDCYL. """ icalc = Bool(False, iotype='in', desc='Print switch. Set to True for verbose output.') title = Str("PDCYl Component", iotype='in', desc='Title of the analysis') # Wing geometry # -------------------- wsweep = Float(iotype='in', units='deg', desc='Wing sweep referenced to the leading edge') war = Float(iotype='in', desc='Wing Aspect Ratio') wtaper = Float(iotype='in', desc=' Wing taper ratio') wtcroot = Float(iotype='in', desc=' Wing thickness-to-cord at root') wtctip = Float(iotype='in', desc=' Wing thickness-to-cord at tip') warea = Float(iotype='in', units='ft**2', desc='Wing planform area') # Material properties # -------------------- ps = Float(iotype='in', desc='Plasticity factor') tmgw = Float(iotype='in', units='inch', desc='Min. gage thickness for the wing') effw = Float(iotype='in', desc='Buckling efficiency of the web') effc = Float(iotype='in', desc='Buckling efficiency of the covers') esw = Float(iotype='in', units='psi', desc="Young's Modulus for wing material") fcsw = Float(iotype='in', units='psi', desc='Ult. compressive strength of wing') dsw = Float(iotype='in', units='lb/inch**3', desc=' Density of the wing material') kdew = Float(iotype='in', desc="Knock-down factor for Young's Modulus") kdfw = Float(iotype='in', desc='Knock-down factor for Ultimate strength') # Geometric parameters # -------------------- istama = Enum( [1, 2], iotype='in', desc=' 1 - Position of wing is unknown; 2 - position is known') cs1 = Float( iotype='in', desc= 'Position of structural wing box from leading edge as percent of root chord' ) cs2 = Float( iotype='in', desc= ' Position of structural wing box from trailing edge as percent of root chord' ) uwwg = Float(iotype='in', units='lb/ft**2', desc=' Wing Weight / Wing Area of baseline aircraft ') xwloc1 = Float(iotype='in', desc=' Location of wing as a percentage of body length') # Structural Concept # -------------------- claqr = Float(iotype='in', desc='Ratio of body lift to wing lift') ifuel = Enum( [1, 2], iotype='in', desc= ' 1 - No fuel is stored in the wing; 2 - Fuel is stored in the wing') cwman = Float(iotype='in', desc='Design maneuver load factor') cf = Float(iotype='in', desc="Shanley's const. for frame bending") # Tails # -------------------- itail = Enum( [1, 2], iotype='in', desc= ' 1 - Control surfaces mounted on tail; 2 - Control surfaces mounted on wing' ) uwt = Float( iotype='in', units='lb/ft**2', desc='(Htail Weight + Vtail Weight) / Htail Area of baseline aircraft') clrt = Float(iotype='in', desc=' Location of tail as a percentage of body length') harea = Float(iotype='in', units='ft**2', desc='Horizontal Tail Area') # Fuselage geometry # -------------------- frn = Float( iotype='in', desc='Fineness ratio of the nose section (length/diameter)') frab = Float( iotype='in', desc='Fineness ratio of the after-body section (length/diameter)') bodl = Float(iotype='in', units='ft', desc='Length of the fuselage ') bdmax = Float(iotype='in', units='ft', desc='Maximum diameter of fuselage') # These vars are listed in the pdcyl code, but they are never read in. Not sure # what that's all about. #vbod = Float(iotype='in', units='ft**3', desc='Fuselage total volume ') #volnose = Float(iotype='in', units='ft**3', desc='Nose Volume') #voltail = Float(iotype='in', units='ft**3', desc='Tail volume ') # Structural Concept # -------------------- ckf = Float(iotype='in', desc='Frame stiffness coefficient') ec = Float(iotype='in', desc='Power in approximation equation for buckling stability') kgc = Float( iotype='in', desc= 'Buckling coefficient for component general buckling of stiffener web panel' ) kgw = Float( iotype='in', desc='Buckling coefficient for component local buckling of web panel') # KCONT(12) ! Structural Geometry Concept Top/Bottom # KCONB(12) ! 2 - Simply stiffened shell, frames, sized for minimum weight in buckling # ! 3 - Z-stiffened shell, frames, best buckling # ! 4 - Z-stiffened shell, frames, buckling-minimum gage compromise # ! 5 - Z-stiffened shell, frames, buckling-pressure compromise # ! 6 - Truss-core sandwich, frames, best buckling # ! 8 - Truss-core sandwich, no frames, best buckling # ! 9 - Truss-core sandwich, no frames, buckling-min. gage-pressure compromise kcont = Enum([2, 3, 4, 5, 6, 8, 9], iotype='in', desc='Structural Geometry Concept Top') kconb = Enum([2, 3, 4, 5, 6, 8, 9], iotype='in', desc='Structural Geometry Concept Bottom') # Material properties # ------------------- ftst = Float(iotype='in', units='psi', desc="Tensile Strength on Top") ftsb = Float(iotype='in', units='psi', desc="Tensile Strength on Bottom") fcst = Float(iotype='in', units='psi', desc="Compressive Strength on Top") fcsb = Float(iotype='in', units='psi', desc="Compressive Strength on Bottom") est = Float(iotype='in', units='psi', desc="Young's Modulus for the shells Top") esb = Float(iotype='in', units='psi', desc="Young's Modulus for the shells Bottom") eft = Float(iotype='in', units='psi', desc="Young's Modulus for the frames Top") efb = Float(iotype='in', units='psi', desc="Young's Modulus for the frames Bottom") dst = Float(iotype='in', units='lb/inch**3', desc="Density of shell material on Top") dsb = Float(iotype='in', units='lb/inch**3', desc="Density of shell material on Bottom") dft = Float(iotype='in', units='lb/inch**3', desc="Density of frame material on Top") dfb = Float(iotype='in', units='lb/inch**3', desc="Density of frame material on Bottom") tmgt = Float(iotype='in', units='inch', desc="Minimum gage thickness Top") tmgb = Float(iotype='in', units='inch', desc="Minimum gage thickness Bottom") kde = Float(iotype='in', desc="Knock-down factor for modulus") kdf = Float(iotype='in', desc="Knock-down factor for strength") # Geometric parameters # -------------------- clbr1 = Float( iotype='in', desc='Fuselage break point as a fraction of total fuselage length') icyl = Enum( [1, 0], iotype='in', desc= ' 1 - modeled with a mid-body cylinder, 0 - use two power-law bodies back to back' ) # Engines # -------------------- neng = Int(iotype='in', desc=' Total number of engines') nengwing = Int(iotype='in', desc=' Number of engines on wing') wfp = Float(iotype='in', desc='(Engine Weight * NENG) / WGTO') clrw1 = Float( iotype='in', desc= ' Fractional location of first engine pair. Input 0 for centerline engine.' ) clrw2 = Float( iotype='in', desc= ' Fractional location of second engine pair. Measured from body centerline.' ) clrw3 = Float( iotype='in', desc= ' Fractional location of third engine pair. Measured from body centerline.' ) # Loads # -------------------- deslf = Float(iotype='in', desc='Design load factor') ultlf = Float(iotype='in', desc='Ultimate load factor (usually 1.5*DESLF)') axac = Float(iotype='in', desc='Axial acceleration') cman = Float(iotype='in', desc=' Weight fraction at maneuver') iload = Enum( [1, 2, 3], iotype='in', desc= '1 - Analyze maneuver only; 2 - Analyze maneuver and landing only; 3 - Analyze bump, landing and maneuver' ) pgt = Float(iotype='in', units='psi', desc="Fuselage gage pressure on top") pgb = Float(iotype='in', units='psi', desc="Fuselage gage pressure on bottom") wfbump = Float(iotype='in', desc=' Weight fraction at bump') wfland = Float(iotype='in', desc=' Weight fraction at landing') # Landing Gear # ------------------- vsink = Float(iotype='in', units='ft/s', desc='Design sink velocity at landing ') stroke = Float(iotype='in', units='ft', desc=' Stroke of landing gear ') clrg1 = Float( iotype='in', desc= 'Length fraction of nose landing gear measured as a fraction of total fuselage length' ) clrg2 = Float( iotype='in', desc= 'Length fraction of main landing gear measured as a fraction of total fuselage length' ) wfgr1 = Float(iotype='in', desc='Weight fraction of nose landing gear') wfgr2 = Float(iotype='in', desc='Weight fraction of main landing gear') igear = Enum( [1, 2], iotype='in', desc= '1 - Main landing gear located on fuselage, 2 - Main landing gear located on wing' ) gfrl = Float( iotype='in', desc= 'Ratio of force taken by nose landing gear to force taken by main gear at landing' ) clrgw1 = Float( iotype='in', desc='Position of wing gear as a fraction of structural semispan') clrgw2 = Float( iotype='in', desc= 'Position of second pair wing gear as a fraction of structural semispan' ) # Weights # ------------------- wgto = Float(iotype='in', units='lb', desc=' Gross takeoff weight') wtff = Float(iotype='in', desc='Weight fraction of fuel') cbum = Float(iotype='in', desc='Weight fraction at bump') clan = Float(iotype='in', desc='Weight fraction at landing') # Factors # -------------------- ischrenk = Int( iotype='in', desc= '1 - use Schrenk load distribution on wing,Else - use trapezoidal distribution' ) icomnd = Enum( [1, 2], iotype='in', desc= '1 - print gross shell dimensions envelope, 2 - print detailed shell geometry' ) wgno = Float( iotype='in', desc='Nonoptimal factor for wing (including the secondary structure)') slfmb = Float(iotype='in', desc='Static load factor for bumps') wmis = Float(iotype='in', desc='Volume component of secondary structure') wsur = Float(iotype='in', desc='Surface area component of secondary structure') wcw = Float(iotype='in', desc='Factor in weight equation for nonoptimal weights') wca = Float(iotype='in', desc='Factor in weight equation for nonoptimal weights') nwing = Int(iotype='in', desc='Number of wing segments for analysis') # Outputs # -------------------- wfuselaget = Float(iotype='out', units='lb', desc='Total fuselage weight') wwingt = Float(iotype='out', units='lb', desc='Total wing weight') def __init__(self, directory=''): """Constructor for the PdcylComp component""" super(PdcylComp, self).__init__(directory) # External Code public variables self.stdin = 'PDCYL.in' self.stdout = 'PDCYL.out' self.stderr = 'PDCYL.err' self.command = ['PDCYL'] self.external_files = [ FileMetadata(path=self.stdin, input=True), FileMetadata(path=self.stdout), FileMetadata(path=self.stderr), ] # Dictionary contains location of every numeric scalar variable fields = {} fields[8] = 'wsweep' fields[9] = 'war' fields[10] = 'wtaper' fields[11] = 'wtcroot' fields[12] = 'wtctip' fields[13] = 'warea' fields[15] = 'ps' fields[16] = 'tmgw' fields[17] = 'effw' fields[18] = 'effc' fields[19] = 'esw' fields[20] = 'fcsw' fields[21] = 'dsw' fields[22] = 'kdew' fields[23] = 'kdfw' fields[25] = 'istama' fields[27] = 'cs1' fields[28] = 'cs2' fields[29] = 'uwwg' fields[30] = 'xwloc1' fields[32] = 'claqr' fields[33] = 'ifuel' fields[35] = 'cwman' fields[36] = 'cf' fields[40] = 'itail' fields[42] = 'uwt' fields[43] = 'clrt' fields[44] = 'harea' fields[49] = 'frn' fields[50] = 'frab' fields[51] = 'bodl' fields[52] = 'bdmax' fields[54] = 'ckf' fields[55] = 'ec' fields[56] = 'kgc' fields[57] = 'kgw' fields[58] = 'kcont' fields[59] = 'kconb' fields[67] = 'ftst' fields[68] = 'ftsb' fields[69] = 'fcst' fields[70] = 'fcsb' fields[71] = 'est' fields[72] = 'esb' fields[73] = 'eft' fields[74] = 'efb' fields[75] = 'dst' fields[76] = 'dsb' fields[77] = 'dft' fields[78] = 'dfb' fields[79] = 'tmgt' fields[80] = 'tmgb' fields[81] = 'kde' fields[82] = 'kdf' fields[84] = 'clbr1' fields[85] = 'icyl' fields[90] = 'neng' fields[91] = 'nengwing' fields[92] = 'wfp' fields[93] = 'clrw1' fields[95] = 'clrw2' fields[96] = 'clrw3' fields[100] = 'deslf' fields[101] = 'ultlf' fields[102] = 'axac' fields[103] = 'cman' fields[104] = 'iload' fields[107] = 'pgt' fields[108] = 'pgb' fields[109] = 'wfbump' fields[110] = 'wfland' fields[114] = 'vsink' fields[115] = 'stroke' fields[116] = 'clrg1' fields[117] = 'clrg2' fields[118] = 'wfgr1' fields[119] = 'wfgr2' fields[120] = 'igear' fields[122] = 'gfrl' fields[123] = 'clrgw1' fields[124] = 'clrgw2' fields[129] = 'wgto' fields[130] = 'wtff' fields[131] = 'cbum' fields[132] = 'clan' fields[136] = 'ischrenk' fields[138] = 'icomnd' fields[140] = 'wgno' fields[141] = 'slfmb' fields[142] = 'wmis' fields[143] = 'wsur' fields[144] = 'wcw' fields[145] = 'wca' fields[146] = 'nwing' self._fields = fields def execute(self): """Run PDCYL.""" #Prepare the input file for PDCYL self.generate_input() #Run PDCYL via ExternalCode's execute function super(PdcylComp, self).execute() #Parse the outut file from PDCYL self.parse_output() def generate_input(self): """Creates the PDCYL custom input file.""" data = [] form = "%.15g %s\n" # It turns out to be simple and quick to generate a new input file each # time, rather than poking values into a template. data.append("\n\n") data.append(self.title) data.append("\n\n") if self.icalc == True: icalc = 3 else: icalc = 0 data.append("%d icalc print switch" % icalc) data.append("\n\n\n") data.append("Wing geometry:\n") for nline in range(8, 14): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("Material properties:\n") for nline in range(15, 24): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("Geometric properties:\n") name = self._fields[25] data.append(form % (self.get(name), name)) data.append("\n") for nline in range(27, 31): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("Structural concept:\n") for nline in range(32, 34): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n") for nline in range(35, 37): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n") data.append("Tails:\n") name = self._fields[40] data.append(form % (self.get(name), name)) data.append("\n") for nline in range(42, 45): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n\n") data.append("Fuselage geometry:\n") for nline in range(49, 53): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("Structural concept:\n") for nline in range(54, 60): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n\n\n\n\n") data.append("Material properties:\n") for nline in range(67, 83): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("Geometric parameters:\n") for nline in range(84, 86): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n\n") data.append("Engines:\n") for nline in range(90, 94): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n") for nline in range(95, 97): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n") data.append("Loads:\n") for nline in range(100, 105): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n") for nline in range(107, 111): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n") data.append("Landing gear:\n") for nline in range(114, 121): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n") for nline in range(122, 125): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n\n") data.append("Weights:\n") for nline in range(129, 133): name = self._fields[nline] data.append(form % (self.get(name), name)) data.append("\n\n") data.append("Factors:\n") name = self._fields[136] data.append(form % (self.get(name), name)) data.append("\n") name = self._fields[138] data.append(form % (self.get(name), name)) data.append("\n") for nline in range(140, 147): name = self._fields[nline] data.append(form % (self.get(name), name)) outfile = open(self.stdin, 'w') outfile.writelines(data) outfile.close() def parse_output(self): """Parses the PCYL output file and extracts data.""" infile = FileParser() infile.set_file(self.stdout) self.wwingt = infile.transfer_keyvar("Total Wing Structural Weight", 1) self.wfuselaget = infile.transfer_keyvar( "Fuselage Total Structural Weight", 1) def load_model(self, filename): """Reads in an existing PDCYL input file and populates the variable tree with its values.""" infile = FileParser() infile.set_file(filename) # Title is a string self.title = infile.transfer_line(2) # Print flag becomes a Bool if infile.transfer_var(4, 1) == 3: self.icalc = True else: self.icalc = False # Named variables in dictionary for key, val in self._fields.iteritems(): self.set(val, infile.transfer_var(key, 1))
class LoftedBladeSurface(Component): pf = VarTree(BladePlanformVT(), iotype='in') base_airfoils = List(iotype='in') blend_var = Array(iotype='in') chord_ni = Int(300, iotype='in') span_ni = Int(300, iotype='in') interp_type = Enum('rthick', ('rthick', 's'), iotype='in') surface_spline = Str('akima', iotype='in', desc='Spline') rot_order = Array(np.array([2, 1, 0]), iotype='in', desc='rotation order of airfoil sections' 'default z,y,x (twist,sweep,dihedral)') surfout = VarTree(BladeSurfaceVT(), iotype='out') surfnorot = VarTree(BladeSurfaceVT(), iotype='out') def execute(self): self.interpolator = BlendAirfoilShapes() self.interpolator.ni = self.chord_ni self.interpolator.spline = self.surface_spline self.interpolator.blend_var = self.blend_var self.interpolator.airfoil_list = self.base_airfoils self.interpolator.initialize() self.span_ni = self.pf.s.shape[0] x = np.zeros((self.chord_ni, self.span_ni, 3)) for i in range(self.span_ni): s = self.pf.s[i] pos_x = self.pf.x[i] pos_y = self.pf.y[i] pos_z = self.pf.z[i] chord = self.pf.chord[i] p_le = self.pf.p_le[i] # generate the blended airfoil shape if self.interp_type == 'rthick': rthick = self.pf.rthick[i] points = self.interpolator(rthick) else: points = self.interpolator(s) points *= chord points[:, 0] += pos_x - chord * p_le # x-coordinate needs to be inverted for clockwise rotating blades x[:, i, :] = (np.array( [-points[:, 0], points[:, 1], x.shape[0] * [pos_z]]).T) # save non-rotated blade (only really applicable for straight blades) x_norm = x.copy() x[:, :, 1] += self.pf.y x = self.rotate(x) self.surfnorot.surface = x_norm self.surfout.surface = x def rotate(self, x): """ rotate blade sections accounting for twist and main axis orientation the blade will be built with a "sheared" layout, ie no rotation around y in the case of sweep. if the main axis includes a winglet, the blade sections will be rotated accordingly. ensure that an adequate point distribution is used in this case to avoid sections colliding in the winglet junction! """ main_axis = Curve(points=np.array([self.pf.x, self.pf.y, self.pf.z]).T) rot_normals = np.zeros((3, 3)) x_rot = np.zeros(x.shape) for i in range(x.shape[1]): points = x[:, i, :] rot_center = main_axis.points[i] # rotation angles read from file angles = np.array([ self.pf.rot_x[i], self.pf.rot_y[i], self.pf.rot_z[i] ]) * np.pi / 180. # compute rotation angles of main_axis t = main_axis.dp[i] rot = np.zeros(3) rot[0] = -np.arctan(t[1] / (t[2] + 1.e-20)) v = np.array([t[2], t[1]]) vt = np.dot(v, v)**0.5 rot[1] = (np.arcsin(t[0] / vt)) angles[0] += rot[0] angles[1] += rot[1] # compute x-y-z normal vectors of rotation n_y = np.cross(t, [1, 0, 0]) n_y = n_y / norm(n_y) rot_normals[0, :] = np.array([1, 0, 0]) rot_normals[1, :] = n_y rot_normals[2, :] = t # compute final rotation matrix rotation_matrix = np.matrix([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) for n, ii in enumerate(self.rot_order): mat = np.matrix(RotMat(rot_normals[ii], angles[ii])) rotation_matrix = mat * rotation_matrix # apply rotation x_rot[:, i, :] = dotXC(rotation_matrix, points, rot_center) return x_rot
class SplineComponentBase(Component): """ FUSED-Wind base class for splines """ spline_type = Enum('pchip', ('pchip', 'bezier', 'bspline', 'akima', 'cubic'), iotype='in', desc='spline type used') nC = Int(iotype='in') Cx = Array(iotype='in', desc='Spanwise distribution of control points [0:1]') x = Array(iotype='in', desc='Spanwise discretization') xinit = Array(np.linspace(0, 1, 10), iotype='in', desc='Initial spanwise distribution') Pinit = Array(np.zeros(10), iotype='in', desc='Initial curve as function of span') P = Array(iotype='out', desc='Output curve') def __init__(self, nC=8): super(SplineComponentBase, self).__init__() self.init_called = False self.nC = nC # the spline engine derived from SplineBase (set by parent class) self.spline = None self.add( 'C', Array( np.zeros(nC), size=(nC, ), dtype=float, iotype='in', desc='spline control points of cross-sectional curve fraction' 'ending point of region')) self.set_spline(self.spline_type) def set_spline(self, spline_type): self.spline = spline_dict[spline_type]() self.spline_type = spline_type def initialize(self): """ """ self.set_spline(self.spline_type) self.C = self.spline(self.Cx, self.xinit, self.Pinit) def execute(self): """ Default behaviour is to copy the input array derived classes need to overwrite this class with specific splines """ if not self.init_called: self.initialize() self.P = self.spline(self.x, self.Cx, self.C)
class HAWC2Wrapper(ExternalCode): solver = Enum('HAWC2', ('HAWC2', 'HAWC2aero', 'HAWC2S'), iotype='in', desc='Choose between running with HAWC2 or HAWC2aero') hawc2bin = Str('hawc2MB.exe', io_type='in', desc='Name of program, e.g. hawc2mb.exe', iotype='in') wp_datafile = Str('wpdata.100', io_type='in', desc='wp data file', iotype='in') wine_cmd = Str('wine', desc='Name of the wine command for Linux/OSX', iotype='in') case_id = Str('hawc2_case', iotype='in') data_directory = Str('data', iotype='in') res_directory = Str(iotype='in') turb_directory = Str('turb', iotype='in') log_directory = Str(iotype='in') control_directory = Str('control', iotype='in') copyback_results = Bool(True, iotype='in') RunHAWCflag = Bool(True, iotype='in') Flag = Bool(True, iotype='in') OutputFlag = Bool(False, iotype='out') def __init__(self): super(HAWC2Wrapper, self).__init__() self._data_directory = 'data' self._control_directory = 'control' self.force_execute = True self.basedir = os.getcwd() def add_external_files(self): self.external_files.extend([ FileMetadata(path=os.path.join(self.basedir, self.hawc2bin), input=True, binary=True, desc='DLL files.'), FileMetadata(path=os.path.join(self.basedir, self.wp_datafile), input=True, binary=True, desc='wpdata file.'), FileMetadata(path=os.path.join(self.basedir, 'resourse.dat'), input=True, binary=True, desc='resourse.dat file.'), FileMetadata(path=os.path.join(self.basedir, '*.DLL'), input=True, binary=True, desc='DLL files.'), FileMetadata(path=os.path.join(self.basedir, '*.dll'), input=True, binary=True, desc='dll files.'), FileMetadata(path=os.path.join(self.data_directory, '*'), input=True, desc='data files.'), FileMetadata(path=os.path.join(self.control_directory, '*'), input=True, binary=True, desc='controller DLLs.'), FileMetadata(path=os.path.join(self.turb_directory, '*'), input=True, binary=True, desc='turbulence files.')]) def execute(self): self._logger.info('executing %s for case %s ...' % (self.solver, self.case_id)) tt = time.time() self.command = [] # check platform and add wine to command list if we're on OS X or Linux _platform = platform.platform() if 'Linux' in _platform or 'Darwin' in _platform: self.command.append(self.wine_cmd) self.command.append(self.hawc2bin) self.command.append(self.case_id+'.htc') self._logger.info('data directory %s' % self.data_directory) try: if self.RunHAWCflag: super(HAWC2Wrapper, self).execute() else: self._logger.info('HAWC2 dry run ...') self.copy_results(os.path.join(self.basedir, self.case_id), '*') self.OutputFlag = True except: self._logger.info('HAWC2 crashed ...') self.OutputFlag = False if self.solver is 'HAWC2S': with open(self.case_id + '.log') as fid: for line in fid.readlines(): if ('Maximum number' in line) and\ ('iterations exceeded' in line): print line if self.copyback_results and 'fd' not in self.parent.itername: results_dir = os.path.join(self.basedir, self.case_id + '_'+self.itername) try: os.mkdir(results_dir) except: pass # self.copy_results_dirs(results_dir, '', overwrite=True) files = glob.glob(self.case_id + '*.*') files.append('error.out') for filename in files: try: shutil.copy(filename, results_dir) #os.remove(filename) except: self._logger.warning('failed copying back file %s %s' % (filename, results_dir)) try: shutil.rmtree(os.path.join(results_dir, 'data'), ignore_errors=True) shutil.copytree('data', os.path.join(results_dir, 'data')) except: self._logger.warning('failed copying back data directory for' + ' case %s' % self.case_id) try: shutil.rmtree(os.path.join(results_dir, 'res'), ignore_errors=True) shutil.copytree('res', os.path.join(results_dir, 'res')) except: self._logger.warning('failed copying back res directory for' + ' case %s' % self.case_id) self._logger.info('HAWC2Wrapper simulation time: %f' % (time.time() - tt)) def zipdir(self, path): zip = zipfile.ZipFile(path + '.zip', 'w') for root, dirs, files in os.walk(path): for file in files: zip.write(os.path.join(root, file)) zip.close() def copy_input_dirs(self, directory, patterns, overwrite=False): """copy """ if isinstance(patterns, basestring): patterns = [patterns] for pattern in patterns: pattern = os.path.join(directory, pattern) for src_path in sorted(glob.glob(pattern)): dst_path = os.path.basename(src_path) if overwrite: try: shutil.rmtree(dst_path) except: pass self._logger.debug(' %s', src_path) try: shutil.copytree(src_path, dst_path) except: raise RuntimeError('Copy failed - directory probably exists. use overwrite = True') def copy_results_dirs(self, directory, patterns, overwrite=False): """copy results from execution directory back to simulation root""" if isinstance(patterns, basestring): patterns = [patterns] for pattern in patterns: for src_path in sorted(glob.glob(pattern)): dst_path = os.path.join(directory, pattern) if overwrite: try: shutil.rmtree(dst_path) except: pass self._logger.debug(' %s', src_path) try: shutil.copytree(src_path, dst_path) except: raise RuntimeError('Copy failed - directory probably exists. use overwrite = True')
class GenDriver(Driver): """ Custom Genetic Driver """ implements(IHasParameters) #, IHasObjective, IOptimizer) # pylint: disable-msg=E1101 opt_type = Enum( "minimize", values=["minimize", "maximize"], iotype="in", desc= 'Sets the optimization to either minimize or maximize the objective function.' ) generations = Int( 10, iotype="in", desc= "The maximum number of generations the algorithm will evolve to before stopping." ) population_size = Float( 50, iotype="in", desc="The size of the population in each generation.") crossover_rate = Float( 0.8, iotype="in", low=0.0, high=1.0, desc= "The crossover rate used when two parent genomes reproduce to form a child genome." ) mutation_rate = Float( 0.03, iotype="in", low=0.0, high=1.0, desc="The mutation rate applied to population members.") #selection_method = Enum("roulette_wheel", ("roulette_wheel","rank","uniform"), iotype="in", desc="The selection method used to pick population members who will survive for breeding into the next generation.") #elitism = Bool(False, iotype="in", desc="Controls the use of elitism in the creation of new generations.") #best_individual = Slot(klass=GenomeBase.GenomeBase, desc="The genome with the best score from the optimization.") def _build_problem(self): """ builds the problem """ alleles = GAllele.GAlleles() count = 0 for param in self.get_parameters().values(): allele = None count += 1 val = param.evaluate()[0] #now grab the value low = param.low high = param.high metadata = param.get_metadata()[1] #then it's a float or an int, or a member of an array if ('low' in metadata or 'high' in metadata) or \ array_test.search(param.targets[0]): #some kind of int if isinstance(val, int_types): allele = GAllele.GAlleleRange(begin=low, end=high, real=False) elif isinstance(val, real_types): #some kind of float allele = GAllele.GAlleleRange(begin=low, end=high, real=True) elif "values" in metadata and \ isinstance(metadata['values'], iterable_types): allele = GAllele.GAlleleList(metadata['values']) if allele: alleles.add(allele) else: self.raise_exception( "%s is not a float, int, or enumerated " "datatype. Only these 3 types are allowed" % param.targets[0], ValueError) self.count = count return alleles def execute(self): """Perform the optimization""" self.set_events() alleles = self._make_alleles() genome = G1DList.G1DList(len(alleles)) genome.setParams(allele=alleles) genome.evaluator.set(self._run_model) genome.mutator.set(Mutators.G1DListMutatorAllele) genome.initializator.set(Initializators.G1DListInitializatorAllele) #TODO: fix tournament size settings #genome.setParams(tournamentPool=self.tournament_size) # Genetic Algorithm Instance #print self.seed #configuring the options ga = GSimpleGA.GSimpleGA(genome, interactiveMode=False, seed=self.seed) pop = ga.getPopulation() pop = pop.scaleMethod.set(Scaling.SigmaTruncScaling) ga.setMinimax(Consts.minimaxType[self.opt_type]) ga.setGenerations(self.generations) ga.setMutationRate(self.mutation_rate) if self.count > 1: ga.setCrossoverRate(self.crossover_rate) else: ga.setCrossoverRate(0) ga.setPopulationSize(self.population_size) ga.setElitism(self.elitism) #setting the selector for the algorithm ga.selector.set(self._selection_mapping[self.selection_method]) #GO ga.evolve(freq_stats=0) self.best_individual = ga.bestIndividual() #run it once to get the model into the optimal state self._run_model(self.best_individual) def _run_model(self, chromosome): self.set_parameters([val for val in chromosome]) self.run_iteration() return self.eval_objective() # uncomment this to add parameter handling #implements(IHasParameters) # declare inputs and outputs here, for example: #x = Float(0.0, iotype='in', desc='description for x') #y = Float(0.0, iotype='out', desc='description for y') def start_iteration(self): super(MyDriver, self).start_iteration() def continue_iteration(self): return super(MyDriver, self).continue_iteration() def pre_iteration(self): super(MyDriver, self).pre_iteration() def run_iteration(self): super(MyDriver, self).run_iteration() def post_iteration(self): super(MyDriver, self).post_iteration()