Dynamic Optimization - Creating an Electric Energy System Optimization Problem🔗
Focus on result interpretation and advanced data input
1. Introduction🔗
This article is the third in a series of articles related to dynamic optimization:
- Concepts and Terminology
- Creating a Hybrid Energy System Optimization Problem
- Creating an Electric Energy System Optimization Problem
- Best Practice and Troubleshooting
A hands on tutorial will be given to guide the user step-by-step through the optimization workflow. In case any basic understanding of optimization problems in general or specific components are missing, please refer here. We strongly recommend to work through the tutorial provided here before continuing.
2. General information and context of the problem🔗
To reduce energy costs, a factory owner wants to install a photovoltaic module on top of his factory roof. To be more independent of fluctuations in energy prices and hours of sunshine, an energy storage is additionally installed in form of a battery. The challenge is now to find the optimal size for the PV module and a suitable capacity for the battery. Therefore, the factory owner asks a simulation engineer to build the system in Modelon Impact to optimize the design.
3. Step-by-step procedure to set up the model🔗
You need a workspace with the library EnergySystems in the dependencies to build this model. For instructions on how to set up a workspace in Impact, please refer here.
A screenshot of the system model is shown below, followed by instructions on how to build the model.
Step 1: Extend from Optimization Template🔗
To start this example, extend the model
EnergySystems.ScenarioSetup.EconomyOptimizationTemplate
and chose a name for your system model. As explained in the previous article, the models economy
and optimizer
are included in the template.
optimizer
- This model consolidates the basic definition of the optimization problem (objective function, time horizon, and discretization) as well as settings for the optimization solver.
- In the 'General' tab of the optimizer, please set
t_opt_end
to30 * 24 * 3600
and - if you have a license - chose the high performance solver (MA57) from the dropdown menulinearSolver
.
economy
- This model gathers and sums economic values (capex, opex, cash flow, etc.) from all components in the system
automatically. It also provides objective functions that can be used in the
Optimizer
. - No parameters need to be set by the user.
constraint
To implement a maximum budget, add the model EnergySystems.ScenarioSetup.Constraint
. For now, deactivate useUpperLimit
and useLowerLimit
, they will be used later.
Best practice tip:
For a better overview in your model, it is recommended to separate the components which are part of the optimization problem from the control and data
components.
Start following the steps below:
-
First instantiate components for the optimization problem. These are the ones "within the box" as you can see in the picture above.
-
Then go to source code view and add a comment line which marks the start and end point of the optimization problem components.
-
Now go back to the canvas view and add components "outside of box". These components are relevant only for the initial simulation that serves as a starting point for the optimization.
-
To allow removing undesired content from the optimization problem, it must be "marked" as such. To do so, go back to the code view and add a condition to the components added below of the comment line of step 2.
Below, you see an example how to make a ramped input conditional. Please adapt
this for the other conditional components. Name the boolean variable for the
condition initialSimulationPhase
.
Modelica.Blocks.Sources.Ramp ramp if initialSimulationPhase "a simple ramp for input" annotation(...);
- Optional: draw bounding box to optimization problem by copy and paste the
command line below to the end of your optimization file (before the
end model
statement). The dimension might have to be adapted.annotation(Diagram(graphics={Rectangle(extent={ {-50,60},{150,-100} },lineColor={61,61,61})}));
Step 2: Components optimization problem (inside the box)🔗
More components will be inserted in addition to this to form your model. For convenience and easy understanding name and connect them according to the picture above
batteryChargeControl, curtailmentControl
- EnergySystems.ScenarioSetup.OptimalControl
- This control is set as a degree of freedom and can be changed by the optimizer to find suitable settings for the system. Depending on the PV power and the current electricity prices, it is decided when the battery is charged.
electricGridPrice, electricConsumption, photovoltaicProduction * EnergySystems.ScenarioSetup.BoundaryCondition * The output of the pv module depends on the solar hours, which are set in the data table.
battery
- EnergySystems.Storage.Electricity.BatteryDualControl
- The battery is the energy storage for the system, which makes the factory more independent of solar hours and electricity prices.
- capacity_ref = 20 * 3600 * 1e5, scalingFactor_free_ = true, scalingFactor_max = 500, set_SOC_final_start_ = true
inverter
- EnergySystems.Converters.Converter_ACDC
- An inverter is needed to change from alternating current to direct current.
- V_ref_DC=12 V, P_ref = 2e6 W
converter_DCDC
- EnergySystems.Converters.Converter_DCDC
- The converter is the connection between different voltage levels in DC.
- P_ref=2e6 W
transformer
- EnergySystems.Converters.Transformer_Unidirectional
- The transformer is the connection between different voltage levels in AC.
- P_ref=0.7e6 W, V_ref=320 V
electricityPurchase
- EnergySystems.SupplyAndDemand.Electricity.Purchase_AC
- This components represents the public electricity grid where you can buy in electricity at the current market price.
- V_ref=1e3 V, flowType=.EnergySystems.Internal.Types.FlowType.FreeFlow
electricityDemand
- EnergySystems.SupplyAndDemand.Electricity.Boundary_AC
- Electricity demand of the factory
- note, there is no revenue from delivering this demand, it is in this case a technical requirement
photovoltaics
- EnergySystems.Photovoltaics.Photovoltaics_simple
- allowCurtailment=true, scalingFactor_free_=true, scalingFactor_max=200,lifetime = 25 yr, P_ref = 1e6 W, capex_ref = 2000 , fixedAnnualOpex_ref = 1e3 1/yr
Step 3: Conditional components (outside the box)🔗
excelTableReader
- EnergySystems.ScenarioSetup.ExcelTableReader
- The excel file reader reads your weather data, in specific the hours of sunshine.
- timeUnitFactor=3600/*24 s, fileName=.Modelica.Utilities.Files. loadResource ("modelica://EnergySystems/Resources/Data/MicrogridData_pv_load_h2.xlsx"), sheetName="example_timeseries_1year", range="A3:D35042", nColumnsInRange=4| |
controller
- EnergySystems.Control.BatteryDispatchable DualController
- The aim of this controller is to enable calculation of valid initial guess trajectories for microgrids including battery storage systems (BESS) or hydrogen storage systems (HESS).
- P_charging_min=-battery.P_max, P_charging_max=battery.P_max, n=1, P_max={EnergySystems.Internal.dummy}
electric_purchasePrice
- Modelica.Blocks.Sources.Sine
- amplitude=0.05 * 0.4, f=1/(723600) 1/s, phase=-0.5.Modelica.Constants.pi, offset = 0.45
Battery set point
- Modelon.Blocks.Sources.RealExpressions
- Nominal and actual values for battery state of charge
- nout=2, x=-{battery.SOC,0.8}
curtailmentPID
- Modelica.Blocks.Continuous.LimPID
- yMax=1, yMin=0, initType=.Modelica.Blocks.Types.Init.InitialOutput, y_start=1
4. Run the optimization🔗
Hover over the play button and choose Energysystems.dynamic Optimization, then click play.
5. Interpret the Results🔗
To be able to judge the results of the optimization, several parameters can be plotted. The relevant questions to ask, are written below. Have a look at ViewResults (if you hover over the eye on the right side, for more information, please refer to Views) where the electricity demand (P_el), the battery charge and discharge (P_charge_abs, P_discharge_abs), the battery state of charge (SOC), the electricity purchase (P_el) and the power generated by the pv module as well as the incoming power (photovoltaics.P_el, photovoltaics.P_el_in) are plotted.
-
Where is electricity produced and where consumed? There are several electricity producers: the photovoltaic module, the electricity purchase component, where electricity can be bought from the market with a varying price but also the battery which not directly produces electricity but is able to provide it when the battery is charged sufficiently.
-
How is PV electricity used? The electricity produced by the photovoltaic module can be used to cover the demand directly but also, to charge the battery. In this model no electricity can be sold to the market when there is more produced than needed. This leads directly to the next question below.
-
Why is the revenue always negative? No income can be generated because there is no sales option included in the model. Therefore, only investments for the photovoltaic module and the battery as well as costs for electricity purchase contribute to the revenue.
-
How does the optimizer use storage? The plotted values show that the battery is charged more in or just before winter time to have enough energy saved when the solar hours drop (Plot: battery, solar power and electricity purchase, battery SOC). When the solar power is not enough anymore, electricity is purchased from the market (Plot: solar power and electricity purchase).
-
Why is PV curtailment needed? In summer, electricity comes directly from the pv module. It can be observed that the power of the pv module is lower in summer, even though the incoming power from the sun is higher. This is due to the curtailment control which lowers the output power according to the demand. The solar module is cheap enough such that the optimizer choose it to provide enough power in winter. Therefore, there is an overproduction in summer. Since no sales option for electricity is included, the additional electricity cannot be used. The converter restricts the power output of the pv module to 2MW. The electricity demand dos not vary between the seasons. (Plot: electricity demand and pv power).
-
What affects the scaling of components The scaling limits of the pv module and the battery are chosen in a way that the optimizer is not running into these limits but instead is free to find an optimal solution. However, in a real world problem, space i.e. for the pv module or the battery can be a restricting factor. The optimizer takes mainly the price into account when it comes to scaling of the components but for the pv module i.e. one factor is also its productivity. This highly depends on the location or in other words on the hours of sunshine.
-
What economic information do I get and how to interpret them? The ESL economy block automatically summarizes the economic values of the system. In addition, each component has its own economic values depending on the parameters set in the "Economy" tab of the corresponding component.The following parameters are being summarized:
- CapEx: The "Capital Expenditure", i.e. the money needed to buy all components
- Annual CapEx: Essentially the sum of each component's CapEx divided by its lifetime, providing a normalized CapEx
- Fixed Annual OpEx: "Operating Expense", i.e. the cost to operate and run a component for one year
Also, there are revenues and costs which depend on whether a resource is being sold or used, e.g. a fuel, electricity or heat or possibly a cost that is depending on a component's usage. These are variable over time and must be accumulated (integrated) over time to be meaningful.
- Variable OpEx (per second): Cost for resources, energy, labor, etc
- Variable Revenues (per second): Income as a result of sales of resources, energy etc.
- Cash Flow (per second): The revenue minus the opex
6. Further Exploration🔗
Price Variations🔗
To understand the example better it makes sense to vary some parameters and check on the differences in the results. If a range of a certain parameter should be investigated, the easiest way is to use a parameter sweep. The procedure is explained in Simulation and parameter sweeps. It is also possible to provide data input through an Excel interface.
Interesting questions are: What happens if * The electricity price increases? * Batteries are cheaper?
Depending on the price it is decided how much is going to be purchased of or from a certain component. If the electricity price increases, there will be less/ no purchase from the market but instead the self-sufficient energy supply (pv module, battery) is scaled up. The same accounts for the battery. The cheaper the battery is, the bigger it will most likely be.
Run the optimization again and observe the differences.
Adding a maximum budget limit🔗
The capex value from the optimization should be 376154. Implementing a limit is done with the constraint model that was added earlier.
+ Activate useUpperLimit
+ Set constraintTarget
to economy.capex
+ Set upperLimitFixed
to 300e3
Rerun the optimization and check the results again.