Result <- list(par = e$FarmVars$BenchmarkSolution)
Profile1 <- rep(1, times = 20)
#Will be identical to Profit(Result$par):
SwitchProfile(Profile1, Result)
Profile2 <- Profile1
Profile2[8] <- 0 #Disable turbine 8.
#Returns farm profit if turbine 8 is off:
SwitchProfile(Profile2, Result)
##########################################
#Warning, this will overwrite e$FarmData. If not dispensable,
#backup before use.
#Computation may be slow.
if (FALSE) {
Result <- list(par = e$FarmVars$BenchmarkSolution)
e$FarmData <- FarmData
n <- length(e$FarmVars$BenchmarkSolution) / 2
Profiles <- matrix(ncol = n, nrow = 360)
Dom <- cbind(rep(0, n), rep(1, n))
for (j in 1:360)
{
e$FarmData$WindDirection <- matrix(data = j, ncol = e$FarmVars$Width,
nrow = e$FarmVars$Width)
message(paste("Processing wind direction: ", j, " degrees.", sep = ""))
flush.console()
Result <- rgenoud::genoud(fn = SwitchProfile, nvars = n, starting.values = runif(n),
Domains = Dom, boundary.enforcement = 2, MemoryMatrix = FALSE, print.level = 0,
Result = Result)
On <- Result$par
On[On < 0.5] <- 0
On[On >= 0.5] <- 1
Profiles[j, ] <- On
}
#Now 'Profiles' is a matrix of 360 rows (degrees) and n columns.
#If the setup is robust against wind direction changes, all values
#in the columns should be ones. If there are zeros left, double
#check these profiles (compare to full turbines setup) manually,
#e.g. using
for (i in 1:nrow(Profiles))
{
if (any(Profiles[i, ] == 0))
{
e$FarmData$WindDirection <- matrix(data = i,
ncol = e$FarmVars$Width, nrow = e$FarmVars$Width)
print(paste("Is unrestricted profit (",
abs(Profit(e$FarmVars$BenchmarkSolution)), ") still
greater than 'profile profit' (",
abs(SwitchProfile(Profiles[i, ], Result)), ")? ",
abs(Profit(e$FarmVars$BenchmarkSolution)) >=
abs(SwitchProfile(Profiles[i, ], Result)), ".", sep = ""))
}
}
#Is absolute profile profit actually greater than the absolute value
#function Profit() returns? If yes, then it is beneficial to turn off
#turbines (use profiles) if wind comes from the given angle.
}
##########################################
#As an alternative to using an optimizer to find the optimal profile,
#all possible profiles can be 'looped through' deterministically using
#the following few lines of code.
#Warning, this will overwrite e$FarmData. If not dispensable,
#backup before use.
#Be advised, computation may be very slow, even if run on modern
#machines and even though using parallelization.
if (FALSE) {
Result <- list(par = e$FarmVars$BenchmarkSolution)
e$FarmData <- FarmData
ComputeProfile <- function(i)
{
e$FarmData$WindDirection <- matrix(data = i, ncol = e$FarmVars$Width,
nrow = e$FarmVars$Width)
BestProfit <- n * e$FarmVars$UnitCost
BestProfile <- rep(0, n)
for (j in 0:MaxNum)
{
ThisProfile <- as.numeric(rev(intToBits(j)))[(32 - (n - 1)):32]
if (length(which(ThisProfile == 1)) > 1)
{
ThisProfit <- SwitchProfile(ThisProfile, Result)
} else
{
ThisProfit <- n * e$FarmVars$UnitCost
}
if (ThisProfit < BestProfit)
{
BestProfit <- ThisProfit
BestProfile <- ThisProfile
}
}
return(BestProfile)
}
n <- length(e$FarmVars$BenchmarkSolution) / 2
MaxNum <- (2 ^ n) - 1
NumCores <- parallel::detectCores() - 1
cl <- snow::makeCluster(NumCores)
ParallelProfile <- new.env()
ParallelProfile$FarmVars <- e$FarmVars
ParallelProfile$FarmData <- e$FarmData
snow::clusterExport(cl, list = ls())
snow::clusterExport(cl, list = ls(envir = as.environment("package:wflo")))
doSNOW::registerDoSNOW(cl)
iterations <- 360
pb <- txtProgressBar(max = iterations, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)
`%dopar%` <- foreach::`%dopar%`
AllProfiles <- foreach::foreach(i = 1:iterations,
.options.snow = opts) %dopar% ComputeProfile(i)
close(pb)
snow::stopCluster(cl)
}
#Afterward, check the resulting list of profiles for remaining zeros as above.
##########################################
#Thinking the thought of wind direction dependent layouts further,
#Profit() can be used to optimize a farm setup that takes all wind
#direction wake patterns into account during the optimization
#stage already.
#Warning, this will overwrite \code{e$FarmData}. If not dispensable,
#backup before use.
#Computation may be slow.
if (FALSE) {
e$FarmData <- FarmData
SumProfit <- function(X)
{
MySum <- as.numeric()
for (i in 1:360)
{
e$FarmData$WindDirection <- matrix(data = i, ncol = e$FarmVars$Width,
nrow = e$FarmVars$Width)
MySum[i] <- Profit(X)
}
MySum <- sum(MySum)
return(MySum)
}
n <- 20
Dom <- cbind(rep(0, 2 * n), rep(1, 2 * n))
Result <- rgenoud::genoud(fn = SumProfit, nvars = 2 * n, starting.values = runif(2 * n),
Domains = Dom, boundary.enforcement = 2, MemoryMatrix = FALSE, print.level = 1)
}
Run the code above in your browser using DataLab