def __init__(self, vertexIds): self.vertices = dict((name, Vertex(self, name)) for name in vertexIds) # 'd1': Vertex('d1'), self.edges = dict()
def init_objects(self): # Add meter meter = MeterPoint() meter.measurementType = MeasurementType.PowerReal meter.name = 'CoRElectricMeter' meter.measurementUnit = MeasurementUnit.kWh self.meterPoints.append(meter) # Add weather forecast service weather_service = TemperatureForecastModel(self.config_path) self.informationServiceModels.append(weather_service) # Add inelastive asset # Source: https://www.ci.richland.wa.us/home/showdocument?id=1890 # Residential customers: 23,768 # Electricity sales in 2015: # Total: 100.0# 879,700,000 kWh 100,400 avg. kW) # Resident: 46.7 327,200,000 37,360 # Gen. Serv.: 38.1 392,300,000 44,790 # Industrial: 15.2 133,700,000 15,260 # Irrigation: 2.4 21,110,000 2,410 # Other: 0.6 5,278,000 603 # 2015 Res. rate: $0.0616/kWh # Avg. annual residential cust. use: 14,054 kWh # Winter peak, 160,100 kW (1.6 x average) # Summer peak, 180,400 kW (1.8 x average) # Annual power supply expenses: $35.5M # ************************************************************************* inelastive_load = LocalAsset() inelastive_load.name = 'InelasticLoad' inelastive_load.maximumPower = -50000 # Remember that a load is a negative power [kW] inelastive_load.minimumPower = -200000 # Assume twice the averag PNNL load [kW] # Add inelastive asset model inelastive_load_model = OpenLoopRichlandLoadPredictor(weather_service) inelastive_load_model.name = 'InelasticLoadModel' inelastive_load_model.defaultPower = -100420 # [kW] inelastive_load_model.defaultVertices = [ Vertex(float("inf"), 0.0, -100420.0) ] # Cross-reference asset & asset model inelastive_load_model.object = inelastive_load inelastive_load.model = inelastive_load_model # Add inelastic as city's asset self.localAssets.extend([inelastive_load]) # Add Market market = Market() market.name = 'dayAhead' market.commitment = False market.converged = False market.defaultPrice = 0.0428 # [$/kWh] market.dualityGapThreshold = self.duality_gap_threshold # [0.02 = 2#] market.initialMarketState = MarketState.Inactive market.marketOrder = 1 # This is first and only market market.intervalsToClear = 1 # Only one interval at a time market.futureHorizon = timedelta( hours=24) # Projects 24 hourly future intervals market.intervalDuration = timedelta( hours=1) # [h] Intervals are 1 h long market.marketClearingInterval = timedelta(hours=1) # [h] market.marketClearingTime = Timer.get_cur_time().replace( hour=0, minute=0, second=0, microsecond=0) # Aligns with top of hour market.nextMarketClearingTime = market.marketClearingTime + timedelta( hours=1) self.markets.append(market) self.campus = self.make_campus() supplier = self.make_supplier() # Add campus as city's neighbor self.neighbors.extend([self.campus, supplier])
# directed_railway.add_edge(harwick_station, peel_station) # directed_railway.add_edge(peel_station, callan_station) # path_exists = directed_railway.find_path('harwick', 'harwick') # print(path_exists) # print("\n\n\nFinding path from harwick to callan\n") # new_path_exists = directed_railway.find_path('harwick', 'callan') # print(new_path_exists) # print("\n\nTrying to find path from harwick to ulfstead\n") # no_path_exists = directed_railway.find_path('harwick', 'ulfstead') # print(no_path_exists) # ------- Test refractor find_path ------------ railway = Graph() callan = Vertex('callan') peel = Vertex('peel') ulfstead = Vertex('ulfstead') harwick = Vertex('harwick') railway.add_vertex(callan) railway.add_vertex(peel) railway.add_vertex(harwick) railway.add_vertex(ulfstead) railway.add_edge(peel, harwick) railway.add_edge(harwick, callan) railway.add_edge(callan, peel) peel_to_ulfstead_path_exists = railway.find_path('peel', 'ulfstead') harwick_to_peel_path_exists = railway.find_path('harwick', 'peel')
def test_creat_vertex(self): my_vertex = Vertex(1., 2., -2.6) assert my_vertex.tolerance == 1e-06 assert my_vertex.x == 1. assert my_vertex.y == 2. assert my_vertex.z == -2.6
def build_graph(): graph = Graph() # MAKE LOCATIONS INTO VERTICES BELOW... rogue_encampment = Vertex("Rogue Encampment") blood_moor = Vertex("Blood Moor") den_of_evil = Vertex("Den Of Evil") cold_plains = Vertex("Cold Plains") cave_1 = Vertex("Cave Level 1") cave_2 = Vertex("Cave Level 2") burial_grounds = Vertex("Burial Grounds") crypt = Vertex("Crypt") mausoleum = Vertex("Mausoleum") stony_field = Vertex("Stony Field") tristram = Vertex("Tristram") underground_passage_1 = Vertex("Underground Passage Level 1") underground_passage_2 = Vertex("Underground Passage Level 2") dark_wood = Vertex("Dark Wood") black_marsh = Vertex("Black Marsh") tower_1 = Vertex("Forgotten Tower Level 1") tower_2 = Vertex("Forgotten Tower Level 2") tower_3 = Vertex("Forgotten Tower Level 3") tower_4 = Vertex("Forgotten Tower Level 4") tower_5 = Vertex("Forgotten Tower Level 5") tamoe_highland = Vertex("Tamoe Highland") monastary_gate = Vertex("Monastary Gate") outer_cloister = Vertex("Outer Cloister") barracks = Vertex("Barracks") jail_1 = Vertex("Jail Level 1") jail_2 = Vertex("Jail Level 2") jail_3 = Vertex("Jail Level 3") inner_cloister = Vertex("Inner Cloister") cathedral = Vertex("Cathedral") catacombs_1 = Vertex("Catacombs Level 1") catacombs_2 = Vertex("Catacombs Level 2") catacombs_3 = Vertex("Catacombs Level 3") catacombs_4 = Vertex("Catacombs Level 4") # ADD ROOMS TO GRAPH BELOW... graph.add_vertex(rogue_encampment) graph.add_vertex(blood_moor) graph.add_vertex(den_of_evil) graph.add_vertex(cold_plains) graph.add_vertex(cave_1) graph.add_vertex(cave_2) graph.add_vertex(burial_grounds) graph.add_vertex(crypt) graph.add_vertex(mausoleum) graph.add_vertex(stony_field) graph.add_vertex(tristram) graph.add_vertex(underground_passage_1) graph.add_vertex(underground_passage_2) graph.add_vertex(dark_wood) graph.add_vertex(black_marsh) graph.add_vertex(tower_1) graph.add_vertex(tower_2) graph.add_vertex(tower_3) graph.add_vertex(tower_4) graph.add_vertex(tower_5) graph.add_vertex(tamoe_highland) graph.add_vertex(monastary_gate) graph.add_vertex(outer_cloister) graph.add_vertex(barracks) graph.add_vertex(jail_1) graph.add_vertex(jail_2) graph.add_vertex(jail_3) graph.add_vertex(inner_cloister) graph.add_vertex(cathedral) graph.add_vertex(catacombs_1) graph.add_vertex(catacombs_2) graph.add_vertex(catacombs_3) graph.add_vertex(catacombs_4) # ADD EDGES BETWEEN ROOMS BELOW... graph.add_edge(rogue_encampment, blood_moor) graph.add_edge(blood_moor, den_of_evil) graph.add_edge(blood_moor, cold_plains) graph.add_edge(cold_plains, cave_1) graph.add_edge(cave_1, cave_2) graph.add_edge(cold_plains, burial_grounds) graph.add_edge(burial_grounds, crypt) graph.add_edge(burial_grounds, mausoleum) graph.add_edge(cold_plains, stony_field) graph.add_edge(stony_field, tristram) graph.add_edge(stony_field, underground_passage_1) graph.add_edge(underground_passage_1, underground_passage_2) graph.add_edge(underground_passage_1, dark_wood) graph.add_edge(dark_wood, black_marsh) graph.add_edge(black_marsh, tower_1) graph.add_edge(tower_1, tower_2) graph.add_edge(tower_2, tower_3) graph.add_edge(tower_3, tower_4) graph.add_edge(tower_4, tower_5) graph.add_edge(black_marsh, tamoe_highland) graph.add_edge(tamoe_highland, monastary_gate) graph.add_edge(monastary_gate, outer_cloister) graph.add_edge(outer_cloister, barracks) graph.add_edge(barracks, jail_1) graph.add_edge(jail_1, jail_2) graph.add_edge(jail_2, jail_3) graph.add_edge(jail_3, inner_cloister) graph.add_edge(inner_cloister, cathedral) graph.add_edge(cathedral, catacombs_1) graph.add_edge(catacombs_1, catacombs_2) graph.add_edge(catacombs_2, catacombs_3) graph.add_edge(catacombs_3, catacombs_4) # DON'T CHANGE THIS CODE #graph.print_map() return graph
def parse_chem(filename): # Properties of the graph. Characterized in the first block of a graph-file n_of_nodes = 0 n_of_edges = 0 nodes_label = True edges_label = True directed_graph = False #Booleans to check in which part of the Chem-Graph we are into_vertices = False into_vertex_labels = False into_edges_one = False into_edges_two = False into_edges_label = False #Lists to save all vertices, edges and teh respective labels to then create the graph-object from vertices_all = [] vertex_labels_all = [] edges_one_all = [] edges_two_all = [] edges_labels_all = [] # Vertex list is characterized in the 2nd block of a graph-file vertex_list = [] # Edge list is characterized in the 3rd block of a graph-file edge_list = [] # dict for accessing the vertices via their names vertex_dict = {} with open(filename, 'r') as file: file_content = file.readlines() for i in range(0, len(file_content)): temp: str = file_content[i].replace('\n', '') temp = temp.replace(' ', '') #finish reading the file after the important first few blocks if temp == '"coords":[': break if temp == '"aid":[': into_vertices = True elif temp == '"element":[': into_vertex_labels = True elif temp == '"aid1":[': into_edges_one = True elif temp == '"aid2":[': into_edges_two = True elif temp == '"order":[': into_edges_label = True elif temp == '],' and into_edges_one: into_edges_one = False elif temp == '],' and into_edges_two: into_edges_two = False elif temp == ']' and into_edges_label: into_edges_label = False elif into_vertices and temp == '],': into_vertices = False elif into_vertex_labels and temp == ']': into_vertex_labels = False elif into_vertices: temp2 = temp.split(',') vertices_all.append(temp2[0]) elif into_vertex_labels: temp2 = temp.split(',') vertex_labels_all.append(temp2[0]) elif into_edges_one: temp2 = temp.split(',') edges_one_all.append(temp2[0]) elif into_edges_two: temp2 = temp.split(',') edges_two_all.append(temp2[0]) elif into_edges_label: temp2 = temp.split(',') edges_labels_all.append(temp2[0]) # creating graph-object after finishing reading the file for i in range(0, len(vertices_all)): v = Vertex(vertices_all[i]) e = element(int(vertex_labels_all[i])) v.set_node_label(e.symbol) vertex_list.append(v) vertex_dict.update({v.name: v}) for i in range(0, len(edges_one_all)): e = Edge(vertex_dict.get(edges_one_all[i]), vertex_dict.get(edges_two_all[i])) e.set_label(edges_labels_all[i]) edge_list.append(e) n_of_nodes = len(vertices_all) n_of_edges = len(edges_one_all) graph = Graph(vertex_list, edge_list, n_of_nodes, n_of_edges, nodes_label, edges_label, directed_graph) return graph
def add_vertex(self, label: str): self.__vertices__[label] = Vertex(label) self.__prev__[label] = None self.__adjacency_map__[label]: dict = {}
from algorithm import Algorithm from edge import Edge from vertex import Vertex node1 = Vertex("A") node2 = Vertex("B") node3 = Vertex("C") node4 = Vertex("D") node5 = Vertex("E") node6 = Vertex("F") node7 = Vertex("G") node8 = Vertex("H") node9 = Vertex("I") node10 = Vertex("J") node11 = Vertex("K") node12 = Vertex("L") node13 = Vertex("M") node14 = Vertex("N") node15 = Vertex("O") node16 = Vertex("P") node17 = Vertex("Q") node18 = Vertex("R") node19 = Vertex("S") node20 = Vertex("T") edge1 = Edge(10, node1, node2) edge2 = Edge(13, node1, node6) edge3 = Edge(10, node2, node1) edge4 = Edge(17, node2, node3) edge5 = Edge(7, node2, node7) edge6 = Edge(17, node3, node2)
from color import Color from vertex import Vertex print(Vertex.__doc__()) #______TRUE VERBOSE______________________ vtx0 = Vertex(0, 0, 0) print vtx0 red = Color(255, 256, 512) green = Color(256, 255, 0) blue = Color(0, 0, 511) unitx = Vertex(1, 0, 0, green) unity = Vertex(0, 1, 0, red) unitz = Vertex(0, 0, 1, blue) print unitx print unity print unitz #______FALSE VERBOSE_____________________ sqra = Vertex(0, 0, 0) sqrb = Vertex(4.2, 0, 0) sqrc = Vertex(4.2, 4.2, 0) sqrd = Vertex(0, 4.2, 0) print sqra print sqrb print sqrc print sqrd
def __init__(self, vs=[], normal=Vertex(0,0,0)): self.vs = vs self.normal = normal
def fill_nodes(self, UDGraph): UDGraph.add_node(Vertex(0, 0)) UDGraph.add_node(Vertex(1 / 3, 0)) UDGraph.add_node(Vertex(1, 0)) UDGraph.add_node(Vertex(2, 0)) UDGraph.add_node(Vertex((sqrt(33) - 3) / 6, 0)) UDGraph.add_node(Vertex(1 / 2, 1 / sqrt(12))) UDGraph.add_node(Vertex(1, 1 / sqrt(3))) UDGraph.add_node(Vertex(3 / 2, sqrt(3) / 2)) UDGraph.add_node(Vertex(7 / 6, sqrt(11) / 6)) UDGraph.add_node(Vertex(1 / 6, (sqrt(12) - sqrt(11)) / 6)) UDGraph.add_node(Vertex(5 / 6, (sqrt(12) - sqrt(11)) / 6)) UDGraph.add_node(Vertex(2 / 3, (sqrt(11) - sqrt(3)) / 6)) UDGraph.add_node(Vertex(2 / 3, (3 * sqrt(3) - sqrt(11)) / 6)) UDGraph.add_node(Vertex(sqrt(33) / 6, 1 / sqrt(12))) UDGraph.add_node(Vertex((sqrt(33) + 3) / 6, 1 / sqrt(3))) UDGraph.add_node( Vertex((sqrt(33) + 1) / 6, (3 * sqrt(3) - sqrt(11)) / 6)) UDGraph.add_node( Vertex((sqrt(33) - 1) / 6, (3 * sqrt(3) - sqrt(11)) / 6)) UDGraph.add_node(Vertex((sqrt(33) + 1) / 6, (sqrt(11) - sqrt(3)) / 6)) UDGraph.add_node(Vertex((sqrt(33) - 1) / 6, (sqrt(11) - sqrt(3)) / 6)) UDGraph.add_node( Vertex((sqrt(33) - 2) / 6, (2 * sqrt(3) - sqrt(11)) / 6)) UDGraph.add_node( Vertex((sqrt(33) - 4) / 6, (2 * sqrt(3) - sqrt(11)) / 6)) UDGraph.add_node( Vertex((sqrt(33) + 13) / 12, (sqrt(11) - sqrt(3)) / 12)) UDGraph.add_node( Vertex((sqrt(33) + 11) / 12, (sqrt(3) + sqrt(11)) / 12)) UDGraph.add_node(Vertex((sqrt(33) + 9) / 12, (sqrt(11) - sqrt(3)) / 4)) UDGraph.add_node( Vertex((sqrt(33) + 9) / 12, (3 * sqrt(3) + sqrt(11)) / 12)) UDGraph.add_node(Vertex((sqrt(33) + 7) / 12, (sqrt(3) + sqrt(11)) / 12)) UDGraph.add_node( Vertex((sqrt(33) + 7) / 12, (3 * sqrt(3) - sqrt(11)) / 12)) UDGraph.add_node( Vertex((sqrt(33) + 5) / 12, (5 * sqrt(3) - sqrt(11)) / 12)) UDGraph.add_node(Vertex((sqrt(33) + 5) / 12, (sqrt(11) - sqrt(3)) / 12)) UDGraph.add_node( Vertex((sqrt(33) + 3) / 12, (3 * sqrt(11) - 5 * sqrt(3)) / 12)) UDGraph.add_node(Vertex((sqrt(33) + 3) / 12, (sqrt(3) + sqrt(11)) / 12)) UDGraph.add_node( Vertex((sqrt(33) + 3) / 12, (3 * sqrt(3) - sqrt(11)) / 12)) UDGraph.add_node(Vertex((sqrt(33) + 1) / 12, (sqrt(11) - sqrt(3)) / 12)) UDGraph.add_node( Vertex((sqrt(33) - 1) / 12, (3 * sqrt(3) - sqrt(11)) / 12)) UDGraph.add_node(Vertex((sqrt(33) - 3) / 12, (sqrt(11) - sqrt(3)) / 12)) UDGraph.add_node(Vertex((15 - sqrt(33)) / 12, (sqrt(11) - sqrt(3)) / 4)) UDGraph.add_node( Vertex((15 - sqrt(33)) / 12, (7 * sqrt(3) - 3 * sqrt(11)) / 12)) UDGraph.add_node( Vertex((13 - sqrt(33)) / 12, (3 * sqrt(3) - sqrt(11)) / 12)) UDGraph.add_node( Vertex((11 - sqrt(33)) / 12, (sqrt(11) - sqrt(3)) / 12))
if v is None: break path.reverse() return path print('Initializing map...') map_file = open('testmap2.json') map_json = json.loads(map_file.read()) vertex_list = [] for v in map_json['vertices']: vertex_list.append( Vertex(v['id'], (v['coordinates']['x'], v['coordinates']['y']))) test_course = Graph(vertex_list) for v in map_json['vertices']: current_v = test_course.search(v['id']) if 'directed' in v: directed = True directed_index = v['directed']['index'] previous_vertex = test_course.search(v['directed']['previous']) else: directed = False directed_index = None previous_vertex = None current_v.directed = directed current_v.directed_index = directed_index
def update_vertices(self, mkt): # Creates active vertices for a non-transactive neighbor, including demand # charges. # # INPUTS: # mkt - Market object # # OUTPUTS: # - Updates self.activeVertices for active time intervals. # Gather active time intervals time_intervals = mkt.timeIntervals # TimeInterval objects # Get the maximum power maxp for this neighbor. maximum_power = self.object.maximumPower # [avg.kW] # The maximum power property is meaningful for both imported (p>0) and # exported (p<0) electricity, but this formulation is intended for # importation (power>0) from an electricity supplier. Warn the user and # return if the maximum power is negative. if maximum_power < 0: _log.warning('Maximum power must be positive in BulkSupplier_dc.m') _log.warning('Returning without creating active vertices for ' + self.name) return # Get the minimum power for this neighbor. minimum_power = self.object.minimumPower # [avg.kW] # Only importation is supported from this non-transactive neighbor. if minimum_power < 0: _log.warning( 'Minimum power must be positive in "BulkSupplier_dc.m') _log.warning('Returning without creating active vertices for ' + self.name) return # Cost coefficient a0. This is unavailable from a supply curve, so it # must be determined directly from the first, constant cost parameter. # It does NOT affect marginal pricing. a0 = self.costParameters[0] # [$/h] # Full-power loss at is defined by the loss factor property and the # maximum power. full_power_loss = maximum_power * self.object.lossFactor # [avg.kW] # Minimum-power loss at Vertex 1 is a fraction of the full-power loss. # (Power losses are modeled proportional to the square of power # transfer.) minimum_power_loss = (minimum_power / maximum_power)**2 * full_power_loss # [avg.kW] # Index through active time intervals for i in range(len(time_intervals)): # Find and delete active vertices in the indexed time interval. # These vertices shall be recreated. self.activeVertices = [ x for x in self.activeVertices if x != time_intervals[i] ] # Find the month number for the indexed time interval start time. # The month is needed for rate lookup tables. month_number = time_intervals[i].startTime.month if is_heavyloadhour(time_intervals[i].startTime): # The indexed time interval is an HLH hour. The electricity rate # is a little higher during HLH hours, and demand-charges may # apply. # Look up the BPA energy rate for month_number. The second # parameter is HLH = 1 (i.e., column 1 of the table). energy_rate = bpa_energy_rate[month_number - 1][0] # HLH energy rate [$/kWh] # Four active vertices are initialized: # #1 at minimum power # #2 at the demand-charge power threshold # #3 at the new demand rate and power threshold # #4 at maximum power and demand rate vertices = [ Vertex(0, 0, 0), Vertex(0, 0, 0), Vertex(0, 0, 0), Vertex(0, 0, 0) ] # Evaluate the first of the four vertices # Segment 1: First-order parameter a1. # This could be stated directly from cost parameters, but this # model allows for dynamic rates, accounts for losses, and models # demand-charges, which would require defining multiple # cost-parameter models. The first-order parameter is the # electricity rate. In this model, the rate is meaningful at a # neighbor node location at zero power transfer. a1 = energy_rate # [$/kWh] # Vertex 1: Full available power transfer at Vertex 1 is thus the # physical transfer limit, minus losses. vertices[0].power = (minimum_power - minimum_power_loss) # Vertex 1: Marginal price of Vertex 1 is augmented by the value # of energy from the neighbor that is lost. (This model assigns # the cost of losses to the recipient (importer) of electricity.) vertices[0].marginalPrice = a1 * ( 1 + self.object.lossFactor * minimum_power / maximum_power ) # [$/kWh] # Evalauate the second of four vertices # Vertex 2: Available power at Vertex 2 is determined by the # current peak demand charge threshold pdt and possibly scheduled # powers prior to the indexed time interval. The demand threshold # in the indexed time interval is at least equal to the # parameter. NOTE this process will work only if the demand # threshold is is updated based on actual, accurate measurements. peak_demand_threshold = self.demandThreshold # [kW] # Also consider, however, scheduled powers prior to the indexed # interval that might have already set a new demand threshold. # For simplicity, presume that new demand thresholds would occur # only during HLH hour types. More complex code will be needed # if only HLH hours must be considered. NOTE this process will # work only if the load forcasts are meaningful and accurate. # Gather scheduled powers sp scheduled_powers = self.scheduledPowers if len(scheduled_powers) == 0: # Powers have been scheduled, order the scheduled powers by # their start time ordered_scheduled_powers = sorted( self.scheduledPowers, key=lambda x: x.timeInterval.startTime) ordered_scheduled_powers = ordered_scheduled_powers[:i + 1] # The peak demand determinant is the greater of the monthly # peak threshold or the prior scheduled powers. ordered_scheduled_powers = [ x.value for x in ordered_scheduled_powers ] ordered_scheduled_powers.append(peak_demand_threshold) peak_demand_threshold = max(ordered_scheduled_powers) # kW # Vertex 2: The power at which demand charges will begin accruing # and therefore marks the start of Vertex 2. It is not affected # by losses because it is based on local metering. vertices[1].power = peak_demand_threshold # [avg.kW] # Vertex 2: Marginal price of Vertex 2 is augmented by the value # of energy from the neighbor that is lost. vertices[1].marginalPrice = a1 * ( 1 + self.object.lossFactor * vertices[1].power / maximum_power) # [$/kWh] # Evaluate the third of four vertices # Look up the demand rate dr for the month_number. The second # parameter is HLH = 1 (i.e., the first column of the table). demand_rate = bpa_demand_rate[month_number - 1][ 0] # bpa_demand_rate(month_number, 1) # [$/kW (per kWh)] # Vertex 3: The power of Vertex 3 is the same as that of Vertex 2 vertices[2].power = peak_demand_threshold # [avg.kW] # Vertex 3: The marginal price at Vertex 3 is shifted strongly by # the demand response rate. The logic here is that cost is # determined by rate * (power-threshold). Therefore, the # effective marginal rate is augmented by the demand rate itself. # NOTE: Some hand-waving is always needed to compare demand and # energy rates. This approach assigns a meaningful production # cost, but it is not correct to say it describes an energy # price. The cost is assigned to the entire hour. Shorter time # intervals should not be further incremented. Evenso, a huge # discontinuity appears in the marginal price. vertices[2].marginalPrice = vertices[ 2].marginalPrice + demand_rate # [$/kWh] # Evaluate the fourth of four vertices # Vertex 4: The power at Vertex 4 is the maximum power, minus losses vertices[3].power = maximum_power - full_power_loss # [avg.kW] # The marginal price at Vertex 4 is affected by both losses and # demand charges. # Marginal price at Vertex 3 from loss component vertices[3].marginalPrice = a1 * (1 + self.object.lossFactor ) # [$/kWh] # Augment marginal price at Vertex 4 with demand-charge impact vertices[3].marginalPrice = vertices[ 3].marginalPrice + demand_rate # [$/kW (per hour)] # Assign production costs for the four vertices # Segment 1: The second-order cost coefficient a2 on the first # line segment is determined from the change in marginal price # divided by change in power. a2 = (vertices[1].marginalPrice - vertices[0].marginalPrice ) # [$/kWh] a2 = a2 / (vertices[1].power - vertices[0].power) # [$/kW^2h] # Vertex 1: The cost at Vertex 1 can be inferred by integrating # from p=0 to Vertex 1. vertices[0].cost = a0 + a1 * vertices[0].power + 0.5 * a2 * ( vertices[0].power)**2 # production cost [$/h] # Vertex 2: The cost at Vertex 2 is on the same trajectory vertices[1].cost = a0 + a1 * vertices[1].power + 0.5 * a2 * ( vertices[1].power)**2 # production cost [$/h] # Vertex 3: Both the power and production cost should be the same # at Vertex 3 as for Vertex 2. vertices[2].cost = vertices[1].cost # production cost [$/h] # Vertex 4: The cost on the third line segment has a new # trajectory that begins with the cost at Vertex 3 (an # integration constant). vertices[3].cost = vertices[ 2].cost # partial production cost [#/h] # Segment 3: The new first-order term for the third line segment # is the marginal price at Vertex 3. This applies only to power # imports that exceed Vertex 3. a1 = vertices[ 2].marginalPrice # first-order coefficient [$/kWh] # Vertex 4: Add the first-order term to the Vertex-4 cost vertices[3].cost = vertices[3].cost + a1 * ( vertices[3].power - vertices[2].power ) # partial production cost [$/h] # Segment 3: NOTE: The second-order coeffiecient a2 on the second # line segment is unchanged from the first segment # Vertex 4: Add the second-order term to the Vertex-4 cost. vertices[3].cost = vertices[3].cost + 0.5 * a2 * ( vertices[3].power - vertices[2].power)**2 # production cost [$/h] # Convert the costs to raw dollars # NOTE: This usage of Matlab hours() toggles a duration back # into a numerical representation, which is correct here. interval_duration = get_duration_in_hour( time_intervals[i].duration) vertices[0].cost = vertices[0].cost * interval_duration # [$] vertices[1].cost = vertices[1].cost * interval_duration # [$] vertices[2].cost = vertices[2].cost * interval_duration # [$] vertices[3].cost = vertices[3].cost * interval_duration # [$] # Create interval values for the active vertices interval_values = [ IntervalValue(self, time_intervals[i], mkt, MeasurementType.ActiveVertex, vertices[0]), IntervalValue(self, time_intervals[i], mkt, MeasurementType.ActiveVertex, vertices[1]), IntervalValue(self, time_intervals[i], mkt, MeasurementType.ActiveVertex, vertices[2]), IntervalValue(self, time_intervals[i], mkt, MeasurementType.ActiveVertex, vertices[3]) ] # Append the active vertices to the list of active vertices # in the indexed time interval self.activeVertices.extend(interval_values) else: # indexed time interval is a LLH hour # LLH hours # The indexed time interval is a LLH hour. The electricity rate # is a little lower, and demand charges are not applicable. # # Look up the BPA energy rate for month m. The second parameter # is LLH = 2 (i.e., column 2 of the table). energy_rate = bpa_energy_rate[month_number - 1][ 1] # bpa_energy_rate(month_number, 2) # Two active vertices are created # #1 at minimum power # #2 at maximum power vertices = [Vertex(0, 0, 0), Vertex(0, 0, 0)] # Evaluate the first of two vertices # First-order parameter a1. a1 = energy_rate # [$/kWh] # Vertex 1: Full available power transfer at Vertex 1 is thus the # physical transfer limit, minus losses. vertices[0].power = (minimum_power - minimum_power_loss ) # [avg.kW] # Vertex 1: Marginal price of Vertex 1 is augmented by the value # of energy from the neighbor that is lost. (This model assigns # the cost of losses to the recipient (importer) of electricity.) vertices[0].marginalPrice = a1 * ( 1 + self.object.lossFactor * minimum_power / maximum_power ) # [$/kWh] # Evaluate the second of two vertices # Vertex 2: The power at Vertex 2 is the maximum power, minus losses vertices[1].power = maximum_power - full_power_loss # [avg.kW] # Vertex 2: The marginal price at Vertex 2 is affected only by # losses. Demand charges do not apply during LLH hours. # # Vertex 2: Marginal price at Vertex 2 from loss component vertices[1].marginalPrice = a1 * (1 + self.object.lossFactor ) # [$/kWh] # Assign production costs for the two vertices # The second-order cost coefficient a2 on the lone line segment # is determined from the change in marginal price divided by # change in power. a2 = (vertices[1].marginalPrice - vertices[0].marginalPrice ) # [$/kWh] a2 = a2 / (vertices[1].power - vertices[0].power) # [$/kW^2h] # The cost at Vertex 1 can be inferred by integrating from # p=0 to Vertex 1. vertices[0].cost = a0 + a1 * vertices[0].power + 0.5 * a2 * ( vertices[0].power)**2 # production cost [$/h] # The cost at Vertex 2 is on the same trajectory vertices[1].cost = a0 + a1 * vertices[1].power + 0.5 * a2 * ( vertices[1].power)**2 # production cost [$/h] # Convert the costs to raw dollars interval_duration = get_duration_in_hour( time_intervals[i].duration) vertices[0].cost = vertices[0].cost * interval_duration # [$] vertices[1].cost = vertices[1].cost * interval_duration # [$] # Create interval values for the active vertices interval_values = [ IntervalValue(self, time_intervals[i], mkt, MeasurementType.ActiveVertex, vertices[0]), IntervalValue(self, time_intervals[i], mkt, MeasurementType.ActiveVertex, vertices[1]) ] # Append the active vertices to the list of active vertices # in the indexed time interval self.activeVertices.extend(interval_values)
print() if __name__ == '__main__': from_vertex = None to_vertex = None vertex_list = list() read_line = sys.stdin.readline() vertex_number = int(read_line) for x in range(0, vertex_number): vertex = Vertex(x) vertex_list.append(vertex) edge_number = sys.stdin.readline() edge_number = edge_number.rstrip('\n') while edge_number != '': edge_number = edge_number.split(' ') from_vertex = int(edge_number[0]) to_vertex = int(edge_number[1]) vertex_list[from_vertex].add_neighbor(vertex_list[to_vertex]) vertex_list[to_vertex].add_neighbor(vertex_list[from_vertex]) edge_number = sys.stdin.readline() edge_number = edge_number.rstrip('\n') #edge_number = re.split("\s+", edge_number)
def __init__(self, v1, v2, v3): self.v1 = v1 self.v2 = v2 self.v3 = v3 vect1 = Vector.generateVector(v1, v2) vect2 = Vector.generateVector(v1, v3) self.n = Vector.cross(vect1, vect2) v1.addAssociatedFace(self) v2.addAssociatedFace(self) v3.addAssociatedFace(self) def toVertexTuple(self): return (self.v1, self.v2, self.v3) def getSurfaceNormal(self): return self.n if __name__ == '__main__': from vertex import Vertex v1 = Vertex(0, 0, 0) v2 = Vertex(0, 1, 0) v3 = Vertex(0, 0, 1) face = Face(v1, v2, v3) print(face.getSurfaceNormal().toTuple())
def __init__(self, number_of_vertices: int): self.vertices: Dict[int, Vertex] = {} for i in range(number_of_vertices): self.vertices[i] = Vertex(i)
def findperim(linesList): cto = distToOrigin(linesList[0].a) ctov = linesList[0].a for i in linesList: if distToOrigin(linesList[i].a) < cto: cto = distToOrigin(linesList[i].a) ctov = linesList[i].a elif distToOrigin(linesList[i].b) < cto: cto = distToOrigin(linesList[i].b) ctov = linesList[i].b else: pass #now cto should have the point closest to the origin #now we find the point farthest to the origin fto = distToOrigin(linesList[0].a) ftov = linesList[0].a for i in linesList: if distToOrigin(linesList[i].a) > fto: fto = distToOrigin(linesList[i].a) ftov = linesList[i].a elif distToOrigin(linesList[i].b) > fto: fto = distToOrigin(linesList[i].b) ftov = linesList[i].b else: pass #now we find the midpoint mid = Vertex((ftov.x - ctov.x) / 2, (ftov.y - ctov.y) / 2, ftov.z) #now we try to find the perimeter based on these facts: #find a line segment in which either point is the same as the previous #if multiple ones, then store the one with the least distance to mid ret = [] ret.append(ctov) last = ctov d = 99999 tba = Vertex(-1, -1, -1) dtba = 99999 while not last.eq(ctov): for i in linesList: if linesList[i].a.eq(last) and dist( mid, linesList[i].b) >= d and dist(last, linesList[i].b) <= dtba: tba = linesList[i].b d = dist(mid, linesList[i].b) dtba = dist(last, linesList[i].b) elif linesList[i].b.eq(last) and dist( mid, linesList[i].a) >= d and dist(last, linesList[i].a) <= dtba: tba = linesList[i].a d = dist(mid, linesList[i].a) dtba = dist(last, linesList[i].a) else: pass d = 99999 dtba = 99999 ret.append(tba) last = linesList[i].a return ret # def main(): # #command line arguments: file, layer thickness, #shell layers, %infill (0-100) # thickness = .4 # layer_height = 1 # shell_no = 2 # infill = .2 # vers = (Vertex(0,0,0), # Vertex(0,10,0), # Vertex(10,0,0), # Vertex(10,10,0), # Vertex(0,0,10), # Vertex(0,10,10), # Vertex(10,0,10), # Vertex(10,10,10)) # facets = ((vers[0], vers[1], vers[2]), # (vers[1], vers[2], vers[3]), # (vers[0], vers[4], vers[5]), # (vers[0], vers[4], vers[1]), # (vers[0], vers[4], vers[2]), # (vers[0], vers[4], vers[6]), # (vers[4], vers[5], vers[6]), # (vers[5], vers[6], vers[7]), # (vers[3], vers[7], vers[1]), # (vers[3], vers[7], vers[2]), # (vers[3], vers[7], vers[5]), # (vers[3], vers[7], vers[6])) # z = 0 # height = 10 # while z <= height: # print "*********************************************************" # print z # lines = [] # for f in facets: # boo = facetIntersect(f[0], f[1], f[2], z) # lines.extend(boo) # #print "intersection num: %.2f" % len(boo) # z = z + layer_height # main()
def insert_vertex(self): """ Inserts a new vertex into the graph """ self.vertices[self.count_vertex()] = Vertex(self.count_vertex())
def parse(filename): # Properties of the graph. Characterized in the first block of a graph-file n_of_nodes = 0 n_of_edges = 0 nodes_label = False edges_label = False directed_graph = False # Vertex list is characterized in the 2nd block of a graph-file vertex_list = [] # Edge list is characterized in the 3rd block of a graph-file edge_list = [] # c is a counter to know in which block of the graph-file we are c = 0 # dict für das Zugreifen auf die Vertices über ihre Namen vertex_dict = {} with open(filename, 'r') as file: file_content = file.readlines() for i in range(0, len(file_content)): temp = file_content[i].replace('\n', '').split(';') if temp == ['']: c += 1 elif temp is not '' and c == 0: if temp[0] == '#nodes': n_of_nodes = temp[1] elif temp[0] == '#edges': n_of_edges = temp[1] elif temp[0] == 'Nodes labelled': if temp[1] == 'True': nodes_label = True else: nodes_label = False elif temp[0] == 'Edges labelled': if temp[1] == 'True': edges_label = True else: edges_label = False elif temp[0] == 'Directed graph': if temp[1] == 'True': directed_graph = True else: directed_graph = False elif c == 1: v = Vertex(temp[0]) if nodes_label: v.set_node_label(temp[1]) vertex_list.append(v) vertex_dict.update( {v.name: v} ) # Vertex wird für Edges-Initialiserung gespeichert (Name=Key) elif c == 2: e = Edge(vertex_dict.get(temp[0]), vertex_dict.get(temp[1]), None, None, directed_graph) if edges_label: e.set_label(temp[2]) edge_list.append(e) graph = Graph(vertex_list, edge_list, n_of_nodes, n_of_edges, nodes_label, edges_label, directed_graph) return graph
def init_objects(self): # Add meter meter = MeterPoint() meter.measurementType = MeasurementType.PowerReal meter.name = 'CampusElectricityMeter' meter.measurementUnit = MeasurementUnit.kWh self.meterPoints.append(meter) # Add weather forecast service weather_service = TemperatureForecastModel(self.config_path, self) self.informationServiceModels.append(weather_service) # Add inelastive asset inelastive_load = LocalAsset() inelastive_load.name = 'InelasticBuildings' # Campus buildings that are not responsive inelastive_load.maximumPower = 0 # Remember that a load is a negative power [kW] inelastive_load.minimumPower = -2 * 8200 # Assume twice the average PNNL load [kW] # Add inelastive asset model inelastive_load_model = OpenLoopPnnlLoadPredictor(weather_service) inelastive_load_model.name = 'InelasticBuildingsModel' inelastive_load_model.engagementCost = [ 0, 0, 0 ] # Transition costs irrelevant inelastive_load_model.defaultPower = -6000 # [kW] inelastive_load_model.defaultVertices = [Vertex(0, 0, -6000.0, 1)] # Cross-reference asset & asset model inelastive_load_model.object = inelastive_load inelastive_load.model = inelastive_load_model # Add solar PV asset solar_pv = SolarPvResource() solar_pv.maximumPower = self.PV_max_kW # [avg.kW] solar_pv.minimumPower = 0.0 # [avg.kW] solar_pv.name = 'SolarPv' solar_pv.description = '120 kW solar PV site on the campus' # Add solar PV asset model solar_pv_model = SolarPvResourceModel() solar_pv_model.cloudFactor = 1.0 # dimensionless solar_pv_model.engagementCost = [0, 0, 0] solar_pv_model.name = 'SolarPvModel' solar_pv_model.defaultPower = 0.0 # [avg.kW] solar_pv_model.defaultVertices = [Vertex(0, 0, 30.0, True)] solar_pv_model.costParameters = [0, 0, 0] solar_pv_model.inject(self, power_topic=self.solar_topic) # Cross-reference asset & asset model solar_pv.model = solar_pv_model solar_pv_model.object = solar_pv # Add inelastive and solar_pv as campus' assets self.localAssets.extend([inelastive_load, solar_pv]) # Add Market market = Market() market.name = 'dayAhead' market.commitment = False market.converged = False market.defaultPrice = 0.04 # [$/kWh] market.dualityGapThreshold = self.duality_gap_threshold # [0.02 = 2#] market.initialMarketState = MarketState.Inactive market.marketOrder = 1 # This is first and only market market.intervalsToClear = 1 # Only one interval at a time market.futureHorizon = timedelta( hours=24) # Projects 24 hourly future intervals market.intervalDuration = timedelta( hours=1) # [h] Intervals are 1 h long market.marketClearingInterval = timedelta(hours=1) # [h] market.marketClearingTime = Timer.get_cur_time().replace( hour=0, minute=0, second=0, microsecond=0) # Aligns with top of hour market.nextMarketClearingTime = market.marketClearingTime + timedelta( hours=1) self.markets.append(market) # City object city = Neighbor() city.name = 'CoR' city.description = 'City of Richland (COR) electricity supplier node' city.maximumPower = 20000 # Remember loads have negative power [avg.kW] city.minimumPower = 0 # [avg.kW] city.lossFactor = self.city_loss_factor # City model city_model = NeighborModel() city_model.name = 'CoR_Model' city_model.location = self.name city_model.transactive = True city_model.defaultPower = 10000 # [avg.kW] city_model.defaultVertices = [ Vertex(0.046, 160, 0, True), Vertex(0.048, 160 + city.maximumPower * (0.046 + 0.5 * (0.048 - 0.046)), city.maximumPower, True) ] city_model.costParameters = [0, 0, 0] city_model.demand_threshold_coef = self.demand_threshold_coef city_model.demandThreshold = self.monthly_peak_power city_model.inject(self, system_loss_topic=self.system_loss_topic, dc_threshold_topic=self.dc_threshold_topic) # Cross-reference object & model city_model.object = city city.model = city_model self.city = city # Add city as campus' neighbor self.neighbors.append(city) # Add buildings for bldg_name in self.building_names: bldg_neighbor = self.make_bldg_neighbor(bldg_name) self.neighbors.append(bldg_neighbor)
def add_edge(self, label1: str, label2: str, weight: int = float("inf")): self.__adjacency_map__[label1][label2] = Vertex(label2, weight)
def vertex(self, substate): if substate not in self.vertices: self.vertices[substate] = Vertex(substate, self) return self.vertices[substate]
def addVertex(self, key): self.numVertices = self.numVertices + 1 newVertex = Vertex(key) self.vertList[key] = newVertex return newVertex
#print("Hello!") # faces = np.array(np.genfromtxt('quads_Torus.csv', delimiter=';')) # verts = np.array(np.genfromtxt('vers_Torus.csv', delimiter=';')) faces = np.array(np.genfromtxt(quads_file, delimiter=';')) verts = np.array(np.genfromtxt(verts_file, delimiter=';')) #faces = np.array(np.genfromtxt('sphere_quads_coarse.csv', delimiter=';')) #verts = np.array(np.genfromtxt('sphere_verts_coarse.csv', delimiter=';')) #faces = np.array([[0, 1 , 2, 3], [1, 5, 6, 2], [0, 1, 5, 4], [3, 2, 6, 7], [0, 3, 7, 4], [4, 5, 6, 7]]) #verts = np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0], [1.0, 1.0, 1.0], [0.0, 1.0, 1.0]]) quads = [None] * faces.shape[0] listOfVertices = [] for i in range(len(verts)): listOfVertices.append(Vertex(i, verts[i])) for i in range(faces.shape[0]): face_vertices = [ listOfVertices[faces[i].astype(int)[j]] for j in range(len(faces[i])) ] quads[i] = Quad(i, face_vertices) for vertex in face_vertices: vertex.addNeighbouringFace(quads[i]) #neighbours_test = quads[4].find_neighbors(quads) [vertices_refined, faces_refined] = DooSabin(listOfVertices, quads, 0.5, 1) [vertices_refined1, faces_refined1] = DooSabin(vertices_refined, faces_refined, 0.5, 2)
def init_objects(self): # Add meter # meter = MeterPoint() # meter.name = 'BuildingElectricMeter' # meter.measurementType = MeasurementType.PowerReal # meter.measurementUnit = MeasurementUnit.kWh # self.meterPoints.append(meter) # Add weather forecast service weather_service = TemperatureForecastModel(self.config_path, self) self.informationServiceModels.append(weather_service) # # Add inelastive asset # inelastive_load = LocalAsset() # inelastive_load.name = 'InelasticBldgLoad' # inelastive_load.maximumPower = 0 # Remember that a load is a negative power [kW] # inelastive_load.minimumPower = -200 # # # Add inelastive asset model # inelastive_load_model = LocalAssetModel() # inelastive_load_model.name = 'InelasticBuildingModel' # inelastive_load_model.defaultPower = -100 # [kW] # inelastive_load_model.defaultVertices = [Vertex(float("inf"), 0, -100, True)] # # # Cross-reference asset & asset model # inelastive_load_model.object = inelastive_load # inelastive_load.model = inelastive_load_model # Add elastive asset elastive_load = LocalAsset() elastive_load.name = 'TccLoad' elastive_load.maximumPower = 0 # Remember that a load is a negative power [kW] elastive_load.minimumPower = -self.max_deliver_capacity # Add inelastive asset model # self.elastive_load_model = LocalAssetModel() self.elastive_load_model = TccModel() self.elastive_load_model.name = 'TccModel' self.elastive_load_model.defaultPower = -0.5 * self.max_deliver_capacity # [kW] self.elastive_load_model.defaultVertices = [ Vertex(0.055, 0, -self.elastive_load_model.defaultPower, True), Vertex(0.06, 0, -self.elastive_load_model.defaultPower / 2, True) ] # Cross-reference asset & asset model self.elastive_load_model.object = elastive_load elastive_load.model = self.elastive_load_model # Add inelastive and elastive loads as building' assets self.localAssets.extend([elastive_load]) # Add Market market = Market() market.name = 'dayAhead' market.commitment = False market.converged = False market.defaultPrice = 0.0428 # [$/kWh] market.dualityGapThreshold = self.duality_gap_threshold # [0.02 = 2#] market.initialMarketState = MarketState.Inactive market.marketOrder = 1 # This is first and only market market.intervalsToClear = 1 # Only one interval at a time market.futureHorizon = timedelta( hours=24) # Projects 24 hourly future intervals market.intervalDuration = timedelta( hours=1) # [h] Intervals are 1 h long market.marketClearingInterval = timedelta(hours=1) # [h] market.marketClearingTime = Timer.get_cur_time().replace( hour=0, minute=0, second=0, microsecond=0) # Aligns with top of hour market.nextMarketClearingTime = market.marketClearingTime + timedelta( hours=1) self.markets.append(market) # Campus object campus = Neighbor() campus.name = 'PNNL_Campus' campus.description = 'PNNL_Campus' campus.maximumPower = self.max_deliver_capacity campus.minimumPower = 0. # [avg.kW] campus.lossFactor = self.campus_loss_factor # Campus model campus_model = NeighborModel() campus_model.name = 'PNNL_Campus_Model' campus_model.location = self.name campus_model.defaultVertices = [ Vertex(0.045, 25, 0, True), Vertex(0.048, 0, self.max_deliver_capacity, True) ] campus_model.demand_threshold_coef = self.demand_threshold_coef # campus_model.demandThreshold = self.demand_threshold_coef * self.monthly_peak_power campus_model.demandThreshold = self.monthly_peak_power campus_model.transactive = True # Avg building meter building_meter = MeterPoint() building_meter.name = self.name + ' ElectricMeter' building_meter.measurementType = MeasurementType.AverageDemandkW building_meter.measurementUnit = MeasurementUnit.kWh campus_model.meterPoints.append(building_meter) # Cross-reference object & model campus_model.object = campus campus.model = campus_model self.campus = campus # Add campus as building's neighbor self.neighbors.append(campus)
# Import Interlude # We’re keeping things organized by storing our classes in separate files, so let’s do a brief review on how to use code from another file. # Python gives us the ability to import code from another file. Here’s how we can use our Vertex class from within graph.py. # # from <file_name> import <class> # # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # inside of ./vertex.py file # class Vertex # # code for the class... # # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # inside of ./graph.py file # from vertex import Vertex # # my_vertex = Vertex("Import Accomplished!") # Use the file explorer to tab between vertex.py, graph.py, and script.py. When you’re ready to continue tab over to script.py. # Inside of script.py, import Graph and Vertex from their respective files. from graph import Graph from vertex import Vertex # Make an instance of Graph and assign it to the variable railway. railway = Graph() # Make an instance of Vertex with the string "Ballahoo" and assign it to the variable station. station = Vertex("Ballahoo") # Call .add_vertex() on railway and pass station as the argument. railway.add_vertex(station)
def make_supplier(self): # Add supplier supplier = Neighbor() supplier.name = 'BPA' supplier.description = 'The Bonneville Power Administration as electricity supplier to the City of Richland, WA' supplier.lossFactor = 0.02 supplier.maximumPower = 200800 # [avg.kW, twice the average COR load] supplier.minimumPower = 0.0 # [avg.kW, will not export] # Add supplier model supplierModel = BulkSupplier_dc() supplierModel.name = 'BPAModel' #supplierModel.demandThreshold = 0.75 * supplier.maximumPower supplierModel.converged = False # Dynamically assigned supplierModel.convergenceThreshold = 0 # Not yet implemented supplierModel.effectiveImpedance = 0.0 # Not yet implemented supplierModel.friend = False # Separate business entity from COR supplierModel.transactive = False # Not a transactive neighbor # Add vertices # The first default vertex is, for now, based on the flat COR rate to # PNNL. The second vertex includes 2# losses at a maximum power that # is twice the average electric load for COR. This is helpful to # ensure that a unique price, power point will be found. In this # model the recipient pays the cost of energy losses. # The first vertex is based on BPA Jan HLH rate at zero power # importation. d1 = Vertex(0, 0, 0) # create first default vertex d1.marginalPrice = 0.04196 # HLH BPA rate Jan 2018 [$/kWh] d1.cost = 2000.0 # Const. price shift to COR customer rate [$/h] d1.power = 0.0 # [avg.kW] # The second default vertex represents imported and lost power at a power # value presumed to be the maximum deliverable power from BPA to COR. d2 = Vertex(0, 0, 0) # create second default vertex # COR pays for all sent power but receives an amount reduced by # losses. This creates a quadratic term in the production cost and # a slope to the marginal price curve. d2.marginalPrice = d1.marginalPrice / (1 - supplier.lossFactor ) # [$/kWh] # From the perspective of COR, it receives the power sent by BPA, # less losses. d2.power = (1 - supplier.lossFactor) * supplier.maximumPower # [avg.kW] # The production costs can be estimated by integrating the # marginal-price curve. d2.cost = d1.cost + d2.power * (d1.marginalPrice + 0.5 * (d2.marginalPrice - d1.marginalPrice) ) # [$/h] supplierModel.defaultVertices = [d1, d2] # COST PARAMTERS # A constant cost parameter is being used here to account for the # difference between wholesale BPA rates to COR and COR distribution # rates to customers like PNNL. A constant of $2,000/h steps the rates # from about 0.04 $/kWh to about 0.06 $/kWh. This may be refined later. # IMPORTANT: This shift has no affect on marginal pricing. supplierModel.costParameters[0] = 2000.0 # [$/h] # Cross-reference object & model supplierModel.object = supplier supplier.model = supplierModel # Meter bpaElectricityMeter = MeterPoint() # Instantiate an electricity meter bpaElectricityMeter.name = 'BpaElectricityMeter' bpaElectricityMeter.description = 'BPA electricity to COR' bpaElectricityMeter.measurementType = MeasurementType.PowerReal bpaElectricityMeter.measurementUnit = MeasurementUnit.kWh supplierModel.meterPoints = [bpaElectricityMeter] return supplier
#import Vertex below.... from vertex import Vertex #import Graph below... from graph import Graph print("\nend imports\n") #Make the Graph instance here #Make an instance of Graph and assign it to the variable railway. railway = Graph() #Make the Vertex instance here #Make an instance of Vertex with the string "Ballahoo" and assign it to the variable station. #station = Vertex("Ballahoo") #Call .add_vertex() here #Call .add_vertex() on railway and pass station as the argument. #railway.add_vertex(station) #Make the Vertex instance here station_one = Vertex("Ballahoo") station_two = Vertex("Penn") #Call .add_vertex() here railway.add_vertex(station_one) railway.add_vertex(station_two) #Call .add_edge() here railway.add_edge(station_one, station_two) print("Edges for {0}: {1}".format(station_one.value, station_one.get_edges())) print("Edges for {0}: {1}".format(station_two.value, station_two.get_edges()))
def test_production(): from local_asset_model import LocalAssetModel from market import Market print('Running test_production()') pf = 'pass' # Create a test object test_object = LocalAssetModel() # Create a test market test_market = Market() # Create several active vertices av av = [ Vertex(0.0200, 5.00, 0.0), Vertex(0.0200, 7.00, 100.0), Vertex(0.0250, 9.25, 200.0) ] # Create a time interval ti dt = datetime.now() at = dt # NOTE: Function Hours() corrects the behavior of Matlab hours(). dur = timedelta(hours=1) mkt = test_market mct = dt st = dt ti = TimeInterval(at, dur, mkt, mct, st) # Assign activeVertices, which are IntervalValues test_object.activeVertices = [ IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[0]), IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[1]), IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2]) ] ## CASE: Various marginal prices when there is more than one vertex test_prices = [-0.010, 0.000, 0.020, 0.0225, 0.030] p = [0] * len(test_prices) #zeros(1, length(test_prices)) for i in range(len(test_prices)): #for i = 1:length(test_prices) p[i] = production(test_object, test_prices[i], ti) print('- the function ran without errors') # p(1) = 0: below first vertex # p(2) = 0: below first vertex # p(3) = 100: at first vertex, which has identical marginal price as second # p(4) = 150: interpolate between vertices # p(5) = 200: exceeds last vertex #if ~all(abs(p - [0, 0, 100, 150, 200]) < 0.001): expected = [0, 0, 100, 150, 200] if not all([p[i] - expected[i] < 0.001 for i in range(len(p))]): pf = 'fail' raise Exception('- the production cost was incorrectly calculated') else: print('- the production cost was correctly calculated') ## CASE: One vertex (inelastic case, a constant) test_object.activeVertices = [ IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2]) ] for i in range(5): p[i] = production(test_object, test_prices[i], ti) #if ~all(p == 200 * ones(1, length(p))): if not all(x == 200 for x in p): pf = 'fail' raise Exception( 'the vertex power should be assigned when there is one vertex') else: print('- the correct power was assigned when there is one vertex') ## CASE: No active vertices (error case): test_object.activeVertices = [] try: p = production(test_object, test_prices[4], ti) pf = 'fail' raise Exception( '- an error should have occurred with no active vertices') except: print('- with no vertices, system returned with warnings, as expected') # Success print('- the test function ran to completion') print('Result: #s\n\n', pf)
def addVertice(self, vertexId): self.vertices[vertexId] = Vertex(self, vertexId)