@@ -0,0 +1,1758 @@
+%22%22%22Add an UnservedLoad component, which ensures the model is always feasible.%0AThis is often useful when the model is constrained to the edge of infeasibility,%0A(e.g., when evaluating a pre-defined, just-feasible construction plan) to avoid%0Aspurious reports of infeasibility.%22%22%22%0Afrom pyomo.environ import *%0A%0Adef define_arguments(argparser):%0A    argparser.add_argument(%22--unserved-load-penalty%22, type=float, default=None,%0A        help=%22Penalty to charge per MWh of unserved load. Usually set high enough to force unserved load to zero (default is $10,000/MWh).%22)%0A%0Adef define_components(m):%0A    # create an unserved load variable with a high penalty cost, %0A    # to avoid infeasibilities when %0A    # evaluating scenarios that are on the edge of infeasibility%0A    # cost per MWh for unserved load (high)%0A    if m.options.unserved_load_penalty is not None:%0A        # always use penalty factor supplied on the command line, if any%0A        m.unserved_load_penalty_per_mwh = Param(initialize=m.options.unserved_load_penalty)%0A    else:%0A        # no penalty on the command line, use whatever is in the parameter files, or 10000%0A        m.unserved_load_penalty_per_mwh = Param(default=10000)%0A%0A    # amount of unserved load during each timepoint%0A    m.UnservedLoad = Var(m.LOAD_ZONES, m.TIMEPOINTS, within=NonNegativeReals)%0A    # total cost for unserved load%0A    m.UnservedLoadPenalty = Expression(m.TIMEPOINTS, rule=lambda m, tp:%0A        sum(m.UnservedLoad%5Blz, tp%5D * m.unserved_load_penalty_per_mwh for lz in m.LOAD_ZONES)%0A    )%0A    # add the unserved load to the model's energy balance%0A    m.LZ_Energy_Components_Produce.append('UnservedLoad')%0A    # add the unserved load penalty to the model's objective function%0A    m.cost_components_tp.append('UnservedLoadPenalty')%0A

Define UservedLoad variable and penalty factor to relax infeasibility when needed.