Total-RD / pymgrid

pymgrid is a python library to generate and simulate a large number of microgrids.
https://pymgrid.readthedocs.io/
GNU Lesser General Public License v3.0
173 stars 66 forks source link

Voltage constraint #236

Open Brandaoss opened 1 year ago

Brandaoss commented 1 year ago

How can I add voltage constraints to the system, the microgrid I'm training to build has 3 different transformed and 7 loads, with 3 PV systems as generators. It is connected to the main grid and further evaluation of PV expansions + storage systems will be added and evaluated. But as of building the current microgrid, I require to add the voltage constraints in order to build the correct power flow.

The current code is as follows: import numpy as np import pandas as pd

np.random.seed(0)

from pymgrid import Microgrid from pymgrid.modules import ( BatteryModule, LoadModule, RenewableModule, GridModule) Fake_data_1.xlsx

Defining the Microgrid

small_battery = BatteryModule(min_capacity=10,

                          max_capacity=100,
                          max_charge=50,
                          max_discharge=50,
                          efficiency=0.9,
                          init_soc=0.2)

large_battery = BatteryModule(min_capacity=10, max_capacity=1000, max_charg Fake_data_1.xlsx e=10, max_discharge=10, efficiency=0.7, init_soc=0.2)

=============================================================================

load_ts = 100+100np.random.rand(24365) # random load data in the range [100, 200].

pv_ts = 200np.random.rand(24365) # random pv data in the range [0, 200].

load = LoadModule(time_series=load_ts)

pv = RenewableModule(time_series=pv_ts)

=============================================================================

Data = pd.read_excel("Fake_data_1.xlsx")

insert PV data

pv_0 = Data["PV0"] pv_1 = Data["PV1"] pv_2 = Data["PV2"] pv_3 = Data["PV3"]

pv_total=np.concatenate((np.expand_dims(pv_0, 1),np.expand_dims(pv_1, 1),np.expand_dims(pv_2, 1),np.expand_dims(pv_3, 1)),axis=1)

pv_ts= np.sum(pv_total,1)

insert load data

load_0 = Data["Load0"] load_1 = Data["Load1"] load_2 = Data["Load2"] load_3 = Data["Load3"] load_4 = Data["Load4"] load_5 = Data["Load5"] load_6 = Data["Load6"] load_7 = Data["Load7"]

load_total=np.concatenate((np.expand_dims(load_0, 1),np.expand_dims(load_1, 1), np.expand_dims(load_2, 1),np.expand_dims(load_3, 1), np.expand_dims(load_4, 1),np.expand_dims(load_5, 1), np.expand_dims(load_6, 1),np.expand_dims(load_7, 1)),axis=1)

load_ts=np.sum(load_total,1)

load = LoadModule(time_series=load_ts)

pv = RenewableModule(time_series=pv_ts)

Add external grid for gaps

grid_ts = [0.2, 0.1, 0.5] np.ones((2490, 3))

grid = GridModule(max_import=100, max_export=100, time_series=grid_ts)

Buildup of the Microgrid

modules = [ small_battery, large_battery, ('pv', pv), load, grid]

microgrid = Microgrid(modules)

unbalanced_energy_module=False

print(microgrid)

Microgrid([load x 1, pv x 1, balancing x 1, battery x 2, grid x 1])

print(microgrid.modules.pv)

[RenewableModule(time_series=<class 'numpy.ndarray'>, raise_errors=False, forecaster=NoForecaster, forecast_horizon=0, forecaster_increase_uncertainty=False, provided_energy_name=renewable_used)]

print(microgrid.modules.grid is microgrid.modules['grid'])

Calculate the efficiency of self-sufficiency for each hour

efficiency = pv_ts / load_ts Total_year_eff = sum(pv_ts)/sum(load_ts)

per day

Daily_eff=np.zeros(365) for i in range(365): Daily_eff[i]=np.average(efficiency[i24:(i24+24)])

Average_Daily_eff=np.average(Daily_eff)

Plot the efficiency of self-sufficiency and the hours when energy is needed from the main grid

import matplotlib.pyplot as plt

plt.plot(Daily_eff) plt.axhline(Average_Daily_eff, color="red", linestyle="--") plt.xlabel("Day") plt.ylabel("% Self-Sufficiency") plt.show()

CONTROLING THE MICROGRID

microgrid.controllable { "battery": "[BatteryModule(min_capacity=10, max_capacity=100, max_charge=50, max_discharge=50, efficiency=0.9, battery_cost_cycle=0.0, battery_transition_model=None, init_charge=None, init_soc=0.2, raise_errors=False), BatteryModule(min_capacity=10, max_capacity=1000, max_charge=10, max_discharge=10, efficiency=0.7, battery_cost_cycle=0.0, battery_transition_model=None, init_charge=None, init_soc=0.2, raise_errors=False)]", "grid": "[GridModule(max_import=100, max_export=100)]" }

print(microgrid.get_empty_action())

microgrid.reset() microgrid.state_series.to_frame()

Battery Discharge

load = -1.0 * microgrid.modules.load.item().current_load pv = microgrid.modules.pv.item().current_renewable

net_load = load + pv # negative if load demand exceeds pv

if net_load > 0: net_load = 0.0

lower of the excess load and the maximum production.

battery_0_discharge = min(-1*net_load, microgrid.modules.battery[0].max_production) net_load += battery_0_discharge

battery_1_discharge = min(-1*net_load, microgrid.modules.battery[1].max_production) net_load += battery_1_discharge

grid_import = min(-1*net_load, microgrid.modules.grid.item().max_production)

Note that positive values denote energy moving into the microgrid

and negative values denote energy leaving the microgrid.

control = {"battery" : [battery_0_discharge, battery_1_discharge], "grid": [grid_import]}

control

obs, reward, done, info = microgrid.run(control, normalized=False)

Results analysis

microgrid.log.loc[:, pd.IndexSlice['load', 0, :]] microgrid.log.loc[:, pd.IndexSlice['pv', 0, :]] microgrid.log.loc[:, 'battery']

RESULT PLOTS

for _ in range(24): microgrid.run(microgrid.sample_action(strict_bound=True))

microgrid.log[[('load', 0, 'load_met'), ('pv', 0, 'renewable_used'), ('balancing', 0, 'loss_load')]].droplevel(axis=1, level=1).plot()

plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.09), fancybox=True, shadow=True, ncol=5)

RULE BASED CONTROL

import pandas as pd

from matplotlib import pyplot as plt

from pymgrid import Microgrid from pymgrid.algos import RuleBasedControl

microgrid = Microgrid.from_scenario(microgrid_number=0) rbc = RuleBasedControl(microgrid)

rbc.reset() rbc_result = rbc.run()

Investigating the results

rbc_result.loc[:, pd.IndexSlice[:, :, 'reward']].cumsum().plot() plt.show()

ahalev commented 1 year ago

Can you give me an example of the voltage constraints you're describing? This isn't something pymgrid supports natively, but I may be able to give suggestions on implementation.

Brandaoss commented 1 year ago

Hi Ahalev,

Im attaching the word document with the table with the data of the transformers, they all have a I/O voltage of 400V/240V which will be the distribution constraint of the grid.

Distribution_transformers.docx