def _create_pseudo(self):
        """Create our pseudo component."""
        if self.comparator == '=':
            subtype = 'equality'
        else:
            subtype = 'inequality'

        # check for simple structure of equality constraint,
        # either
        #     var1 = var2
        #  OR
        #     var1 - var2 = 0
        #  OR
        #     var1 = 0
        lrefs = list(self.lhs.ordered_refs())
        rrefs = list(self.rhs.ordered_refs())

        try:
            leftval = float(self.lhs.text)
        except ValueError:
            leftval = None

        try:
            rightval = float(self.rhs.text)
        except ValueError:
            rightval = None

        pseudo_class = PseudoComponent

        if self.comparator == '=':
            # look for var1-var2=0
            if len(lrefs) == 2 and len(rrefs) == 0:
                if rightval == 0. and \
                        _remove_spaces(self.lhs.text) == \
                            lrefs[0]+'-'+lrefs[1]:
                    pseudo_class = SimpleEQConPComp
            # look for 0=var1-var2
            elif len(lrefs) == 0 and len(rrefs) == 2:
                if leftval==0. and \
                       _remove_spaces(self.rhs.text) == \
                            rrefs[0]+'-'+rrefs[1]:
                    pseudo_class = SimpleEQConPComp
            # look for var1=var2
            elif len(lrefs) == 1 and len(rrefs) == 1:
                if lrefs[0] == self.lhs.text and \
                           rrefs[0] == self.rhs.text:
                    pseudo_class = SimpleEQConPComp
            # look for var1=0
            elif len(lrefs) == 1 and len(rrefs) == 0 and rightval is not None:
                pseudo_class = SimpleEQ0PComp

        self._pseudo = pseudo_class(self.lhs.scope,
                                    self._combined_expr(),
                                    pseudo_type='constraint',
                                    subtype=subtype,
                                    exprobject=self)

        self.pcomp_name = self._pseudo.name
    def _add_ineq_constraint(self, lhs, rel, rhs, name=None, scope=None):
        """Adds an inequality constraint as three strings; a left-hand side,
        a comparator ('<','>','<=', or '>='), and a right-hand side.
        """
        if rel == '=':
            msg = "Equality constraints are not supported on this driver"
            self._parent.raise_exception(msg, ValueError)

        if not isinstance(lhs, basestring):
            msg = "Constraint left-hand-side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(rhs, basestring):
            msg = "Constraint right-hand-side (%s) is not a string" % rhs
            raise ValueError(msg)
        ident = _remove_spaces(rel.join([lhs, rhs]))
        if ident in self._constraints:
            self._parent.raise_exception('A constraint of the form "%s" already'
                                         ' exists in the driver. Add failed.'
                                         % ident, ValueError)
        elif name is not None and name in self._constraints:
            self._parent.raise_exception('A constraint named "%s" already exists'
                                         ' in the driver. Add failed.'
                                         % name, ValueError)

        constraint = Constraint(lhs, rel, rhs, scope=_get_scope(self, scope))
        constraint.activate()

        if name is None:
            self._constraints[ident] = constraint
        else:
            self._constraints[name] = constraint

        self._parent.config_changed()
    def _add_eq_constraint(self, lhs, rhs, name=None, scope=None,
                           linear=False, jacs=None):
        """Adds an equality constraint as two strings, a left-hand side and
        a right-hand side.
        """
        if not isinstance(lhs, basestring):
            msg = "Constraint left-hand side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(rhs, basestring):
            msg = "Constraint right-hand-side (%s) is not a string" % rhs
            raise ValueError(msg)
        ident = _remove_spaces('='.join((lhs, rhs)))
        if ident in self._constraints:
            self.parent.raise_exception('A constraint of the form "%s" already'
                                        ' exists in the driver. Add failed.'
                                        % ident, ValueError)
        elif name is not None and name in self._constraints:
            self.parent.raise_exception('A constraint named "%s" already exists'
                                        ' in the driver. Add failed.'
                                        % name, ValueError)

        constraint = Constraint(lhs, '=', rhs, scope=_get_scope(self, scope),
                                jacs=jacs)
        constraint.linear = linear

        if IDriver.providedBy(self.parent):
            #constraint.activate(self.parent)
            self.parent.config_changed()

        name = ident if name is None else name
        self._constraints[name] = constraint
    def _add_eq_constraint(self,
                           lhs,
                           rhs,
                           name=None,
                           scope=None,
                           linear=False):
        """Adds an equality constraint as two strings, a left-hand side and
        a right-hand side.
        """
        if not isinstance(lhs, basestring):
            msg = "Constraint left-hand side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(rhs, basestring):
            msg = "Constraint right-hand-side (%s) is not a string" % rhs
            raise ValueError(msg)
        ident = _remove_spaces('='.join((lhs, rhs)))
        if ident in self._constraints:
            self.parent.raise_exception(
                'A constraint of the form "%s" already'
                ' exists in the driver. Add failed.' % ident, ValueError)
        elif name is not None and name in self._constraints:
            self.parent.raise_exception(
                'A constraint named "%s" already exists'
                ' in the driver. Add failed.' % name, ValueError)

        constraint = Constraint(lhs, '=', rhs, scope=_get_scope(self, scope))
        constraint.linear = linear
        constraint.activate()

        name = ident if name is None else name
        self._constraints[name] = constraint

        self.parent.config_changed()
 def remove_constraint(self, expr_string):
     """Removes the constraint with the given string."""
     ident = _remove_spaces(expr_string)
     if ident in self._eq._constraints:
         self._eq.remove_constraint(expr_string)
     else:
         self._ineq.remove_constraint(expr_string)
 def remove_constraint(self, expr_string):
     """Removes the constraint with the given string."""
     ident = _remove_spaces(expr_string)
     if ident in self._eq._constraints:
         self._eq.remove_constraint(expr_string)
     else:
         self._ineq.remove_constraint(expr_string)
예제 #7
0
    def _add_ineq_constraint(self, lhs, rel, rhs, name=None, scope=None):
        """Adds an inequality constraint as three strings; a left-hand side,
        a comparator ('<','>','<=', or '>='), and a right-hand side.
        """
        if rel == '=':
            msg = "Equality constraints are not supported on this driver"
            self._parent.raise_exception(msg, ValueError)

        if not isinstance(lhs, basestring):
            msg = "Constraint left-hand-side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(rhs, basestring):
            msg = "Constraint right-hand-side (%s) is not a string" % rhs
            raise ValueError(msg)
        ident = _remove_spaces(rel.join([lhs, rhs]))
        if ident in self._constraints:
            self._parent.raise_exception(
                'A constraint of the form "%s" already'
                ' exists in the driver. Add failed.' % ident, ValueError)
        elif name is not None and name in self._constraints:
            self._parent.raise_exception(
                'A constraint named "%s" already exists'
                ' in the driver. Add failed.' % name, ValueError)

        constraint = Constraint(lhs, rel, rhs, scope=_get_scope(self, scope))
        constraint.activate()

        if name is None:
            self._constraints[ident] = constraint
        else:
            self._constraints[name] = constraint

        self._parent.config_changed()
    def add_2sided_constraint(self,
                              lhs,
                              center,
                              rhs,
                              rel,
                              name=None,
                              scope=None,
                              linear=False):
        """Adds an 2-sided constraint as four strings; a left-hand side, a
        center, a right-hand side, and a comparator ('<','>','<=', or '>=')
        """
        if rel == '=':
            msg = "Equality is not supported in a double sided constraint"
            self.parent.raise_exception(msg, ValueError)

        if not isinstance(lhs, basestring):
            msg = "Constraint left-hand-side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(center, basestring):
            msg = "Constraint center-side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(rhs, basestring):
            msg = "Constraint right-hand-side (%s) is not a string" % rhs
            raise ValueError(msg)

        # Let's define left as low and right as high
        if rel == '>':
            rel = '<'
            rhs, lhs = lhs, rhs

        ident = _remove_spaces(rel.join((lhs, center, rhs)))
        if ident in self._constraints:
            self.parent.raise_exception(
                'A constraint of the form "%s" already'
                ' exists in the driver. Add failed.' % ident, ValueError)
        elif name is not None and name in self._constraints:
            self.parent.raise_exception(
                'A constraint named "%s" already exists'
                ' in the driver. Add failed.' % name, ValueError)

        constraint = Constraint2Sided(lhs,
                                      center,
                                      rhs,
                                      rel,
                                      scope=_get_scope(self, scope))
        constraint.linear = linear

        if IDriver.providedBy(self.parent):
            constraint.activate(self.parent)
            self.parent.config_changed()

        if name is None:
            self._constraints[ident] = constraint
        else:
            self._constraints[name] = constraint
 def remove_constraint(self, key):
     """Removes the constraint with the given string."""
     key = _remove_spaces(key)
     cnst = self._constraints.get(key)
     if cnst:
         cnst.deactivate()
         del self._constraints[key]
     else:
         msg = "Constraint '%s' was not found. Remove failed." % key
         self.parent.raise_exception(msg, AttributeError)
     self.parent.config_changed()
예제 #10
0
 def remove_constraint(self, key):
     """Removes the constraint with the given string."""
     key = _remove_spaces(key)
     cnst = self._constraints.get(key)
     if cnst:
         cnst.deactivate()
         del self._constraints[key]
     else:
         msg = "Constraint '%s' was not found. Remove failed." % key
         self.parent.raise_exception(msg, AttributeError)
     self.parent.config_changed()
    def add_response(self, expr, name=None, scope=None):
        """We need to create our special variable trees."""

        super(AdaptiveSampleDriver, self).add_response(expr, name, scope)

        path = _remove_spaces(expr) if name is None else name
        path = make_legal_path(path)

        desc = 'Holds all outputs processed by this driver.'
        self._add_vartrees('all_case_outputs', path, desc)

        desc = 'Holds just the DOE outputs.'
        self._add_vartrees('DOE_outputs', path, desc)
    def add_response(self, expr, name=None, scope=None):
        """We need to create our special variable trees."""

        super(AdaptiveSampleDriver, self).add_response(expr, name, scope)

        path = _remove_spaces(expr) if name is None else name
        path = make_legal_path(path)

        desc = 'Holds all outputs processed by this driver.'
        self._add_vartrees('all_case_outputs', path, desc)

        desc = 'Holds just the DOE outputs.'
        self._add_vartrees('DOE_outputs', path, desc)
예제 #13
0
 def remove_objective(self, expr):
     """Removes the specified objective expression. Spaces within
     the expression are ignored.
     """
     expr = _remove_spaces(expr)
     obj = self._objectives.get(expr)
     if obj:
         obj.deactivate()
         del self._objectives[expr]
     else:
         self.parent.raise_exception(
             "Trying to remove objective '%s' "
             "that is not in this driver." % expr, AttributeError)
     self.parent.config_changed()
    def remove_response(self, expr):
        """Removes the specified response expression. Spaces within
        the expression are ignored.
        """
        super(HasVarTreeResponses, self).remove_response(expr)

        path = make_legal_path(_remove_spaces(expr))
        obj = self.parent
        names = ["case_outputs"] + path.split(".")
        for name in names[:-1]:
            obj = obj.get(name)

        name = names[-1]
        obj.remove_trait(name)
예제 #15
0
    def remove_response(self, expr):
        """Removes the specified response expression. Spaces within
        the expression are ignored.
        """
        super(HasVarTreeResponses, self).remove_response(expr)

        path = make_legal_path(_remove_spaces(expr))
        obj = self.parent
        names = ['case_outputs'] + path.split('.')
        for name in names[:-1]:
            obj = obj.get(name)

        name = names[-1]
        obj.remove_trait(name)
예제 #16
0
 def remove_objective(self, expr):
     """Removes the specified objective expression. Spaces within
     the expression are ignored.
     """
     expr = _remove_spaces(expr)
     obj = self._objectives.get(expr)
     if obj:
         obj.deactivate()
         del self._objectives[expr]
     else:
         self._parent.raise_exception("Trying to remove objective '%s' "
                                      "that is not in this driver." % expr,
                                      AttributeError)
     self._parent.config_changed()
예제 #17
0
    def add_objective(self, expr, name=None, scope=None):
        """Adds an objective to the driver.

        expr: string
            String containing the objective expression.

        name: string (optional)
            Name to be used to refer to the objective in place of the expression
            string.

        scope: object (optional)
            The object to be used as the scope when evaluating the expression.

         """
        if self._max_objectives > 0 and \
                        len(self._objectives) >= self._max_objectives:
            self.parent.raise_exception(
                "Can't add objective '%s'. Only %d"
                " objectives are allowed" % (expr, self._max_objectives),
                RuntimeError)
        expr = _remove_spaces(expr)
        if expr in self._objectives:
            self.parent.raise_exception(
                "Trying to add objective '%s' to"
                " driver, but it's already there" % expr, AttributeError)
        if name is not None and name in self._objectives:
            self.parent.raise_exception(
                "Trying to add objective '%s' to"
                " driver using name '%s', but name is"
                " already used" % (expr, name), AttributeError)

        scope = self._get_scope(scope)
        expreval = Objective(expr, scope)
        unresolved_vars = expreval.get_unresolved()
        if unresolved_vars:
            msg = "Can't add objective '{0}' because of invalid variables {1}"
            error = ConnectedExprEvaluator._invalid_expression_error(
                unresolved_vars, expreval.text, msg)
            self.parent.raise_exception(str(error), type(error))

        name = expr if name is None else name

        expreval.activate()

        self._objectives[name] = expreval

        self.parent.config_changed()
    def add_objective(self, expr, name=None, scope=None):
        """Adds an objective to the driver.

        expr: string
            String containing the objective expression.

        name: string (optional)
            Name to be used to refer to the objective in place of the expression
            string.

        scope: object (optional)
            The object to be used as the scope when evaluating the expression.

         """
        if self._max_objectives > 0 and \
           len(self._objectives) >= self._max_objectives:
            self.parent.raise_exception("Can't add objective '%s'. Only %d"
                                        " objectives are allowed"
                                        % (expr, self._max_objectives),
                                        RuntimeError)
        expr = _remove_spaces(expr)
        if expr in self._objectives:
            self.parent.raise_exception("Trying to add objective '%s' to"
                                        " driver, but it's already there"
                                        % expr, AttributeError)
        if name is not None and name in self._objectives:
            self.parent.raise_exception("Trying to add objective '%s' to"
                                        " driver using name '%s', but name is"
                                        " already used" % (expr, name),
                                        AttributeError)

        scope = self._get_scope(scope)
        expreval = Objective(expr, scope)
        unresolved_vars = expreval.get_unresolved()
        if unresolved_vars:
            msg = "Can't add objective '{0}' because of invalid variables {1}"
            error = ConnectedExprEvaluator._invalid_expression_error(unresolved_vars, expreval.text, msg)
            self.parent.raise_exception(str(error), type(error))

        name = expr if name is None else name

        expreval.activate()

        self._objectives[name] = expreval

        self.parent.config_changed()
    def add_2sided_constraint(self, lhs, center, rhs, rel, name=None, scope=None,
                               linear=False, jacs=None):
        """Adds an 2-sided constraint as four strings; a left-hand side, a
        center, a right-hand side, and a comparator ('<','>','<=', or '>=')
        """
        if rel == '=':
            msg = "Equality is not supported in a double sided constraint"
            self.parent.raise_exception(msg, ValueError)

        if not isinstance(lhs, basestring):
            msg = "Constraint left-hand-side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(center, basestring):
            msg = "Constraint center-side (%s) is not a string" % lhs
            raise ValueError(msg)
        if not isinstance(rhs, basestring):
            msg = "Constraint right-hand-side (%s) is not a string" % rhs
            raise ValueError(msg)

        # Let's define left as low and right as high
        if rel == '>':
            rel = '<'
            rhs, lhs = lhs, rhs

        ident = _remove_spaces(rel.join((lhs, center, rhs)))
        if ident in self._constraints:
            self.parent.raise_exception('A constraint of the form "%s" already'
                                        ' exists in the driver. Add failed.'
                                        % ident, ValueError)
        elif name is not None and name in self._constraints:
            self.parent.raise_exception('A constraint named "%s" already exists'
                                        ' in the driver. Add failed.'
                                        % name, ValueError)

        constraint = Constraint2Sided(lhs, center, rhs, rel,
                                      scope=_get_scope(self, scope), jacs=jacs)
        constraint.linear = linear

        if IDriver.providedBy(self.parent):
            #constraint.activate(self.parent)
            self.parent.config_changed()

        if name is None:
            self._constraints[ident] = constraint
        else:
            self._constraints[name] = constraint
예제 #20
0
    def add_response(self, expr, name=None, scope=None):
        """Adds a response to the driver."""
        super(HasVarTreeResponses, self).add_response(expr, name, scope)

        path = _remove_spaces(expr) if name is None else name
        path = make_legal_path(path)
        obj = self.parent
        names = ['case_outputs'] + path.split('.')
        for name in names[:-1]:
            if obj.get_trait(name):
                val = obj.get(name)
            else:
                val = VariableTree()
                obj.add_trait(name, VarTree(val, iotype='out'))
            obj = val

        name = names[-1]
        obj.add_trait(name, List(iotype='out'))
    def add_response(self, expr, name=None, scope=None):
        """Adds a response to the driver."""
        super(HasVarTreeResponses, self).add_response(expr, name, scope)

        path = _remove_spaces(expr) if name is None else name
        path = make_legal_path(path)
        obj = self.parent
        names = ["case_outputs"] + path.split(".")
        for name in names[:-1]:
            if obj.get_trait(name):
                val = obj.get(name)
            else:
                val = VariableTree()
                obj.add_trait(name, VarTree(val, iotype="out"))
            obj = val

        name = names[-1]
        obj.add_trait(name, List(iotype="out"))
예제 #22
0
    def add_objective(self, expr, name=None, scope=None):
        """Adds an objective to the driver.

        expr: string
            String containing the objective expression.

        name: string (optional)
            Name to be used to refer to the objective in place of the expression
            string.

        scope: object (optional)
            The object to be used as the scope when evaluating the expression.

         """
        if self._max_objectives > 0 and \
           len(self._objectives) >= self._max_objectives:
            self.parent.raise_exception("Can't add objective '%s'. Only %d"
                                        " objectives are allowed"
                                        % (expr, self._max_objectives),
                                        RuntimeError)
        expr = _remove_spaces(expr)
        if expr in self._objectives:
            self.parent.raise_exception("Trying to add objective '%s' to"
                                        " driver, but it's already there"
                                        % expr, AttributeError)
        if name is not None and name in self._objectives:
            self.parent.raise_exception("Trying to add objective '%s' to"
                                        " driver using name '%s', but name is"
                                        " already used" % (expr, name),
                                        AttributeError)

        scope = self._get_scope(scope)
        try:
            expreval = Objective(expr, scope)
        except Exception as err:
            self.parent.raise_exception(str(err), type(err))

        name = expr if name is None else name

        if IDriver.providedBy(self.parent):
            #expreval.activate(self.parent)
            self.parent.config_changed()

        self._objectives[name] = expreval
예제 #23
0
    def add_response(self, expr, name=None, scope=None):
        """Adds a response to the driver.

        expr: string
            String containing the response expression.

        name: string (optional)
            Name to be used to refer to the response in place of the expression
            string.

        scope: object (optional)
            The object to be used as the scope when evaluating the expression.

        """
        expr = _remove_spaces(expr)
        if expr in self._responses:
            self.parent.raise_exception(
                "Trying to add response '%s' to"
                " driver, but it's already there" % expr, AttributeError)
        if name is not None and name in self._responses:
            self.parent.raise_exception(
                "Trying to add response '%s' to"
                " driver using name '%s', but name is"
                " already used" % (expr, name), AttributeError)

        scope = self._get_scope(scope)
        try:
            expreval = Response(expr, scope)
            unresolved_vars = expreval.get_unresolved()
        except AttributeError:
            unresolved_vars = [expr]
        if unresolved_vars:
            msg = "Can't add response '{0}' because of invalid variables {1}"
            error = ConnectedExprEvaluator._invalid_expression_error(
                unresolved_vars, expr, msg)
            self.parent.raise_exception(str(error), type(error))

        name = expr if name is None else name

        #expreval.activate(self.parent)

        self._responses[name] = expreval
        self.parent.config_changed()
    def add_response(self, expr, name=None, scope=None):
        """Adds a response to the driver.

        expr: string
            String containing the response expression.

        name: string (optional)
            Name to be used to refer to the response in place of the expression
            string.

        scope: object (optional)
            The object to be used as the scope when evaluating the expression.

        """
        expr = _remove_spaces(expr)
        if expr in self._responses:
            self.parent.raise_exception(
                "Trying to add response '%s' to" " driver, but it's already there" % expr, AttributeError
            )
        if name is not None and name in self._responses:
            self.parent.raise_exception(
                "Trying to add response '%s' to" " driver using name '%s', but name is" " already used" % (expr, name),
                AttributeError,
            )

        scope = self._get_scope(scope)
        try:
            expreval = Response(expr, scope)
            unresolved_vars = expreval.get_unresolved()
        except AttributeError:
            unresolved_vars = [expr]
        if unresolved_vars:
            msg = "Can't add response '{0}' because of invalid variables {1}"
            error = ConnectedExprEvaluator._invalid_expression_error(unresolved_vars, expr, msg)
            self.parent.raise_exception(str(error), type(error))

        name = expr if name is None else name

        # expreval.activate(self.parent)

        self._responses[name] = expreval
        self.parent.config_changed()
예제 #25
0
    def add_objective(self, expr, name=None, scope=None):
        """Adds an objective to the driver. 
        
        expr: string
            String containing the objective expression.
            
        name: string (optional)
            Name to be used to refer to the objective in place of the expression
            string.
            
        scope: object (optional)
            The object to be used as the scope when evaluating the expression.

         """
        if self._max_objectives > 0 and len(self._objectives) >= self._max_objectives:
            self._parent.raise_exception("Can't add objective '%s'. Only %d objectives are allowed" % (expr,self._max_objectives),
                                         RuntimeError)
        expr = _remove_spaces(expr)
        if expr in self._objectives: 
            self._parent.raise_exception("Trying to add objective "
                                         "'%s' to driver, but it's already there" % expr,
                                         AttributeError)
        if name is not None and name in self._objectives:
            self._parent.raise_exception("Trying to add objective "
                                         "'%s' to driver using name '%s', but name is already used" % (expr,name),
                                         AttributeError)
            
        scope = self._get_scope(scope)
        expreval = Objective(expr, scope, getter='get_attr')
        if not expreval.check_resolve():
            self._parent.raise_exception("Can't add objective because I can't evaluate '%s'." % expr, 
                                         ValueError)

        name = expr if name is None else name

        expreval.activate()
      
        self._objectives[name] = expreval
            
        self._parent.config_changed()
    def activate(self, driver):
        """Make this constraint active by creating the appropriate
        connections in the dependency graph.
        """
        if self.pcomp_name is None:
            if self.comparator == '=':
                subtype = 'equality'
            else:
                subtype = 'inequality'

            # check for simple structure of equality constraint,
            # either
            #     var1 = var2
            #  OR
            #     var1 - var2 = 0
            #  OR
            #     var1 = 0
            lrefs = list(self.lhs.ordered_refs())
            rrefs = list(self.rhs.ordered_refs())

            try:
                leftval = float(self.lhs.text)
            except ValueError:
                leftval = None

            try:
                rightval = float(self.rhs.text)
            except ValueError:
                rightval = None

            pseudo_class = PseudoComponent

            if self.comparator == '=':
                # look for var1-var2=0
                if len(lrefs) == 2 and len(rrefs) == 0:
                    if rightval == 0. and \
                            _remove_spaces(self.lhs.text) == \
                                lrefs[0]+'-'+lrefs[1]:
                        pseudo_class = SimpleEQConPComp
                # look for 0=var1-var2
                elif len(lrefs) == 0 and len(rrefs) == 2:
                    if leftval==0. and \
                           _remove_spaces(self.rhs.text) == \
                                rrefs[0]+'-'+rrefs[1]:
                        pseudo_class = SimpleEQConPComp
                # look for var1=var2
                elif len(lrefs) == 1 and len(rrefs) == 1:
                    if lrefs[0] == self.lhs.text and \
                               rrefs[0] == self.rhs.text:
                        pseudo_class = SimpleEQConPComp
                # look for var1=0
                elif len(lrefs) == 1 and len(
                        rrefs) == 0 and rightval is not None:
                    pseudo_class = SimpleEQ0PComp

            pseudo = pseudo_class(self.lhs.scope,
                                  self._combined_expr(),
                                  pseudo_type='constraint',
                                  subtype=subtype,
                                  exprobject=self)

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