Example #1
0
class MIMOEquation(Component):
    """Equation with 2 inputs and 2 outputs"""

    # pylint: disable-msg=E1101
    x1 = Float(1.0, iotype='in', desc='Global Design Variable')
    x2 = Float(1.0, iotype='in', desc='Global Design Variable')
    x3 = Float(1.0, iotype='in', desc='Global Design Variable')
    x4 = Float(1.0, iotype='in', desc='Global Design Variable')
    x5 = Float(1.0, iotype='in', desc='Global Design Variable')

    f1 = Float(iotype='out', desc='Output of this Discipline')
    f2 = Float(iotype='out', desc='Output of this Discipline')
    f3 = Float(iotype='out', desc='Output of this Discipline')
    f4 = Float(iotype='out', desc='Output of this Discipline')
    f5 = Float(iotype='out', desc='Output of this Discipline')

    def execute(self):
        """Should converge to x=[0,0,0,0,0]"""

        xx = numpy.array([self.x1, self.x2, self.x3, self.x4, self.x5])

        d = numpy.array([3, 2, 1.5, 1, 0.5])
        c = 0.01

        ff = -d * numpy.array(xx) - c * numpy.array(xx)**3

        self.f1 = ff[0]
        self.f2 = ff[1]
        self.f3 = ff[2]
        self.f4 = ff[3]
        self.f5 = ff[4]
Example #2
0
class DumbComp(Component):
    """A component whose output is independent of the input."""

    # pylint: disable-msg=E1101
    x1 = Float(1.0, iotype='in', desc='Global Design Variable')
    f1 = Float(3.14, iotype='out', desc='Output of this Discipline')

    def execute(self):
        """Do nothing"""

        pass
Example #3
0
 def setUp(self):
     """this setup function will be called before each test in this class"""
     self.hobj = Container()
     self.hobj.add('float1', 
                         Float(98.9, low=0., high=99.0, desc="Stuff",
                               iotype='in', units='ft'))
     self.hobj.add('float2', 
                         Float(13.2, iotype='out', units='inch', low=-9999.))
     self.hobj.add('float3', 
                         Float(low=0., high=99.,
                                    iotype='in', units='kg'))
     
     self.hobj.float1 = 3.1415926
     self.hobj.float2 = 42.
     self.hobj.float3 = 1.1
 def test_attributes(self):
     try:
         self.hobj.add('badbounds',
                       Float(98.0, low=100.0, high=0.0, iotype='in'))
     except Exception, err:
         errstring = "Lower bound is greater than upper bound."
         self.assertEqual(str(err), errstring)
Example #5
0
 def test_default_value_type(self):
     try:
         self.hobj.add('bad_default',
                             Float('Bad Wolf'))
     except ValueError, err:
         self.assertEqual(str(err), 
             "Default value should be a float.")
Example #6
0
 def test_default_value(self):
     try:
         self.hobj.add('out_of_bounds',
                             Float(5.0, low=3, high=4))
     except ValueError, err:
         self.assertEqual(str(err), 
             "Default value is outside of bounds [3.0, 4.0].")
    def test_constructor_defaults(self):

        self.hobj.add('float_nodefault1',
                      Float(low=3.0, high=4.0, iotype='in', units='kg'))
        self.assertEqual(3.0, self.hobj.float_nodefault1)

        self.hobj.add('float_nodefault2',
                      Float(high=4.0, iotype='in', units='kg'))
        self.assertEqual(4.0, self.hobj.float_nodefault2)

        self.hobj.add('float_nodefault3', Float(iotype='in', units='kg'))
        self.assertEqual(0.0, self.hobj.float_nodefault3)

        self.hobj.add('float_nounits', Float(low=3.0, high=4.0, iotype='in'))
        if hasattr(self.hobj.float_nounits, 'units'):
            self.fail("Unitless Float should not have units")
Example #8
0
 def test_int_limits(self):
     # Ensure limits that are ints don't cause something like this:
     #     Trait 'symmetry_angle' must be a float in the range (0, 180]
     #     but attempted value is 11.25
     self.hobj.add('symmetry_angle',
                         Float(low=0, exclude_low=True, high=180))
     self.hobj.symmetry_angle = 11.25
     self.assertEqual(self.hobj.symmetry_angle, 11.25)
Example #9
0
 def test_exclusions(self):
     
     self.hobj.add('float4', Float(low=3.0, high=4.0, \
                               exclude_low=True, exclude_high=True, \
                               iotype='in', units='kg'))
     try:
         self.hobj.float4 = 3.0
     except ValueError, err:
         self.assertEqual(str(err), 
             ": Variable 'float4' must be a float in the range (3.0, 4.0), but a value of 3.0 <type 'float'> was specified.")
Example #10
0
    def test_set_to_default(self):
        self.assertEqual(3.1415926, self.hobj.float1)
        self.hobj.add('float4', Float(iotype='in', units='kg'))
        self.assertEqual(0., self.hobj.float4)
        self.hobj.float4 = 6.5
        self.assertEqual(6.5, self.hobj.float4)

        self.hobj.revert_to_defaults()

        self.assertEqual(98.9, self.hobj.float1)
        self.assertEqual(0., self.hobj.float4)
Example #11
0
class SellarDiscipline1(Component):
    """Component containing Discipline 1"""

    # pylint: disable-msg=E1101
    z1 = Float(0.0, iotype='in', desc='Global Design Variable')
    z2 = Float(0.0, iotype='in', desc='Global Design Variable')
    x1 = Float(0.0, iotype='in', desc='Local Design Variable')
    y2 = Float(0.0, iotype='in', desc='Disciplinary Coupling')

    y1 = Float(iotype='out', desc='Output of this Discipline')

    def execute(self):
        """Evaluates the equation  
        y1 = z1**2 + z2 + x1 - 0.2*y2"""

        z1 = self.z1
        z2 = self.z2
        x1 = self.x1
        y2 = self.y2

        self.y1 = z1**2 + z2 + x1 - 0.2 * y2
Example #12
0
class ElNetLength(TopfarmComponent):
    wt_positions = Array(
        [],
        unit='m',
        iotype='in',
        desc='Array of wind turbines attached to particular positions')
    #wt_layout = VarTree(GenericWindFarmTurbineLayout(), iotype='in', desc='wind turbine properties and layout')
    elnet_layout = Dict(
        iotype='out')  #VarTree(GenericWindTurbineCableLayout(), iotype='out')
    elnet_length = Float(iotype='out',
                         desc='The total inner cable length',
                         unit='m')
    scaling = Float(1.0, iotype='in', desc='')

    def execute(self):
        elnet_layout = elnet(self.wt_positions)
        if self.scaling == 0.0:
            #using the first run as a baseline for scaling:
            self.scaling = sum(elnet_layout.values())
        self.elnet_length = sum(elnet_layout.values()) / self.scaling
        self.elnet_layout = elnet_layout
Example #13
0
class SellarDiscipline2(Component):
    """Component containing Discipline 2"""

    # pylint: disable-msg=E1101
    z1 = Float(0.0, iotype='in', desc='Global Design Variable')
    z2 = Float(0.0, iotype='in', desc='Global Design Variable')
    y1 = Float(0.0, iotype='in', desc='Disciplinary Coupling')

    y2 = Float(iotype='out', desc='Output of this Discipline')

    def execute(self):
        """Evaluates the equation  
        y1 = y1**(.5) + z1 + z2"""

        z1 = self.z1
        z2 = self.z2

        # Note: this may cause some issues. However, y1 is constrained to be
        # above 3.16, so lets just let it converge, and the optimizer will
        # throw it out
        y1 = abs(self.y1)

        self.y2 = y1**(.5) + z1 + z2
Example #14
0
class FoundationLength(TopfarmComponent):
    wt_positions = Array(
        [],
        unit='m',
        iotype='in',
        desc='Array of wind turbines attached to particular positions')
    ##wt_layout = VarTree(GenericWindFarmTurbineLayout(), iotype='in', desc='wind turbine properties and layout')
    borders = Array(iotype='in',
                    desc='The polygon defining the borders ndarray([n_bor,2])',
                    unit='m')
    depth = Array(iotype='in',
                  desc='An array of depth ndarray([n_d, 2])',
                  unit='m')
    foundation_length = Float(
        iotype='out', desc='The total foundation length of the wind farm')
    foundations = Array(iotype='out',
                        desc='The foundation length ofeach wind turbine')
    scaling = Float(1.0, iotype='in', desc='scaling of the foundation')
    inc = 0

    def execute(self):
        foundation_func = LinearNDInterpolator(self.depth[:, 0:2],
                                               self.depth[:, 2])
        self.foundations = array([
            foundation_func(self.wt_positions[i, 0], self.wt_positions[i, 1])
            for i in range(self.wt_positions.shape[0])
        ])
        #dist = DistFromBorders()(wt_positions=self.wt_positions, borders=self.borders).dist
        min_depth = self.depth[:, 2].min()
        self.foundations[isnan(self.foundations)] = min_depth

        if self.scaling == 0.0:
            # Using the baseline for scaling
            self.scaling = sum(self.foundations)

        self.foundation_length = sum(self.foundations) / self.scaling
Example #15
0
 def test_intvalues(self):
     f1 = Float(3,low=2,high=4)
     d1 = f1.default_value/2
     self.assertAlmostEqual(d1, 1.5, places=4)
Example #16
0
 def test_bogus_units(self):
     try:
         uf = Float(0., iotype='in', units='bogus')
     except ValueError, err:
         self.assertEqual(str(err), 
                          "Units of 'bogus' are invalid")
Example #17
0
class AEP(TopfarmComponent):

    # Inputs
    wind_speeds = List([], iotype='in', units='m/s',
        desc='The different wind speeds to run [nWS]')

    wind_directions = List([], iotype='in', units='deg',
        desc='The different wind directions to run [nWD]')

    wt_positions = Array(iotype='in')

    scaling = Float(1.0, iotype='in', desc='Scaling of the AEP')

    # Outputs
    array_aep = Array([], iotype='out', units='kW*h',
        desc='The energy production per sector [nWD, nWS]')

    gross_aep = Float(iotype='out', units='kW*h',
        desc='Gross Annual Energy Production before availability and loss impacts')

    net_aep = Float(iotype='out', units='kW*h',
        desc='Net Annual Energy Production after availability and loss impacts')

    capacity_factor = Float(0.0, iotype='out',
        desc='Capacity factor for wind plant')


    def __init__(self, wt_layout, wind_rose, wf, **kwargs):
        """

        :param wt_layout: GenericWindFarmTurbineLayout()
        :param wind_rose: WeibullWindRoseVT()
        :param wf: GenericWindFarm()
        :param scaling: float [default = 1.0]
                        The scaling used to calculate the net_aep. If it is set to 0.0, the scaling
                        will be set to the net_aep the first time the simulation is run.
        """
        self.wf = wf
        self.wf.wt_layout = wt_layout
        self.wind_rose = wind_rose
        super(AEP, self).__init__(**kwargs)

    def execute(self):

        # build the cdf vector of the wind speed for each wind rose wind direction sector
        cdfw = []
        for iwd, wd in enumerate(self.wind_rose.wind_directions):
            cdfw.append(weibullCDF(self.wind_speeds, self.wind_rose.A[iwd], self.wind_rose.k[iwd]))

        # calculate the probability in each wind direction sector, using the CDF of the wind rose wind direction
        cdfd0 = [sum(self.wind_rose.frequency[:i]) for i in range(len(self.wind_rose.frequency)+1)]
        wd = np.hstack([self.wind_rose.wind_directions, [360]])
        cdfd1 = interp1d(wd, cdfd0)(self.wind_directions)

        net_aep = 0.0
        gross_aep = 0.0
        cwd = 0
        net_aeps = np.zeros([len(self.wind_directions)])
        gross_aeps = np.zeros([len(self.wind_directions)])
        self.powers = np.zeros([len(self.wind_directions), len(self.wind_speeds)])
        for iwd, wd in enumerate(self.wind_directions):
            if cwd < len(self.wind_rose.wind_directions):
                while wd >= self.wind_rose.wind_directions[cwd+1] and cwd < len(self.wind_rose.wind_directions)-2:
                    # switching wind rose wind direction sector
                    cwd += 1
            powers = np.zeros([len(self.wind_speeds)])
            for iws, ws in enumerate(self.wind_speeds):
                self.wf.wt_layout.wt_positions=self.wt_positions
                self.wf.wind_speed=ws
                self.wf.wind_direction=wd
                self.wf.run()
                powers[iws] = self.wf.power
            self.powers[iwd,:] = powers
            # Integrating over the wind speed CDF
            net_aeps[iwd] = np.trapz(powers, cdfw[cwd]) * 365.0 * 24.0
            for i in range(self.wt_positions.shape[0]):
                power_curve = interp1d(self.wf.wt_layout.wt_list[i].power_curve[:,0],
                                       self.wf.wt_layout.wt_list[i].power_curve[:,1])(self.wind_speeds)
                gross_aeps[iwd] += np.trapz(power_curve, cdfw[cwd]) * 365.0 * 24.0

        # Integrating over the wind direction CDF
        net_aep = np.trapz(net_aeps, cdfd1)
        gross_aep = np.trapz(gross_aeps, cdfd1)

        self.capacity_factor = net_aep / gross_aep

        if self.scaling == 0.0:
            # The scaling has to be calculated
            self.scaling = net_aep

        self.net_aep = net_aep / self.scaling
        self.gross_aep = gross_aep
Example #18
0
class AEPFortranMultipleWindRoses(TopfarmComponent):

    # Inputs
    wind_speeds = List([], iotype='in', units='m/s',
        desc='The different wind speeds to run [nWS]')

    wind_directions = List([], iotype='in', units='deg',
        desc='The different wind directions to run [nWD]')

    turbulence_intensity = Float(0.1, iotype='in',
        desc='The turbulence intensity at the site')

    wt_positions = Array(iotype='in')

    wind_roses = List(iotype='in', desc='List of weibull wind_rose arrays')

    scaling = Float(1.0, iotype='in', desc='Scaling of the AEP')

    # Outputs
    array_aep = Array([], iotype='out', units='kW*h',
        desc='The energy production per sector [nWD, nWS]')

    gross_aep = Float(iotype='out', units='kW*h',
        desc='Gross Annual Energy Production before availability and loss impacts')

    net_aep = Float(iotype='out', units='kW*h',
        desc='Net Annual Energy Production after availability and loss impacts')

    capacity_factor = Float(0.0, iotype='out',
        desc='Capacity factor for wind plant')


    def __init__(self, wt_layout, wf, **kwargs):
        """

        :param wt_layout: GenericWindFarmTurbineLayout()
        :param wf: GenericWindFarm()
        :param scaling: float [default = 1.0]
                        The scaling used to calculate the net_aep. If it is set to 0.0, the scaling
                        will be set to the net_aep the first time the simulation is run.
        """
        self.wf = wf
        self.wf.wt_layout = wt_layout
        #self.wind_rose = wind_rose
        super(AEPFortranMultipleWindRoses, self).__init__(**kwargs)

    def execute(self):
        wt_net_aep = np.zeros([self.wt_positions.shape[0]])
        wt_gross_aep = np.zeros([self.wt_positions.shape[0]])
        cwd = 0
        wind_speeds, wind_directions = np.meshgrid(self.wind_speeds, self.wind_directions)

        # Runnning all the wind speeds and wind directions at the same time
        self.wf.wt_layout.wt_positions=self.wt_positions
        self.wf.wind_speeds = wind_speeds.flatten()
        self.wf.wind_directions = wind_directions.flatten()
        self.wf.turbulence_intensities = self.turbulence_intensity * ones_like(self.wf.wind_directions)
        self.wf.run()
        powers = self.wf.wt_power.reshape([len(self.wind_directions),
                                           len(self.wind_speeds),
                                           self.wt_positions.shape[0]])
        self.powers = powers

        for iwt, wt in enumerate(self.wf.wt_layout.wt_list):
            net_aeps = np.zeros([len(self.wind_directions)])
            gross_aeps = np.zeros([len(self.wind_directions)])

            # build the cdf vector of the wind speed for each wind rose wind direction sector
            cdfw = []
            for iwd, wd in enumerate(self.wind_roses[iwt].wind_directions):
                cdfw.append(weibullCDF(self.wind_speeds, self.wind_roses[iwt].A[iwd], self.wind_roses[iwt].k[iwd]))

            # calculate the probability in each wind direction sector, using the CDF of the wind rose wind direction
            cdfd0 = [sum(self.wind_roses[iwt].frequency[:i]) for i in range(len(self.wind_roses[iwt].frequency)+1)]
            wd = np.hstack([self.wind_roses[iwt].wind_directions, [360]])
            cdfd1 = interp1d(wd, cdfd0)(self.wind_directions)
            cwd = 0
            for iwd, wd in enumerate(self.wind_directions):
                # self.wind_directions is not the same as self.wind_roses[iwt].wind_directions, so we have to match both sectors
                if cwd < len(self.wind_roses[iwt].wind_directions):
                    while wd >= self.wind_roses[iwt].wind_directions[cwd+1] and \
                          cwd < len(self.wind_roses[iwt].wind_directions)-2:
                        # switching wind rose wind direction sector
                        cwd += 1
                # Integrating over the wind speed CDF
                net_aeps[iwd] = np.trapz(powers[iwd,:,iwt], cdfw[cwd]) * 365.0 * 24.0
                for i in range(self.wt_positions.shape[0]):
                    power_curve = interp1d(wt.power_curve[:,0],
                                           wt.power_curve[:,1])(self.wind_speeds)
                    gross_aeps[iwd] += np.trapz(power_curve, cdfw[cwd]) * 365.0 * 24.0

            # Integrating over the wind direction CDF
            wt_net_aep[iwt] = np.trapz(net_aeps, cdfd1)
            wt_gross_aep[iwt] = np.trapz(gross_aeps, cdfd1)

        net_aep = wt_net_aep.sum()
        gross_aep = wt_gross_aep.sum()

        self.capacity_factor = net_aep / gross_aep

        if self.scaling == 0.0:
            # The scaling has to be calculated
            self.scaling = net_aep

        self.net_aep = net_aep / self.scaling
        self.gross_aep = gross_aep