Skip to content
Snippets Groups Projects
test_esipp_problem.py 281 KiB
Newer Older
  • Learn to ignore specific revisions
  •     #     assert ipp.results["Problem"][0]["Number of nonzeros"] == 49
    
        #     # *********************************************************************
        #     # *********************************************************************
    
        #     # validation
            
        #     # if uC,M 1,q,0 = 0, then xC,N 1,q,1 = 17.1     # infeasible
        #     # if uC,M 1,q,0 = 1, then xC,N 1,q,1 = 20.1.    # only feasible option
        #     # if uC,M 1,q,1 = 0, then xC,N 1,q,2 = 19.095   # only feasible option
        #     # if uC,M 1,q,1 = 1, then xC,N 1,q,2 = 22.095   # infeasible
        #     # if uC,M 1,q,2 = 0, then xC,N 1,q,3 = 18.14025 # feasible
        #     # if uC,M 1,q,2 = 1, then xC,N 1,q,3 = 21.14025 # feasible
            
        #     true_u_imqk = {
        #         ('mycvt', 0, q, 0): 1,
        #         ('mycvt', 0, q, 1): 0,
        #         ('mycvt', 0, q, 2): 0, # could also be 1
        #         }
            
        #     true_x_inqk = {
        #         ('mycvt', 0, q, 0): 20.1,
        #         ('mycvt', 0, q, 1): 19.095,
        #         ('mycvt', 0, q, 2): 18.14025, # could also be 21.14025
        #         }
            
        #     # check the inputs
        #     for imqk, u in true_u_imqk.items():
        #         assert math.isclose(
        #             pyo.value(ipp.instance.var_u_imqk[imqk]),
        #             u,
        #             abs_tol=1e-6,
        #         ) 
            
        #     # check the states
        #     for inqk, x in true_x_inqk.items():
        #         assert math.isclose(
        #             pyo.value(ipp.instance.var_x_inqk[inqk]),
        #             x,
        #             abs_tol=1e-6,
        #         )
        
        
            
        # *************************************************************************
        # *************************************************************************
        
        # TODO: test non-simplifiable problems with time varying prices on select assessments
        # TODO: test non-simplifiable problems with volume varying prices on select assessments
    
        
            
        # *************************************************************************
        # *************************************************************************
        
        def test_problem_with_tree_network(self):
            
            # assessment
            q = 0
            tf = EconomicTimeFrame(
                discount_rate=3.5/100,
                reporting_periods={q: (0,)},
                reporting_period_durations={q: (365 * 24 * 3600,)},
                time_intervals={q: (0,)},
                time_interval_durations={q: (1,)},
            )
    
            # 2 nodes: one import, one regular
            mynet = Network()
    
            # import node
            node_IMP = "thatimpnode"
            mynet.add_import_node(
                node_key=node_IMP,
                prices={
                    qpk: ResourcePrice(prices=1.0, volumes=None)
                    for qpk in tf.qpk()
                },
            )
    
            # node A
            node_A = "thatnodea"
            mynet.add_source_sink_node(
                node_key=node_A,
                base_flow={(q, 0): 0.50},
            )
            # node B
            node_B = "thatnodeb"
            mynet.add_source_sink_node(
                node_key=node_B,
                base_flow={(q, 0): 0.25},
            )
            # node C
            node_C = "thatnodec"
            mynet.add_source_sink_node(
                node_key=node_C,
                base_flow={(q, 0): 1.25},
            )
            
            list_imp_arcs = [
                (node_IMP, node_A), # IA
                (node_IMP, node_B), # IB
                (node_IMP, node_C), # IC
                ]
            for i, node_pair in enumerate(list_imp_arcs):
            
                # import arcs: IA, IB, IC
                new_arc = Arcs(
                    name="IA",
                    efficiency=None,
                    efficiency_reverse=None,
                    static_loss=None,
                    capacity=[2],
                    minimum_cost=[6],
                    specific_capacity_cost=i,
                    capacity_is_instantaneous=False,
                    validate=False,
                )
                mynet.add_directed_arc(*node_pair, arcs=new_arc)        
            
            # arcs: AB, BA, BC, CB, AC, CA
            
            list_other_arcs = [
                (node_A, node_B), # AB
                (node_B, node_A), # BA
                (node_B, node_C), # BC
                (node_C, node_B), # CB
                (node_A, node_C), # AC
                (node_C, node_A), # CA
                ]
            
            for node_pair in list_other_arcs:
                # arc
                new_arc_tech = Arcs(
                    name="any",
                    efficiency=None,
                    efficiency_reverse=None,
                    static_loss=None,
                    capacity=[3],
                    minimum_cost=[2],
                    specific_capacity_cost=0,
                    capacity_is_instantaneous=False,
                    validate=False,
                )
                mynet.add_directed_arc(*node_pair, arcs=new_arc_tech)
    
            # identify node types
            mynet.identify_node_types()
    
            # no sos, regular time intervals
            ipp = self.build_solve_ipp(
                solver_options={},
                perform_analysis=False,
                plot_results=False,  # True,
    
                print_solver_output=False,
    
                time_frame=tf,
                networks={"mynet": mynet},
                static_losses_mode=True,  # just to reach a line,
                mandatory_arcs=[],
                max_number_parallel_arcs={},
                simplify_problem=True,
            )
    
            assert ipp.has_peak_total_assessments()
            assert ipp.results["Problem"][0]["Number of constraints"] == 61 
            assert ipp.results["Problem"][0]["Number of variables"] == 53 
            assert ipp.results["Problem"][0]["Number of nonzeros"] == 143
            
            # *********************************************************************
            # *********************************************************************
    
            # validation
    
            # only the IA arc should be installed
            true_imp_arcs_selected = [True, False, False]
            for node_pair, true_arc_decision in zip(list_imp_arcs, true_imp_arcs_selected):
                assert (
                    true_arc_decision
                    in ipp.networks["mynet"]
                    .edges[(*node_pair, 0)][Network.KEY_ARC_TECH]
                    .options_selected
                )
            # only two arcs between A, B and C can be installed
            arcs_selected = tuple(
                1
                for node_pair in list_other_arcs
                if True in ipp.networks["mynet"]
                .edges[(*node_pair, 0)][Network.KEY_ARC_TECH]
                .options_selected
                )
            assert sum(arcs_selected) == 2
            # the network must be tree-shaped
            assert ipp.networks["mynet"].has_tree_topology()
            # capex
            assert math.isclose(pyo.value(ipp.instance.var_capex), 10.0, abs_tol=1e-3)
            # the objective function
            assert math.isclose(pyo.value(ipp.instance.obj_f), -1.193236715e+01, abs_tol=1e-3)
    
            
            
        # *************************************************************************
        # *************************************************************************
        
        def test_problem_with_reverse_tree_network(self):
            
            # assessment
            q = 0
            tf = EconomicTimeFrame(
                discount_rate=3.5/100,
                reporting_periods={q: (0,)},
                reporting_period_durations={q: (365 * 24 * 3600,)},
                time_intervals={q: (0,)},
                time_interval_durations={q: (1,)},
            )
    
            # 2 nodes: one import, one regular
            mynet = Network()
    
            # export node
            node_EXP = "thatexpnode"
            mynet.add_export_node(
                node_key=node_EXP,
                prices={
                    qpk: ResourcePrice(prices=1.0, volumes=None)
                    for qpk in tf.qpk()
                },
            )
    
            # node A
            node_A = "thatnodea"
            mynet.add_source_sink_node(
                node_key=node_A,
                base_flow={(q, 0): -0.50},
            )
            # node B
            node_B = "thatnodeb"
            mynet.add_source_sink_node(
                node_key=node_B,
                base_flow={(q, 0): -0.25},
            )
            # node C
            node_C = "thatnodec"
            mynet.add_source_sink_node(
                node_key=node_C,
                base_flow={(q, 0): -1.25},
            )
            
            list_imp_arcs = [
                (node_A, node_EXP), # AE
                (node_B, node_EXP), # BE
                (node_C, node_EXP), # CE
                ]
            for i, node_pair in enumerate(list_imp_arcs):
            
                # import arcs: AE, BE, CE
                new_arc = Arcs(
                    name="arc_"+str(node_pair),
                    efficiency=None,
                    efficiency_reverse=None,
                    static_loss=None,
                    capacity=[2],
                    minimum_cost=[6],
                    specific_capacity_cost=i,
                    capacity_is_instantaneous=False,
                    validate=False,
                )
                mynet.add_directed_arc(*node_pair, arcs=new_arc)        
            
            # arcs: AB, BA, BC, CB, AC, CA
            
            list_other_arcs = [
                (node_A, node_B), # AB
                (node_B, node_A), # BA
                (node_B, node_C), # BC
                (node_C, node_B), # CB
                (node_A, node_C), # AC
                (node_C, node_A), # CA
                ]
            
            for node_pair in list_other_arcs:
                # arc
                new_arc_tech = Arcs(
                    name="any",
                    efficiency=None,
                    efficiency_reverse=None,
                    static_loss=None,
                    capacity=[3],
                    minimum_cost=[2],
                    specific_capacity_cost=0,
                    capacity_is_instantaneous=False,
                    validate=False,
                )
                mynet.add_directed_arc(*node_pair, arcs=new_arc_tech)
    
            # identify node types
            mynet.identify_node_types()
    
            # no sos, regular time intervals
            ipp = self.build_solve_ipp(
                solver_options={},
                perform_analysis=False,
                plot_results=False,  # True,
                print_solver_output=False,
                time_frame=tf,
                networks={"mynet": mynet},
                static_losses_mode=True,  # just to reach a line,
                mandatory_arcs=[],
                max_number_parallel_arcs={},
                simplify_problem=True,
            )
    
            assert ipp.has_peak_total_assessments()
            assert ipp.results["Problem"][0]["Number of constraints"] == 61 
            assert ipp.results["Problem"][0]["Number of variables"] == 53 
            assert ipp.results["Problem"][0]["Number of nonzeros"] == 143
            
            # *********************************************************************
            # *********************************************************************
    
            # validation
    
            # only the IA arc should be installed
            true_imp_arcs_selected = [True, False, False]
            for node_pair, true_arc_decision in zip(list_imp_arcs, true_imp_arcs_selected):
                assert (
                    true_arc_decision
                    in ipp.networks["mynet"]
                    .edges[(*node_pair, 0)][Network.KEY_ARC_TECH]
                    .options_selected
                )
            # only two arcs between A, B and C can be installed
            arcs_selected = tuple(
                1
                for node_pair in list_other_arcs
                if True in ipp.networks["mynet"]
                .edges[(*node_pair, 0)][Network.KEY_ARC_TECH]
                .options_selected
                )
            assert sum(arcs_selected) == 2
            # the network must be tree-shaped
            assert ipp.networks["mynet"].has_tree_topology()
            # capex
            assert math.isclose(pyo.value(ipp.instance.var_capex), 10.0, abs_tol=1e-3)
            # the objective function
            assert math.isclose(pyo.value(ipp.instance.obj_f), -(10+(-11.93236715+10)), abs_tol=1e-3)
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
    # *****************************************************************************
    
    # *****************************************************************************