I want to implement a battery system for a renewable plant of energy who feeds a machine. For example, The machine requires 1000 kw/h or the energy closest to that amount. If the energy generated exceeds 1000 kw/h, the surplus could be used to charge the battery, which, let's say, is 100 kw. If the energy produced is less than 1000 kw/h and there is energy in the battery, the energy from the battery should be used to power the machine. An example generated energy dataset could be the following:
data set energia
Path | Hour 1 | Hour 2 | Hour 3 | Hour 4 | Hour 5 | Hour 6 | ... | Hour 8760 |
---|---|---|---|---|---|---|---|---|
1 | 950,0 | 947,1 | 982,4 | 1013,5 | 1003,0 | 1087,7 | ... | |
2 | 1046,9 | 947,9 | 981,9 | 1031,9 | 984,8 | 931,8 | ... | |
3 | 996,1 | 1031,0 | 978,8 | 972,7 | 826,8 | 952,0 | ... | |
4 | 943,4 | 1015,2 | 1007,2 | 994,8 | 1017,4 | 979,8 | ... |
Where should I obtain a new energy and battery charge level data set as follows:
data set Bateria
Path | Hour 1 | Hour 2 | Hour 3 | Hour 4 | Hour 5 | Hour 6 |
---|---|---|---|---|---|---|
1 | 0,0 | 0,0 | 0,0 | 13,5 | 16,5 | 100,0 |
2 | 46,9 | 0,0 | 0,0 | 31,9 | 16,7 | 0,0 |
3 | 0,0 | 31,0 | 9,8 | 0,0 | 0,0 | 0,0 |
4 | 0,0 | 15,2 | 22,3 | 17,2 | 34,6 | 14,4 |
New data set Energia
Path | Hour 1 | Hour 2 | Hour 3 | Hour 4 | Hour 5 | Hour 6 |
---|---|---|---|---|---|---|
1 | 950,0 | 947,1 | 982,4 | 1013,5 | 1003,0 | 1087,7 |
2 | 1046,9 | 994,8 | 981,9 | 1031,9 | 1000,0 | 948,5 |
3 | 996,1 | 1031,0 | 1000,0 | 982,5 | 826,8 | 952,0 |
4 | 943,4 | 1015,2 | 1007,2 | 1000,0 | 1017,4 | 1000,0 |
I am doing the simulation for-loop each of the hours in 1 year (8760) with a thousand possible paths of energy generation values. I am currently making a for for each column where I check the conditions (ther is more conditions), the code is the next:
carga_bateria<- data.frame(matrix(0, nrow = 1040, ncol = 8760))
for (i in 2:8760) {
cond1<-energia[,i]>pot_elec
carga_bateria[cond1,i]=carga_bateria[cond1,i-1]*(1-0.02/100)+pmin(n_bat*7.55-carga_bateria[cond1,i-1]*(1-0.02/100),(energia[cond1,i]-pot_elec)*0.85)
# si la energia generada es mayor a la necsitada entonces la bateria queda con la carga anterior con la perdida de 0.02% + el minimo entre
#la bateria que hace falta y el excedente generado incluyendo la perdida de eficiencia al cargar de 85%.
cond2<-(energia[,i]+pmax(carga_bateria[,i-1]*(1-0.02/100)-n_bat*7.55*0.2,0))<pot_elec*0.3#cuando ni incluyendo la bateria en t-1 llega al 30% de la capacidad del electrolizador, entonces tambien se carga bateria
carga_bateria[cond2,i]=carga_bateria[cond2,i-1]*(1-0.02/100)+pmin(n_bat*7.55-carga_bateria[cond2,i-1]*(1-0.02/100),(energia[cond2,i])*0.85)
cond3<- pot_elec>energia[,i]&(pot_elec-energia[,i])<(carga_bateria[,i-1]*(1-0.02/100)-n_bat*7.55*0.2)#Caso desacarga parcial bateria, si el faltante lo puede cubrir la bateria
carga_bateria[cond3,i]=carga_bateria[cond3,i-1]*(1-0.02/100)-(pot_elec-energia[cond3,i]) #la bateria se descargaga en ese faltante
energia[cond3,i]<- pot_elec #la energia llega a la capacidad
cond4<- (energia[,i]+pmax(carga_bateria[,i-1]*(1-0.02/100)-n_bat*7.55*0.2,0))>pot_elec*0.3&(energia[,i]+pmax(carga_bateria[,i-1]*(1-0.02/100)-n_bat*7.55*0.2,0))<pot_elec# caso de descarga total
carga_bateria[cond4,i]= n_bat*7.55*0.2#la bateria se descargaga totalmente
energia[cond4,i]<- energia[cond4,i]+(carga_bateria[cond4,i-1]*(1-0.02/100)-n_bat*7.55*0.2) #la energia llega a la capacidad
cond99<-!cond1&!cond2&!cond3&!cond4
carga_bateria[cond99,i]=carga_bateria[cond99,i-1]*(1-0.02/100)
validacion[1,i]<-sum(cond1);validacion[2,i]<-sum(cond2);validacion[3,i]<-sum(cond3);validacion[4,i]<-sum(cond4)
validacion[5,i]<- sum(cond1,cond2,cond3,cond4)
}
but I want to make the process as efficient as possible. I would believe that parallelization is not an option since the analysis is sequential and conditional, although I don't know.
Vectorizing what we can. Additional speed would probably have to come from Rcpp
.
Example data:
energia <- matrix(rnorm(876e4, 1e3, 20), 1e3)
Process:
system.time({
Bateria <- array(0, dim(energia))
Energia <- energia - 1e3
Bateria[,1] <- pmax(pmin(Energia[,1], 100), 0)
for (i in 2:ncol(energia)) {
Bateria[,i] <- pmax(pmin(Bateria[,i - 1] + Energia[,i], 100), 0)
}
Energia[,1] <- energia[,1]
Energia[,-1] <- energia[,-1] - pmin(0, Rfast::coldiffs(Bateria))
})
#> user system elapsed
#> 0.49 0.15 0.62
Resulting in
energia[1:10, 1:7]
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 1020.3650 973.7161 1012.1916 1011.4977 1003.0202 999.4796 1036.0359
#> [2,] 1029.7795 988.7669 994.9009 958.9296 995.9292 958.8030 983.2274
#> [3,] 977.9996 1000.7481 995.8109 972.9857 990.2269 1000.8311 992.5563
#> [4,] 1003.8806 998.7856 985.7410 1015.4744 1023.4497 1001.2701 1017.1896
#> [5,] 1013.1368 1035.9297 998.8231 990.3747 1013.2639 983.5665 1000.1635
#> [6,] 1011.3533 1021.4186 1012.0547 988.0986 982.9560 1045.1527 972.7560
#> [7,] 994.0441 997.9712 996.2793 983.3372 954.3548 998.1092 1005.5494
#> [8,] 970.3797 1005.9268 1033.7725 1008.7859 1015.1895 1037.7978 986.7629
#> [9,] 966.4012 999.3218 998.5642 977.3220 1018.2797 1007.8780 1009.1757
#> [10,] 1038.1993 1002.0838 1002.3877 1001.0923 975.2968 930.2707 1002.9185
Bateria[1:10, 1:7]
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 20.36501 0.0000000 12.19160 23.68929 26.70945 26.1890759 62.225017
#> [2,] 29.77954 18.5464758 13.44736 0.00000 0.00000 0.0000000 0.000000
#> [3,] 0.00000 0.7481351 0.00000 0.00000 0.00000 0.8311082 0.000000
#> [4,] 3.88059 2.6661657 0.00000 15.47445 38.92413 40.1942133 57.383772
#> [5,] 13.13683 49.0665635 47.88970 38.26436 51.52831 35.0948033 35.258318
#> [6,] 11.35329 32.7718892 44.82658 32.92519 15.88119 61.0338416 33.789819
#> [7,] 0.00000 0.0000000 0.00000 0.00000 0.00000 0.0000000 5.549418
#> [8,] 0.00000 5.9267888 39.69932 48.48522 63.67473 100.0000000 86.762890
#> [9,] 0.00000 0.0000000 0.00000 0.00000 18.27970 26.1576981 35.333428
#> [10,] 38.19931 40.2830995 42.67077 43.76306 19.05989 0.0000000 2.918507
Energia[1:10, 1:7]
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 1020.3650 994.0811 1012.1916 1011.4977 1003.0202 1000.0000 1036.0359
#> [2,] 1029.7795 1000.0000 1000.0000 972.3769 995.9292 958.8030 983.2274
#> [3,] 977.9996 1000.7481 996.5590 972.9857 990.2269 1000.8311 993.3874
#> [4,] 1003.8806 1000.0000 988.4071 1015.4744 1023.4497 1001.2701 1017.1896
#> [5,] 1013.1368 1035.9297 1000.0000 1000.0000 1013.2639 1000.0000 1000.1635
#> [6,] 1011.3533 1021.4186 1012.0547 1000.0000 1000.0000 1045.1527 1000.0000
#> [7,] 994.0441 997.9712 996.2793 983.3372 954.3548 998.1092 1005.5494
#> [8,] 970.3797 1005.9268 1033.7725 1008.7859 1015.1895 1037.7978 1000.0000
#> [9,] 966.4012 999.3218 998.5642 977.3220 1018.2797 1007.8780 1009.1757
#> [10,] 1038.1993 1002.0838 1002.3877 1001.0923 1000.0000 949.3306 1002.9185