0% found this document useful (0 votes)
6 views

Assignment-3 Example

Uploaded by

Danny Zaeem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Assignment-3 Example

Uploaded by

Danny Zaeem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Life-Cycle Assessment – Group Project Assignment 3

Life-Cycle Assessment

Group Project Assignment 3

Maintenance Planning of Integrated Systems

and

Multi-Objective Optimization

A Bridge Example
studentsupport@civilsystems.tu-berlin.de

When designing high performing civil systems, engineers are facing several challenges. One very
actual challenge is related to the intricate relationships between civil systems and another one which
the engineers faced since the beginning of the civil engineering field is related to design optimization.
Keeping the first challenge in mind, one important aspect is related to maintenance planning. The
assumed interventions during life cycle and their frequency impact the use of the other influenced
systems. In the end, this become a multi-objective optimization problem when the engineers aim to
optimize a design function based on specific objectives defined as the performance criteria at the
beginning of the project.

This document provides you with a step by step tutorial to show how to implement such analyses in
R. Moreover, we will also look at the available R implementations of the optimization algorithms to
support and informed decision making process.

This tutorial is structured as follow:


1. Engineering high performing products
2. Prerequisite – supporting tools
3. Integrated Maintenance Planning
4. Life Cycle Inventory and Analysis of Integrated Civil Systems
5. Multi-Objective Optimization
1. Engineering high performing products
The integration context we are going to explore in this tutorial contains the bridge we explored during
the second assignment and the road which provides access to the bridge. In this context, the main
assumptions are that the deterioration rate of the bridge is higher than the deterioration rate of the
road. By this, the interventions we assume for the bridge such as Maintenance (M) partial replacement
(SDO) and deck replacement (DR) will have a higher occurrence frequency compared to the ones we
assumed for the road. One first challenge the engineers need to solve is related to the alignment of
the maintenance strategies.

In our context, a measure of high performance for our integrated system is represented by the product
availability. To quantify this measure as an objective for optimization problems, we will use the total
duration of the interruptions as indicator. Mathematically formalized, minimize D(x) = {d1(x) +
d2(x) + d3(x)+...+dk(x)}

Another measure of high performance we consider regarding the maintenance planning is the distance
between two successive interventions . Defined as objective, we want to maximize it.

page1
Life-Cycle Assessment – Group Project Assignment 3
maximize d(x), where d(x) is the function of minimum distance between two successive
interventions.

In term of life cycle analysis, the performance indicators are the minimized impact on the
environment, quantified by different levels of energy consumption, greenhouse gases emissions and
the costs associated with these.

page2
Life-Cycle Assessment – Group Project Assignment 3
2. Prerequisite – supporting tools
As a first step, you need to start by installing R and RStudio. To do this, visit the ISIS page of the
course, where you will find several resources under the section R Introduction.

Go to https://cran.r-project.org/ and download the R distribution suitable for your system. Use the
downloaded installer to install R on your machine.

Go to https://www.rstudio.com/products/rstudio/ and download the RStudio distribution suitable for


your system. Use the downloaded installer to install RStudio on your machine.

Start RStudio and on console run the following commands to install the required packages we are
going to used through this tutorial:
> install.packages(“timelineS“)
>install.packages(“lubridate”)
> install.packages(“ggplot2")
> install.packages(“dplyr")
> install.packages(“reshape2")
> install.packages(“rPref”)
> install.packages(“mco”)
> install.packages(“MASS”)

The packages in light gray where used also during the second assignment. If you are using the same
machine/computer, you don’t need to install these again.
Please note that these commands need to be run only once on your machine, and you will be able to
use the packages every time you need. Do no include these on your R-Script, as it is not necessary to
run these commands every time as the script.
To get started with the next part, please got to the main menu File → New File → R Script to start
a new script. The shortcut for this is represented by the following combination of keys:
Ctrl+Shift+N.
On the new appeared window, right on top, write the following code line:

rm (list = ls())

Every time when you run your script, this command will clean your environment. By this, you make
sure that you cannot use any of the variables you created previously and the environment is clean,
allowing you to use only the data and variables you initialize with your current script.

Make sure that you save your newly created file. By this you will be able to open it later. Go to File
→ Save As and choose a name for your file, as well a location were you want to save it and to access

page3
Life-Cycle Assessment – Group Project Assignment 3
it later. You will have to do this only once, and later on, as you are working and adding more code
lines to your file, you can use File → Save of the shortcut Ctrl+S to save your progress. Make sure
that you save your script file on a regular basis, in order to avoid possible data loss.

In order to use the packages you previously installed, please add the following lines of code to your
script:

library(timelineS)
library(lubridate)
library(ggplot2)
library(dplyr)
library(reshape2)
library(rPref)
library(mco)
library(MASS)

By using the above presented commands, we specify that we want to use that specific library for the
script we develop.

At this point, we are ready to start with the next part of our assignment.

page4
Life-Cycle Assessment – Group Project Assignment 3
3. Integrated Maintenance Planning
Use the same functions which created during the second assignment: plot.timeline() and
dist.events(). Below you will find both functions.

plot.timeline <- function(lifetime, events.name, start.Date, plot.Name) {


dataP <- data.frame(Events = events.name, Event_Dates = ymd(start.Date) +
years(lifetime))
timelineS(dataP, main = plot.Name,
labels = events.name, label.direction = "up", label.position = 3)
}
dist.Events <- function (lifetime, events, start.Date, option.Name) {
#sort the events
events <- sort(events, decreasing = T)
#create the distribution of the events
distribution.events <- sapply(events, seq, from = 0, to =
lifetime)
#all events unlisted
all.events <- melt(distribution.events)
colnames(all.events) <- c("frequency", "event")
#sort the events ascending
all.events <- all.events[order(all.events$frequency),]
#get the unique sequence of events
unique.events <- all.events[!duplicated(all.events$frequency),]
unique.events$event[which(unique.events$frequency == 0)] <- "DC"
#plot the timeline
#plot.timeline(unique.events$frequency, unique.events$event, start.Date,
option.Name) return(unique.events)
}
Please notice that inside dist.Events() function the plot of the timelines is commented. We do this in
order to avoid issues for future searches of the design space.
Next, we will define a function which will help us combine the life cycle timelines of two civil
engineered systems, to identify how these overlap.

combine.lifeTimelines <- function(product.1, product.2, p1.dur, p2.dur) {


#function body
}

We continue with developing the body of the function. As a first step, define the vector which will
contain the results by writing the following line of code.

base <- list(Names = c(), frequency = c(), duration = c())

Similar to the previous assignment, we will take the lifetime distribution of both products and we will
combine these in a list containing unique values.

base$frequency <- sort(unique(c(product.1$frequency,


product.2$frequency)), decreasing =
FALSE)

For both products we assume the same starting data, as well as, the same lifetime. The following lines
of code initialize and name the beginning and the end of the combine sequence, for which we consider
that the duration of the interventions is 0. This means that we do not take into account the construction
time, as well as, the time needed to dismantle/demolish the product.

page5
Life-Cycle Assessment – Group Project Assignment 3
base$Names[1] <- "DC"
base$duration[1] <- 0
base$Names[length(base$frequency)] <- "END"
base$duration[length(base$frequency)] <- 0
As a next step, we iterate over the combined list, and using if() - else() statements we will add the
right names for each phase based on the values we have in the unique list of events. To do this, add
the following lines of code.
for(index in 2:(length(base$frequency) - 1)) {
phase.1 <- product.1$event[which(product.1$frequency ==
base$frequency[index])] phase.2 <-
product.2$event[which(product.2$frequency ==
base$frequency[index])] if(length(phase.1) != 0 && length(phase.2)
!= 0) { base$Names[index] <- paste(phase.1, phase.2)
base$duration[index] <- max(p1.dur[which(names(p1.dur) == phase.1)],
p2.dur[which(names(p2.dur) == phase.2)])
} else if(length(phase.1) != 0 && length(phase.2) == 0) {
base$Names[index] <- phase.1
base$duration[index] <- p1.dur[which(names(p1.dur) == phase.1)]
} else if (length(phase.1) == 0 && length(phase.2) != 0) {
base$Names[index] <- phase.2
base$duration[index] <- p2.dur[which(names(p2.dur) == phase.2)]
} else {
base$duration[index] <- 0
}
}
return(base)

Once we finish the function, we can define the information we need for the life cycle timelines of the
two products. Similar to the previous assignment, we will need to define the start date – start.Date -
, the duration for the lifetime we assume for our products – lifetime – and, the interventions and their
frequency. Please keep in mind that the frequency of each intervention is defined in years. c(SDO.r
par(mfrow = c(2, 1))
start.Date = "2020-01-01"
lifetime <- 70
events.Op1.Bridge = c(SDO = 15, M = 5, DR = 30, END = lifetime)
Additionally, we will define the information about the duration of each specific intervention. We will
keep the same names for the sake of simplicity, as well as, to automate some of the tasks. In this case,
we define the duration of the intervention in days.

duration.ev.Bridge <- c(SDO = 7, M = 2, DR = 21)

Similarly, we define the interventions and the duration of the interventions for the road.

events.Op1.Road <- c(SDO.r = 17, M.r = 7, R.r = 35, END = lifetime)


duration.ev.Road <- c(SDO.r = 7, M.r = 2, R.r = 21)

As you notice, we used different names for the interventions, because we want to be able to identify
in our results to interventions on the bridge and the intervention on the road. Next, we will add the
name of the design options, similarly to the previous assignment.
design.Options.Bridge <- list(desing.Op1 <- "1.Cast in place deck and concrete prefab girders")
design.Options.Road <- list(desing.Op1.Road <- "Road")

page6
Life-Cycle Assessment – Group Project Assignment 3
Now that we have the information we need, we will first call the function dist.Events() to generate
the distribution of the interventions over the lifetime. To do this, add the following lines of code.
design.Options.Bridge <- list(desing.Op1.Bridge <- "1.Cast in place deck and concrete prefab
girders") maintenance.Road <- dist.Events(lifetime, events.Op1.Road, start.Date,
design.Options.Road)

With the two lines of code presented above, we get the graphical representation of the timelines
presented bellow.

In order to combine both timelines, call the function combine.lifeTimelines() using the following
line of code.

integrated.interv <- combine.lifeTimelines(maintenance.Bridge, maintenance.Road,


duration.ev.Bridge, duration.ev.Road)

At this point, we can analyze the total duration of the interruptions, using the following line of code.

sum(integrated.interv$duration)

This generates the following output.


> sum(integrated.interv$duration)
[1] 137

Based on the defined planning strategy, we currently have a total of 137 days interruptions for 70
years lifetime.
Let’s implement another maintenance strategy. Add the following lines of code to your script.

page7
Life-Cycle Assessment – Group Project Assignment 3
events.Op1.Bridge = c(SDO = 15, M = 5, DR = 30, END = lifetime)
duration.ev.Bridge <- c(SDO = 7, M = 2, DR = 21)
events.Op1.Road <- c(SDO.r = 15, M.r = 6, R.r = 30, END = lifetime)
duration.ev.Road <- c(SDO.r = 7, M.r = 2, R.r = 21)
design.Options.Bridge <- list(desing.Op1.Bridge <- "1.Cast in place deck and concrete
prefab girders")
design.Options.Road <- list(desing.Op1.Road <- "Road")
maintenance.Bridge <- dist.Events(lifetime, events.Op1.Bridge, start.Date,
design.Options.Bridge)
maintenance.Road <- dist.Events(lifetime, events.Op1.Road, start.Date,
design.Options.Road)
integrated.interv <- combine.lifeTimelines(maintenance.Bridge, maintenance.Road,
duration.ev.Bridge, duration.ev.Road) sum(integrated.interv$duration)

As expected, due to high overlap of the maintenance strategies, the numbers of days of interruptions
is smaller than previously. In this last case we have got a total of 92 days of interruptions. In practice,
aligning the maintenance strategies of different civil systems, subsystems and components is one
challenge the engineers need to face.

In order to explore more scenarios, we will create a function to automate this exploration. To do this,
add the following lines of codes.
design.explore <- function(events1, events2) {
results <- c()
for(i in 1: dim(events1)[1]) {
ev1 <- unlist(events1[i, ])
dist.1 <- dist.Events(lifetime, ev1, start.Date, desing.Op1)
dur.ev1 <- ev1/2
for (j in 1: dim(events1)[1]) {
ev2 <- unlist(events2[j, ])
dist.2 <- dist.Events(lifetime, ev2, start.Date, design.Options.Road)
dur.ev2 <- ev2/2
combined.lifetime <- combine.lifeTimelines(dist.1, dist.2,
dur.ev1, dur.ev2)
min.dist.int <- min(abs(combined.lifetime$frequency[1:(length(combined.lifetime$frequency) - 1)]
combined.lifetime$frequency[2:length(combined.lifetime$frequency)]))
results <- rbind(results, c(ev1, ev2, dur = sum(combined.lifetime$duration), dist.inter = min.dist.int))
} }
return(as.data.frame(results))
}

The function logic works as follows. It accepts two matrices as input, containing different
maintenance scenarios. events1 is the matrix containing the possible scenarios for the first civil
system, in our case the bridge, where events2 is the matrix that contains different maintenance
strategies. The function iterates through all the scenarios available for each product and it runs the
simulations. The results returned contains the two options analyzed, as well as total duration of the
interruptions.

Now that we have the function, we will generate the scenarios space. To do this, we will create first
a parameter which will allow us to control how the parameters will vary.
n.grid <- 5

Next, we will use the expand.grid() function to generate the options. We define the ranges for our
intervention scenarios, as follow:
• for the bridge interventions
◦ 10 >= SDO <= 20
◦ 3 >= M <= 8
◦ 20 >= DR <= 35
• for the road interventions
page8
Life-Cycle Assessment – Group Project Assignment 3
◦ 12 >= SDO.r <= 25
◦ 5 >= M.r <= 10
◦ 27 >= R.r <= 37

The following lines of code will generate the intervention matrix scenarios for the bridge.
events.grid.bridge <- expand.grid(SDO = sample(seq(10,20, by = 1), n.grid),
M = sample(seq(3,8,1), n.grid),
DR = sample(seq(20, 35, 1), n.grid))

As a fist step, we generate the design space for each variable which is a sequence of numbers within
the interval [min, max]. Then, we use the function sample(x, n) to get a number of n random samples
from the x vector, in our case the generated sequence. expand.grid() will take the values of each
variable, and will combine these into a matrix, making sure that the all possible combinations are
covered.

Next, we defined a similar design space matrix for the road, using the following line of code.
events.grid.road <- expand.grid(SDO.r = sample(seq(12, 25, by = 1), n.grid),
M.r = sample(seq(5,10,1), n.grid),
R.r = sample(seq(27, 37, 1), n.grid))

Using these two matrices we created, we call the function design.explore() using the following line
of code.
response.space <- design.explore(events.grid.bridge, events.grid.road)

We can now visualize and select the maxima based on specific preferences using rPref package. To
do this, we use low() and high() functions provided by rPref package. Our preference is to minimize
the duration of the interruptions and to maximize the distance between interventions. We can define
this preference using the following line of code. As pointed out in the beginning, we want to minimize
the total duration of interruptions. For this we will use low() function. Also, we want to maximize the
distance between two successive interruptions. For this we will use the function high().
p <- low(dur)* high(dist.inter)

Using psel() function now we can evaluate the preference we define and to select that alternative
which is the best for our preference. In order to do this, we will add the following line of code.
sky <- psel(response.space, p)

Typing sky in the console, will provide the design option which is the best.
> sky
SDO M DR SDO.r M.r R.r dur dist.inter
3648 16 8 29 16 8 29 69 2
13123 16 8 20 16 8 32 74 4
We can also get all the alternatives ranked. To do this, we will add the following line of code.
pareto2 <- psel(response.space, p, top = nrow(response.space))

We can easily visualize the way our options were classified by using the following line of code.

page9
Life-Cycle Assessment – Group Project Assignment 3
ggplot(response.space, aes(x = dur, y = dist.inter)) +
geom_point(shape = 21) +
geom_point(data = pareto2, size = 3, aes(color = factor(pareto2$.level)))
The result is as shown in figure below. In this figure the alternatives we explored are ranked based on
the defined preference. These are presented as 151 groups.. We know the color of the highest rated
alternatives, but at this point it is difficult to identify these. A good way to improve the graphical
representation is to make use of Pareto Frontier.

We can easily create a small function in order to find the Pareto frontier for different preferences.
You can use the following wikipedia page to read more about Pareto frontier.
https://en.wikipedia.org/wiki/Pareto_efficiency
show_front <- function(pref) {
plot(response.space$dur, response.space$dist.inter)
sky <- psel(response.space, pref)
plot_front(response.space, pref, col = rgb(0, 0, 1))
points(sky$dur, sky$dist.inter, lwd = 3) }

To visualize the Pareto frontier of out preference p add the following line of code.
show_front(p)

The graph plotted looks like the figure bellow. The blue line represented the Pareto frontier, where
the dark black point in the top-left corner represent the best alternative based on the defined
preferences.

page10
Life-Cycle Assessment – Group Project Assignment 3

Now, we can easily simulate different alternatives for preferences, as shown bellow. Again, we can
see that based on the new defined preference, we have a new pareto frontier, as well as, a new best
design option.
p <- high(dur) * low(dist.inter)
show_front(p)

This method is good at ranking the results we obtain, but is just a ranking method based on predefined
preferences. Later, in section 5, we will explore the idea of multi objective optimizations, using
algorithms, which based on predefined design space will automatically look for optimal solutions.
1. Life Cycle Inventory and Analysis of Integrated Civil Systems
For the life cycle analysis, we will update the model we developed in the previous assignment. Some
parts will be simplified as we will consider only one solution for the bridge deck. Also, we will update
the model in order to take into account the second civil system we considered: the road.

We keep the same the life cycle inventory we create during the previous assignment.
LCI.materials <- read.csv("LCImaterials.csv")

page11
Life-Cycle Assessment – Group Project Assignment 3
We will update the function we created previously, to remove the options which we are no longer
going to be used, as well as to consider the impact of the interventions based on their distribution over
lifetime. In order to make it easily to identify the updates, these are indicated with black.
LCA.bridge <- function(length, width, height, thickness, girder.Option,
deck.Option, materials, dist.event) { prefab.girder.Section <- 0.78
asphalt.Q <- length * width * thickness
#based on the use of each material, we will split the data frame
materials.split <- split(materials, materials$scope)

#new line to get the interventions s


<- summary(as.factor(dist.event$event))
s2 <- as.data.frame(rbind(Freq = s), stringsAsFactors=F, row.names =
1:length(s))
# calculate the volume of the deck based on different materials strategies
if(deck.Option == "RC") {
deck.volume <- length * width * height
interventions.deck <- s2$DC + s2$DR + 0.25 * s2$SDO + 0.35 * (if (!is.null(s2$PR)) {s2$PR}
else {0})
} else if (deck.Option == "Road") {
deck.volume <- length * width * height
interventions.deck <- s2$DC + s2$R.r + 0.25 * s2$SDO.r + 0.35 * (if (!is.null(s2$R.r))
{s2$R.r} else {0})
deck.Option <- "RC"

}
#girder options
if (girder.Option == "PRC") { #get the numbers of girders n <-round(width /
1.75, 0) interventions.girders <- s2$DC + if (!is.null(s2$DR)) {s2$DR} else{ 0 } +
0.55 * (if(! is.null(s2$PR)) {s2$PR} else {0})

#get the volume of the concrete for the prefab girders


girders.V <- n * prefab.girder.Section * length
} else if (girder.Option == "none") {
n <- 0 girders.V <- 0
interventions.girders <- 0
}
asph.interventions = length(dist.event$event)-1
asphalt <- mutate(materials.split$asphalt, bridge.Q = asphalt.Q, interventions =
asph.interventions)
deck <- mutate(materials.split[[deck.Option]], bridge.Q = deck.volume, interventions =
interventions.deck)
if (!is.null(materials.split[[girder.Option]])) {
girders <- mutate(materials.split[[girder.Option]], bridge.Q = girders.V, interventions =
interventions.girders)
LCA.matrix <- rbind(deck, girders, asphalt)
} else {
LCA.matrix <- rbind(deck, asphalt)

LCA.matrix <- mutate(LCA.matrix, TotalMaterials.Q = quantities * bridge.Q / 1000,


materials.LC = TotalMaterials.Q * interventions,
Energy.LC = materials.LC * energy,
CO2.LC = materials.LC * CO2 * 1000,
NOx.LC = materials.LC * NOx * 1000,
SO2.LC = materials.LC * SO2 * 1000)
LCA.results <- list(Energy = sum(LCA.matrix$Energy.LC),
CO2 = sum(LCA.matrix$CO2.LC),
NOx = sum(LCA.matrix$NOx.LC),
SO2 = sum(LCA.matrix$SO2.LC))

return(LCA.results) }

page12
Life-Cycle Assessment – Group Project Assignment 3
First update: based on the distribution of the interventions provided with the dist.event, we extract the
frequency of different events repetition in s2 variable. Next, we are using these values to calculate
the impact of the interventions over the lifecycle. For the variables interventions.deck and
interventions.girders. Later one, we automatically extract the interventions for the asphalt
replacement.

We define the main variables we need to run the function using the following lines of code.
b.length <- 25 # units: m
b.width <- 15 #units: m
bd.depth <- 0.35 #units: m
asphalt.tk <- 0.12 #units: m
r.depth <- 0.5 #units: m
r.lenght <- 200 #m 100 meters on each side of the
bridge girder.Options <- c("PRC", "none") deck.options
<- c("RC", "Road")
Moving forward, we will call the function to calculate the impact on the environment.
Option.bridge <- LCA.bridge(b.length, b.width, bd.depth, asphalt.tk,
girder.Options[1], deck.options[1], LCI.materials, maintenance.Bridge)

Option.road <- LCA.bridge(r.lenght, b.width, r.depth, asphalt.tk,


girder.Options[2], deck.options[2], LCI.materials, maintenance.Road)

Once we have the results for both products, we will combine the effect of both into one dataframe
integrated.Design <- as.data.frame(list(Energy = Option.bridge$Energy + Option.road$Energy,
CO2 = Option.bridge$CO2 + Option.road$CO2,
NOx = Option.bridge$NOx + Option.road$NOx, SO2
= Option.bridge$SO2 + Option.road$SO2))

Typing in console integrated.Design, we will get the following results


> integrated.Design
Energy CO2 NOx SO2
1 2671533 249476045 1093423 2485655
We also want to consider the costs of the impact on the environment. For this we define the following
unit prices.
Energy.costs <- 0.128
CO2.unitcost <- 26 # per metric tone
NOx.unitCost <- 42 # per metric tone
SO2.unitCosts <- 85 # per metric tone
These will be used to create a new column, containing the costs, in milliards.
integrated.Design <- mutate(integrated.Design, Costs = (Energy * Energy.costs +
CO2*CO2.unitcost +
NOx * NOx.unitCost +
SO2 * SO2.unitCosts)/10^9)

The results we obtained are listed below.


> integrated.Design
Energy CO2 NOx SO2 Costs
1 2671533 249476045 1093423 2485655 6.743924

now, we are ready to start looking at the multi-objective optimization.

page13
Life-Cycle Assessment – Group Project Assignment 3
2. Multi-Objective Optimization

In this section, we are going to implement a genetic algorithm for the multi criteria optimization.
We are going to use the nsga2() function, part of the mco package. For this, we need to define the
function to be minimized, the number of input variables, the numbers of output measures, as well as
the lower and upper bounds for the input variables.

In order to create the function to be minimized, we need to look at the input and output variables.

We are going to analyze different maintenance planning strategies. For this, the durations of the
interventions will be considered in a specific range, as defined in section 3.
• for the bridge interventions
◦ 10 >= SDO <= 20
◦ 3 >= M <= 8
◦ 20 >= DR <= 35
• for the road interventions
◦ 12 >= SDO.r <= 25
◦ 5 >= M.r <= 10
◦ 27 >= R.r <= 37
Then, another input variables which we will vary within a range is the bridge width.
Bridge deck depth, depth of the concrete slab of the road, as well thickness of the asphalt will be
variables depending on the intervention strategies.

The output variables will be the total duration of the interventions, the minimum distance between
two consecutive interventions, energy, CO2, NOx, SO2, and Costs.

Based on this information, we can define the fitness function. To do this, add the following lines of
code.
fitness <-
function(x) {
#define the output
dimension z <-
numeric(7)
#function body

return(z) }

First we will need to call the functions to distribute the interventions over the lifetime. To do this, add
the following lines of code to the body of our function.
x <- round(x, 0)
y <- expand.grid(SDO = x[1], M = x[2], DR = x[3], SDO.r = x[4], M.r = x[5], R.r = x[6])

dur.ev1 <- unlist(y[1:3] / 2)


dur.ev2 <- unlist(y[4:6] / 2)

dist.1 <- apply(y[1:3], 1, FUN = dist.Events, lifetime = lifetime, start.Date = start.Date)


dist.2 <- apply(y[4:6], 1, FUN = dist.Events, lifetime = lifetime, start.Date = start.Date)
results <- combine.lifeTimelines(dist.1[[1]], dist.2[[1]], dur.ev1, dur.ev2)
The output we are looking to obtain is represented by the total number of interruption and the
minimum distance between interventions. Using the following lines of code, we will add these to the
output vector.

page14
Life-Cycle Assessment – Group Project Assignment 3
z[1] <- sum(results[["duration"]])
z[2] <- -min(abs(results$frequency[1:(length(results$frequency) - 1)]
results$frequency[2:length(results$frequency)]))

As the function we are going to use for optimization aim to minimize a specific function, we need to
handle those objectives which we want to maximize. To do this, we will negate the results. This way,
the maximum value will become the minimum one. For z[2] contains the results for the distance
between two successive interventions and the defined objective for this is maximize(). Because of
this, we negated the results.
Next step, we will define those variables which are static, as well as the bridge width based on the
value generated by the GA function.
b.width <- x[7]
b.length <- 25 # units: m
bd.depth <- 0.35 #units m
asphalt.tk <- 0.12 #units m
r.depth <- 0.5 #m
r.lenght <- 200 #m 100 meters on each side of the
bridge materials <- LCI.materials girder.Options <-
c("PRC", "none") deck.options <- c("RC", "Road")
Energy.costs <- 0.128
CO2.unitcost <- 26
NOx.unitCost <- 42
SO2.unitCosts <- 85

Having these, we can call the function we defined for life cycle analysis, as well the logic for design
integration.
product.1.bridge <- LCA.bridge(b.length, b.width, bd.depth, asphalt.tk,
girder.Options[1], deck.options[1], LCI.materials, dist.1[[1]])

product.2.road <- LCA.bridge(r.lenght, b.width, r.depth, asphalt.tk,


girder.Options[2], deck.options[2], LCI.materials, dist.2[[1]])

integrated.system <- as.data.frame(list(Energy = product.1.bridge$Energy +


product.2.road$Energy,
CO2 = product.1.bridge$CO2 + product.2.road$CO2,
NOx = product.1.bridge$NOx + product.2.road$NOx,
SO2 = product.1.bridge$SO2 + product.2.road$SO2)) integrated.system <- mutate(integrated.system,
Costs = (Energy * Energy.costs +
CO2*CO2.unitcost +
NOx * NOx.unitCost +
SO2 * SO2.unitCosts)/10^9)

Next, we will take the results obtained and we will feed these to the output variable.
z[3] <- integrated.system$Energy
z[4] <- integrated.system$CO2
z[5] <- integrated.system$NOx
z[6] <- integrated.system$SO2
z[7] <- integrated.system$Costs

Now the fitness function is complete. We will define the GA optimization function by adding the
following lines of code.
r2 <- nsga2(fitness, idim = 7, odim = 7,
generations=5, popsize=4,
lower.bounds=c(10, 3, 20, 12, 4, 27, 25),
upper.bounds= c(20, 8, 35, 25, 10, 37, 45))
Where:

page15
Life-Cycle Assessment – Group Project Assignment 3
• fitness is the function we defined
• idim – input dimension and odim is the output dimension
• generations represent the number of generations to breed. A small number results in a
suboptimal solution;
• popsize represent the number of optimal alternatives to look at.
• lower.bounds and upper.bounds represent the limits we defined for the input variables. In
this case, the variables are as following: c(SDO, M, DR, SDO.r, M.r, R.r, b.width)

Running this function, we will get the following results:


$par
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 10.36427 7.752290 20.49377 12.03201 8.206984 35.76146 35.99361
[2,] 10.43091 5.537964 26.89310 12.11614 7.662745 35.97776 36.27023
[3,] 10.36576 3.628547 23.08348 22.13312 8.131028 33.42270 25.24560
[4,] 10.09437 3.628547 23.08348 22.96611 8.131028 33.42270 25.24560

$value
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 101.0 -2 5879694 548745044 2404114 5409606 14.82891
[2,] 126.0 -2 5504947 513993945 2252381 5103671 13.89296
[3,] 159.5 -1 4796944 447697005 1962688 4444371 12.10094
[4,] 139.5 -1 5002502 466928286 2047015 4640791 12.62122

$pareto.optimal
[1] TRUE TRUE TRUE TRUE

attr(,"class")
[1] "nsga2" "mco"

where:
• $par contains the input parameters of the individual of the population based on the size we
defined.
• $value represents the results of the simulations
• $pareto.optimal indicates which individual output is part of the pareto front.

We will increase the population size to 100 and the number of generations to 10, and we will run the
optimization again, as follows:
r2 <- nsga2(fitness, idim = 7, odim = 7,
generations=10, popsize=100,
lower.bounds=c(10, 3, 20, 12, 4, 27, 25),
upper.bounds= c(20, 8, 35, 25, 10, 37, 45))

This time we will create plots from data. To do this, we will transform the results in a dataframe using
the following lines of code.
r2Results <- as.data.frame(r2$value)
outNames <- c("duration", "interv.dist", "energy", "co2", "nox", "so2", "cost" )
colnames(r2Results) <- outNames

We will also extract those values which represent the pareto front and transform these into a data
frame.
pareto3 <- as.data.frame(paretoFront(r2))
colnames(pareto3) <- outNames

page16
Life-Cycle Assessment – Group Project Assignment 3
We can now use the ggplot2 package to plot the pareto front. In this case we will look at the pareto
front described by the total duration of the interventions and the cost.
ggplot(r2Results, aes(x = duration, y = cost)) + geom_point(shape = 21) +
geom_point(data = pareto3, size = 3, color="red") + geom_line(data =
pareto3, color="blue")

The red points form the pareto front represented by the blue line.

Of course, we want to see how the accumulated impact of the input parameters on the performance
criteria. We will implement a last piece of code which allows us to this.
input.params <- round(r2$par, 0)
all.results <- cbind(input.params, r2Results,
r2$pareto.optimal) colnames(all.results) <- c("SDO", "M", "DR",
"SDO.r", "M.r", "R.r",
"b.width", "duration", "interv.dist",
"energy", "co2", "nox", "so2", "cost",
"pareto")
par(mfrow = c(1,1))
parcoord(all.results[, 1:14], var.label = T,
col = ifelse(all.results$pareto == TRUE, "indianred",
"skyblue2"), lty = ifelse(all.results$pareto == TRUE, 1, 3),
lwd = ifelse(all.results$pareto == TRUE, 3, 1))
The plot created looks as shown below.

page17
Life-Cycle Assessment – Group Project Assignment 3

The red lines represent the solutions from the Pareto front – the optimal solutions. The blue lines
represent the non-optimal solutions.

page18
Life-Cycle Assessment – Group Project Assignment 3
Please do not hesitate to contact us in case you should have any questions or you are stuck
(studentsupport@civilsystems.tu-berlin.de), we often can solve problems quickly. Please also make
use of the support sessions (Übungen) in the Computercluster 180 (Di,Do – 14:00 – 16:00) or of the
online support on Adobe Connect (Mi, 13:00 – 14:30).

We wish you fun and luck with this project assignment!

page19

You might also like