Exemplo n.º 1
0
 def test_bogus(self):
     # now try some bogus expressions
     try:
         ex = ExprEvaluator('abcd.efg', self.top)
         ex.evaluate()
     except AttributeError, err:
         self.assertEqual(str(err), "can't evaluate expression 'abcd.efg': : object has no attribute 'abcd.efg'")
Exemplo n.º 2
0
    def test_reparse_on_scope_change(self):
        self.top.comp.x = 99.5
        self.top.comp.y = -3.14

        ex = ExprEvaluator('comp.x', self.top)
        self.assertEqual(99.5, ex.evaluate())
        self.assertEqual(new_text(ex), "scope.get('comp.x')")

        ex.scope = self.top.a
        try:
            ex.set(0.5)
        except AttributeError as err:
            self.assertEqual(str(err), "a: object has no attribute 'comp.x'")
        else:
            self.fail("AttributeError expected")
        self.assertEqual(new_text(ex), "scope.get('comp.x')")
        self.assertEqual(99.5,
                         ex.evaluate(self.top))  # set scope back to self.top
        self.assertEqual(new_text(ex), "scope.get('comp.x')")

        ex.text = 'comp.y'
        try:
            ex.evaluate(self.top.a)
        except AttributeError as err:
            self.assertEqual(
                str(err),
                "can't evaluate expression 'comp.y': a: 'A' object has no attribute 'comp'"
            )
        else:
            self.fail("AttributeError expected")
        ex.scope = self.top
        ex.set(11.1)
        self.assertEqual(11.1, self.top.comp.y)
        self.assertEqual(new_text(ex), "scope.get('comp.y')")
    def test_reparse_on_scope_change(self):
        self.top.comp.x = 99.5
        self.top.comp.y = -3.14

        ex = ExprEvaluator('comp.x', self.top)
        self.assertEqual(99.5, ex.evaluate())
        self.assertEqual(new_text(ex), "scope.get('comp.x')")

        ex.scope = self.top.a
        try:
            ex.set(0.5)
        except AttributeError as err:
            self.assertEqual(str(err), "a: object has no attribute 'comp.x'")
        else:
            self.fail("AttributeError expected")
        self.assertEqual(new_text(ex), "scope.get('comp.x')")
        self.assertEqual(99.5, ex.evaluate(self.top)) # set scope back to self.top
        self.assertEqual(new_text(ex), "scope.get('comp.x')")

        ex.text = 'comp.y'
        try:
            ex.evaluate(self.top.a)
        except AttributeError as err:
            self.assertEqual(str(err), "can't evaluate expression 'comp.y':"
                             " a: 'A' object has no attribute 'comp'")
        else:
            self.fail("AttributeError expected")
        ex.scope = self.top
        ex.set(11.1)
        self.assertEqual(11.1, self.top.comp.y)
        self.assertEqual(new_text(ex), "scope.get('comp.y')")
Exemplo n.º 4
0
 def test_no_scope(self):
     ex = ExprEvaluator('abs(-3)+int(2.3)+math.floor(5.4)')
     self.assertEqual(ex.evaluate(), 10.0)
     
     ex.text = 'comp.x'
     try:
         ex.evaluate()
     except Exception, err:
         self.assertEqual(str(err), "can't evaluate expression 'comp.x': expression has no scope")
Exemplo n.º 5
0
    def test_bogus(self):
        # now try some bogus expressions
        try:
            ex = ExprEvaluator('abcd.efg', self.top)
            ex.evaluate()
        except AttributeError, err:

            self.assertEqual(str(err), "can't evaluate expression 'abcd.efg':"
                                       " : 'Assembly' object has no attribute 'abcd'")
    def test_bogus(self):
        # now try some bogus expressions
        try:
            ex = ExprEvaluator('abcd.efg', self.top)
            ex.evaluate()
        except AttributeError, err:

            self.assertEqual(str(err), "can't evaluate expression 'abcd.efg':"
                             " : name 'abcd' is not defined")
Exemplo n.º 7
0
    def test_no_scope(self):
        ex = ExprEvaluator('abs(-3)+int(2.3)+math.floor(5.4)')
        self.assertEqual(ex.evaluate(), 10.0)

        ex.text = 'comp.x'
        try:
            ex.evaluate()
        except Exception, err:
            self.assertEqual(str(err), "can't evaluate expression 'comp.x':"
                                       " 'NoneType' object has no attribute 'get'")
Exemplo n.º 8
0
    def test_bogus(self):
        # now try some bogus expressions
        try:
            ex = ExprEvaluator('abcd.efg', self.top)
            ex.evaluate()
        except AttributeError, err:

            self.assertEqual(
                str(err), "can't evaluate expression 'abcd.efg':"
                " : name 'abcd' is not defined")
    def test_no_scope(self):
        ex = ExprEvaluator('abs(-3)+int(2.3)+math.floor(5.4)')
        self.assertEqual(ex.evaluate(), 10.0)

        ex.text = 'comp.x'
        try:
            ex.evaluate()
        except Exception, err:
            self.assertEqual(str(err), "can't evaluate expression 'comp.x':"
                             " 'NoneType' object has no attribute 'get'")
Exemplo n.º 10
0
 def test_slice(self):
     ex = ExprEvaluator('a1d[1::2]', self.top.a)
     self.assertTrue(all(numpy.array([2.,4.,6.]) == ex.evaluate()))
     ex.text = 'a1d[2:4]'
     self.assertTrue(all(numpy.array([3.,4.]) == ex.evaluate()))
     ex.text = 'a1d[2:]'
     self.assertTrue(all(numpy.array([3.,4.,5.,6.]) == ex.evaluate()))
     ex.text = 'a1d[::-1]'
     self.assertTrue(all(numpy.array([6.,5.,4.,3.,2.,1.]) == ex.evaluate()))
     ex.text = 'a1d[:2]'
     self.assertTrue(all(numpy.array([1.,2.]) == ex.evaluate()))
Exemplo n.º 11
0
 def test_slice(self):
     ex = ExprEvaluator('a1d[1::2]', self.top.a)
     self.assertTrue(all(array([2., 4., 6.]) == ex.evaluate()))
     ex.text = 'a1d[2:4]'
     self.assertTrue(all(array([3., 4.]) == ex.evaluate()))
     ex.text = 'a1d[2:]'
     self.assertTrue(all(array([3., 4., 5., 6.]) == ex.evaluate()))
     ex.text = 'a1d[::-1]'
     self.assertTrue(all(array([6., 5., 4., 3., 2., 1.]) == ex.evaluate()))
     ex.text = 'a1d[:2]'
     self.assertTrue(all(array([1., 2.]) == ex.evaluate()))
Exemplo n.º 12
0
    def test_no_scope(self):
        ex = ExprEvaluator('abs(-3)+int(2.3)+math.floor(5.4)')
        self.assertEqual(ex.evaluate(), 10.0)

        ex.text = 'comp.x'
        try:
            ex.evaluate()
        except Exception, err:
            self.assertEqual(
                str(err),
                "can't evaluate expression 'comp.x': expression has no scope")
Exemplo n.º 13
0
class Constraint(object):
    """ Object that stores info for a single constraint. """
    
    def __init__(self, lhs, comparator, rhs, scaler, adder, scope=None):
        self.lhs = ExprEvaluator(lhs, scope=scope)
        if not self.lhs.check_resolve():
            raise ValueError("Constraint '%s' has an invalid left-hand-side." \
                              % ' '.join([lhs, comparator, rhs]))
        self.comparator = comparator
        self.rhs = ExprEvaluator(rhs, scope=scope)
        if not self.rhs.check_resolve():
            raise ValueError("Constraint '%s' has an invalid right-hand-side." \
                              % ' '.join([lhs, comparator, rhs]))
        
        if not isinstance(scaler, float):
            raise ValueError("Scaler parameter should be a float")
        self.scaler = scaler
        
        if scaler <= 0.0:
            raise ValueError("Scaler parameter should be a float > 0")
        
        if not isinstance(adder, float):
            raise ValueError("Adder parameter should be a float")
        self.adder = adder
        
    def evaluate(self, scope):
        """Returns a tuple of the form (lhs, rhs, comparator, is_violated)."""
        
        lhs = (self.lhs.evaluate(scope) + self.adder)*self.scaler
        rhs = (self.rhs.evaluate(scope) + self.adder)*self.scaler
        return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs))
        
    def evaluate_gradient(self, scope, stepsize=1.0e-6, wrt=None):
        """Returns the gradient of the constraint eq/inep as a tuple of the
        form (lhs, rhs, comparator, is_violated)."""
        
        lhs = self.lhs.evaluate_gradient(scope=scope, stepsize=stepsize, wrt=wrt)
        for key, value in lhs.iteritems():
            lhs[key] = (value + self.adder)*self.scaler
            
        rhs = self.rhs.evaluate_gradient(scope=scope, stepsize=stepsize, wrt=wrt)
        for key, value in rhs.iteritems():
            rhs[key] = (value + self.adder)*self.scaler
            
        return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs))
        
    def get_referenced_compnames(self):
        return self.lhs.get_referenced_compnames().union(self.rhs.get_referenced_compnames())

    def __str__(self):
        return ' '.join([self.lhs.text, self.comparator, self.rhs.text])
Exemplo n.º 14
0
    def test_ext_slice(self):
        #Convoluted mess to test all cases of 3 x 3 x 3 array
        #where inner arrays are 2D identity matrices
        #Should cover all cases
        for k in xrange(3):
            expr = 'ext1[{0}, :, :]'.format(k)
            expr = ExprEvaluator(expr, self.top.a)
            comp = (eye(3) == expr.evaluate()).all()
            self.assertTrue(comp)

            expr = 'ext1[:, {0}, :]'.format(k)
            expr = ExprEvaluator(expr, self.top.a)
            comp = (tile(roll(array([1., 0., 0.]), k),
                         (3, 1)) == expr.evaluate()).all()
            self.assertTrue(comp)

            expr = 'ext1[:, :, {0}]'.format(k)
            expr = ExprEvaluator(expr, self.top.a)
            comp = (tile(roll(array([1., 0., 0.]), k),
                         (3, 1)) == expr.evaluate()).all()
            self.assertTrue(comp)

            for j in xrange(3):
                expr = 'ext1[:, {0}, {1}]'.format(j, k)
                expr = ExprEvaluator(expr, self.top.a)

                if j == k:
                    comp = all(array([1., 1., 1.]) == expr.evaluate())
                    self.assertTrue(comp)
                else:
                    comp = all(array([0., 0., 0.]) == expr.evaluate())
                    self.assertTrue(comp)

                expr = 'ext1[{0}, :, {1}]'.format(j, k)
                expr = ExprEvaluator(expr, self.top.a)
                arr = array([1., 0., 0.])
                comp = all(roll(arr, k) == expr.evaluate())
                self.assertTrue(comp)

                expr = 'ext1[{0}, {1}, :]'.format(j, k)
                expr = ExprEvaluator(expr, self.top.a)
                arr = array([1., 0., 0.])
                comp = all(roll(arr, k) == expr.evaluate())
                self.assertTrue(comp)

                for i in xrange(3):
                    expr = 'ext1[{0}, {1}, {2}]'.format(i, j, k)
                    expr = ExprEvaluator(expr, self.top.a)

                    if j == k:
                        comp = all(array([1.]) == expr.evaluate())
                        self.assertTrue(comp)
                    else:
                        comp = all(array([0.]) == expr.evaluate())
                        self.assertTrue(comp)
Exemplo n.º 15
0
    def test_ext_slice(self):
        #Convoluted mess to test all cases of 3 x 3 x 3 array
        #where inner arrays are 2D identity matrices
        #Should cover all cases
        for k in xrange(3):
            expr = 'ext1[{0}, :, :]'.format(k)
            expr = ExprEvaluator(expr, self.top.a)
            comp = (eye(3) == expr.evaluate()).all()
            self.assertTrue(comp)

            expr = 'ext1[:, {0}, :]'.format(k)
            expr = ExprEvaluator(expr, self.top.a)
            comp = (tile(roll(array([1., 0., 0.]), k), (3, 1)) == expr.evaluate()).all()
            self.assertTrue(comp)

            expr = 'ext1[:, :, {0}]'.format(k)
            expr = ExprEvaluator(expr, self.top.a)
            comp = (tile(roll(array([1., 0., 0.]), k), (3, 1)) == expr.evaluate()).all()
            self.assertTrue(comp)

            for j in xrange(3):
                expr = 'ext1[:, {0}, {1}]'.format(j, k)
                expr = ExprEvaluator(expr, self.top.a)

                if j == k:
                    comp = all(array([1., 1., 1.]) == expr.evaluate())
                    self.assertTrue(comp)
                else:
                    comp = all(array([0., 0., 0.]) == expr.evaluate())
                    self.assertTrue(comp)

                expr = 'ext1[{0}, :, {1}]'.format(j, k)
                expr = ExprEvaluator(expr, self.top.a)
                arr = array([1., 0., 0.])
                comp = all(roll(arr, k) == expr.evaluate())
                self.assertTrue(comp)

                expr = 'ext1[{0}, {1}, :]'.format(j, k)
                expr = ExprEvaluator(expr, self.top.a)
                arr = array([1., 0., 0.])
                comp = all(roll(arr, k) == expr.evaluate())
                self.assertTrue(comp)

                for i in xrange(3):
                    expr = 'ext1[{0}, {1}, {2}]'.format(i, j, k)
                    expr = ExprEvaluator(expr, self.top.a)

                    if j == k:
                        comp = all(array([1.]) == expr.evaluate())
                        self.assertTrue(comp)
                    else:
                        comp = all(array([0.]) == expr.evaluate())
                        self.assertTrue(comp)
Exemplo n.º 16
0
    def _create(self, target, low, high, scaler, adder, start, fd_step,
                key, scope):
        """ Create one Parameter or ArrayParameter. """
        try:
            expreval = ExprEvaluator(target, scope)
        except Exception as err:
            raise err.__class__("Can't add parameter: %s" % err)
        if not expreval.is_valid_assignee():
            raise ValueError("Can't add parameter: '%s' is not a"
                             " valid parameter expression"
                             % expreval.text)
        try:
            val = expreval.evaluate()
        except Exception as err:
            val = None  # Let Parameter code sort out why.

        name = key[0] if isinstance(key, tuple) else key

        if isinstance(val, ndarray):
            return ArrayParameter(target, low=low, high=high,
                                  scaler=scaler, adder=adder,
                                  start=start, fd_step=fd_step,
                                  name=name, scope=scope,
                                  _expreval=expreval, _val=val,
                                  _allowed_types=self._allowed_types)
        else:
            return Parameter(target, low=low, high=high,
                             scaler=scaler, adder=adder,
                             start=start, fd_step=fd_step,
                             name=name, scope=scope,
                             _expreval=expreval, _val=val,
                             _allowed_types=self._allowed_types)
Exemplo n.º 17
0
    def _create(self, target, low, high, scaler, adder, start, fd_step,
                key, scope):
        """ Create one Parameter or ArrayParameter. """
        try:
            expreval = ExprEvaluator(target, scope)
        except Exception as err:
            raise err.__class__("Can't add parameter: %s" % err)
        if not expreval.is_valid_assignee():
            raise ValueError("Can't add parameter: '%s' is not a"
                             " valid parameter expression"
                             % expreval.text)
        try:
            val = expreval.evaluate()
        except Exception as err:
            val = None  # Let Parameter code sort out why.

        name = key[0] if isinstance(key, tuple) else key

        if isinstance(val, ndarray):
            return ArrayParameter(target, low=low, high=high,
                                  scaler=scaler, adder=adder,
                                  start=start, fd_step=fd_step,
                                  name=name, scope=scope,
                                  _expreval=expreval, _val=val,
                                  _allowed_types=self._allowed_types)
        else:
            return Parameter(target, low=low, high=high,
                             scaler=scaler, adder=adder,
                             start=start, fd_step=fd_step,
                             name=name, scope=scope,
                             _expreval=expreval, _val=val,
                             _allowed_types=self._allowed_types)
class Constraint(object):
    """ Object that stores info for a single constraint. """
    def __init__(self, lhs, comparator, rhs, scaler, adder, scope=None):
        self.lhs = ExprEvaluator(lhs, scope=scope)
        if not self.lhs.check_resolve():
            raise ValueError("Constraint '%s' has an invalid left-hand-side." \
                              % ' '.join([lhs, comparator, rhs]))
        self.comparator = comparator
        self.rhs = ExprEvaluator(rhs, scope=scope)
        if not self.rhs.check_resolve():
            raise ValueError("Constraint '%s' has an invalid right-hand-side." \
                              % ' '.join([lhs, comparator, rhs]))

        if not isinstance(scaler, float):
            raise ValueError("Scaler parameter should be a float")
        self.scaler = scaler

        if scaler <= 0.0:
            raise ValueError("Scaler parameter should be a float > 0")

        if not isinstance(adder, float):
            raise ValueError("Adder parameter should be a float")
        self.adder = adder

    def evaluate(self, scope):
        """Returns a tuple of the form (lhs, rhs, comparator, is_violated)."""

        lhs = (self.lhs.evaluate(scope) + self.adder) * self.scaler
        rhs = (self.rhs.evaluate(scope) + self.adder) * self.scaler
        return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs))

    def get_referenced_compnames(self):
        return self.lhs.get_referenced_compnames().union(
            self.rhs.get_referenced_compnames())

    def __str__(self):
        return ' '.join([self.lhs.text, self.comparator, self.rhs.text])
Exemplo n.º 19
0
 def test_property(self):
     ex = ExprEvaluator('some_prop', self.top.a)
     self.assertEqual(ex.evaluate(), 7)
Exemplo n.º 20
0
class SimEconomy(Driver):
    """ Simulation of vehicle performance over a given velocity profile. Such
    a simulation can be used to mimic the EPA city and highway driving tests.
    This is a specialized simulation driver whose workflow should consist of a
    Vehicle assembly, and whose connections are as follows:
    
    Connections
    Parameters: [ velocity (Float),
                  throttle (Float),
                  current_gear (Enum) ]
    Objectives: [ acceleration (Float), 
                  fuel burn (Float),
                  overspeed (Bool),
                  underspeed (Bool) ]
                  
    Connection Inputs
    velocity_str: str
        Variable location for vehicle velocity.
    
    throttle_str: str
        Variable location for vehicle throttle position.
    
    gear_str: str
        Variable location for vehicle gear position.
    
    acceleration_str: str
        Variable location for vehicle acceleration.
    
    fuel_burn_str: str
        Variable location for vehicle fuel burn.
    
    overspeed_str: str
        Variable location for vehicle overspeed.
    
    underspeed_str: str
        Variable location for vehicle underspeed.
    
    Simulation Inputs
    profilename: str
        Name of the file that contains profile (csv format)
        
    end_speed: float
        Ending speed for the simulation (default 60 mph)
    
    timestep: float
        Simulation time step (default .01)
        
    Outputs
    fuel_economy: float
        Fuel economy over the simulated profile.
    """

    velocity_str = Str(iotype='in',
                       desc='Location of vehicle input: velocity.')
    throttle_str = Str(iotype='in',
                       desc='Location of vehicle input: throttle.')
    gear_str = Str(iotype='in',
                   desc='Location of vehicle input: current_gear.')
    acceleration_str = Str(iotype='in',
                           desc='Location of vehicle output: acceleration.')
    fuel_burn_str = Str(iotype='in',
                        desc='Location of vehicle output: fuel_burn.')
    overspeed_str = Str(iotype='in',
                        desc='Location of vehicle output: overspeed.')
    underspeed_str = Str(iotype='in',
                         desc='Location of vehicle output: underspeed.')

    profilename = Str('', iotype='in', \
                        desc='Name of the file that contains profile (csv)')

    # These can be used to adjust driving style.
    throttle_min = Float(.07, iotype='in', desc='Minimum throttle position')
    throttle_max = Float(1.0, iotype='in', desc='Maximum throttle position')
    shiftpoint1 = Float(10.0, iotype='in', \
                        desc='Always in first gear below this speed')

    tolerance = Float(0.01,
                      iotype='in',
                      desc='Convergence tolerance for Bisection solution')

    fuel_economy = Float(0.0,
                         iotype='out',
                         units='s',
                         desc='Simulated fuel economy over profile')

    def __init__(self, *args, **kwargs):
        super(SimEconomy, self).__init__(*args, **kwargs)

        self._velocity_str_expr = None
        self._throttle_str_expr = None
        self._gear_str_expr = None
        self._acceleration_str_expr = None
        self._fuel_burn_str_expr = None
        self._overspeed_str_expr = None
        self._underspeed_str_expr = None

    def _velocity_str_changed(self, oldval, newval):
        self._velocity_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _throttle_str_changed(self, oldval, newval):
        self._throttle_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _gear_str_changed(self, oldval, newval):
        self._gear_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _acceleration_str_changed(self, oldval, newval):
        self._acceleration_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _fuel_burn_str_changed(self, oldval, newval):
        self._fuel_burn_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _overspeed_str_changed(self, oldval, newval):
        self._overspeed_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _underspeed_str_changed(self, oldval, newval):
        self._underspeed_str_expr = ExprEvaluator(newval, scope=self.parent)

    def execute(self):
        """ Simulate the vehicle over a velocity profile."""

        # Set initial throttle, gear, and velocity
        throttle = 1.0
        gear = 1
        time1 = 0.0
        velocity1 = 0.0

        profile_stream = resource_stream('openmdao.examples.enginedesign',
                                         self.profilename)
        profile_reader = reader(profile_stream, delimiter=',')

        distance = 0.0
        fuelburn = 0.0

        self._gear_str_expr.set(gear)

        for row in profile_reader:

            time2 = float(row[0])
            velocity2 = float(row[1])
            converged = 0

            command_accel = (velocity2 - velocity1) / (time2 - time1)

            #------------------------------------------------------------
            # Choose the correct Gear
            #------------------------------------------------------------

            # First, if speed is less than 10 mph, put it in first gear.
            # Note: some funky gear ratios might not like this.
            # So, it's a hack for now.

            if velocity1 < self.shiftpoint1:
                gear = 1
                self._gear_str_expr.set(gear)

            # Find out min and max accel in current gear.

            throttle = self.throttle_min
            self._velocity_str_expr.set(velocity1)
            self._throttle_str_expr.set(throttle)
            gear = self._findgear(velocity1, throttle, gear)
            acceleration = self._acceleration_str_expr.evaluate(self.parent)
            accel_min = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')

            # Upshift if commanded accel is less than closed-throttle accel
            # The net effect of this will often be a shift to a higher gear
            # when the vehicle stops accelerating, which is reasonable.
            # Note, this isn't a While loop, because we don't want to shift
            # to 5th every time we slow down.
            if command_accel < accel_min and gear < 5 and \
               velocity1 > self.shiftpoint1:

                gear += 1
                self._gear_str_expr.set(gear)
                gear = self._findgear(velocity1, throttle, gear)
                acceleration = self._acceleration_str_expr.evaluate(
                    self.parent)
                accel_min = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')

            throttle = self.throttle_max
            self._throttle_str_expr.set(throttle)
            self.run_iteration()
            acceleration = self._acceleration_str_expr.evaluate(self.parent)
            accel_max = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')

            # Downshift if commanded accel > wide-open-throttle accel
            while command_accel > accel_max and gear > 1:

                gear -= 1
                self._gear_str_expr.set(gear)
                gear = self._findgear(velocity1, throttle, gear)
                acceleration = self._acceleration_str_expr.evaluate(
                    self.parent)
                accel_max = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')

            # If engine cannot accelerate quickly enough to match profile,
            # then raise exception
            if command_accel > accel_max:
                self.raise_exception("Vehicle is unable to achieve " \
                "acceleration required to match EPA driving profile.",
                                                RuntimeError)

            #------------------------------------------------------------
            # Bisection solution to find correct Throttle position
            #------------------------------------------------------------

            # Deceleration at closed throttle
            throttle = self.throttle_min
            self._throttle_str_expr.set(throttle)
            self.run_iteration()
            acceleration = self._acceleration_str_expr.evaluate(self.parent)

            if command_accel >= accel_min:

                min_acc = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
                max_acc = accel_max
                min_throttle = self.throttle_min
                max_throttle = self.throttle_max
                new_throttle = .5 * (min_throttle + max_throttle)

                # Numerical solution to find throttle that matches accel
                while not converged:

                    throttle = new_throttle
                    self._throttle_str_expr.set(throttle)
                    self.run_iteration()
                    acceleration = self._acceleration_str_expr.evaluate(
                        self.parent)
                    new_acc = convert_units(acceleration, 'm/(s*s)',
                                            'mi/(h*s)')

                    if abs(command_accel - new_acc) < self.tolerance:
                        converged = 1
                    else:
                        if new_acc < command_accel:
                            min_throttle = new_throttle
                            min_acc = new_acc
                            step = (command_accel - min_acc) / (max_acc -
                                                                new_acc)
                            new_throttle = min_throttle + \
                                        step*(max_throttle-min_throttle)
                        else:
                            max_throttle = new_throttle
                            step = (command_accel - min_acc) / (new_acc -
                                                                min_acc)
                            new_throttle = min_throttle + \
                                        step*(max_throttle-min_throttle)
                            max_acc = new_acc

            distance += .5 * (velocity2 + velocity1) * (time2 - time1)
            burn_rate = self._fuel_burn_str_expr.evaluate(self.parent)
            fuelburn += burn_rate * (time2 - time1)

            velocity1 = velocity2
            time1 = time2

            #print "T = %f, V = %f, Acc = %f" % (time1, velocity1,
            #command_accel)
            #print gear, accel_min, accel_max

        # Convert liter to gallon and sec/hr to hr/hr
        distance = convert_units(distance, 'mi*s/h', 'mi')
        fuelburn = convert_units(fuelburn, 'L', 'galUS')
        self.fuel_economy = distance / fuelburn

    def _findgear(self, velocity, throttle, gear):
        """ Finds the nearest gear in the appropriate range for the
        currently commanded vehicle state (throttle, velocity).
        
        This is intended to be called recursively.
        """

        self.run_iteration()

        overspeed = self._overspeed_str_expr.evaluate(self.parent)
        underspeed = self._underspeed_str_expr.evaluate(self.parent)

        if overspeed:
            gear += 1

            if gear > 4:
                self.raise_exception("Transmission gearing cannot " \
                "achieve acceleration and speed required by EPA " \
                "test.", RuntimeError)

        elif underspeed:
            gear -= 1

            # Note, no check needed for low gearing -- we allow underspeed
            # while in first gear.

        else:
            return gear

        self._gear_str_expr.set(gear)
        gear = self._findgear(velocity, throttle, gear)

        return gear
Exemplo n.º 21
0
class SimAcceleration(Driver):
    """ Simulation of vehicle acceleration performance. This is a specialized
    simulation driver whose workflow should consist of a Vehicle assembly, and
    whose connections are as follows:
    
    Connection Inputs
    velocity_str: str
        Variable location for vehicle velocity.
    
    throttle_str: str
        Variable location for vehicle throttle position.
    
    gear_str: str
        Variable location for vehicle gear position.
    
    acceleration_str: str
        Variable location for vehicle acceleration.
    
    overspeed_str: str
        Variable location for vehicle overspeed.
    
    Simulation Inputs
    end_speed: float
        Ending speed for the simulation (default 60 mph)
    
    timestep: float
        Simulation time step (default .01)
        
    Outputs
    accel_time: float
        Time to perform the acceleration test.
    """
    
    velocity_str = Str(iotype='in',
                       desc='Location of vehicle input: velocity.')
    throttle_str = Str(iotype='in',
                       desc='Location of vehicle input: throttle.')
    gear_str = Str(iotype='in',
                       desc='Location of vehicle input: current_gear.')
    acceleration_str = Str(iotype='in',
                       desc='Location of vehicle output: acceleration.')
    overspeed_str = Str(iotype='in',
                       desc='Location of vehicle output: overspeed.')

    end_speed = Float(60.0, iotype='in', units='mi/h',
                      desc='Simulation final speed')
    timestep = Float(0.1, iotype='in', units='s', 
                     desc='Simulation time step size')
    
    accel_time = Float(0.0, iotype='out', units='s',
                       desc = 'Acceleration time')
    
    def __init__(self):
        super(SimAcceleration, self).__init__()
        
        self._velocity_str_expr = None
        self._throttle_str_expr = None
        self._gear_str_expr = None
        self._acceleration_str_expr = None
        self._overspeed_str_expr = None
    
    def _velocity_str_changed(self, oldval, newval):
        self._velocity_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _throttle_str_changed(self, oldval, newval):
        self._throttle_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _gear_str_changed(self, oldval, newval):
        self._gear_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _acceleration_str_changed(self, oldval, newval):
        self._acceleration_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _overspeed_str_changed(self, oldval, newval):
        self._overspeed_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def execute(self):
        """ Simulate the vehicle model at full throttle."""
        
        # Set initial throttle, gear, and velocity
        time = 0.0
        velocity = 0.0
        throttle = 1.0
        gear = 1
        
        while velocity < self.end_speed:
            
            self._velocity_str_expr.set(velocity)
            self._throttle_str_expr.set(throttle)
            self._gear_str_expr.set(gear)
            self.run_iteration()
            
            acceleration = self._acceleration_str_expr.evaluate(self.parent)
            overspeed = self._overspeed_str_expr.evaluate(self.parent)
            
            # If the next gear can produce more torque, let's shift.
            if gear < 5:
                self._gear_str_expr.set(gear+1)
                self.run_iteration()
            
                acceleration2 = self._acceleration_str_expr.evaluate(self.parent)
                if acceleration2 > acceleration:
                    gear += 1
                    acceleration = acceleration2
                    overspeed = self._overspeed_str_expr.evaluate(self.parent)
                
            
            # If RPM goes over MAX RPM, shift gears
            # (i.e.: shift at redline)
            if overspeed:
                gear += 1
                self._gear_str_expr.set(gear)
                self.run_iteration()
                acceleration = self._acceleration_str_expr.evaluate(self.parent)
                overspeed = self._overspeed_str_expr.evaluate(self.parent)
                
                if overspeed:
                    self.raise_exception("Gearing problem in Accel test.", 
                                             RuntimeError)

            acceleration = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
            
            if acceleration <= 0.0:
                self.raise_exception("Vehicle could not reach maximum speed "+\
                                     "in Acceleration test.", RuntimeError)
                
            velocity += (acceleration*self.timestep)
        
            time += self.timestep
                   
        self.accel_time = time
Exemplo n.º 22
0
    def test_set_evaluate(self):
        ex = ExprEvaluator('comp.x', self.top)
        self.assertEqual(3.14, ex.evaluate())

        ex.set(75.4)
        self.assertEqual(75.4, self.top.comp.x)

        self.top.comp.contlist = [A(), A(), A()]
        self.top.comp.contlist[1].a1d = [4] * 5
        ex = ExprEvaluator('comp.contlist[1].a1d[3]', self.top)
        self.assertEqual(ex.evaluate(), 4)

        ex.set(123)
        self.assertEqual(ex.evaluate(), 123)

        ex = ExprEvaluator("comp.contlist[1].some_funct(3,5,'sub')", self.top)
        self.assertEqual(ex.evaluate(), -2)

        ex = ExprEvaluator("comp.get_cont(1).some_funct(3,5,'add')", self.top)
        self.assertEqual(ex.evaluate(), 8)

        ex = ExprEvaluator("comp.get_cont(1).a1d[2]", self.top)
        self.assertEqual(ex.evaluate(), 4)

        ex = ExprEvaluator("a2d[1][0]", self.top.a)
        self.assertEqual(ex.evaluate(), 2.)
        ex.set(7.)
        self.assertEqual(self.top.a.a2d[1][0], 7.)

        ex = ExprEvaluator("a2d[1,0]", self.top.a)
        self.assertEqual(ex.evaluate(), 7.)
        ex.set(11.)
        self.assertEqual(self.top.a.a2d[1][0], 11.)

        ex = ExprEvaluator("a2d[1]", self.top.a)

        self.assertTrue(all(ex.evaluate() == array([11., 3.])))
        ex.set([0.1, 0.2])
        self.assertTrue(all(self.top.a.a2d[1] == array([0.1, 0.2])))

        self.top.comp.cont = A()

        ex = ExprEvaluator("comp.cont.a2d[1][0]", self.top)
        self.assertEqual(ex.evaluate(), 2.)
        ex.set(7.)
        self.assertEqual(self.top.comp.cont.a2d[1][0], 7.)

        ex = ExprEvaluator("comp.cont.a2d[1,0]", self.top)
        self.assertEqual(ex.evaluate(), 7.)
        ex.set(11.)
        self.assertEqual(self.top.comp.cont.a2d[1][0], 11.)

        # try a numpy function
        try:
            import numpy
        except ImportError:
            pass
        else:
            ex = ExprEvaluator("numpy.eye(2)", self.top.a)
            val = ex.evaluate()

            self.assertTrue((val == numpy.eye(2)).all())

        ex = ExprEvaluator("comp.get_cont(1).a1d", self.top)
        self.assertEqual(list(ex.evaluate()), [4, 4, 4, 123, 4])

        ex = ExprEvaluator("comp.get_attrib('get_cont')(1).a1d", self.top)
        self.assertEqual(list(ex.evaluate()), [4, 4, 4, 123, 4])
Exemplo n.º 23
0
    def __init__(self, target, parent, high=None, low=None, 
                 scaler=None, adder=None, start=None, 
                 fd_step=None, scope=None, name=None):
        self._metadata = None
        
        if scaler is None and adder is None:
            self._transform = self._do_nothing
            self._untransform = self._do_nothing
        else:
            if scaler is None:
                scaler = 1.0
            else:
                try:
                    scaler = float(scaler)
                except (TypeError, ValueError):
                    msg = "Bad value given for parameter's 'scaler' attribute."
                    parent.raise_exception(msg, ValueError)
            if adder is None:
                adder = 0.0
            else:
                try:
                    adder = float(adder)
                except (TypeError, ValueError):
                    msg = "Bad value given for parameter's 'adder' attribute."
                    parent.raise_exception(msg, ValueError)
        
        self.low = low
        self.high = high
        self.start = start
        self.scaler = scaler
        self.adder = adder
        self.fd_step = fd_step
        if name is not None: 
            self.name = name
        else: 
            self.name = target
        
        try:
            expreval = ExprEvaluator(target, scope)
        except Exception as err:
            parent.raise_exception("Can't add parameter: %s" % str(err),
                                   type(err))
        if not expreval.is_valid_assignee():
            parent.raise_exception("Can't add parameter: '%s' is not a valid parameter expression" % 
                                   expreval.text, ValueError)

        self._expreval = expreval
        
        try:
            # metadata is in the form (varname, metadata), so use [1] to get
            # the actual metadata dict 
            metadata = self.get_metadata()[1]
        except AttributeError:
            parent.raise_exception("Can't add parameter '%s' because it doesn't exist." % target,
                                   AttributeError)
            
        if 'iotype' in metadata and metadata['iotype'] == 'out':
            parent.raise_exception("Can't add parameter '%s' because '%s' is an output." % (target, target),
                                   RuntimeError)
        try:
            # So, our traits might not have a vartypename?
            self.vartypename = metadata['vartypename']
        except KeyError:
            self.vartypename = None
            
        try:
            val = expreval.evaluate()
        except Exception as err:
            parent.raise_exception("Can't add parameter because I can't evaluate '%s'." % target, 
                                   ValueError)
            
        self.valtypename = type(val).__name__

        if self.vartypename == 'Enum':
            return    # it's an Enum, so no need to set high or low
        
        if not isinstance(val, real_types) and not isinstance(val, int_types):
            parent.raise_exception("The value of parameter '%s' must be a real or integral type, but its type is '%s'." %
                                   (target,type(val).__name__), ValueError)
        
        meta_low = metadata.get('low') # this will be None if 'low' isn't there
        if meta_low is not None:
            if low is None:
                self.low = self._untransform(meta_low)
            elif low < self._untransform(meta_low):
                parent.raise_exception("Trying to add parameter '%s', " 
                                       "but the lower limit supplied (%s) exceeds the " 
                                       "built-in lower limit (%s)." % 
                                       (target, low, meta_low), ValueError)
        else:
            if low is None:
                parent.raise_exception("Trying to add parameter '%s', "
                                       "but no lower limit was found and no " 
                                       "'low' argument was given. One or the "
                                       "other must be specified." % target,ValueError)

        meta_high = metadata.get('high') # this will be None if 'low' isn't there
        if meta_high is not None:
            if high is None:
                self.high = self._untransform(meta_high)
            elif high > self._untransform(meta_high):
                parent.raise_exception("Trying to add parameter '%s', " 
                                       "but the upper limit supplied (%s) exceeds the " 
                                       "built-in upper limit (%s)." % 
                                       (target, high, meta_high), ValueError)
        else:
            if high is None:
                parent.raise_exception("Trying to add parameter '%s', "
                                   "but no upper limit was found and no " 
                                   "'high' argument was given. One or the "
                                   "other must be specified." % target,ValueError)


        if self.low > self.high:
            parent.raise_exception("Parameter '%s' has a lower bound (%s) that exceeds its upper bound (%s)" %
                                   (target, self.low, self.high), ValueError)
Exemplo n.º 24
0
class SimEconomy(Driver):
    """ Simulation of vehicle performance over a given velocity profile. Such
    a simulation can be used to mimic the EPA city and highway driving tests.
    This is a specialized simulation driver whose workflow should consist of a
    Vehicle assembly, and whose connections are as follows:
    
    Connections
    Parameters: [ velocity (Float),
                  throttle (Float),
                  current_gear (Enum) ]
    Objectives: [ acceleration (Float), 
                  fuel burn (Float),
                  overspeed (Bool),
                  underspeed (Bool) ]
                  
    Connection Inputs
    velocity_str: str
        Variable location for vehicle velocity.
    
    throttle_str: str
        Variable location for vehicle throttle position.
    
    gear_str: str
        Variable location for vehicle gear position.
    
    acceleration_str: str
        Variable location for vehicle acceleration.
    
    fuel_burn_str: str
        Variable location for vehicle fuel burn.
    
    overspeed_str: str
        Variable location for vehicle overspeed.
    
    underspeed_str: str
        Variable location for vehicle underspeed.
    
    Simulation Inputs
    profilename: str
        Name of the file that contains profile (csv format)
        
    end_speed: float
        Ending speed for the simulation (default 60 mph)
    
    timestep: float
        Simulation time step (default .01)
        
    Outputs
    fuel_economy: float
        Fuel economy over the simulated profile.
    """

    velocity_str = Str(iotype='in',
                       desc='Location of vehicle input: velocity.')
    throttle_str = Str(iotype='in',
                       desc='Location of vehicle input: throttle.')
    gear_str = Str(iotype='in',
                       desc='Location of vehicle input: current_gear.')
    acceleration_str = Str(iotype='in',
                       desc='Location of vehicle output: acceleration.')
    fuel_burn_str = Str(iotype='in',
                       desc='Location of vehicle output: fuel_burn.')
    overspeed_str = Str(iotype='in',
                       desc='Location of vehicle output: overspeed.')
    underspeed_str = Str(iotype='in',
                       desc='Location of vehicle output: underspeed.')

    profilename = Str('', iotype='in', \
                        desc='Name of the file that contains profile (csv)')
    
    # These can be used to adjust driving style.
    throttle_min = Float(.07, iotype='in', desc='Minimum throttle position')
    throttle_max = Float(1.0, iotype='in', desc='Maximum throttle position')
    shiftpoint1 = Float(10.0, iotype='in', \
                        desc='Always in first gear below this speed')
    
    tolerance = Float(0.01, iotype='in', 
                      desc='Convergence tolerance for Bisection solution')
    
    fuel_economy = Float(0.0, iotype='out', units='s',
                       desc = 'Simulated fuel economy over profile')
    

    def __init__(self, *args, **kwargs):
        super(SimEconomy, self).__init__(*args, **kwargs)
        
        self._velocity_str_expr = None
        self._throttle_str_expr = None
        self._gear_str_expr = None
        self._acceleration_str_expr = None
        self._fuel_burn_str_expr = None
        self._overspeed_str_expr = None
        self._underspeed_str_expr = None
    
    def _velocity_str_changed(self, oldval, newval):
        self._velocity_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _throttle_str_changed(self, oldval, newval):
        self._throttle_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _gear_str_changed(self, oldval, newval):
        self._gear_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _acceleration_str_changed(self, oldval, newval):
        self._acceleration_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _fuel_burn_str_changed(self, oldval, newval):
        self._fuel_burn_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _overspeed_str_changed(self, oldval, newval):
        self._overspeed_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def _underspeed_str_changed(self, oldval, newval):
        self._underspeed_str_expr = ExprEvaluator(newval, scope=self.parent)
    
    def execute(self):
        """ Simulate the vehicle over a velocity profile."""
        
        # Set initial throttle, gear, and velocity
        throttle = 1.0
        gear = 1
        time1 = 0.0
        velocity1 = 0.0
        
        profile_stream = resource_stream('openmdao.examples.enginedesign',
                                         self.profilename)
        profile_reader = reader(profile_stream, delimiter=',')
        
        distance = 0.0
        fuelburn = 0.0
        
        self._gear_str_expr.set(gear)
        
        for row in profile_reader:
            
            time2 = float(row[0])
            velocity2 = float(row[1])
            converged = 0
            
            command_accel = (velocity2-velocity1)/(time2-time1)
            
            #------------------------------------------------------------
            # Choose the correct Gear
            #------------------------------------------------------------

            # First, if speed is less than 10 mph, put it in first gear.
            # Note: some funky gear ratios might not like this.
            # So, it's a hack for now.
            
            if velocity1 < self.shiftpoint1:
                gear = 1
                self._gear_str_expr.set(gear)
                
            # Find out min and max accel in current gear.
            
            throttle = self.throttle_min
            self._velocity_str_expr.set(velocity1)
            self._throttle_str_expr.set(throttle)
            gear = self._findgear(velocity1, throttle, gear)                    
            acceleration = self._acceleration_str_expr.evaluate(self.parent)
            accel_min = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
            
            # Upshift if commanded accel is less than closed-throttle accel
            # The net effect of this will often be a shift to a higher gear
            # when the vehicle stops accelerating, which is reasonable.
            # Note, this isn't a While loop, because we don't want to shift
            # to 5th every time we slow down.
            if command_accel < accel_min and gear < 5 and \
               velocity1 > self.shiftpoint1:
                
                gear += 1
                self._gear_str_expr.set(gear)
                gear = self._findgear(velocity1, throttle, gear)                    
                acceleration = self._acceleration_str_expr.evaluate(self.parent)
                accel_min = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
            
            throttle = self.throttle_max
            self._throttle_str_expr.set(throttle)
            self.run_iteration()
            acceleration = self._acceleration_str_expr.evaluate(self.parent)
            accel_max = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
            
            # Downshift if commanded accel > wide-open-throttle accel
            while command_accel > accel_max and gear > 1:
                
                gear -= 1
                self._gear_str_expr.set(gear)
                gear = self._findgear(velocity1, throttle, gear)                    
                acceleration = self._acceleration_str_expr.evaluate(self.parent)
                accel_max = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
            
            # If engine cannot accelerate quickly enough to match profile, 
            # then raise exception    
            if command_accel > accel_max:
                self.raise_exception("Vehicle is unable to achieve " \
                "acceleration required to match EPA driving profile.", 
                                                RuntimeError)
                    
            #------------------------------------------------------------
            # Bisection solution to find correct Throttle position
            #------------------------------------------------------------

            # Deceleration at closed throttle
            throttle = self.throttle_min
            self._throttle_str_expr.set(throttle)
            self.run_iteration()
            acceleration = self._acceleration_str_expr.evaluate(self.parent)
            
            if command_accel >= accel_min:
                
                min_acc = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
                max_acc = accel_max
                min_throttle = self.throttle_min
                max_throttle = self.throttle_max
                new_throttle = .5*(min_throttle + max_throttle)
                
                # Numerical solution to find throttle that matches accel
                while not converged:
                
                    throttle = new_throttle
                    self._throttle_str_expr.set(throttle)
                    self.run_iteration()
                    acceleration = self._acceleration_str_expr.evaluate(self.parent)
                    new_acc = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')
                    
                    if abs(command_accel-new_acc) < self.tolerance:
                        converged = 1
                    else:
                        if new_acc < command_accel:
                            min_throttle = new_throttle
                            min_acc = new_acc
                            step = (command_accel-min_acc)/(max_acc-new_acc)
                            new_throttle = min_throttle + \
                                        step*(max_throttle-min_throttle)
                        else:
                            max_throttle = new_throttle
                            step = (command_accel-min_acc)/(new_acc-min_acc)
                            new_throttle = min_throttle + \
                                        step*(max_throttle-min_throttle)
                            max_acc = new_acc
                      
            distance += .5*(velocity2+velocity1)*(time2-time1)
            burn_rate = self._fuel_burn_str_expr.evaluate(self.parent)
            fuelburn += burn_rate*(time2-time1)
            
            velocity1 = velocity2
            time1 = time2
            
            #print "T = %f, V = %f, Acc = %f" % (time1, velocity1, 
            #command_accel)
            #print gear, accel_min, accel_max
            
        # Convert liter to gallon and sec/hr to hr/hr
        distance = convert_units(distance, 'mi*s/h', 'mi')
        fuelburn = convert_units(fuelburn, 'L', 'galUS')
        self.fuel_economy = distance/fuelburn
        
       
    def _findgear(self, velocity, throttle, gear):
        """ Finds the nearest gear in the appropriate range for the
        currently commanded vehicle state (throttle, velocity).
        
        This is intended to be called recursively.
        """

        self.run_iteration()
        
        overspeed = self._overspeed_str_expr.evaluate(self.parent)
        underspeed = self._underspeed_str_expr.evaluate(self.parent)
        
        if overspeed:
            gear += 1
            
            if gear > 4:
                self.raise_exception("Transmission gearing cannot " \
                "achieve acceleration and speed required by EPA " \
                "test.", RuntimeError)
            
        elif underspeed:
            gear -= 1
            
            # Note, no check needed for low gearing -- we allow underspeed 
            # while in first gear.
                
        else:
            return gear
            
        self._gear_str_expr.set(gear)
        gear = self._findgear(velocity, throttle, gear)        

        return gear
class Constraint2Sided(Constraint):
    """ Object that stores info for a double-sided constraint. """
    def __init__(self, lhs, center, rhs, comparator, scope):
        self.lhs = ExprEvaluator(lhs, scope=scope)
        unresolved_vars = self.lhs.get_unresolved()

        if unresolved_vars:
            msg = "Left hand side of constraint '{0}' has invalid variables {1}"
            expression = ' '.join((lhs, comparator, center, comparator, rhs))

            raise ExprEvaluator._invalid_expression_error(unresolved_vars,
                                                          expr=expression,
                                                          msg=msg)
        self.center = ExprEvaluator(center, scope=scope)
        unresolved_vars = self.center.get_unresolved()

        if unresolved_vars:
            msg = "Center of constraint '{0}' has invalid variables {1}"
            expression = ' '.join((lhs, comparator, center, comparator, rhs))

            raise ExprEvaluator._invalid_expression_error(unresolved_vars,
                                                          expr=expression,
                                                          msg=msg)
        self.rhs = ExprEvaluator(rhs, scope=scope)
        unresolved_vars = self.rhs.get_unresolved()

        if unresolved_vars:
            msg = "Right hand side of constraint '{0}' has invalid variables {1}"
            expression = ' '.join((lhs, comparator, center, comparator, rhs))

            raise ExprEvaluator._invalid_expression_error(unresolved_vars,
                                                          expr=expression,
                                                          msg=msg)
        self.comparator = comparator
        self.pcomp_name = None
        self._size = None

        # Linear flag: constraints are nonlinear by default
        self.linear = False

        self.low = self.lhs.evaluate()
        self.high = self.rhs.evaluate()

    def activate(self, driver):
        """Make this constraint active by creating the appropriate
        connections in the dependency graph.
        """
        if self.pcomp_name is None:

            scope = self.lhs.scope
            refs = list(self.center.ordered_refs())
            pseudo_class = PseudoComponent

            # look for a<var1<b
            if len(refs) == 1 and self.center.text == refs[0]:
                pseudo_class = SimpleEQ0PComp

            pseudo = pseudo_class(scope,
                                  self.center,
                                  pseudo_type='constraint',
                                  subtype='inequality',
                                  exprobject=self)

            self.pcomp_name = pseudo.name
            scope.add(pseudo.name, pseudo)
            getattr(scope, pseudo.name).make_connections(scope, driver)

    def _combined_expr(self):
        """Only need the center expression
        """
        return self.center

    def copy(self):
        """ Returns a copy of our self. """
        return Constraint2Sided(str(self.lhs),
                                str(self.center),
                                str(self.rhs),
                                self.comparator,
                                scope=self.lhs.scope)

    def get_referenced_compnames(self):
        """Returns a set of names of each component referenced by this
        constraint.
        """
        return self.center.get_referenced_compnames()

    def get_referenced_varpaths(self, copy=True, refs=False):
        """Returns a set of names of each component referenced by this
        constraint.
        """
        return self.center.get_referenced_varpaths(copy=copy, refs=refs)

    def __str__(self):
        return ' '.join(
            (str(self.lhs), str(self.center), str(self.rhs), self.comparator))

    def __eq__(self, other):
        if not isinstance(other, Constraint2Sided):
            return False
        return (self.lhs, self.center, self.comparator, self.rhs) == \
               (other.lhs, self.center, other.comparator, other.rhs)
class Constraint2Sided(Constraint):
    """ Object that stores info for a double-sided constraint. """

    def __init__(self, lhs, center, rhs, comparator, scope, jacs=None):
        self.lhs = ExprEvaluator(lhs, scope=scope)
        unresolved_vars = self.lhs.get_unresolved()

        self._pseudo = None
        self.pcomp_name = None

        if unresolved_vars:
            msg = "Left hand side of constraint '{0}' has invalid variables {1}"
            expression = ' '.join((lhs, comparator, center, comparator,
                                   rhs))

            raise ExprEvaluator._invalid_expression_error(unresolved_vars,
                                                          expr=expression,
                                                          msg=msg)
        self.center = ExprEvaluator(center, scope=scope)
        unresolved_vars = self.center.get_unresolved()

        if unresolved_vars:
            msg = "Center of constraint '{0}' has invalid variables {1}"
            expression = ' '.join((lhs, comparator, center, comparator,
                                   rhs))

            raise ExprEvaluator._invalid_expression_error(unresolved_vars,
                                                          expr=expression,
                                                          msg=msg)
        self.rhs = ExprEvaluator(rhs, scope=scope)
        unresolved_vars = self.rhs.get_unresolved()

        if unresolved_vars:
            msg = "Right hand side of constraint '{0}' has invalid variables {1}"
            expression = ' '.join((lhs, comparator, center, comparator,
                                   rhs))

            raise ExprEvaluator._invalid_expression_error(unresolved_vars,
                                                          expr=expression,
                                                          msg=msg)
        self.comparator = comparator
        self._size = None

        # Linear flag: constraints are nonlinear by default
        self.linear = False

        self.low = self.lhs.evaluate()
        self.high = self.rhs.evaluate()

        # User-defined jacobian function
        self.jacs = jacs

        self._create_pseudo()

    def _create_pseudo(self):
        """Create our pseudo component."""
        scope = self.lhs.scope
        refs = list(self.center.ordered_refs())
        pseudo_class = PseudoComponent

        # look for a<var1<b
        if len(refs) == 1 and self.center.text == refs[0]:
            pseudo_class = SimpleEQ0PComp

        self._pseudo = pseudo_class(scope,
                                    self.center,
                                    pseudo_type='constraint',
                                    subtype='inequality',
                                    exprobject=self)

        self.pcomp_name = self._pseudo.name

    def _combined_expr(self):
        """Only need the center expression
        """
        return self.center

    def copy(self):
        """ Returns a copy of our self. """
        return Constraint2Sided(str(self.lhs), str(self.center), str(self.rhs),
                          self.comparator, scope=self.lhs.scope,
                          jacs=self.jacs)

    def get_referenced_compnames(self):
        """Returns a set of names of each component referenced by this
        constraint.
        """
        return self.center.get_referenced_compnames()

    def get_referenced_varpaths(self, copy=True, refs=False):
        """Returns a set of names of each component referenced by this
        constraint.
        """
        return self.center.get_referenced_varpaths(copy=copy, refs=refs)

    def name_changed(self, old, new):
        """Update expressions if necessary when an object is renamed."""
        self.rhs.name_changed(old, new)
        self.lhs.name_changed(old, new)
        self.center.name_changed(old, new)

    def __str__(self):
        return ' '.join((str(self.lhs), str(self.center), str(self.rhs), self.comparator))

    def __eq__(self, other):
        if not isinstance(other, Constraint2Sided):
            return False
        return (self.lhs, self.center, self.comparator, self.rhs) == \
               (other.lhs, self.center, other.comparator, other.rhs)
Exemplo n.º 27
0
    def __init__(self, target, parent, high=None, low=None, scaler=None, adder=None, fd_step=None, scope=None):
        self._metadata = None

        if scaler is None and adder is None:
            self._transform = self._do_nothing
            self._untransform = self._do_nothing
        else:
            if scaler is None:
                scaler = 1.0
            else:
                try:
                    scaler = float(scaler)
                except TypeError:
                    parent.raise_exception("bad scaler", TypeError)
            if adder is None:
                adder = 0.0
            else:
                try:
                    adder = float(adder)
                except TypeError:
                    parent.raise_exception("bad adder", TypeError)

        self.low = low
        self.high = high
        self.scaler = scaler
        self.adder = adder
        self.fd_step = fd_step

        try:
            expreval = ExprEvaluator(target, scope)
        except Exception as err:
            parent.raise_exception("Can't add parameter: %s" % str(err), type(err))
        if not expreval.is_valid_assignee():
            parent.raise_exception(
                "Can't add parameter: '%s' is not a valid parameter expression" % expreval.text, ValueError
            )

        self._expreval = expreval

        try:
            # metadata is in the form [(varname, metadata)], so use [0][1] to get
            # the actual metadata dict (since we're a Parameter we'll only be
            # referencing one variable.
            metadata = self.get_metadata()[0][1]
        except AttributeError:
            parent.raise_exception("Can't add parameter '%s' because it doesn't exist." % target, AttributeError)
        try:
            self.vartypename = metadata["vartypename"]
        except KeyError:
            self.vartypename = None
        try:
            val = expreval.evaluate()
        except Exception as err:
            parent.raise_exception("Can't add parameter because I can't evaluate '%s'." % target, ValueError)
        if self.vartypename != "Enum" and not isinstance(val, (float, float32, float64, int, int32, int64)):
            parent.raise_exception(
                "The value of parameter '%s' must be of type float or int, but its type is '%s'."
                % (target, type(val).__name__),
                ValueError,
            )

        self.valtypename = type(val).__name__

        meta_low = metadata.get("low")  # this will be None if 'low' isn't there
        if low is None:
            self.low = meta_low
        else:
            if meta_low is not None and low < self._transform(meta_low):
                parent.raise_exception(
                    "Trying to add parameter '%s', "
                    "but the lower limit supplied (%s) exceeds the "
                    "built-in lower limit (%s)." % (target, low, meta_low),
                    ValueError,
                )
            self.low = low

        meta_high = metadata.get("high")  # this will be None if 'high' isn't there
        if high is None:
            self.high = meta_high
        else:  # high is not None
            if meta_high is not None and high > self._transform(meta_high):
                parent.raise_exception(
                    "Trying to add parameter '%s', "
                    "but the upper limit supplied (%s) exceeds the "
                    "built-in upper limit (%s)." % (target, high, meta_high),
                    ValueError,
                )
            self.high = high

        if self.vartypename == "Enum":
            return  # it's an Enum, so no need to set high or low
        else:
            if self.low is None:
                parent.raise_exception(
                    "Trying to add parameter '%s', "
                    "but no lower limit was found and no "
                    "'low' argument was given. One or the "
                    "other must be specified." % target,
                    ValueError,
                )
            if self.high is None:
                parent.raise_exception(
                    "Trying to add parameter '%s', "
                    "but no upper limit was found and no "
                    "'high' argument was given. One or the "
                    "other must be specified." % target,
                    ValueError,
                )
        if low is None:
            self.low = self._transform(self.low)
        if high is None:
            self.high = self._transform(self.high)

        if self.low > self.high:
            parent.raise_exception(
                "Parameter '%s' has a lower bound (%s) that exceeds its upper bound (%s)"
                % (target, self.low, self.high),
                ValueError,
            )
Exemplo n.º 28
0
    def test_set_evaluate(self):
        ex = ExprEvaluator('comp.x', self.top)
        self.assertEqual(3.14, ex.evaluate())

        ex.set(75.4)
        self.assertEqual(75.4, self.top.comp.x)
        
        self.top.comp.contlist = [A(), A(), A()]
        self.top.comp.contlist[1].a1d = [4]*5
        ex = ExprEvaluator('comp.contlist[1].a1d[3]', self.top)
        self.assertEqual(ex.evaluate(), 4)
        
        ex.set(123)
        self.assertEqual(ex.evaluate(), 123)
        
        ex = ExprEvaluator("comp.contlist[1].some_funct(3,5,'sub')", self.top)
        self.assertEqual(ex.evaluate(), -2)
        
        ex = ExprEvaluator("comp.get_cont(1).some_funct(3,5,'add')", self.top)
        self.assertEqual(ex.evaluate(), 8)
        
        ex = ExprEvaluator("comp.get_cont(1).a1d[2]", self.top)
        self.assertEqual(ex.evaluate(), 4)
        
        ex = ExprEvaluator("a2d[1][0]", self.top.a)
        self.assertEqual(ex.evaluate(), 2.)
        ex.set(7.)
        self.assertEqual(self.top.a.a2d[1][0], 7.)
        
        ex = ExprEvaluator("a2d[1,0]", self.top.a)
        self.assertEqual(ex.evaluate(), 7.)
        ex.set(11.)
        self.assertEqual(self.top.a.a2d[1][0], 11.)
        
        ex = ExprEvaluator("a2d[1]", self.top.a)
        self.assertTrue(all(ex.evaluate() == numpy.array([11.,3.])))
        ex.set([0.1,0.2])
        self.assertTrue(all(self.top.a.a2d[1] == numpy.array([0.1,0.2])))
        
        self.top.comp.cont = A()
        
        ex = ExprEvaluator("comp.cont.a2d[1][0]", self.top)
        self.assertEqual(ex.evaluate(), 2.)
        ex.set(7.)
        self.assertEqual(self.top.comp.cont.a2d[1][0], 7.)
        
        ex = ExprEvaluator("comp.cont.a2d[1,0]", self.top)
        self.assertEqual(ex.evaluate(), 7.)
        ex.set(11.)
        self.assertEqual(self.top.comp.cont.a2d[1][0], 11.)
        
        ex = ExprEvaluator("comp.get_cont(1).a1d", self.top)
        self.assertTrue(all(ex.evaluate() == numpy.array([4,4,4,123,4])))
        
        ex = ExprEvaluator("comp.get_attr('get_cont')(1).a1d", self.top)
        self.assertTrue(all(ex.evaluate() == numpy.array([4,4,4,123,4])))
        
        # try an expression that's a simple assignment
        ex = ExprEvaluator("f = 10.333", self.top.a)
        self.assertEqual(ex.evaluate(), None)
        self.assertEqual(self.top.a.f, 10.333)
Exemplo n.º 29
0
 def test_property(self):
     ex = ExprEvaluator('some_prop', self.top.a)
     self.assertEqual(ex.evaluate(), 7)
Exemplo n.º 30
0
class Constraint(object):
    """ Object that stores info for a single constraint. """
    def __init__(self, lhs, comparator, rhs, scaler, adder, scope=None):
        self.lhs = ExprEvaluator(lhs, scope=scope)
        if not self.lhs.check_resolve():
            raise ValueError("Constraint '%s' has an invalid left-hand-side." \
                              % ' '.join([lhs, comparator, rhs]))
        self.comparator = comparator
        self.rhs = ExprEvaluator(rhs, scope=scope)
        if not self.rhs.check_resolve():
            raise ValueError("Constraint '%s' has an invalid right-hand-side." \
                              % ' '.join([lhs, comparator, rhs]))

        if not isinstance(scaler, float):
            raise ValueError("Scaler parameter should be a float")
        self.scaler = scaler

        if scaler <= 0.0:
            raise ValueError("Scaler parameter should be a float > 0")

        if not isinstance(adder, float):
            raise ValueError("Adder parameter should be a float")
        self.adder = adder

    def copy(self):
        return Constraint(self.lhs.text,
                          self.comparator,
                          self.rhs.text,
                          self.scaler,
                          self.adder,
                          scope=self.lhs.scope)

    def evaluate(self, scope):
        """Returns a tuple of the form (lhs, rhs, comparator, is_violated)."""

        lhs = (self.lhs.evaluate(scope) + self.adder) * self.scaler
        rhs = (self.rhs.evaluate(scope) + self.adder) * self.scaler
        return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs))

    def evaluate_gradient(self, scope, stepsize=1.0e-6, wrt=None):
        """Returns the gradient of the constraint eq/inep as a tuple of the
        form (lhs, rhs, comparator, is_violated)."""

        lhs = self.lhs.evaluate_gradient(scope=scope,
                                         stepsize=stepsize,
                                         wrt=wrt)
        for key, value in lhs.iteritems():
            lhs[key] = (value + self.adder) * self.scaler

        rhs = self.rhs.evaluate_gradient(scope=scope,
                                         stepsize=stepsize,
                                         wrt=wrt)
        for key, value in rhs.iteritems():
            rhs[key] = (value + self.adder) * self.scaler

        return (lhs, rhs, self.comparator, not _ops[self.comparator](lhs, rhs))

    def get_referenced_compnames(self):
        return self.lhs.get_referenced_compnames().union(
            self.rhs.get_referenced_compnames())

    def __str__(self):
        return ' '.join([self.lhs.text, self.comparator, self.rhs.text])

    def __eq__(self, other):
        if not isinstance(other, Constraint):
            return False
        return (self.lhs,self.comparator,self.rhs,self.scaler,self.adder) == \
               (other.lhs,other.comparator,other.rhs,other.scaler,other.adder)
Exemplo n.º 31
0
class SimAcceleration(Driver):
    """ Simulation of vehicle acceleration performance. This is a specialized
    simulation driver whose workflow should consist of a Vehicle assembly, and
    whose connections are as follows:
    
    Connection Inputs
    velocity_str: str
        Variable location for vehicle velocity.
    
    throttle_str: str
        Variable location for vehicle throttle position.
    
    gear_str: str
        Variable location for vehicle gear position.
    
    acceleration_str: str
        Variable location for vehicle acceleration.
    
    overspeed_str: str
        Variable location for vehicle overspeed.
    
    Simulation Inputs
    end_speed: float
        Ending speed for the simulation (default 60 mph)
    
    timestep: float
        Simulation time step (default .01)
        
    Outputs
    accel_time: float
        Time to perform the acceleration test.
    """

    velocity_str = Str(iotype='in',
                       desc='Location of vehicle input: velocity.')
    throttle_str = Str(iotype='in',
                       desc='Location of vehicle input: throttle.')
    gear_str = Str(iotype='in',
                   desc='Location of vehicle input: current_gear.')
    acceleration_str = Str(iotype='in',
                           desc='Location of vehicle output: acceleration.')
    overspeed_str = Str(iotype='in',
                        desc='Location of vehicle output: overspeed.')

    end_speed = Float(60.0,
                      iotype='in',
                      units='mi/h',
                      desc='Simulation final speed')
    timestep = Float(0.1,
                     iotype='in',
                     units='s',
                     desc='Simulation time step size')

    accel_time = Float(0.0, iotype='out', units='s', desc='Acceleration time')

    def __init__(self):
        super(SimAcceleration, self).__init__()

        self._velocity_str_expr = None
        self._throttle_str_expr = None
        self._gear_str_expr = None
        self._acceleration_str_expr = None
        self._overspeed_str_expr = None

    def _velocity_str_changed(self, oldval, newval):
        self._velocity_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _throttle_str_changed(self, oldval, newval):
        self._throttle_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _gear_str_changed(self, oldval, newval):
        self._gear_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _acceleration_str_changed(self, oldval, newval):
        self._acceleration_str_expr = ExprEvaluator(newval, scope=self.parent)

    def _overspeed_str_changed(self, oldval, newval):
        self._overspeed_str_expr = ExprEvaluator(newval, scope=self.parent)

    def execute(self):
        """ Simulate the vehicle model at full throttle."""

        # Set initial throttle, gear, and velocity
        time = 0.0
        velocity = 0.0
        throttle = 1.0
        gear = 1

        while velocity < self.end_speed:

            self._velocity_str_expr.set(velocity)
            self._throttle_str_expr.set(throttle)
            self._gear_str_expr.set(gear)
            self.run_iteration()

            acceleration = self._acceleration_str_expr.evaluate(self.parent)
            overspeed = self._overspeed_str_expr.evaluate(self.parent)

            # If the next gear can produce more torque, let's shift.
            if gear < 5:
                self._gear_str_expr.set(gear + 1)
                self.run_iteration()

                acceleration2 = self._acceleration_str_expr.evaluate(
                    self.parent)
                if acceleration2 > acceleration:
                    gear += 1
                    acceleration = acceleration2
                    overspeed = self._overspeed_str_expr.evaluate(self.parent)

            # If RPM goes over MAX RPM, shift gears
            # (i.e.: shift at redline)
            if overspeed:
                gear += 1
                self._gear_str_expr.set(gear)
                self.run_iteration()
                acceleration = self._acceleration_str_expr.evaluate(
                    self.parent)
                overspeed = self._overspeed_str_expr.evaluate(self.parent)

                if overspeed:
                    self.raise_exception("Gearing problem in Accel test.",
                                         RuntimeError)

            acceleration = convert_units(acceleration, 'm/(s*s)', 'mi/(h*s)')

            if acceleration <= 0.0:
                self.raise_exception("Vehicle could not reach maximum speed "+\
                                     "in Acceleration test.", RuntimeError)

            velocity += (acceleration * self.timestep)

            time += self.timestep

        self.accel_time = time
Exemplo n.º 32
0
    def test_set_evaluate(self):
        ex = ExprEvaluator('comp.x', self.top)
        self.assertEqual(3.14, ex.evaluate())

        ex.set(75.4)
        self.assertEqual(75.4, self.top.comp.x)

        self.top.comp.contlist = [A(), A(), A()]
        self.top.comp.contlist[1].a1d = [4]*5
        ex = ExprEvaluator('comp.contlist[1].a1d[3]', self.top)
        self.assertEqual(ex.evaluate(), 4)

        ex.set(123)
        self.assertEqual(ex.evaluate(), 123)

        ex = ExprEvaluator("comp.contlist[1].some_funct(3,5,'sub')", self.top)
        self.assertEqual(ex.evaluate(), -2)

        ex = ExprEvaluator("comp.get_cont(1).some_funct(3,5,'add')", self.top)
        self.assertEqual(ex.evaluate(), 8)

        ex = ExprEvaluator("comp.get_cont(1).a1d[2]", self.top)
        self.assertEqual(ex.evaluate(), 4)

        ex = ExprEvaluator("a2d[1][0]", self.top.a)
        self.assertEqual(ex.evaluate(), 2.)
        ex.set(7.)
        self.assertEqual(self.top.a.a2d[1][0], 7.)

        ex = ExprEvaluator("a2d[1,0]", self.top.a)
        self.assertEqual(ex.evaluate(), 7.)
        ex.set(11.)
        self.assertEqual(self.top.a.a2d[1][0], 11.)

        ex = ExprEvaluator("a2d[1]", self.top.a)

        self.assertTrue(all(ex.evaluate() == array([11., 3.])))
        ex.set([0.1, 0.2])
        self.assertTrue(all(self.top.a.a2d[1] == array([0.1, 0.2])))


        self.top.comp.cont = A()

        ex = ExprEvaluator("comp.cont.a2d[1][0]", self.top)
        self.assertEqual(ex.evaluate(), 2.)
        ex.set(7.)
        self.assertEqual(self.top.comp.cont.a2d[1][0], 7.)

        ex = ExprEvaluator("comp.cont.a2d[1,0]", self.top)
        self.assertEqual(ex.evaluate(), 7.)
        ex.set(11.)
        self.assertEqual(self.top.comp.cont.a2d[1][0], 11.)

        # try a numpy function
        try:
            import numpy
        except ImportError:
            pass
        else:
            ex = ExprEvaluator("numpy.eye(2)", self.top.a)
            val = ex.evaluate()

            self.assertTrue((val == numpy.eye(2)).all())

        ex = ExprEvaluator("comp.get_cont(1).a1d", self.top)
        self.assertEqual(list(ex.evaluate()), [4, 4, 4, 123, 4])

        ex = ExprEvaluator("comp.get_attrib('get_cont')(1).a1d", self.top)
        self.assertEqual(list(ex.evaluate()), [4, 4, 4, 123, 4])
Exemplo n.º 33
0
    def __init__(self,
                 target,
                 high=None,
                 low=None,
                 scaler=None,
                 adder=None,
                 start=None,
                 fd_step=None,
                 scope=None,
                 name=None):
        self._metadata = None

        if scaler is None and adder is None:
            self._transform = self._do_nothing
            self._untransform = self._do_nothing
        else:
            if scaler is None:
                scaler = 1.0
            else:
                try:
                    scaler = float(scaler)
                except (TypeError, ValueError):
                    raise ValueError(
                        "Bad value given for parameter's 'scaler' attribute.")
            if adder is None:
                adder = 0.0
            else:
                try:
                    adder = float(adder)
                except (TypeError, ValueError):
                    raise ValueError(
                        "Bad value given for parameter's 'adder' attribute.")

        self.low = low
        self.high = high
        self.start = start
        self.scaler = scaler
        self.adder = adder
        self.fd_step = fd_step
        if name is not None:
            self.name = name
        else:
            self.name = target

        try:
            expreval = ExprEvaluator(target, scope)
        except Exception as err:
            raise err.__class__("Can't add parameter: %s" % str(err))
        if not expreval.is_valid_assignee():
            raise ValueError(
                "Can't add parameter: '%s' is not a valid parameter expression"
                % expreval.text)

        self._expreval = expreval

        try:
            # metadata is in the form (varname, metadata), so use [1] to get
            # the actual metadata dict
            metadata = self.get_metadata()[1]
        except AttributeError:
            raise AttributeError(
                "Can't add parameter '%s' because it doesn't exist." % target)

        if 'iotype' in metadata and metadata['iotype'] == 'out':
            raise RuntimeError(
                "Can't add parameter '%s' because '%s' is an output." %
                (target, target))
        try:
            # So, our traits might not have a vartypename?
            self.vartypename = metadata['vartypename']
        except KeyError:
            self.vartypename = None

        try:
            val = expreval.evaluate()
        except Exception as err:
            raise ValueError(
                "Can't add parameter because I can't evaluate '%s'." % target)

        self.valtypename = type(val).__name__

        if self.vartypename == 'Enum':
            return  # it's an Enum, so no need to set high or low

        if not isinstance(val, real_types) and not isinstance(val, int_types):
            raise ValueError(
                "The value of parameter '%s' must be a real or integral type, but its type is '%s'."
                % (target, type(val).__name__))

        meta_low = metadata.get(
            'low')  # this will be None if 'low' isn't there
        if meta_low is not None:
            if low is None:
                self.low = self._untransform(meta_low)
            elif low < self._untransform(meta_low):
                raise ValueError(
                    "Trying to add parameter '%s', "
                    "but the lower limit supplied (%s) exceeds the "
                    "built-in lower limit (%s)." % (target, low, meta_low))
        else:
            if low is None:
                raise ValueError("Trying to add parameter '%s', "
                                 "but no lower limit was found and no "
                                 "'low' argument was given. One or the "
                                 "other must be specified." % target)

        meta_high = metadata.get(
            'high')  # this will be None if 'low' isn't there
        if meta_high is not None:
            if high is None:
                self.high = self._untransform(meta_high)
            elif high > self._untransform(meta_high):
                raise ValueError(
                    "Trying to add parameter '%s', "
                    "but the upper limit supplied (%s) exceeds the "
                    "built-in upper limit (%s)." % (target, high, meta_high))
        else:
            if high is None:
                raise ValueError("Trying to add parameter '%s', "
                                 "but no upper limit was found and no "
                                 "'high' argument was given. One or the "
                                 "other must be specified." % target)

        if self.low > self.high:
            raise ValueError(
                "Parameter '%s' has a lower bound (%s) that exceeds its upper bound (%s)"
                % (target, self.low, self.high))