#' Run a simulation for calculating water values for a specific area
#'
#' @param area The area concerned by the simulation.
#' @param simulation_name The name of the simulation, \code{s} is a placeholder for the constraint value defined by \code{nb_disc_stock}.
#' @param nb_disc_stock Number of simulation to launch, a vector of energy constraint
#' will be created from maximum pumping power to the hydro storage maximum and of length this parameter.
#' @param nb_mcyears Number of Monte Carlo years to simulate or a vector of years indexes to launch.
#' @param binding_constraint Name of the binding constraint.
# constraint_values Vector of energy constraints on the link between the area and the fictive area.
#' @param fictive_area Name of the fictive area to create, argument passed to \code{\link{setupWaterValuesSimulation}}.
#'
#' @param thermal_cluster Name of the thermal cluster to create, argument passed to \code{\link{setupWaterValuesSimulation}}.
#' @param path_solver Character containing the Antares Solver path, argument passed to \code{\link[antaresEditObject]{runSimulation}}.
#' @param wait Argument passed to \code{\link[antaresEditObject]{runSimulation}}.
#' @param show_output_on_console Argument passed to \code{\link[antaresEditObject]{runSimulation}}.
#' @param overwrite If area or cluster already exists, should they be overwritten?
#' @param link_from area that will be linked to the created fictive area. If it's
#' \code{NULL} it will takes the area concerned by the simulation.
#' @param otp_dest the path in which the script save Rdata file.
#' @param file_name the Rdata file name.
#' @param remove_areas Character vector of area(s) to remove from the created district.
#' @param shiny Boolean. True to run the script in shiny mod.
#' @param pumping Boolean. True to take into account the pumping.
#' @param efficiency in [0,1]. efficient ratio of pumping.
#' @param launch_simulations Boolean. True to to run the simulations.
#' @param reset_hydro Boolean. True to reset hydro inflow to 0 before the simulation.
#' @param opts
#' List of simulation parameters returned by the function
#' \code{antaresRead::setSimulationPath}
#' @param ... further arguments passed to or from other methods.
#' @param area area
#' @param simulation_name character
#' @param nb_disc_stock integer
#' @param nb_mcyears list
#' @param constraint_values constraint values to use to run simulations, generated by the function \code{\link{constraint_generator}}
#' @param binding_constraint character
#' @param expansion Binary. True if mode expansion was used to run simulations
#'
#' @note This function have side effects on the Antares study used, a fictive area is created and a new district as well.
#'
#' @export
#'
runWaterValuesSimulation <- function(area,
simulation_name = "wv_sim_%s",
nb_disc_stock = 10,
nb_mcyears = NULL,
binding_constraint = "weekly_water_amount",
fictive_area = NULL,
thermal_cluster = NULL,
path_solver=NULL,
wait = TRUE,
show_output_on_console = FALSE,
overwrite = FALSE,
link_from=NULL,
remove_areas=NULL,
opts = antaresRead::simOptions(),
shiny=F,otp_dest=NULL,file_name=NULL,
pumping=F,
efficiency=NULL,
launch_simulations=T,
reset_hydro=T,
constraint_values=NULL,
expansion=T,
...){
#check the study is well selected
assertthat::assert_that(class(opts) == "simOptions")
fictive_areas <- area
# check the name format
if(!endsWith(simulation_name,"_%s")){
simulation_name <- paste0(simulation_name,"_%s")
}
if (!stringr::str_detect(file_name,area)){
file_name <- paste0(area,"_",file_name)
}
# restore hydro inflow if there is a previous intercepted simulation.
restoreHydroStorage(area = area, opts = opts,silent = T)
# restore Pump power if there is a previous intercepted simulation.
restorePumpPower(area = area, opts = opts,silent = T)
restore_fictive_fatal_prod_demand(area = area, opts = opts,silent = T)
# MC years
assertthat::assert_that(is.numeric(nb_mcyears)==TRUE)
if(length(nb_mcyears)==1){
play_years <- seq(1,nb_mcyears)
}else{
play_years <- nb_mcyears
}
antaresEditObject::setPlaylist(playlist = play_years,opts = opts)
#assert the weekly output of the area:
antaresEditObject::editArea(name = area,
filtering =
antaresEditObject::filteringOptions(filter_synthesis = c("hourly" , "weekly", "annual"),
filter_year_by_year = c("hourly", "weekly", "annual"))
,opts = opts)
#generating the fictive area parameters
fictive_area <- if (!is.null(fictive_area)) fictive_area else paste0("watervalue_", area)
thermal_cluster <- if (!is.null(thermal_cluster)) thermal_cluster else "water_value_cluster"
# Get max hydro power that can be generated in a week
if (is.null(constraint_values)){
constraint_values <- constraint_generator(area=area,nb_disc_stock=nb_disc_stock,
pumping=pumping,
pumping_efficiency = efficiency,
opts=opts, mcyears=play_years)
}
if ("mcYear" %in% names(constraint_values)){
constraint_values <- constraint_values %>%
dplyr::filter(.data$mcYear %in% play_years, .data$week %in% 1:52)
} else {
constraint_values <- constraint_values %>%
dplyr::filter(.data$week %in% 1:52)
}
nb_disc_stock <- dplyr::n_distinct(constraint_values$sim)
# Get efficiency
if (is.null(efficiency)){
efficiency <- getPumpEfficiency(area = area)
}
#create the fictive areas
opts <- setupWaterValuesSimulation(
area = area,
fictive_area_name = fictive_area,
thermal_cluster = thermal_cluster,
overwrite = overwrite,
remove_areas=remove_areas,
reset_hydro=reset_hydro,
opts = opts,
link_from = link_from,
pumping=pumping,
max_load=max(abs(constraint_values$u))*10
)
#generate the flow sens
fictive_areas <- c(paste0(fictive_area,"_turb"),paste0(fictive_area,"_bc"))
coeff_turb <- generate_link_coeff(area,fictive_areas[1], pumping, opts)
coeff_bc <- generate_link_coeff(area,fictive_areas[2], pumping, opts)
coeff <- c(coeff_turb,coeff_bc)
if(pumping){
fictive_areas <- c(fictive_areas,paste0(fictive_area,"_pump"))
coeff_pump <- generate_link_coeff(area,fictive_areas[3], pumping, opts)
coeff <- c(coeff,coeff_pump)
}
restoreScenarioBuilder(opts=opts, fictive_area = fictive_areas[2])
# Start the simulations
simulation_names <- vector(mode = "character", length = nb_disc_stock)
# Implement binding constraint
generate_constraints(coeff=coeff,name_constraint=binding_constraint,
efficiency=efficiency,opts=opts,area = area)
for (i in 1:nb_disc_stock) {
# Prepare simulation parameters
name_sim <- dplyr::distinct(constraint_values,.data$sim)$sim[[i]]
constraint_value <- dplyr::filter(constraint_values,.data$sim==name_sim)
generate_rhs_bc(constraint_value=constraint_value,coeff=coeff,opts=opts)
sim_name <- paste0(file_name,"_",sprintf(simulation_name, format(
stringr::str_extract(name_sim, "\\d+$"), decimal.mark = ",")))
message("# ------------------------------------------------------------------------")
message(paste0("Running simulation: ", i, " - ", sim_name))
message("# ------------------------------------------------------------------------")
# run the simulation
if(launch_simulations){
antaresEditObject::runSimulation(
name = sim_name,
mode = if (!expansion){"economy"}else{"expansion"},
wait = wait,
path_solver = path_solver,
show_output_on_console = show_output_on_console,
opts = opts
)
}
simulation_names[i] <- sim_name
if(launch_simulations){
#Simulation Control
sim_name <- utils::tail(getSimulationNames(pattern =sim_name , opts = opts),n=1)
sim_check <- file.path(opts$studyPath,"output",sim_name)
if(!dir.exists(file.path(sim_check,"economy","mc-all"))){
#remove the Binding Constraints
disable_constraint(binding_constraint,opts,pumping,area = area)
restoreScenarioBuilder(opts=opts, fictive_area = fictive_areas[2])
# remove the fictive area
suppressWarnings({
for (fictive_area in fictive_areas){
antaresEditObject::removeArea(fictive_area,opts = opts)
}
})
# restore hydrostorage
restoreHydroStorage(area = area, opts = opts)
restorePumpPower(area = area, opts = opts)
restore_fictive_fatal_prod_demand(area = area, opts = opts)
stop("Simulation Error. Please check simulation log.")
}
}
}
#remove the Binding Constraints
disable_constraint(binding_constraint,opts,pumping,area = area)
restoreScenarioBuilder(opts=opts, fictive_area = fictive_areas[2])
# remove the fictive area
if(launch_simulations){
suppressWarnings({
for (fictive_area in fictive_areas){
antaresEditObject::removeArea(fictive_area,opts = opts)
}
})
}
# restore hydrostorage
restoreHydroStorage(area = area, opts = opts)
restorePumpPower(area = area, opts = opts)
restore_fictive_fatal_prod_demand(area = area, opts = opts)
simulation_res <- list(
simulation_names = simulation_names,
simulation_values = constraint_values,
area = area,
mc_years = nb_mcyears,
pumping = pumping,
eff = efficiency,
expansion = expansion,
fictive_areas = fictive_areas
)
if(!is.null(otp_dest)){
main_path <- getwd()
setwd(otp_dest)
save(simulation_res,file=paste0(file_name,".RData"))
setwd(main_path)
}
return(simulation_res)
}
#' Reset an Antares study. In case, there is a problem when executing \code{runWaterValuesSimulation},
#' run this function to restore the study.
#'
#' @param opts List of simulation parameters returned by the function
#' \code{antaresRead::setSimulationPath}
#' @param area The area concerned by the simulation
#' @param pumping Boolean. True to take into account the pumping.
#' @param fictive_area Name of the fictive area created
#' @param binding_constraint character
#'
#' @export
resetStudy <- function(opts, area, pumping,fictive_area = NULL,
binding_constraint="weekly_water_amount"){
fictive_area <- if (!is.null(fictive_area)) fictive_area else paste0("watervalue_", area)
disable_constraint(binding_constraint,opts,pumping,area = area)
fictive_areas <- c(paste0(fictive_area,"_turb"),paste0(fictive_area,"_bc"))
if(pumping){
fictive_areas <- c(fictive_areas,paste0(fictive_area,"_pump"))
}
restoreScenarioBuilder(opts=opts, fictive_area = fictive_areas[2])
for (fictive_area in fictive_areas){
if (fictive_area %in% opts$areaList){
antaresEditObject::removeArea(fictive_area,opts = opts)
}
}
# restore hydrostorage
restoreHydroStorage(area = area, opts = opts)
restorePumpPower(area = area, opts = opts)
restore_fictive_fatal_prod_demand(area = area, opts = opts)
}
#' Run a simulation for calculating water values for a specific area
#'
#' @param simulation_name The name of the simulation, \code{s} is a placeholder for the constraint value defined by \code{nb_disc_stock}.
#' @param nb_mcyears Number of Monte Carlo years to simulate or a vector of years indexes to launch.
#' @param binding_constraint Name of the binding constraint.
#' @param path_solver Character containing the Antares Solver path, argument passed to \code{\link[antaresEditObject]{runSimulation}}.
#' @param wait Argument passed to \code{\link[antaresEditObject]{runSimulation}}.
#' @param show_output_on_console Argument passed to \code{\link[antaresEditObject]{runSimulation}}.
#' @param overwrite If area or cluster already exists, should they be overwritten?
#' @param otp_dest the path in which the script save Rdata file.
#' @param file_name the Rdata file name.
#' @param shiny Boolean. True to run the script in shiny mod.
#' @param launch_simulations Boolean. True to to run the simulations.
#' @param reset_hydro Boolean. True to reset hydro inflow to 0 before the simulation.
#' @param opts
#' List of simulation parameters returned by the function
#' \code{antaresRead::setSimulationPath}
#' @param ... further arguments passed to or from other methods.
#' @param simulation_name character
#' @param nb_mcyears list
#' @param constraint_values constraint values to use to run simulations, generated by the function \code{\link{constraint_generator}}
#' @param binding_constraint character
#' @param list_areas List of areas concerned by the simulation.
#' @param list_pumping List of bools to tell if pumping is available in areas
#' @param list_efficiency List of pumping efficiency
#' @param expansion Binary. True if mode expansion was used to run simulations
#'
#' @note This function have side effects on the Antares study used, a fictive area is created and a new district as well.
#'
#' @export
#'
runWaterValuesSimulationMultiStock <- function(list_areas,
list_pumping,
list_efficiency,
simulation_name = "wv_sim_%s",
nb_mcyears = NULL,
binding_constraint = "weekly_water_amount",
path_solver=NULL,
wait = TRUE,
show_output_on_console = FALSE,
overwrite = FALSE,
opts = antaresRead::simOptions(),
shiny=F,otp_dest=NULL,file_name=NULL,
launch_simulations=T,
reset_hydro=T,
constraint_values=NULL,
expansion=T,...){
#check the study is well selected
assertthat::assert_that(class(opts) == "simOptions")
# check the name format
if(!endsWith(simulation_name,"_%s")){
simulation_name <- paste0(simulation_name,"_%s")
}
# MC years
assertthat::assert_that(is.numeric(nb_mcyears)==TRUE)
if(length(nb_mcyears)==1){
play_years <- seq(1,nb_mcyears)
}else{
play_years <- nb_mcyears
}
antaresEditObject::setPlaylist(playlist = play_years,opts = opts)
if ("mcYear" %in% names(constraint_values)){
constraint_values <- constraint_values %>%
dplyr::filter(.data$mcYear %in% play_years, .data$week %in% 1:52)
} else {
constraint_values <- constraint_values %>%
dplyr::filter(.data$week %in% 1:52)
}
nb_disc_stock <- dplyr::n_distinct(constraint_values$sim)
remove_area <- c()
list_coeff <- list()
for (area in list_areas){
# restore hydro inflow if there is a previous intercepted simulation.
restoreHydroStorage(area = area, opts = opts,silent = T)
# restore Pump power if there is a previous intercepted simulation.
restorePumpPower(area = area, opts = opts,silent = T)
restore_fictive_fatal_prod_demand(area = area, opts = opts,silent = T)
#assert the weekly output of the area:
antaresEditObject::editArea(name = area,
filtering =
antaresEditObject::filteringOptions(filter_synthesis = c("hourly" , "weekly", "annual"),
filter_year_by_year = c("hourly", "weekly", "annual"))
,opts = opts)
#generating the fictive area parameters
fictive_area <- paste0("watervalue_", area)
thermal_cluster <- "water_value_cluster"
#create the fictive areas
opts <- setupWaterValuesSimulation(
area = area,
fictive_area_name = fictive_area,
thermal_cluster = thermal_cluster,
overwrite = overwrite,
reset_hydro=reset_hydro,
opts = opts,
pumping=list_pumping[area],
max_load=max(abs(constraint_values$u))*10
)
#generate the flow sens
fictive_areas <- c(paste0(fictive_area,"_turb"),paste0(fictive_area,"_bc"))
coeff_turb <- generate_link_coeff(area,fictive_areas[1],list_pumping[area], opts)
coeff_bc <- generate_link_coeff(area,fictive_areas[2], list_pumping[area], opts)
coeff <- c(coeff_turb,coeff_bc)
if(list_pumping[area]){
fictive_areas <- c(fictive_areas,paste0(fictive_area,"_pump"))
coeff_pump <- generate_link_coeff(area,fictive_areas[3], list_pumping[area], opts)
coeff <- c(coeff,coeff_pump)
}
if (length(list_coeff)==0){
list_coeff <- list(coeff)
} else {
list_coeff <- c(list_coeff,list(coeff))
}
remove_area <- c(remove_area,fictive_areas)
restoreScenarioBuilder(opts=opts, fictive_area = fictive_areas[2])
# Implement binding constraint
generate_constraints(coeff=coeff,name_constraint=paste0(binding_constraint,"_",area),
efficiency=list_efficiency[area],opts=opts,area = area)
}
opts <- antaresEditObject::createDistrict(
name = "water values district",
caption = "water values district",
comments = "Used for calculate water values",
apply_filter = "add-all",
remove_area = remove_area,
output = TRUE,
overwrite = TRUE,
opts = opts
)
# Start the simulations
simulation_names <- vector(mode = "character", length = nb_disc_stock)
for (i in 1:nb_disc_stock) {
# Prepare simulation parameters
name_sim <- dplyr::distinct(constraint_values,.data$sim)$sim[[i]]
for (j in 1:length(list_areas)){
constraint_value <- dplyr::filter(constraint_values,.data$sim==name_sim,
.data$area==list_areas[[j]]) %>%
dplyr::select(-c("area"))
if (length(list_areas)==1){
coeff <- list_coeff
} else {
coeff <- list_coeff[[j]]
}
generate_rhs_bc(constraint_value=constraint_value,coeff=coeff,opts=opts)
}
sim_name <- paste0(file_name,"_",sprintf(simulation_name, format(
stringr::str_extract(name_sim, "\\d+$"), decimal.mark = ",")))
message("# ------------------------------------------------------------------------")
message(paste0("Running simulation: ", i, " - ", sim_name))
message("# ------------------------------------------------------------------------")
# run the simulation
if(launch_simulations){
antaresEditObject::runSimulation(
name = sim_name,
mode = if (!expansion){"economy"}else{"expansion"},
wait = wait,
path_solver = path_solver,
show_output_on_console = show_output_on_console,
opts = opts
)
}
simulation_names[i] <- sim_name
if(launch_simulations){
#Simulation Control
sim_name <- utils::tail(getSimulationNames(pattern =sim_name , opts = opts),n=1)
sim_check <- file.path(opts$studyPath,"output",sim_name)
if(!dir.exists(file.path(sim_check,"economy","mc-all"))){
#remove the Binding Constraints
for (j in 1:length(list_areas)){
area <- list_areas[[j]]
disable_constraint(paste0(binding_constraint,"_",area),opts,list_pumping[[j]],area = area)
restoreScenarioBuilder(opts=opts, fictive_area = paste0("watervalue_", area,"_bc"))
# restore hydrostorage
restoreHydroStorage(area = area, opts = opts)
restorePumpPower(area = area, opts = opts)
restore_fictive_fatal_prod_demand(area = area, opts = opts)
}
# remove the fictive area
suppressWarnings({
for (fictive_area in remove_area){
antaresEditObject::removeArea(fictive_area,opts = opts)
}
})
stop("Simulation Error. Please check simulation log.")
}
}
}
for (j in 1:length(list_areas)){
area <- list_areas[[j]]
disable_constraint(paste0(binding_constraint,"_",area),opts,list_pumping[[j]],area = area)
restoreScenarioBuilder(opts=opts, fictive_area = paste0("watervalue_", area,"_bc"))
# restore hydrostorage
restoreHydroStorage(area = area, opts = opts)
restorePumpPower(area = area, opts = opts)
restore_fictive_fatal_prod_demand(area = area, opts = opts)
}
# remove the fictive area
if(launch_simulations){
suppressWarnings({
for (fictive_area in remove_area){
antaresEditObject::removeArea(fictive_area,opts = opts)
}
})
}
simulation_res <- list(
simulation_names = simulation_names,
simulation_values = constraint_values,
list_areas = list_areas,
mc_years = nb_mcyears
)
if(!is.null(otp_dest)){
main_path <- getwd()
setwd(otp_dest)
save(simulation_res,file=paste0(file_name,".RData"))
setwd(main_path)
}
return(simulation_res)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.