| Title: | Building sector model with heterogeneous renovation and construction of the stock |
|---|---|
| Description: | This building stock model represents residential and commercial buildings at customisable regional and temporal resolution. The building stock is quantified in floor area and distinguished by building type (SFH/MFH) and location (rural/urban). In each building category, construction cohorts are tracked explicitly. This allows to characterise buildings specifically for each subset of buildings. The evolution of the building stock follows from the flows of constructed, renovated and demolished buildings and is optimised under cost minimisation with a benefit for heterogeneity in the choice of construction and renovation alternatives. This benefit captures heterogeneity in the preferences of the agents and the building structure. |
| Authors: | Robin Hasse [aut, cre] (ORCID: <https://orcid.org/0000-0003-1818-3186>), Ricarda Rosemann [aut] (ORCID: <https://orcid.org/0009-0006-5939-3197>) |
| Maintainer: | Robin Hasse <[email protected]> |
| License: | LGPL-3 |
| Version: | 0.14.1 |
| Built: | 2026-06-03 13:36:52 UTC |
| Source: | https://github.com/pik-piam/brick |
This building stock model represents residential and commercial buildings at customisable regional and temporal resolution. The building stock is quantified in floor area and distinguished by building type (SFH/MFH) and location (rural/urban). In each building category, construction cohorts are tracked explicitly. This allows to characterise buildings specifically for each subset of buildings. The evolution of the building stock follows from the flows of constructed, renovated and demolished buildings and is optimised under cost minimisation with a benefit for heterogeneity in the choice of construction and renovation alternatives. This benefit captures heterogeneity in the preferences of the agents and the building structure.
Maintainer: Robin Hasse [email protected] (ORCID)
Authors:
Ricarda Rosemann [email protected] (ORCID)
Useful links:
Write the specific costs to the input.gdx
.addSpecCostToInput( m, path, optimVar, xinit, tcalib, dims, vinExists, vinCalib, varName = "x", shiftIntang = TRUE ).addSpecCostToInput( m, path, optimVar, xinit, tcalib, dims, vinExists, vinCalib, varName = "x", shiftIntang = TRUE )
m |
Gams transfer container with previous input data |
path |
character, path to this run |
optimVar |
list of data frames with optimization variables of all flows |
xinit |
list of data frames with initial specific intangible costs of all flows |
tcalib |
numeric, calibration time steps |
dims |
list of characters, dimensions of each flow |
vinExists |
data frame of vintages that exist for each time period |
vinCalib |
data frame with vintages that exist in calibration periods |
varName |
character, optimization variable to calculate specific costs from. Needs to be a column of optimVarCon and optimVarRen, should be either 'x' or 'xA'. |
shiftIntang |
logical indicating whether intangible costs should be shifted to positive range |
Add the calibration targets to the input gdx
.addTargetsToInput(mInput, path, p_calibTarget, dims).addTargetsToInput(mInput, path, p_calibTarget, dims)
mInput |
gamstransfer container of the input gdx |
path |
character, path to output folder of this run |
p_calibTarget |
list of data frames of calibration targets |
dims |
list of characters, dimensions of data |
gamstransfer container with the modified input gdx (invisibly)
Append current date and time
.addTimeStamp(x).addTimeStamp(x)
x |
character |
character with time stamp suffix
If for any combination the condition is still not satisfied: Set the step size to zero and print a warning if no descent has been detected. Use the last step size of the iteration otherwise.
.adjustStepSizeAfterIteration(totalStep, stepSizeParams).adjustStepSizeAfterIteration(totalStep, stepSizeParams)
totalStep |
data frame with combinations for which the condition is not satisfied |
stepSizeParams |
data frame with the parameters of the step size adaptation procedure |
data frame with step size and related paramters, updated if applicable.
Aggregate data across given dimensions by a given function
.aggregateDim(df, agg, func = sum, valueNames = "value").aggregateDim(df, agg, func = sum, valueNames = "value")
df |
data frame with data to be aggregated |
agg |
character, columns with the dimensions to be aggregated |
func |
function to be used for aggregation |
valueNames |
character, names of the columns containing the values to aggregate |
data frame with aggregated data
This is copied code from madrat to create the hash for additional arguments to 'madrat::retrieveData' besides the regionmapping. This way, we can recreate the file name of the tgz file with the input data.
.argsHash(formals, useLabels).argsHash(formals, useLabels)
formals |
named list with arguments |
useLabels |
logical, should be |
Ideally, this should be an exported function of madrat rather than copied code.
character with hash
Robin Hasse
Convert factor to numeric vector. This only works for factors with numeric levels.
.asNumeric(x, warn = TRUE).asNumeric(x, warn = TRUE)
x |
factor vector |
warn |
logical, if |
numeric vector
Check if the Armijo condition holds or if a local minimum of the outer objective has been identified. Return only data combinations for which it does not hold.
.checkStepCondition( prevStep, stepSizeParams, outerObjective, sensitivityArmijo ).checkStepCondition( prevStep, stepSizeParams, outerObjective, sensitivityArmijo )
prevStep |
data frame with data combinations that did not satisfy the step size condition in the previous step |
stepSizeParams |
data frame with step size and related parameters |
outerObjective |
data frame containing the value of the outer objective function.
Needs to contain the columns |
sensitivityArmijo |
numeric, parameter of the Armijo condition specifying how strict the condition is |
data frame of combinations that satisfy neither the Armijo condition nor the local minimum criterion in the objective function
Returns TRUE if and only if both the absolute and the relative stopping criterion
are satisfied for all subsets.
.checkStoppingCriterion( outerObjective, p_calibTarget, tcalib, threshold, zeroFlow = FALSE ).checkStoppingCriterion( outerObjective, p_calibTarget, tcalib, threshold, zeroFlow = FALSE )
outerObjective |
data frame containing the value of the outer objective function. |
p_calibTarget |
list of data frames with historic flows |
tcalib |
numeric, time periods on which the calibration is executed |
threshold |
list of numeric, absolute and relative threshold of the stopping criterion |
zeroFlow |
logical, whether renovation flow data should be filtered for zero flows |
logical, whether the stopping criterion is satisfied for all subsets
Read in brick results and compute the total outer objective function by combining resuls from construction and renovation.
.combineOuterObjective( m, outerObjective, p_calibTarget, tcalib, dims, varName = "f", agg = NULL ).combineOuterObjective( m, outerObjective, p_calibTarget, tcalib, dims, varName = "f", agg = NULL )
m |
Gams transfer container to read brick results from |
outerObjective |
data frame to write the outer objective to |
p_calibTarget |
data frame with historic flows |
tcalib |
numeric, calibration time steps |
dims |
named character, dimensions of the flows |
varName |
character, column name in |
agg |
character, dimension(s) to aggregate the data over |
data frame with the outer objective computed from all calibration variables
stored in column f or fA.
If applicable, joined with previously computed value for f.
Combine the step size paramters delta and phi-derivative from construction and renovation flows
.combineStepSizeParams(deviation).combineStepSizeParams(deviation)
deviation |
named list of data frames with deviation and adjustment term |
data frame with step size adaptation parameters computed from all calibration variables
Read in objective function values for slightly shifted optimization variables
and compute the gradient of the objective function.
Set the adjustment term d to the negative of the gradient.
.computeDescentDirection( m, dims, tcalib, flow = c("construction", "renovation", "renovationBS", "renovationHS") ).computeDescentDirection( m, dims, tcalib, flow = c("construction", "renovation", "renovationBS", "renovationHS") )
m |
Gams transfer container with current Brick results |
dims |
character, dimensions of the desired result object |
tcalib |
numeric, time steps to calibrate on |
flow |
character, either 'construction' or 'renovation' |
data frame with the adjustment term d.
d
Compute the deviation between historic data and Brick results as the log ratio.
Then compute the adjustment term for the calibration d
.computeDeviation( m, target, dims, tcalib, renAllowed, vinExists, flow = c("construction", "renovation", "renovationBS", "renovationHS"), agg = NULL, calibResolution = "full" ).computeDeviation( m, target, dims, tcalib, renAllowed, vinExists, flow = c("construction", "renovation", "renovationBS", "renovationHS"), agg = NULL, calibResolution = "full" )
m |
Gams transfer container with current Brick results |
target |
data frame of historical data |
dims |
character, dimensions of historic data and Brick results |
tcalib |
numeric, time steps to calibrate on |
renAllowed |
data frame with allowed renovation transitions |
vinExists |
data frame with existing vintages for each time period |
flow |
character, either 'construction' or 'renovation' |
agg |
character, dimensions to aggregate Brick results and target data over |
calibResolution |
character, resolution of the calibration for renovation flows |
data frame containing the deviation from the target dev and the adjustment term d.
In case of the logit calibration, this outer objective function is virtual: We are not actually performing an optimization algorithm on this function, but only use it for the step size adaptation.
.computeOuterObjective(m, gamsVar, target, dims, tcalib, agg = NULL).computeOuterObjective(m, gamsVar, target, dims, tcalib, agg = NULL)
m |
Gams transfer container object to read set values from |
gamsVar |
data frame with brick results for the given variable |
target |
data frame with historic data |
dims |
character, dimensions of data |
tcalib |
numeric, calibration time steps |
agg |
character, dimension(s) to aggregate the data over |
data frame with the outer objective computed from one calibration variable
Compute the step size adaptation paramters delta and phi-derivative
.computeStepSizeParams(deviation).computeStepSizeParams(deviation)
deviation |
data frame with deviation and adjustment term 'd' |
data frame with step size adaptation parameters delta and phiDeriv.
Compute the sum of the squares for a calibration target
.computeSumSqTarget(target, zeroFlow = FALSE).computeSumSqTarget(target, zeroFlow = FALSE)
target |
data frame with calibration target data |
zeroFlow |
logical, whether data should be filtered for the zero flow |
data frame with the same dimensions as the outer objective, aggregated by computing the sum of the squares
Create a list of empty data frames with given names
.createListWithEmptyDf(nm).createListWithEmptyDf(nm)
nm |
character, names of the empty data frames |
list of empty data frames
remove all records of temporal parameters that are outside of thist
and make zero values explicit by filling with EPS.
.cropParamsToThist(gdx, thist).cropParamsToThist(gdx, thist)
gdx |
character, file path to gdx |
thist |
numeric vector of historic periods |
Assemble specific costs from initial specific costs and the optimization variable
.determineSpecCost( optimVar, xinit, dims, tcalib, flow = c("construction", "renovation", "renovationBS", "renovationHS"), varName = "x", vinExists = NULL, vinCalib = NULL, shiftIntang = TRUE ).determineSpecCost( optimVar, xinit, dims, tcalib, flow = c("construction", "renovation", "renovationBS", "renovationHS"), varName = "x", vinExists = NULL, vinCalib = NULL, shiftIntang = TRUE )
optimVar |
data frame with the optimization variable 'x' and optionally 'xA' |
xinit |
data frame with initial specific intangible costs |
dims |
character, dimensions of the optimization variable |
tcalib |
numeric, calibration time steps |
flow |
character, type of flow, either construction or renovation |
varName |
character, optimization variable to calculate specific costs from. Should be either 'x' or 'xA'. |
vinExists |
data frame of vintages that exist for each time period |
vinCalib |
data frame with vintages that exist in calibration periods |
shiftIntang |
logical indicating whether intangible costs should be shifted to positive range |
data frame with specific intangible costs for the given flow
Replace zeros in value column with the gams special value EPS. This way, the value is saved in gdx files by gams.
.explicitZero(x, value = "value").explicitZero(x, value = "value")
x |
data.frame |
value |
character, name of value column |
data.frame with explicit zeros in value column
Robin Hasse
Performs successive semi_joins with passed data frames by all common columns. Useful to filter allowed renovations or vintages that exist.
.filter(x, ...).filter(x, ...)
x |
data.frame |
... |
data frames that only have columns existing also in |
filtered data frame
Robin Hasse
used to select a specifc level or scenario from a data frame with alternative values.
.filterLevel(df, lvl, switchName = "", lvlCol = "level").filterLevel(df, lvl, switchName = "", lvlCol = "level")
df |
data.frame |
lvl |
value used to select rows |
switchName |
character, corresponding BRICK switch name (only used for more informative error message) |
lvlCol |
character, colname containing |
data.frame with selected rows without lvlCol
Search for config file in multiple steps. The file is found if
* config is a full file path already
* config is the name of a file in the config folder
* there is exactly one file in configFolder matching the pattern
passed via config
.findCfg(config, configFolder, isFinalCfg).findCfg(config, configFolder, isFinalCfg)
config |
character, config file, either a path to a yaml file or the name of the file in 'inst/config/' |
configFolder |
character, directory to search for configs. If NULL, the BRICK-internal config folder is used. |
isFinalCfg |
logical, is this the final config and not an intermediate? |
file path to config
Determine the so far minimum step size. If the outerObjective is increasing again after a decrease, set the step size to the value yielding the current minimum.
.findMinimumStepSize(totalStep, stepSizeParams, outerObjective).findMinimumStepSize(totalStep, stepSizeParams, outerObjective)
totalStep |
data frame with combinations to perform the adjustment ot the step size on |
stepSizeParams |
data frame with the parameters of the step size adjustment algorithm |
outerObjective |
data frame containing the value of the outer objective function. |
data frame with the updated step size where applicable and allrelevant step size parameters
Depending on what is passed via originGDX, this function returns the
file path if it exists, looks for recognised file names in the given
directory if it exists or looks for the latest run with the given name in the
outputFolder.
.findOriginGdxFile(originGdx, outputFolder).findOriginGdxFile(originGdx, outputFolder)
originGdx |
character, file path to run or gdx file used as historical or scenario name |
outputFolder |
directory of output folder, only required if
|
file path to origin gdx file
Find region mapping
.findRegionMapping(regionmapping).findRegionMapping(regionmapping)
regionmapping |
character. If |
data frame with region mapping
Select parameters and freeze them to the value in a selected period
.freezeParameters(m, params, period).freezeParameters(m, params, period)
m |
gamstransfer Container with parameters |
params |
character vector of parameter names |
period |
numeric, period that all values are freezed to; has to be an element of ttot |
gams Container
Robin Hasse
Get BRICK mapping
.getMapping(mapping).getMapping(mapping)
mapping |
character or list of characters, name of BRICK mapping. If
|
data frame or list of data frames
Robin Hasse
Initialize the data frame for the optimization variables
.initOptimVar(mInput, tcalib, dims, renAllowed, vinExists).initOptimVar(mInput, tcalib, dims, renAllowed, vinExists)
mInput |
Gamstransfer container with the input data |
tcalib |
numeric, calibration time periods |
dims |
character, dimensions to initialize the data with |
renAllowed |
data frame with allowed renovation transitions |
vinExists |
data frame with allowed vintage and time period combinations |
data frame of desired dimension with x = 0 (column to contain the optimzation variable) and xA = 0.
Initialize the data frame for the objective function value
.initOuterObjective(mInput).initOuterObjective(mInput)
mInput |
Gamstransfer container with the input data |
data frame with required dimensions for the outer objective
Compute the initial step size of the step size iteration algorithm
.initStepSize(i, stepSizeParams, outerObjective, stepSizeInit).initStepSize(i, stepSizeParams, outerObjective, stepSizeInit)
i |
numeric, iteration number of overall calibration procedure |
stepSizeParams |
data frame with parameters for the step size adaptation |
outerObjective |
data frame with previous and current values of outer objective function;
needs to contain the columns |
stepSizeInit |
numeric, lower bound for the initial step size |
data frame with the initial step size and initial values for the minimum outer objective and corresponding step size
Insert element between each element of a vector
.insertBetween(x, insert).insertBetween(x, insert)
x |
vector |
insert |
element to insert |
vector of length length(x) * 2 - 1
Robin Hasse
Perform isTRUE on each vecotr element
.isTRUE(x).isTRUE(x)
x |
vector |
logical vector
Robin Hasse
Calculate log-Likelihood of historical values
.logLikelihood(res, target).logLikelihood(res, target)
res |
numeric, result values |
target |
numeric, historic values |
numeric, negative of the log likelihood
fill value column with average across vintages
.makeIdentVin(x).makeIdentVin(x)
x |
data.frame with brick parameter, requires vin and value columns |
data.frame with identical structure but averaged values
Lapply with output named by given list
.namedLapply(nm, ...).namedLapply(nm, ...)
nm |
list of characters, lapply input list and name of output |
... |
further inputs to lapply |
named list
Just a check to get a helpful error if gamstransfer is missing. Once the
package is available on GitHub, it should be listed as a dependency and this
file can be removed. The check is disabled during contiunous integration (CI)
i.a. GitHub actions and during devtools:check which is called by
lucode2::buildLibrary.
.onLoad(libname, pkgname).onLoad(libname, pkgname)
libname |
not used |
pkgname |
not used |
Robin Hasse
Overwrite a named list with another named list. The result corresponds to the overwritten list unless a value is overwritten by the overwriting list.
.overwriteList(x, y, isFinalCfg, defaultCfgPath).overwriteList(x, y, isFinalCfg, defaultCfgPath)
x |
named list, provides the structure and default values that can be
overwritten by |
y |
named list, overwrites |
isFinalCfg |
logical, is this the final config and not an intermediate? |
defaultCfgPath |
character, path to default config. Only used for more helpful error message. |
This function is called recursively until the default config is reached. Therefor, the list structure will always correspond to the default config. No config based directly or indirectly on the default can have list keys that the default config doesn't have.
named list with the structure of x that is (partly)
overwritten by y.
Pick lines from data.frame by identifiers
.pick(x, ..., .colsMustExist = TRUE).pick(x, ..., .colsMustExist = TRUE)
x |
data.frame |
... |
<column> = <selectionElement> |
.colsMustExist |
logical, if |
data.frame with filtered rows without identifier columns
Print message that the calibration converged.
.printConvergenceMessage(iteration, threshold).printConvergenceMessage(iteration, threshold)
iteration |
numeric, number of current iteration |
threshold |
list of numeric, absolute and relative threshold of the stopping criterion |
Read calibration targets from input folder
.readCalibTarget(dims, mInput).readCalibTarget(dims, mInput)
dims |
named character, dimensions of each variable of the calibration |
mInput |
gamstransfer container with the input.gdx |
list of data frames with calibration targets for each variable
Read yaml file from given path, check minimum requirement (title exists) and save the file path as a attribute.
.readCfg(file).readCfg(file)
file |
character, path to config file |
named list with config parameters
Only applicable for optimization calibration.
.readOuterObjectiveOptim(m, outerObjective, varName = "f").readOuterObjectiveOptim(m, outerObjective, varName = "f")
m |
Gams transfer container to read brick results from |
outerObjective |
data frame to write the outer objective to |
varName |
character, column name in |
data frame with outer objective read from Gams results stored in column f or fA.
If applicable, joined with previously computed value for f.
Create reference mapping name
.refMapName(ref, file = FALSE).refMapName(ref, file = FALSE)
ref |
character, reference name |
file |
file extension appended unless set to |
character with reference mapping name
Robin Hasse
If Gams was not successful, set the outer objective to infinity so that it cannot be accepted by the step size adaptation. Copy relevant files to trace the error (gdx, main.log and main.lst)
.rejectErrorRun( path, outerObjective, gamsSuccess, iteration, iterationStepSize, varName = "fA", gdxName = "calibrationA.gdx" ).rejectErrorRun( path, outerObjective, gamsSuccess, iteration, iterationStepSize, varName = "fA", gdxName = "calibrationA.gdx" )
path |
character, run path where all files, in particular Gams files, are stored |
outerObjective |
data frame with data on outer objective |
gamsSuccess |
data frame containing whether Gams was successful for each subset |
iteration |
numeric, current calibration iteration |
iterationStepSize |
numeric, current iteration of step size adaptation |
varName |
character, column of outer objective to be modified |
gdxName |
character, name of the gdx file to be copied. |
data frame, outer objective with modifications in the column given by varName
Calculate sum of squared differences between results and historic values
.sumSquare(res, target = 0).sumSquare(res, target = 0)
res |
numeric, result values |
target |
numeric, historic values |
numeric, sum of squared differences
Wrapper around unique that also drops elements that differ in cases
but are identical to gams as it is case-insensitive.
.unique(x).unique(x)
x |
a vector or a data frame |
an object of the same kind but possibly fewer elements. Vectors can be shorter and data frames can have fewer rows
Robin Hasse
Update the step size for the selected combinations
.updateStepSize( totalStep, stepSizeParams, outerObjective, stepReduction, lastIteration ).updateStepSize( totalStep, stepSizeParams, outerObjective, stepReduction, lastIteration )
totalStep |
data frame with combinations to perform the adjustment ot the step size on |
stepSizeParams |
data frame with the parameters of the step size adjustment algorithm |
outerObjective |
data frame containing the value of the outer objective function. |
stepReduction |
numeric, factor applied to stepSize to reduce the step size. Should be < 1. |
lastIteration |
logical, if this is the last iteration of the step size adaptation |
data frame with the current step size and all related parameters. The step size and the minimum outer objective and minimum step size are updated for selected combinations only.
Adjust 'x' by adding the adjustment term 'd' multiplied by the step size
.updateX(optimVar, deviation, stepSizeParams, dims, nameTo = "x").updateX(optimVar, deviation, stepSizeParams, dims, nameTo = "x")
optimVar |
data frame with the optimization variable 'x' and optionally 'xA' |
deviation |
data frame with deviation and adjustment term 'd' |
stepSizeParams |
data frame with parameters of step size adaptation, including step size 'stepSize' |
dims |
character, dimensions of the optimization variable |
nameTo |
character, optimization variable to write the result to |
data frame with the updated optimization variable x or xA
Update the optimization variable 'x' for selected combinations only
.updateXSelect(totalStep, optimVar, deviation, stepSizeParams, dims).updateXSelect(totalStep, optimVar, deviation, stepSizeParams, dims)
totalStep |
data frame with combinations to perform the adjustment of 'x' on |
optimVar |
data frame with the optimization variables |
deviation |
data frame with the deviation from historic data and the adjustment parameter 'd' |
stepSizeParams |
data frame with the parameters of the step size adaptatation procedure |
dims |
character, dimensions of the optimization variable |
data frame with the optimzation variable which was updated for the desired combinations
Write the intangible costs to a .csv file
.writeCostIntang( file, optimVar, xinit, dims, tcalib, flow = c("construction", "renovation", "renovationBS", "renovationHS"), vinExists = NULL, vinCalib = NULL ).writeCostIntang( file, optimVar, xinit, dims, tcalib, flow = c("construction", "renovation", "renovationBS", "renovationHS"), vinExists = NULL, vinCalib = NULL )
file |
character, path to file to which results should be written |
optimVar |
data frame with optimization variable, needs to contain column 'x' |
xinit |
data frame with initial intangible specific costs |
dims |
character, dimensions of the optimization variable |
tcalib |
numeric, calibration time steps |
flow |
character, specifies flow considered. Must be cosntruction or renovation |
vinExists |
data frame with existing vintage and time step combinations |
vinCalib |
data frame with vintage and time step combinations that exist during calibration |
Write the stock of the calibration result to a csv file
.writeStock(m, path).writeStock(m, path)
m |
Gams container with the calibration output.gdx |
path |
character, path to the calibration run |
Add assumed intangible costs
addAssump(df, assumpFile, vinDimMap = NULL, key = NULL)addAssump(df, assumpFile, vinDimMap = NULL, key = NULL)
df |
data.frame for the cost of construction or renovation |
assumpFile |
character, file path to assumption file |
vinDimMap |
data frame with mapping for vintages to start and end years. |
key |
character, renovation asset, either |
data frame with added intangible cost
Robin Hasse
Temporary function that prepares historic stock and flows for calibration
aggregateMatching(path, config, overwrite = FALSE)aggregateMatching(path, config, overwrite = FALSE)
path |
character, path to calibration run |
config |
named list, configuration of calibration run |
overwrite |
logical, should existing data be overwritten? |
This functionality will migrate to mredgebuidlings but this infrastructure requires more time to be developed.
Robin Hasse
This is meant to work with the installed package BRICK but also when loading
the package via devtools::load_all("path/to/brick")
brick.file(..., mustWork = TRUE)brick.file(..., mustWork = TRUE)
... |
character vectors, specifying subdirectory and files within brick |
mustWork |
if TRUE, an error is given if there are no matching files |
A character vector of positive length, containing the file paths
that matched ... in BRICK.
Robin Hasse
Check which file is the gdx file written by Gams from main.log. Read model and solver status from this gdx file and print.
checkGamsSuccess(path, runType = "scenario", silent = FALSE)checkGamsSuccess(path, runType = "scenario", silent = FALSE)
path |
character, path to search for gams output files |
runType |
character, type of this run |
silent |
logical, whether no messages should be printed. |
Stop with error message if:
- main.log does not exist
- the gdx file does not exist
- more than one gdx file was written.
logical, whether GAMS was successful for all subsets
Ricarda Rosemann
Only works for sequential renovation right now.
checkStockBal(path)checkStockBal(path)
path |
character, directory of a brick run |
named list with deviations of each balance equation
Robin Hasse
Copy gams scripts to output folder
copyGamsFiles(path, overwrite = FALSE)copyGamsFiles(path, overwrite = FALSE)
path |
character vector with folders to write input data into |
overwrite |
logical, should existing input.gdx be overwritten? |
Robin Hasse
Copy history gdx to output folder
copyHistoryGdx( path, outputFolder = NULL, config, overwrite = FALSE, thistOnly = TRUE )copyHistoryGdx( path, outputFolder = NULL, config, overwrite = FALSE, thistOnly = TRUE )
path |
character vector with folders to write input data into |
outputFolder |
directory of output folder |
config |
named list with run configuration |
overwrite |
logical, should existing input.gdx be overwritten? |
thistOnly |
logical, crop temporal parameters to historic periods |
Robin Hasse
Copy initial gdx to output folder
copyInitialGdx(path, startingPoint, overwrite = FALSE)copyInitialGdx(path, startingPoint, overwrite = FALSE)
path |
character vector with folders to write input data into |
startingPoint |
character with path to the starting point or the respective directory |
overwrite |
logical, should existing input.gdx be overwritten? |
Robin Hasse
read results from matching run and aggregate them spatially and temporally to the resolution of calibration runs
createCalibrationTarget( path, calibConfig, outDir = NULL, digits = 4, rmCorrectionRun = FALSE )createCalibrationTarget( path, calibConfig, outDir = NULL, digits = 4, rmCorrectionRun = FALSE )
path |
character, directory of matching folder |
calibConfig |
character, calibration config |
outDir |
character, directory to save calibration target files in |
digits |
integer indicating the number of decimal places |
rmCorrectionRun |
logical, if |
The temporal aggregation of renovation flows is non-trivial: It is generally possible that buildings can change states multiple time within one aggregated time step but they can't be tracked through renovations individually. Currently, we first assume the mean of renovations across all years of an aggregated time step. In a second step, we perform a renovation correction run with BRICK that minimises deviation from these mean flows and the stock subject to the stock balance and building shell and heating system life times. The correction assures consistency, mostly changing the zero flow that depends most on the temporal resolution. This renovation correction run is performed in a sub folder of the matching run.
named list with aggregated and corrected stock and flows
Robin Hasse
Create a complete set of input data for the gams optimisation.
createInputData(path, config, overwrite = FALSE)createInputData(path, config, overwrite = FALSE)
path |
character vector with folders to write input data into |
config |
named list with run configuration |
overwrite |
logical, should existing input.gdx be overwritten? |
This function reads static input data according to the input data revision in the config and creates all required sets and parameters for the gams optimisation depending on the switches in the config.
Robin Hasse
This function also performs auto gams code generation to load the reference sets and parameters
createMatchingData(path, config, overwrite = FALSE)createMatchingData(path, config, overwrite = FALSE)
path |
character vector with folders to run the model in |
config |
run configurations |
overwrite |
logical, should existing data be overwritten? |
Robin Hasse
Add all parameters to gams container based on config
createParameters(m, config, inputDir)createParameters(m, config, inputDir)
m |
gams Container, central object to store all data for input.gdx |
config |
named list with run configuration |
inputDir |
directory of input folder |
gams Container with parameters added
Robin Hasse
Create a folder for the model to run in and copy required gams files there.
createRunFolder( path, config = NULL, overwrite = FALSE, recursive = FALSE, showWarnings = TRUE )createRunFolder( path, config = NULL, overwrite = FALSE, recursive = FALSE, showWarnings = TRUE )
path |
character vector, containing the path(s) to the folder(s) to be created. |
config |
list with run configuration |
overwrite |
logical, should existing folders be overwritten? |
recursive |
logical, should elements of the path other than the last be created? |
showWarnings |
logical, should a warning on not created paths be shown? |
Robin Hasse
Add all sets to gams container based on config
createSets(m, config)createSets(m, config)
m |
gams Container, central object to store all data for input.gdx |
config |
named list with run configuration |
gams Container with sets added
Robin Hasse
Create a data frame that has a column for each set and the full crossing of all set entries as rows
expandSets(..., .m = NULL)expandSets(..., .m = NULL)
... |
gams sets |
.m |
gams Container with sets referenced in |
data.frame with full crossing of set entries
Robin Hasse
Search the given output folder for the run with the most recent time stamp and return the path to this run. If the output folder contains only one run, return its path, also if it does not contain a time stamp.
findLastRun(outputFolder)findLastRun(outputFolder)
outputFolder |
character, output folder to search in |
Ricarda Rosemann
Retrieve mapping file from BRICK
getBrickMapping( name, type = "sectoral", error.missing = TRUE, returnPathOnly = FALSE )getBrickMapping( name, type = "sectoral", error.missing = TRUE, returnPathOnly = FALSE )
name |
character, file name of the mapping file |
type |
character, Mapping type (e.g. "regional", or "sectoral") |
error.missing |
logical, return error if the file does not exist |
returnPathOnly |
logical, file name of the mapping file |
Robin Hasse
Get Brick dimension mapping
getDimMap(dim, granularity = NULL)getDimMap(dim, granularity = NULL)
dim |
character, dimension name |
granularity |
character, name of BRICK granularity |
data.frame with dimension mapping
Robin Hasse
Preparations of a model run, send the model to SLURM if desired
initModel( config = NULL, path = NULL, configFolder = NULL, outputFolder = "output", references = NULL, restart = FALSE, runReporting = TRUE, sendToSlurm = NULL, slurmQOS = NULL, tasksPerNode = NULL, timeLimit = NULL, tasks32 = FALSE )initModel( config = NULL, path = NULL, configFolder = NULL, outputFolder = "output", references = NULL, restart = FALSE, runReporting = TRUE, sendToSlurm = NULL, slurmQOS = NULL, tasksPerNode = NULL, timeLimit = NULL, tasks32 = FALSE )
config |
run configurations |
path |
character vector with folders to run the model in |
configFolder |
character, directory to search for configs. If NULL, the BRICK-internal config folder is used. |
outputFolder |
directory of output folder |
references |
named character vector of matching references |
restart |
logical or character vector of elements to be restarted. If FALSE (default), then no restart is initiated. If TRUE, then the run in the given path or the latest run is restarted with default settings. Allowed elements of the character vector are:
|
runReporting |
logical, whether to run the reporting, i.e. write the mif |
sendToSlurm |
boolean whether or not the run should be started via SLURM |
slurmQOS |
character, slurm QOS to be used |
tasksPerNode |
numeric, number of tasks per node to be requested |
timeLimit |
character, time limit of the slurm job given in the format hh:mm:ss |
tasks32 |
boolean whether or not the SLURM run should be with 32 tasks |
This function creates the run folder with the necessary config and gams files. It then either calls the function to start the model directly or passes the model to SLURM.
path (invisible)
Ricarda Rosemann
Lines between marker comments are replaced by given lines. The respective script file gets overwritten.
insertGamsCode(path, script, section, insert, keepComments = TRUE)insertGamsCode(path, script, section, insert, keepComments = TRUE)
path |
character, description |
script |
characer, name of gams script |
section |
character, section name |
insert |
character vector, code line that are inserted |
keepComments |
logical, if TRUE, lines starting with |
Before
!! AUTOCODE.<section> <old code> !! AUTOCODE_end.<section>
After
!! AUTOCODE.<section> <insert> !! AUTOCODE_end.<section>
Robin Hasse
Insert reference-dependent code for matching into gams scripts
insertMatchingCode(path)insertMatchingCode(path)
path |
character vector with folders to run the model in |
Robin Hasse
Checks whether slurm is available so that jobs can be submitted, e.g., via sbatch ....
isSlurmAvailable()isSlurmAvailable()
logical(1). Whether slurm is available.
Convert named list to data.frame
listToDf(x, split = NULL)listToDf(x, split = NULL)
x |
named list with keys as column names |
split |
character, split names by this pattern and assume same value for each separated item |
data.frame with column for each key
Robin Hasse
Load calibration targets from matching results
loadCalibrationTarget(config)loadCalibrationTarget(config)
config |
named list with run configuration |
directory of input folder
Ricarda Rosemann
Load Input data from mredgebuildings
loadMadratData(config)loadMadratData(config)
config |
named list with run configuration |
directory of input folder
Robin Hasse
Helper function to turn a named list into a string appended to the gams command line call
makeHandle(lst, type = c("gams", "model"))makeHandle(lst, type = c("gams", "model"))
lst |
named list of flags |
type |
character, type of flags (either '"gams"' or '"model"') |
Gams parameters are lower case flags and follow one minus '-'. Model switches are upper case flags and follow two minuses '–'.
character of flags
Robin Hasse
extract different periods from a given BRICK config
periodFromConfig(config, periodType)periodFromConfig(config, periodType)
config |
named list with run configuration |
periodType |
type of period(s) |
numeric vector with periods
Robin Hasse
Plot heat map of reference deviation
plotRefDeviation(path, dropZeroWeightRefs = TRUE, dropUnmappedRefVars = TRUE)plotRefDeviation(path, dropZeroWeightRefs = TRUE, dropUnmappedRefVars = TRUE)
path |
character, directory of output folder |
dropZeroWeightRefs |
logical, if TRUE, references with zero weight are not shown |
dropUnmappedRefVars |
logical, if TRUE, reference variables that are not mapped to BRICK variables are not shown |
Robin Hasse
Plot an overview of the stock and flows
plotSummary(path, facet = "typ", showHistStock = FALSE, splitRen = FALSE)plotSummary(path, facet = "typ", showHistStock = FALSE, splitRen = FALSE)
path |
character, path to the run |
facet |
character, dimension to resolve as facets |
showHistStock |
logical, show given historic next to the modeled stock |
splitRen |
logical, plot renovation with identical replacement semi-transparent |
Robin Hasse
Read config file in yaml format
readConfig(config = NULL, configFolder = NULL, readDirect = FALSE)readConfig(config = NULL, configFolder = NULL, readDirect = FALSE)
config |
character, config file, either a path to a yaml file or the
name of the file in |
configFolder |
character, directory to search for configs. If NULL, the BRICK-internal config folder is used. |
readDirect |
logical, specify whether |
If no argument is given, the default config is used.
named list with run config
Robin Hasse
Read madrat input files from input folder
readInput(filename, dims, inputDir = NULL)readInput(filename, dims, inputDir = NULL)
filename |
character, filename |
dims |
character vector, column names |
inputDir |
character, directory of input folder |
data.frame with data of the given input file
Robin Hasse
Read symbol from gams container
readSymbol(x, symbol = NULL, selectArea = TRUE, stringAsFactor = TRUE)readSymbol(x, symbol = NULL, selectArea = TRUE, stringAsFactor = TRUE)
x |
gams Container, Parameter, Variable or Set or path to gdx |
symbol |
character, name of gams object if x is a Container else NULL |
selectArea |
logical, select area quantity and remove this dimension |
stringAsFactor |
logical, keep default factors from gams |
Robin Hasse
The mif file contains reporting variables for the given model run.
reportMif(path, file = NULL, tmpl = NULL)reportMif(path, file = NULL, tmpl = NULL)
path |
character, path to the run |
file |
character, path of mif file. If |
tmpl |
character, BRICK reporting template. There has to be a brickSets
mapping named with the same suffix: |
Robin Hasse
Read reference configuration from existing run und update the set of selected references and the reference weights in the reference.gdx
reweightMatchingReferences(path)reweightMatchingReferences(path)
path |
character, path to run |
gamstransfer container with updates reference gdx content
Robin Hasse
Two methods for the Brick calibration are available: The logit calibration and the optimization calibration.
runCalibration( path, parameters, tcalib, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )runCalibration( path, parameters, tcalib, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )
path |
character vector with folders to run gams in |
parameters |
named list of calibration parameters |
tcalib |
numeric, time periods to calibrate on |
gamsOptions |
named list of GAMS options |
switches |
named list of model switches |
fileName |
character vector with gams file names |
gamsCall |
system command to call gams |
The general procedure is as follows:
We aim to minimize the deviation between historic values and Brick results.
An intangible component of the specific construction and renovation costs is iteratively
adjusted to achieve this. Thus the intangible costs serve as the optimization variable x
and a functional evaluation of the deviation represents the objective function f.
Brick is run iteratively and from each run, an adjustment term d is computed.
The optimization variable is adjusted according to x = x + stepSize * d, where
the step size is determined according to the Armijo step size adaptation algorithm,
supplemented with a heuristic that picks the step size resulting in the (locally) minimum outer objective.
The implementation is centered around the following objects:
The optimization variable x and its variant(s) required in the step size adaptation
are gathered in the data frame optimVarCon for construction and optimVarRen
for renovation.
The objective function value f and its variant(s) are gathered in the data
frame outerObjective
The adjustment term d and related variables if applicable are gathered in the
data frame deviationCon for construction and deviationRen for renovation.
The step size stepSize and related parameters required for the step size adaptation
algorithm are gathered in the data frame stepSizeParams.
Ricarda Rosemann
The adjustment term is computed as if Brick were a pure logit model:
d = log(<brick result>/<historic value>).
runCalibrationLogit( path, parameters, tcalib, dims, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )runCalibrationLogit( path, parameters, tcalib, dims, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )
path |
character vector with folders to run gams in |
parameters |
named list of calibration parameters |
tcalib |
numeric, time periods to calibrate on |
dims |
list of characters with dimensions of stock and flow variables |
gamsOptions |
named list of GAMS options |
switches |
named list of model switches |
fileName |
character vector with gams file names |
gamsCall |
system command to call gams |
Here the armijo step size algorithm may not be applicable; if this is the case, the first local minimum objective is used.
This implements a gradient descent method to perform the minimization of the deviation. The adjustment term is computed as the negative of the gradient of the objective function.
runCalibrationOptim( path, parameters, tcalib, dims, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )runCalibrationOptim( path, parameters, tcalib, dims, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )
path |
character vector with folders to run gams in |
parameters |
named list of calibration parameters |
tcalib |
numeric, time periods to calibrate on |
dims |
list of characters with dimensions of stock and flow variables |
gamsOptions |
named list of GAMS options |
switches |
named list of model switches |
fileName |
character vector with gams file names |
gamsCall |
system command to call gams |
Run the gams model in a given directory.
runGams( path, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )runGams( path, gamsOptions = NULL, switches = NULL, fileName = "main.gms", gamsCall = "gams" )
path |
character vector with folders to run gams in |
gamsOptions |
named list of GAMS options |
switches |
named list of model switches |
fileName |
character vector with gams file names |
gamsCall |
system command to call gams |
The file 'input.gdx' has to exist in the given directory.
Robin Hasse
Based on user input, construct the SLURM configuration string.
setSlurmConfig(slurmQOS, tasksPerNode = 16, tasks32 = FALSE, timeLimit = NULL)setSlurmConfig(slurmQOS, tasksPerNode = 16, tasks32 = FALSE, timeLimit = NULL)
slurmQOS |
string, name of the desired QOS (Quality of Service) |
tasksPerNode |
numeric, number of tasks per node to be requested |
tasks32 |
boolean, specify whether a node with 32 tasks should be requested |
timeLimit |
character, time limit of the slurm job given in the format hh:mm:ss |
Check if SLURM configuration is admissible.
string with SLURM configuration
Ricarda Rosemann
Run the model with given configuration.
startModel(path, runReporting = TRUE)startModel(path, runReporting = TRUE)
path |
character vector with folders to run the model in |
runReporting |
logical, whether to run the reporting, i.e. write the mif |
This function creates a run folder with necessary gams files if missing. It then computes the input data and finally runs the optimisation.
Robin Hasse
Missing periods are interpolated linearly and extrapolated constantly, additional periods are removed and all other dimensions are filtered to the elements defined in the model sets.
toModelResolution(x, m, value = "value", unfilteredDims = NULL)toModelResolution(x, m, value = "value", unfilteredDims = NULL)
x |
data.frame with temporal dimension |
m |
gams Container with sets as known dimensions |
value |
character, name of value column |
unfilteredDims |
character, dimensions to be neither filtered nor extrapolated |
data.frame with temporal resolution according to model
Robin Hasse