Veda2.0 Released!


NCAP_AFC and seasonal storage
#1
Hi,

We are using NCAP_AFC to model storage, both daynite and seasonal storage. 
The daynite storage is working proparly by converting the investment cost from energy to capacity through: invcost * NCAP_AFC * (24/8760). 
For the seasonal storage, we are unsure if the convertion is functioning as intended. Is it correct to multiple with 2190/8760 instead of 24/8760, considering 4 seasons within a year? 

Thank you in advance.
Reply
#2
I am not quite able to follow your thinking.

> The daynite storage is working proparly by converting the investment cost from energy to capacity through: invcost * NCAP_AFC * (24/8760).

If you use NCAP_AFC(ELCC,DAYNITE), where ELCC is the output electricity, then the capacity represents the max. output level of ELCC.  Typically such output capacity is in the unit of GW, and PRC_CAPACT would typically be 31.536 (where the flow unit is PJ).

Let's say you want to model a battery storage with an energy capacity of 6 GWh per GW, i.e. 6 hours' capacity. Therefore, if we denote the investment cost per GWh by ICE, then the investment cost per GW is ICP = 6 × ICE.  These specs can be modeled by defining:

  ●  PRC_CAPACT(r,p) = 31.536;
  ●  NCAP_AFC(r,y,p,ELCC,DAYNITE) = 1;
  ●  NCAP_AFC(r,y,p,ACT,DAYNITE) = 0.25;
  ●  NCAP_COST(r,y,p,cur) = ICP;

The availability factor NCAP_AFC(ACT,DAYNITE)=0.25 is due to the fact that the NCAP_AFC(ACT,DAYNITE)=1 corresponds to storage energy availability equivalent to a nominal full-load power output over the full DAYNITE cycle, i.e. 24 hours, and 6 / 24 = 0.25. For a seasonal storage, NCAP_AFC(ACT,SEASON)=1 would correspond to storage energy availability equivalent to full power output over the full year, i.e. 8760 hours. Therefore, if you would like to model a seasonal storage with 100 hours' energy capacity, you should define NCAP_AFC(ACT,SEASON) = 100/8760 = 0.0114155.  I just verified that these should indeed work as expected.

For example, if you have a DAYNITE storage with investment costs of 100 €/kWh, and energy capacity of 6 GWh/GW, one could define NCAP_COST = 600 (assuming the capacity unit is GW, and the currency unit is M€). Similarly, if you have a SEASON storage with investment costs of 100 €/kWh, and energy capacity of 100 GWh/GW, you should define NCAP_COST = 10,000 (assuming the same units as above). Using NCAP_AFC as a multiplier, we get:

  ●  NCAP_COST(r,y,p,cur) = NCAP_AFC(ACT,DAYNITE) × 24 × ICE (DAYNITE case)
  ●  NCAP_COST(r,y,p,cur) = NCAP_AFC(ACT,SEASON) × 8760 × ICE (SEASON case)

Consequently, I am not directly able to see why you say that the investment cost from energy to capacity would be converted through: invcost * NCAP_AFC * (24/8760).  But I can see it might be so if using some different combination for the units of the output capacity and ICE. Could you therefore mention also your assumptions on the units, or otherwise explain why in your case that expression would seem to result in a correct conversion? But anyway, the difference between the DAYNITE and SEASON cases should remain as described above.
Reply
#3
An additional refinement to my previous message:

As described in the Documentation (Part II), Section 4.3.7 Availability factors for storage processes, any storage efficiency would of course also affect the nominal full discharge from the storage. Therefore, if the energy capacity should, for example, correspond to 6 hour's full output also after considering storage losses, then the availability factor NCAP_AFC(ACT,DAYNITE) should be adjusted with the storage efficiency, e.g. NCAP_AFC(ACT,DAYNITE) = 6 / 24 / STG_EFF.
Reply
#4
Dear Antti,
Thank you for the fast response!

I see that we have used the same methodology as you, with a small error in the investment cost. With a battery storage of 6 hours capacity, we have used NCAP_AFC(NRG, DAYNITE) = 1 and NCAP_AFC(ACT,DAYNITE) = (6/24)/STG_EFF.
To convert the investment cost from GWh to GW (e.g. 100 €/kWh), we previously used ICE * (6/24) * (24/8760). We have now adjusted this to only ICE * 6/24 * 24.

We are also working with flexible timeslices, and for some model runs we use 48 timeslice (4x12h). Would it be correct to adjust the daynite storage to NCAP_AFC = (6/12)/STF_EFF and NCAP_COST = NCAP_AFC * 12 * ICE?
Reply
#5
Ok, thanks for the follow-up.

But were you able to concur about the seasonal storage case as well? Note also that when using a general storage (STS) defined on the DAYNITE level, you also have the seasonal storage capability, but the parameters are defined in the same way as for a regular DAYNITE storage (you could use any NCAP_AFC > 1 for a large energy capacity).

> We are also working with flexible timeslices, and for some model runs we use 48 timeslice (4x12h). Would it be correct to adjust the daynite storage to NCAP_AFC = (6/12)/STF_EFF and NCAP_COST = NCAP_AFC * 12 * ICE?

Hmm... again I am not sure I follow.  Please first explain what this 4x12 h actually means?  Does the 4 still stand for the number of seasons?  And what does the 12h mean?  Are you changing the TS_CYCLE or G_CYCLE default values, and if so, how?
Reply
#6
Just to explain my confusion about your follow-up question:

The number 24 in the expression I derived for NCAP_COST above (NCAP_COST(r,y,p,cur) = NCAP_AFC(ACT,DAYNITE) × 24 × ICE (DAYNITE case)) is related to the length of each DAYNITE cycle in hours (it was in hours because of the unit of ICE (M€/GWh)).  Now, you suggested the expression NCAP_COST = NCAP_AFC * 12 * ICE, for your 48 timeslice (4x12h) case, which seems to imply that you have changed the length of the DAYNITE cycle to 12 hours(?). Doing so would in my view be rather unusual (because daytime and nightime usually have very different load profiles), and I cannot see how that could be a useful modeling approach.  But if you have indeed changed the cycle length in this way, you should also have defined either TS_CYCLE or G_CYCLE to correspond with your new DAYNITE cycle length.  Could you therefore confirm whether that is the case?
Reply
#7
I will now try and clarify the follow-up question below:

> We are also working with flexible timeslices, and for some model runs we use 48 timeslice (4x12h). Would it be correct to adjust the daynite storage to NCAP_AFC = (6/12)/STF_EFF and NCAP_COST = NCAP_AFC * 12 * ICE?

The meaning of the storage availability parameter NCAP_AFC(ACT, tslvl) is, in general, invariant over different timeslice configurations, insofar as the default lengths of the timeslice cycles are not changed. Therefore, NCAP_AFC(ACT,DAYNITE) always defines the maximum available energy capacity in proportion to the nominal full-load output from a DAYNITE storage over one day (24 hours), as described in the documentation. The only exception to that general rule is when the length of the timeslice cycles are changed, by using G_CYCLE. In that case the meaning of NCAP_AFC(ACT,DAYNITE) would be changed to refer to the nominal full-load output from a DAYNITE storage over one DAYNITE cycle, whatever the new length of that cycle is.

Nonetheless, there is also a more recent TIMES attribute available for changing the length of the timeslice cycles: TS_CYCLE.  With this TS_CYCLE parameter, one can define the lengths of the timeslice cycles individually under each parent timeslice.  This functionality can be useful e.g. if one should wish to model one season in more detail, for example using a whole representative week, and other seasons with just a representative day.  In such a case, it would of course not be possible to interpret NCAP_AFC by using the cycle lengths as defined by TS_CYCLE, because those may be mutually inconsistent.  And therefore, G_CYCLE is always used as the reference when interpreting NCAP_AFC(ACT, tslvl). That can also be considered useful in terms of model and data independence: It would be quite undesirable if the meaning of some parameters would change when the timeslice configuration is changed.  Therefore, if there is a need for changing the lengths of timeslice cycles, using TS_CYCLE is recommended over G_CYCLE.

In summary, the meaning of the storage availability parameter NCAP_AFC(ACT, tslvl) is invariant over different timeslice configurations, including different lengths of the timeslice cycles, as long as G_CYCLE is not being changed. Consequently, also the investment costs of a storage should never need to be changed when using different timeslice configurations, as long as G_CYCLE is not being changed.
Reply
#8
Dear Antti,
I apologize for the late response. I was not able to find time to implement this in the model before christmas.
I have changed the modelling according to your suggestions, but we have some challenges with how to intepret the results with the new approach.
Could uou explain how to:
- Calculate the capacity in terms of energy from the results?
- What does VAR_Act, VAR_Fin and VAR_Fout represent? I assume VAR_CAP is the capacity in terms of power. Is it correct that the VAR_Fin and VAR_Fout is the charge and discharge of the battery in every hour in power?
Reply
#9
> we have some challenges with how to intepret the results with the new approach.

I am a bit confused by that, as I was not presenting any new approach, but only the functionality described in the documentation, which has been essentially unchanged for the past decade or so.

> Could you explain how to: - Calculate the capacity in terms of energy from the results?

I am sorry but I am not sure what this question implies. The capacity of each process is a results attribute, so no need to calculate it as such. Normally, storage capacity would represent the energy capacity. However, as described in the documentation, when using NCAP_AFC(output) for a storage process, the capacity then represents the nominal maximum output level, in power  terms, just like it does for power plant processes. And then, an availability factor defined for NCAP_AFC(ACT,SEASON) can be used for defining the available storage energy capacity, which for a seasonal storage would be simply VAR_CAP × PRC_CAPACT × NCAP_AFC(ACT,SEASON) (in gross terms). As you know, PRC_CAPACT is the conversion from the capacity unit to the activity unit, and the availability factor NCAP_AFC(ACT,SEASON) gives the assumed available energy capacity in proportion to that annual "full load" amount.

> - What does VAR_Act, VAR_Fin and VAR_Fout represent?

VAR_ACT represents the process activity, which for a storage processes is the energy stored in each timeslice. VAR_Fin represents the input flow into the storage, VAR_Fout represents the output flow from the storage (taking into account the STG_EFF). Therefore, VAR_Fin and VAR_Fout indeed represent the charging / discharging flows. Basically all energy flows in a TIMES model are in terms of energy (in each timeslice), and not power (unless you specifically implement user-defined conversions for representing power flows). Because of that, you can sum up the flows over timeslices to obtain total ANNUAL energy flows. But there is a reporting attribute for power flows (VAR_Pout).
Reply
#10
Thank you for the reply.
If the storage is DAYNITE (and not seasonal), does the same equation for converting the storage capacity to energy apply? If not, can you please write the equation also for DAYNITE storage?
Reply
#11
In the general case, you just need to divide by the number of cycles on the process tslvl level, over full year, i.e. G_CYCLE:

  ● energy capacity =  VAR_CAP × PRC_CAPACT    (when capacity is the max. amount of energy stored)
  ● energy capacity =  VAR_CAP × PRC_CAPACT × NCAP_AFC(ACT,tslvl) / G_CYCLE(tslvl)  (capacity is the nominal max. output level)

As a reminder, G_CYCLE(DAYNITE) is 365, while G_CYCLE(SEASON)=1.
Reply
#12
Hi again Antti,

We are still a bit puzzled by the results of storage processes, and hope you can help clarify it.
We are trying to model a seasonal hydrogen storage, using STS and Daynite declaration. The NCAP_AFC~Daynite = 1000/24 = 42, assuming a 1000h storage.

From our understanding, the STS declaration should allow the energy content of the storage to be transferred between days, meaning that the storage will not have to be 0 at the beginning and end of every daynite cycle. Attached is a screenshot of the VAR_ACT, VAR_Fin and VAR_FOut of the first (and partly second day) of the first month.
Should it not be the case that VAR_ACT(M01_D01) + SUM(VAR_Fin(M01_D01_H01-H24)) = VAR_ACT(M01_D02)? In our case, 11.90 + (0.79*24) = 30.86 (not 50.55).
Also, shouldn't the VAR_ACT(M01_D01_02) = VAR_ACT(M01_D01_01) + VAR_FIn(M01_D01_01= - VAR_FOut(M01_D01_01)? In our case, 1.48 + 0.79 = 2.27 (not 2.97).

Is there another declaration (other than STS + DAYNITE) that should be used to ensure that storage is balanced between daynite cycles?

In our case, we have the following timeslice definition:
SEASON = M01-M12
Weekly = D01-D30
Daynite = H01-H24


Attached Files Thumbnail(s)
   
Reply
#13
I assume that you are not using the STSFLX option, can you confirm?

Anyway, STS storages have in your case three storage components, DAYNITE, WEEKLY and SEASON, and the storage can charge and discharge the WEEKLY pool by exchanging with the DAYNITE pool as well as the SEASON pool.

> Should it not be the case that VAR_ACT(M01_D01) + SUM(VAR_Fin(M01_D01_H01-H24)) = VAR_ACT(M01_D02)? In our case, 11.90 + (0.79*24) = 30.86 (not 50.55).

I cannot see well what is going in the example you showed.  Can you provide the model input files for me to explain it to you?  I mean the files *.DD and *.RUN for the case in question? (Plus the listing file *.LST.)
Reply
#14
> Is there another declaration (other than STS + DAYNITE) that should be used to ensure that storage is balanced between daynite cycles?

It is an interesting question.  However, I think the balance of  STS storages below DAYNITE is pretty much in line with that, as follows:

* storage level in time-slice s
        SUM(RS_BELOW(R,ANNUAL,S),%VAR%_ACT(R,V,T,P,S%SOW%))
    =E=
* storage level in previous time-slice
        SUM(RS_BELOW(R,ANNUAL,SL(S--RS_STG(R,S))), %VAR%_ACT(R,V,T,P,SL%SOW%)
            +
* balancer flows
            (%VAR%_SOUT(R,V,T,P,%PGPRIM%,SL%SOW%) -
              SUM(PRC_TS(R,P,TS)$RS_BELOW1(R,TS,S),%VAR%_SOUT(R,V,T,P,%PGPRIM%,TS%SOW%)*RS_FR(R,SL,TS))


As you can see, in your case the storage level of each day would be equal to the storage level in the previous day plus the exchanges between the DAYNITE and SEASON pools (balancer flows).  Of course, as you pointed out, from your picture it is not so easy to see the balance, and that's why I would be curious to see what is going on there and explain it. Nonetheless, there is always the possibility of some kind of a bug as well (although I have not seen any problems myself or other reports of problems), and therefore it would also be valuable to check what is going on in your case.  Smile

But if you would, in fact, be able to formulate better balance equations for general storage in TIMES, that would also be a great contribution!
Reply
#15
Thanks for the files, it was good to verify what was going on there.

I could not see any issues with respect to the storage behavior, in terms of what is expected according to the design.  As mentioned, the general storage type STS allows storing energy on all levels: SEASON, WEEKLY and DAYNITE.  The storage capacity will of course limit long-time storage, and the capacity constraint also appears working as expected.

The storage is thus balanced between daynite cycles, taking into account any exchange between the pools.  In your example, the amount of storage in the SEASON pool was peaking at the beginning of January, but was being discharged to the WEEKLY pool during January, 19.684 GWh per day. Therefore, the storage in the WEEKLY pool at the beginning of M01_D02  was: 

VAR_ACT(M01_D02) =  VAR_ACT(M01_D01) + SUM(VAR_Fin(M01_D01_H01-H24)) + 19.684 = 11.90 + (0.79*24) + 19.684 =  50.55.

The exchange with the SEASON pool is included just to enable storage over seasons as well, which would not be possible without those exchanges.  However, I encourage you to propose any better formulation for general storage, if you have a good idea for an improved approach.

BTW: I noticed that you still use TIMES v4.6.6, which is two years old.  I ran your model with both that and with v4.8.3, and the latest version generated the model twice as fast compared to the older version (133 secs vs. 267 secs). The value of the objective function was identical. This relates to your earlier post: https://forum.kanors-emr.org/showthread.php?tid=1343
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Battery storage double check Ryo Ishida 4 608 24-10-2024, 09:31 AM
Last Post: Ryo Ishida
  Battery storage double check Ryo Ishida 0 209 15-10-2024, 06:16 PM
Last Post: Ryo Ishida
  NCAP_AFC and NCAP_AFA AngeBlanchard 23 13,435 10-10-2024, 05:31 AM
Last Post: [email protected]
  A quick question about hydrogen storage [email protected] 0 254 11-09-2024, 12:17 AM
Last Post: [email protected]
Lightbulb Battery/Storage, NCAP_AFCS for individual timeslices anik 2 593 17-07-2024, 05:10 PM
Last Post: anik
  The power storage [email protected] 0 521 15-05-2024, 11:30 PM
Last Post: [email protected]
  Capacity for storage frangb99 12 2,931 28-04-2024, 06:58 PM
Last Post: frangb99
  problem with kre storage frangb99 24 6,932 23-02-2024, 07:56 PM
Last Post: frangb99
  STORAGE MODELLING PROBLEM. frangb99 4 1,382 22-02-2024, 11:27 PM
Last Post: frangb99
  Load Shifting Storage Processes DOlih 12 10,337 18-11-2021, 12:19 AM
Last Post: DOlih

Forum Jump:


Users browsing this thread: 4 Guest(s)