Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the temporal parameters in the constraints #110

Closed
Tracked by #61
abelsiqueira opened this issue Sep 20, 2023 · 15 comments · Fixed by #212
Closed
Tracked by #61

Add the temporal parameters in the constraints #110

abelsiqueira opened this issue Sep 20, 2023 · 15 comments · Fixed by #212
Assignees
Labels
question Marker that this issue should be discussed at the next meeting Type: addition Add something that doesn't exist Zone: optimisation model Improvements or changes to the optimisation model (e.g., objective function, variables, constraints)

Comments

@abelsiqueira
Copy link
Member

abelsiqueira commented Sep 20, 2023

Follow the formulation and add these constraints in the optimization model.

@clizbe clizbe added Zone: optimisation model Improvements or changes to the optimisation model (e.g., objective function, variables, constraints) Type: addition Add something that doesn't exist labels Sep 21, 2023
@abelsiqueira abelsiqueira self-assigned this Oct 17, 2023
@abelsiqueira
Copy link
Member Author

To add the temporal parameters, we need to use the matrices (#109), being implemented in #144, and we also need to know how to generate the input for the functions in #109.
In other words:

How is the temporal resolution being included in the model?

The available data (the tiny test) only has hourly information for each profile.

@abelsiqueira abelsiqueira added the question Marker that this issue should be discussed at the next meeting label Oct 17, 2023
@abelsiqueira abelsiqueira removed their assignment Oct 23, 2023
@abelsiqueira
Copy link
Member Author

@datejada @clizbe How do you think we should manage this input? Should it be full code? Other CSVs?

@datejada
Copy link
Member

I'm not quite sure which is the best place yet, sorry. We can discuss it tomorrow with the whole team (including German). For the time being, if you are working on this today, please make it the simplest/easiest possible, so if we agree on something tomorrow, you can change it more straightforward.

@abelsiqueira abelsiqueira self-assigned this Oct 24, 2023
@abelsiqueira abelsiqueira mentioned this issue Oct 24, 2023
4 tasks
@abelsiqueira
Copy link
Member Author

This issue is a bit hard, and I am not sure how to break it down, so we might have to bite the bullet.
I will write down some thoughts which might be helpful in the discussion, but also for myself.

Naming (until #208 is resolved): RPs have a number of time steps. Each assets and flow is defined over time intervals. Each balance constraint is split into time periods.

Assets and flows time intervals are read from file and transformed into ranges (a:b).
Ranges occupy little space in memory, so we can then define the sets K_A[(a, rp)] and K_F[(f, rp)] to be the ranges for each asset/flow, and rp pair. We can then define the variables that used to depend on K, to depend on K_A and K_F. The variables are now indexed on ranges, i.e., we have flow[(("a1", "a2"), 1, 1:3)].

The balance constraints happen at assets, and we know which flows go through those assets. Therefore, we can compute the periods of the constraints and index by assets and rp. This means that we have a set P[(a, rp)] of ranges for each asset. There are periods, not intervals, though. Since we have the period, given a flow variable, we can immediately compute the ratio of that variable that is used in that constraint. In other words, if a variable f is define for intervals K_F = [1:3, 4:6, 7:9], and the periods are P = [1:4, 5:9], then we can compute the ratio as

$$\displaystyle \frac{|T \cap I|}{|I|},$$

where T in P and I in K_F. So instead of

@constraint(model, balance[a in A, rp in RP, k in K[rp],
  sum(flow[f, rp, k] for f in F ...)

we have

@constraint(model, balance[a in A, rp in RP, T in P[(a, rp)],
  sum(ratio(T, I) * flow[f, rp, I] for f in F, I in K_F[(f, rp)] ...)

In other words, we are adding an extra loop, but we avoid computing and storing a matrix.

The asset profiles that appear in these equations can just be summed over the time period.

@abelsiqueira
Copy link
Member Author

abelsiqueira commented Oct 30, 2023

@datejada, @clizbe, I am not sure what is the time index of the storage_level. Should it be indexed on the time interval of that asset, or the constraint's time period?
And in that context, what is tau - 1?

@datejada
Copy link
Member

@abelsiqueira The storage_level has its own time index definition. We need to specify it in the storage asset. This means that the storage asset has two temporal definitions: one for the flows and the other for the storage level. If the storage temporal definition is not specified, then it should be the same as the one for the flows.

@datejada
Copy link
Member

@abelsiqueira, we don't mind adding extra loops, as long as they don't create extra and unnecessary constraints/variables. The readability is another concern, but so far, it is still okay. We need to be clear in the documentation.

@abelsiqueira
Copy link
Member Author

That conditional should happen at the data input level, maybe as part of a UI. But for the model, I have to assume that all data is available.
Then I could have, for instance:

  • storage_level defined for intervals [1:3, 4:6, 7:9, 10:12]
  • the constraint defined for intervals [1:4, 5:8, 9:12] (because of flows)

The original constraint had storage_level at k - 1. How does that change?

@datejada
Copy link
Member

The k-1 means the storage level from the previous interval, so in your example, if the k is using the 4:6 interval, the k-1 will be the 1:3 interval variable

@abelsiqueira
Copy link
Member Author

Feels like the RP periods should be involved?

@datejada
Copy link
Member

Correct, it is the k-1 from the same RPas k for k>1 (we will add later what happens for k=1)

@abelsiqueira
Copy link
Member Author

Did not understand

@abelsiqueira
Copy link
Member Author

What I am getting at is: k is the individual time step. Storage level is defined for intervals I in [1:3, 4:6, ...] and the constraint should be palance for periods T in [1:4, 5:8, ...].
If you translate the $s_k = s_{k-1} + \delta_k$ constraints using:

  • $\dfrac{1}{3}s_{1:3}$ instead of $s_1$, $s_2$ and $s_3$, and similar for other intervals
  • Sum 4 of these equations at a time

Then it is like having two matrices, one for $s_k$, and one for $s_{k-1}$.

@datejada
Copy link
Member

Sorry, I didn't explain myself correctly, and it was me the one that didn't understand it at the beginning. Now, I see what bothers you and after reviewing the equation again:

  1. s represents the storage level at the end of the interval. It is the total stored energy in the asset at the end of I, so for the the second interval i=4:6, s is the storage level at k=6
  2. For the constraint you want to know the storage level at the end of the previous interval, So, in the example, you want to have s at k=3 for your "k-1"
  3. This leads us to the conclusion that for storage assets, we might want the constraints written according to the intervals of the storage asset and aggregate the flows depending on that.

In any case, we should discuss it in more detail with @g-moralesespana in tomorrow's session. Hopefully, in person, we can make it more clear for all of us. Sorry 😞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Marker that this issue should be discussed at the next meeting Type: addition Add something that doesn't exist Zone: optimisation model Improvements or changes to the optimisation model (e.g., objective function, variables, constraints)
Projects
None yet
3 participants