User Constraints
User constraints allow the user to define arbitrary linear constraints involving most of the problem variables. This section describes this function and how to use it.
Key User Constraint Concepts
- The basic principle: The basic steps involved in forming a user constraint are:
- Creating a user constraint object: One creates a new user_constraint object which will be used as a unique handle for the specific constraint and on which constraint-level parameters will be defined.
- Specify which variables are involved in the constraint: this generally involves creating a relationship involving the user_constraint object. For example, specifying the relationship unit_flow__user_constraint specifies that the corresponding unit_flow variable is involved in the constraint. The table below contains a complete list of variables and the corresponding relationships to set.
- Specify the variable coefficients: this will generally involve specifying a parameter named
coefficient_for_*on the relationship defined above to specify the coefficient on that particular variable in the constraint. For example, to define the coefficient on the unit_flow variable, one specifies the coefficient_for_unit_flow parameter on the appropriate unit_flow__user_constraint relationship. The table below contains a complete list of variables and the corresponding coefficient parameters to set. - Specify the right-hand-side constant term: The constraint should be formed in conventional form with all constant terms moved to the right-hand side. The right-hand-side constant term is specified by setting the right_hand_side user_constraint parameter.
- Specify the constraint sense: this is done by setting the constraint_sense user_constraint parameter. The allowed values are
==,>=and<=. - Coefficients can be defined on some parameters themselves. For example, one may specify a coefficient on a node's demand parameter. This is done by specifying the relationship node__user_constraint and specifying the coefficient_for_demand parameter on that relationship
- Specify the constraint sense: this is done by setting the constraint_sense user_constraint parameter. The allowed values are
- Temporal resolution: A user_constraint will employ the coarsest resolution of the variables attributed to it via the
coefficient_for_*parameters.
- Note that a user_constraint won't be generated unless at least one
coefficient_for_*parameter is defined! (Even if the value is set to zero!) - Thus, the resolution of a user_constraint can be tweaked by including variables with the desired resolution using a zero coefficient. (Not very clean, but works?)
- Piecewise unit_flow coefficients: As described in operating_points, specifying this parameter decomposes the unit_flow variable into a number of sub operating segment variables named unit_flow_op in the model and with an additional index,
ifor the operating segment. The intention of this functionality is to allow unit_flow coefficients to be defined individually per segment to define a piecewise linear function. To accomplish this, the steps are as described above with the exception that one must define operating_points on the appropriate node__to_unit or unit__to_node as an array type with the dimension corresponding to the number of operating points and then set the coefficient_for_unit_flow for the appropriate unit_flow__user_constraint relationship, also as an array type with the same number of elements. Note that if operating points is defined as an array type with more than one element, coefficient_for_unit_flow may be defined as either an array or non-array type. However, if operating_points is of non-array type, corresponding coefficient_for_unit_flows must also be of non-array types. - Variables, relationships and coefficient guide for user constraints The table below provides guidance regarding what relationships and coefficients to set for various problem variables and parameters.