hongyuanjia / epluspar Goto Github PK
View Code? Open in Web Editor NEWConduct parametric analysis on EnergyPlus models in R
Home Page: https://hongyuanjia.github.io/epluspar
License: Other
Conduct parametric analysis on EnergyPlus models in R
Home Page: https://hongyuanjia.github.io/epluspar
License: Other
cmdstanr provides a clean interface to Stan services with minimal dependencies.
There is user observing significant time saving:
Simple linear regression with 5 observations:
system.time for rstan was (85.876 5.269 47.514).
Same model in CmdStanR (compilation + sampling):
system.time ( 1.522 0.321 2.435 )
Using sensitivity::morrisMultOut()
to support multi-dimension outputs.
Evaluate improvement in code efficiency for the following
Current way to specify parameters in SensitivityJob
class is using $param()
which only makes it possible to specify a single field value range.
sen <- Sensitivity$new(path_idf, path_epw)
sen$param(
# Syntax: Object Name = list(Field = c(Min, Max, Levels))
GP01 = list(Thickness = c(min = 0.01, max = 1, levels = 5)),
`Supply Fan 1` = list(Fan_Total_Efficiency = c(0.1, 1.0, 5)),
# See `r` and `grid_jump` in `sensitivity::morris`
.rep = 12, .grid_jump = 4
)
There are cases when the user may want to modify the same field in all related objects, e.g. change the fan efficiency for all fans. Below are several possible interfaces that came into my mind:
(A) Use a special notation :=
(borrowed from data.table package) in $param()
to indicate that input field range should be applied to all objects in that class. For example:
sen$param(`Fan:VariableVolume` := list(Fan_Total_Efficiency = c(0.1, 1.0, 5)))
(B) Since SensitivityJob
class inherits from ParametricJob
class in current implementation, the user always can use $apply_measure()
to apply complex modifications on the seed mode. Changing the example in README to modify the efficiency in all fans is equivalent to:
my_actions <- function (idf, thickness, fan_efficiency) {
# change the thickness of a single material
idf$set(GP01 = list(Thickness = thickness))
# change the efficiency of all fans
fan <- idf$to_table(class = "Fan:VariableVolume", all = TRUE)
fan[field == "Fan Total Efficiency", value := as.character(fan_efficiency)]
idf$update(fan)
idf
}
sen$apply_measure(my_action,
thickness = c(min = 0.01, max = 1, levels = 5),
fan_efficiency = c(0.1, 1.0, 5)
)
sensitivity::morris()
.It may be better to do both ways to provide more options for different level users.
Good sir,
I have been trying to add an object to my IDF file using eplusr, but I kept encountering an error. Below are my codes and the error.
mywork<-(WindowMaterial:Glazing = list(Name = "clear glass 4 mm",
Optical_Data_Type = "SpectralAverage",
SpectralAverage =0.0039,
Solar_Transmittance_at_Normal_Incidence =0.812 ,
Front_Side_Solar_Reflectance_at_Normal_Incidence =0.076 ,
Back_Side_Solar_Reflectance_at_Normal_Incidence =0.075,
Visible_Transmittance_at_Normal_Incidence =0.893,
Front_Side_Visible_Reflectance_at_Normal_Incidence =0.084,
Back_Side_Visible_Reflectance_at_Normal_Incidence =0.084,
Infrared_Transmittance_at_Normal_Incidence =0,
Front_Side_Infrared_Hemispherical_Emissivity =0.840,
Back_Side_Infrared_Hemispherical_Emissivity =0.840,
Conductivity = 0.9))
idf$add(mywork)
Error in WindowMaterial:Glazing = list(Name = "clear glass 4 mm", Optical_Data_Type = "SpectralAverage", :
object 'WindowMaterial' not found
Good day Sir @hongyuanjia,
Please I have been trying to store certain design parameters from my optimization process so I can access them afterwards. All my efforts have not been successful. Below is a sample of my code. Kindly assist me.
iteration <- 0
wall_insulation <- 0
roof_insulation <- 0
win_frame <- ""
total_investment_opaque <- 0
#create a data frame
hold <- data.frame(iteration, wall_insulation,
roof_insulation, win_frame,
total_investment_opaque)
#-------------------------------------------------------------------------------
# combine all measures into one
design_options <- function(idf, wall_insulation_thickness,
roof_insulation_thickness,
window_frame,
) {
# get results
types <- set_type (idf, window_frame)
set_insulation_wall(idf, wall_insulation_thickness)
set_insulation_roof(idf, roof_insulation_thickness)
#set vital variables for data frame hold
hold$wall_insulation <- wall_insulation_thickness
hold$roof_insulation <- roof_insulation_thickness
hold$win_frame <- window_frame
idf
}
#-------------------------------------------------------------------------------
add_init_cost_to_db <- function(idf, param) {
initial_investment <- sum(initial_investment_envelope,
initial_investment_floor)
#set data frame hold
hold$total_investment_opaque<- initial_investment
}
wall_insulation <- hold$wall_insulation
roof_insulation <- hold$roof_insulation
win_frame <- hold$win_frame
total_investment_opaque<- hold$total_investment_opaque
iteration <<- iteration + 1
vitalsimulationresults <- rbind( vitalsimulationresults, data.frame
(iteration, wall_insulation,
roof_insulation, win_frame,
total_investment_opaque))
Hello @hongyuanjia,
Before any comments, I want to thank you and your collaborators for your great job with the packages eplusr and epluspar. These tools are very useful.
I am trying to carry out a Bayesian calibration with epluspar. However, I am facing a problem with adding the following custom meter in $output() :
Meter:Custom,
CustomLights, !- Name
Electricity, !- Resource Type
Depto201_8376d7ca, !- Key Name 1
Zone Lights Electricity Energy, !- Output Variable or Meter Name 1
Depto202_065db6d5, !- Key Name 2
Zone Lights Electricity Energy, !- Output Variable or Meter Name 2
Depto203_ee2eff98, !- Key Name 3
Zone Lights Electricity Energy, !- Output Variable or Meter Name 3
Depto204_b3ba733f, !- Key Name 4
Zone Lights Electricity Energy, !- Output Variable or Meter Name 4
Depto205_ca4768b6, !- Key Name 5
Zone Lights Electricity Energy, !- Output Variable or Meter Name 5
Depto206_2149faff, !- Key Name 6
Zone Lights Electricity Energy; !- Output Variable or Meter Name 6
When I run a simulation with the seed .idf file the custom meter is present in the mdd file :
══ EnergyPlus Meter Data Dictionary File ════════════════════════════════════════════════════════════════════════════════════════════════════════
── Details ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
index reported_time_step report_type variable units
1: 623 Zone Meter CUSTOMLIGHTS
However, when I try to add it with $output() I have the following error :
Error: Invaid variable name found in input 'key_value': 'CUSTOMLIGHTS'.
The custom does not appear in the data frame mdd <- bc$read_mdd().
Custom meters is very useful to calibrate the model using measured data from submetering data.
Best regards
Fabien
eplusr will report an " invalid character" error while changing the temperature of schedule in epScan.
Hello @hongyuanjia
I have read your publication titled: eplusr: A framework for integrating building energy simulation and data-driven analytics.
I tried to run a simply optimization problem to help me understand Epluspar R package much better, but I kept encountering an error.
I selected only one parameter for my optimization, which is the wall insulation, to be varied from 1cm to 6cm.
My objective function is to minimize Energy Per Conditioned Building Area [kWh/m2].
Here is the modified listing I tried to run:
#load packages
library(eplusr)
library(tidyverse) # for data-driven analysis
library(epluspar)
# read IDF
idf <- read_idf(system.file("extdata/1D 2F.idf", package = "eplusr"))
# read EPW
path_epw <- file.path(eplus_config(8.9)$dir, "WeatherData/Nicosia_hour.epw")
epw <- read_epw(path_epw)
# create a GA optimization job
ga <- gaoptim_job(idf, epw)
#Optimization variables#
# define a measure to change the insulation thickness of the exterior wall
set_insulation <- function (idf, thickness) {
idf$set(`polystyrene eps (5 cm)` = list(thickness = thickness))
idf
}
# combine measures into one
design_options <- function (idf,insulation_thickness) {
idf <- set_insulation(idf, insulation_thickness)
idf
}
# specify design space of parameters
ga$apply_measure(design_options,insulation_thickness = float_space(0.01, 0.06,0.01))
# define an objective function to energy per conditioned building area
primary_energy <- function (idf) {
as.double(idf$last_job()$tabular_data(
report_name = "Site and Source Energy",
row_name = "Total Site Energy",
column_name = "Energy Per Conditioned Building Area [kWh/m2]" )
$value)
}
# set optimization objectives
ga$objective(primary_energy,.n=NULL, .dir = "min")
# specify how to mix solutions
ga$recombinator()
# specify how to change parts of one solution randomly
ga$mutator()
# specify how to select best solutions
ga$selector()
# specify the conditions when to terminate the computation
ga$terminator(max_gen = 100L)
# run optimization
ga$run(mu = 20)
# get all population
population <- ga$population()
# get Pareto set
pareto <- ga$pareto_set()
Here is the error I kept encountered when I tried to run it:
> # run optimization
> ga$run(mu = 20)
-- Initialization --------------------------------------------------------------
* Create initial population
Checking if parameter(s) has been set ...
Checking if objective(s) has been set ...
Validating parameter function 'design_options' ...
Validating objective function(s)...
Error: Idf has been modified since read or last saved. Please save it using `$save()` before running.
>
Good day Sir.
The code bellow, has been working perfectly for sometime.
But after an update to my packages yesterday, It refused to work again.
#load packages
library(eplusr)
library(tidyverse)
library(epluspar)
library(openxlsx)
library(ggplot2)
library(formattable)
# read base case file
idf <- read_idf(system.file("extdata/1D 2F base_case.idf", package = "eplusr"))
# read weather file path
path_epw <- file.path(eplus_config(8.9)$dir, "WeatherData/Nicosia_hour.epw")
# run case simulation
job <- idf$run(path_epw)
#Extract tabular data
primary_energy <- as.double(idf$last_job()$tabular_data(
report_name = "AnnualBuildingUtilityPerformanceSummary",
table_name = "Site and Source Energy",
row_name = "Total Site Energy",
column_name = "Total Energy")
$value)
> Error in l$contains : $ operator is invalid for atomic vectors
> ga$validate()
Checking if parameter(s) has been set ...
Checking if objective(s) has been set ...
Validating parameter function 'zonal_design' ...
Validating objective function(s)...
Error: Validation failed. Test simulation did not complete successfully. The error messages are:
> ══ EnergyPlus Error File ════════════════════════════════════════════════════════
> * EnergyPlus version: 9.2.0 (921312fa1d)
> * Simulation started: 2021-03-18 20:35:00
> * Terminated: TRUE
> * Successful: FALSE
> * Warning[W]: 70
> * Severe[S]: 1
> * Fatal[F]: 1
>
> ── During Simulation Initiation ─────────────────────────────────────────────────
> [W 1/70] Timestep: Requested number (1) is less than the suggested minimum of 4.
> Please see entry for Timestep in Input/Output Reference for discussion
> of considerations.
> [W 2/70] ProcessScheduleInput: DecodeHHMMField, Invalid "until" field value is
>
In addition: Warning message:
Simulation ended with errors. Simulation results may not be correct.
>
In sensitivity::morris()
, there is a scale
parameter to scale the input design of experiments before computing the elementary effects so that all factors vary within the range [0,1].
This argument should be added and be set to TRUE
by default.
The morris class in python SALib package does this by default in its sample()
method.
Once #1 is closed, prepare to submit epluspar to CRAN. Also related to ideas-lab-nus/eplusr-paper#2
Good day, I have been trying to install epluspar package, but I kept receiving the following error message.
Error: Failed to install 'epluspar' from GitHub:
(converted from warning) installation of package ‘C:/Users/Toshiba/AppData/Local/Temp/RtmpcN6aMt/file225c784e4a27/epluspar_0.0.0.9000.tar.gz’ had non-zero exit status
In addition: Warning messages:
1: In untar2(tarfile, files, list, exdir) :
skipping pax global extended headers
2: In untar2(tarfile, files, list, exdir) :
skipping pax global extended headers
* Check whether terminator conditions are met
── Generation [17] ────────────────────────────────────────────────────
* Generate offspring
* Evaluate fitness values
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
Target object does not refer to any objects.
* Evaluate fitness values --> Average fitness: 700364.673805543
* Prepare next generation
* Update log
* Check whether terminator conditions are met
── Generation [18] ────────────────────────────────────────────────────
Hi @hongyuanjia,
I am trying to perform energy vs cost-optimization using Epluspar.
Considering the limitations of energyplus in cost analysis, I decided to have my cost variables assigned in an R data frame. My first objective to minimize energy seems ok because it is dependent on Idf file. However, my second objective cost minimization kept prompting the following error:
Error: Objective function 'global_cost' must have an parameter named 'idf'.
In addition: Warning message:
In formals(fun) : argument is not a function
Please I need suggestions to overcome this error.
Choose a proper name for this package. Possibles:
epcalib
= ep
+ calib
epluscalib
= eplus
+ calib
epstats
= ep
+ stats
epanalysis
= ep
+ analysis
epluspar
= eplus
+ par
(parameter OR parametric analysis in R)Good day Hongyuanjia,
please I need help with functions in epluspar.
If
choice_space is used to specify optimization parameter of character type
float_space is used to specify optimization parameter of float type in a sequential manner
integer_spaceis used to specify optimization parameter of integer type in a sequential manner
what functions can I use to specify float and integer parameters in an orderly manner I wish them to be respectively ?
For example, to enter parameters: 20,40,50,60,90
path_idf <- "RefBldgLargeOfficeNew2004_Chicago.idf"
path_epw <- file.path(eplus_config(8.7)$dir, "WeatherData", "USA_CA_San.Francisco.Intl.AP.724940_TMY3.epw")
sen <- sensi_job(path_idf, path_epw)
lvls <- 6
sen$param(
.("Core_bottom People", "Core_mid People", "Core_top People", "Perimeter_bot_ZN_1 People", "Perimeter_bot_ZN_2 People",
"Perimeter_bot_ZN_3 People", "Perimeter_bot_ZN_4 People", "Perimeter_mid_ZN_1 People", "Perimeter_mid_ZN_2 People",
"Perimeter_mid_ZN_3 People", "Perimeter_mid_ZN_4 People", "Perimeter_top_ZN_1 People", "Perimeter_top_ZN_2 People",
"Perimeter_top_ZN_3 People", "Perimeter_top_ZN_4 People") :=
list(Zone_Floor_Area_per_Person = c(min=13.935, max=23.225, levels = lvls)),
.names = c("var"),
.r = 8, .grid_jump = 1
)
#> Error: `.name` should have the same length as number of input parameters, which is 15.
@hongyuanjia, greetings of the day.
Bellow is an objective function code, that is meant to evaluate discomfort hours, by extracting data from the table displayed above.
# Evaluate discomfort hours
discomfort_hours <- function(idf) {
# Local definition of time (hours) not meeting adaptive comfort model
discomfort_time <- as.double(idf$last_job()$tabular_data(
report_name = "AdaptiveComfortSummary",
table_name = "Time Not Meeting the Adaptive Comfort Models during Occupied Hours",
row_name = "OCCUPANTS",
column_name = "ASHRAE55 80% Acceptability Limits"
)
$value)
# Evaluate the discomfort hours
discomfort_time<-(discomfort_time/8760)*100
# return discomfort hours
discomfort_time
}
However, I encountered the following error when I tried to run the code. Please, can you help me resolve the problem, sir?
-- Initialization --------------------------------------------------------------------------------------
* Create initial population
Checking if parameter(s) has been set ...
Checking if objective(s) has been set ...
Validating parameter function 'design_options' ...
Validating objective function(s)...
[1] 'combined_primary_energy' --> OK
[2] 'combined_global_cost' --> OK
Error: Objective function 'discomfort_hours' should return at least a length-one vector instead of a 0-length one.
Since this package is public, we can now build a public package site using pkgdown.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.