🛈

Note:  See Building/Process Energy Efficiency for a description of the typical policy variables used and factors to consider when modeling a building efficiency policy. 

Also see the Mechanics of Creating Policy Files for more information on the structure of policy files and on Julia coding syntax used in policy files.



The ResCom_EIP.jl policy file contains both residential and commercial building standards. In this file, we see a separate data struct being created to hold the residential variables (which are stored in RInput, ROutput, and RCalDB) and a second data struct to hold the commercial variables (which are stored in CInput, COutput, and CCalDB).  


Several ways can be used to access variables having the same name across sectors, such as in the residential, commercial, industrial, and transportation sectors. See Data Structs for information on accessing variables in the data struct. 


Sample Policy File:  ResCom_EIP.jl

#

# ResCom_EIP.jl  - NRCan RDD Projects. 

#

# More details about this policy are available in the following file: 

# \\ncr.int.ec.gc.ca\shares\e\ECOMOD\Documentation\Policy - Buildings Policies.docx

#


using EnergyModel


module ResCom_EIP


import ...EnergyModel: ReadDisk,WriteDisk,Select

import ...EnergyModel: HisTime,ITime,MaxTime,First,Future,Final,Yr

import ...EnergyModel: @finite_math,finite_inverse,finite_divide,finite_power,finite_exp,finite_log

import ...EnergyModel: DB


const VariableArray{N} = Array{Float32,N} where {N}

const SetArray = Vector{String}


Base.@kwdef struct RControl

  db::String


  CalDB::String = "RCalDB"

  Input::String = "RInput"

  Outpt::String = "ROutput"

  BCNameDB::String = ReadDisk(db,"MainDB/BCNameDB") #  Base Case Name


  Area::SetArray = ReadDisk(db,"MainDB/AreaKey")

  AreaDS::SetArray = ReadDisk(db,"MainDB/AreaDS")

  Areas::Vector{Int} = collect(Select(Area))

  EC::SetArray = ReadDisk(db,"$Input/ECKey")

  ECC::SetArray = ReadDisk(db,"MainDB/ECCKey")

  ECCDS::SetArray = ReadDisk(db,"MainDB/ECCDS")

  ECCs::Vector{Int} = collect(Select(ECC))

  ECDS::SetArray = ReadDisk(db,"$Input/ECDS")

  ECs::Vector{Int} = collect(Select(EC))

  Enduse::SetArray = ReadDisk(db,"$Input/EnduseKey")

  EnduseDS::SetArray = ReadDisk(db,"$Input/EnduseDS")

  Enduses::Vector{Int} = collect(Select(Enduse))

  Nation::SetArray = ReadDisk(db,"MainDB/NationKey")

  NationDS::SetArray = ReadDisk(db,"MainDB/NationDS")

  Nations::Vector{Int} = collect(Select(Nation))

  Tech::SetArray = ReadDisk(db,"$Input/TechKey")

  TechDS::SetArray = ReadDisk(db,"$Input/TechDS")

  Techs::Vector{Int} = collect(Select(Tech))

  Year::SetArray = ReadDisk(db,"MainDB/YearKey")

  YearDS::SetArray = ReadDisk(db,"MainDB/YearDS")

  Years::Vector{Int} = collect(Select(Year))


  ANMap::VariableArray{2} = ReadDisk(db,"MainDB/ANMap") # [Area,Nation] Map between Area and Nation

  DmdRef::VariableArray{5} = ReadDisk(BCNameDB,"$Outpt/Dmd") # [Enduse,Tech,EC,Area,Year] Demand (TBtu/Yr)

  PEERef::VariableArray{5} = ReadDisk(BCNameDB,"$Outpt/PEE") # [Enduse,Tech,EC,Area,Year] Base Year Process Efficiency ($/Btu)

  PEE::VariableArray{5} = ReadDisk(db,"$Outpt/PEE") # [Enduse,Tech,EC,Area,Year] Process Efficiency ($/Btu)

  PEM::VariableArray{3} = ReadDisk(db,"$CalDB/PEM") # Maximum Process Efficiency ($/Btu) [Enduse,EC,Area]

  PEMM::VariableArray{5} = ReadDisk(db,"$CalDB/PEMM") # [Enduse,Tech,EC,Area,Year] Process Efficiency Max. Mult. ($/Btu/$/Btu)

  PEMMRef::VariableArray{5} = ReadDisk(BCNameDB,"$CalDB/PEMM") # [Enduse,Tech,EC,Area,Year] Base Year Process Efficiency Max. Mult. ($/Btu/$/Btu)

  PERRRExo::VariableArray{5} = ReadDisk(db,"$Outpt/PERRRExo") # [Enduse,Tech,EC,Area,Year] Process Energy Exogenous Retrofits ((mmBtu/Yr)/Yr)

  PEStd::VariableArray{5} = ReadDisk(db,"$Input/PEStd") # [Enduse,Tech,EC,Area,Year] Process Efficiency Standard ($/Btu)

  PEStdP::VariableArray{5} = ReadDisk(db,"$Input/PEStdP") # [Enduse,Tech,EC,Area,Year] Process Efficiency Standard Policy ($/Btu)

  PInvExo::VariableArray{5} = ReadDisk(db,"$Input/PInvExo") # [Enduse,Tech,EC,Area,Year] Process Exogenous Investments (M$/Yr)

  xInflation::VariableArray{2} = ReadDisk(db,"MInput/xInflation") # [Area,Year] Inflation Index ($/$)


  # Scratch Variables

  CCC::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Variable for Displaying Outputs

  Change::VariableArray{2} = zeros(Float32,length(EC),length(Year)) # [EC,Year] Change in Policy Variable

  DDD::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Variable for Displaying Outputs

  DmdFrac::VariableArray{5} = zeros(Float32,length(Enduse),length(Tech),length(EC),length(Area),length(Year)) # [Enduse,Tech,EC,Area,Year] Device Energy Requirement (mmBtu/Yr)

  DmdTotal::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Total Demand (TBtu/Yr)

  PEENew::VariableArray{5} = zeros(Float32,length(Enduse),length(Tech),length(EC),length(Area),length(Year)) # [Enduse,Tech,EC,Area,Year] New PEE

  PERRRExoTotal::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Total Process Energy Removed (mmBtu/Yr)

  PEStd1::VariableArray{5} = zeros(Float32,length(Enduse),length(Tech),length(EC),length(Area),length(Year)) # [Enduse,Tech,EC,Area,Year] Process Efficiency Standard Policy ($/Btu)

  PolicyCost::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Policy Cost (M$/Yr)

end


function ResPolicy(db)

  data = RControl(; db)

  (; CalDB,Input) = data   

  (; ECs) = data 

  (; Enduse,Enduses,Nation) = data

  (; Techs) = data

  (; ANMap,Change,DmdFrac,DmdRef,DmdTotal) = data

  (; PEENew,PEERef,PEM,PEMM,PEMMRef) = data

  (; PEStd,PEStdP,PEStd1,PInvExo,) = data

  (; PolicyCost,xInflation) = data


  CN = Select(Nation,"CN")

  areas = findall(ANMap[:,CN] .== 1)


  #

  # Store Original PEStdP

  #

  @. PEStd1 = PEStdP


  #

  # New facilities are x% more efficient/year beginning in 2022

  #

  @. Change = 1.0


  years = collect(Yr(2024):Yr(2026))

  for year in years, ec in ECs

    Change[ec,year] = 1.066

  end


  for year in years, area in areas, ec in ECs, tech in Techs, eu in Enduses

    PEENew[eu,tech,ec,area,year] = PEERef[eu,tech,ec,area,Yr(2017)]*Change[ec,year]

  end


  for year in years, area in areas, ec in ECs, tech in Techs, eu in Enduses

    PEMM[eu,tech,ec,area,year] = max(PEMM[eu,tech,ec,area,year],

      PEMM[eu,tech,ec,area,Yr(2017)]*Change[ec,year],PEMMRef[eu,tech,ec,area,Yr(2017)]*

        Change[ec,year])

    PEStdP[eu,tech,ec,area,year] = min(PEM[eu,ec,area]*

      PEMM[eu,tech,ec,area,year]*.98,max(PEStd[eu,tech,ec,area,year],

        PEStdP[eu,tech,ec,area,year],PEERef[eu,tech,ec,area,year],

          PEENew[eu,tech,ec,area,year]))

  end


  #

  # Adjust PEMM to account for growth of PEE in forecast

 

  for year in years, area in areas, ec in ECs, tech in Techs, eu in Enduses

    @finite_math PEMM[eu,tech,ec,area,year] = PEMM[eu,tech,ec,area,year]/

      (PEERef[eu,tech,ec,area,year]/PEERef[eu,tech,ec,area,Yr(2017)])

  end


  WriteDisk(db,"$Input/PEStdP",PEStdP)

  WriteDisk(db,"$CalDB/PEMM",PEMM)


  #

  # Program Costs are $82 million (CN$) spent equally between 2022 and 2026

 

  for year in years

    PolicyCost[year] = 16.4

  end


  #

  # Split out PolicyCost using reference Dmd values. PInv only uses Process Heat.

 

  Heat = Select(Enduse,"Heat")


  for year in years

    DmdTotal[year] = 

      sum(DmdRef[Heat,tech,ec,area,year] for area in areas, ec in ECs, tech in Techs)

  end


  for year in years, area in areas, ec in ECs, tech in Techs

    @finite_math DmdFrac[Heat,tech,ec,area,year] = 

      DmdRef[Heat,tech,ec,area,year]/DmdTotal[year]

  end


  for year in years, area in areas, ec in ECs, tech in Techs

    PInvExo[Heat,tech,ec,area,year] = PInvExo[Heat,tech,ec,area,year]+PolicyCost[year]/

      xInflation[area,Yr(2018)]*DmdFrac[Heat,tech,ec,area,year]

  end


  WriteDisk(db,"$Input/PInvExo",PInvExo)

  

end


Base.@kwdef struct CControl

  db::String

  

  CalDB::String = "CCalDB"

  Input::String = "CInput"

  Outpt::String = "COutput"

  BCNameDB::String = ReadDisk(db,"MainDB/BCNameDB") #  Base Case Name


  Area::SetArray = ReadDisk(db,"MainDB/AreaKey")

  AreaDS::SetArray = ReadDisk(db,"MainDB/AreaDS")

  Areas::Vector{Int} = collect(Select(Area))

  EC::SetArray = ReadDisk(db,"$Input/ECKey")

  ECC::SetArray = ReadDisk(db,"MainDB/ECCKey")

  ECCDS::SetArray = ReadDisk(db,"MainDB/ECCDS")

  ECCs::Vector{Int} = collect(Select(ECC))

  ECDS::SetArray = ReadDisk(db,"$Input/ECDS")

  ECs::Vector{Int} = collect(Select(EC))

  Enduse::SetArray = ReadDisk(db,"$Input/EnduseKey")

  EnduseDS::SetArray = ReadDisk(db,"$Input/EnduseDS")

  Enduses::Vector{Int} = collect(Select(Enduse))

  Nation::SetArray = ReadDisk(db,"MainDB/NationKey")

  NationDS::SetArray = ReadDisk(db,"MainDB/NationDS")

  Nations::Vector{Int} = collect(Select(Nation))

  Tech::SetArray = ReadDisk(db,"$Input/TechKey")

  TechDS::SetArray = ReadDisk(db,"$Input/TechDS")

  Techs::Vector{Int} = collect(Select(Tech))

  Year::SetArray = ReadDisk(db,"MainDB/YearKey")

  YearDS::SetArray = ReadDisk(db,"MainDB/YearDS")

  Years::Vector{Int} = collect(Select(Year))


  ANMap::VariableArray{2} = ReadDisk(db,"MainDB/ANMap") # [Area,Nation] Map between Area and Nation

  DmdRef::VariableArray{5} = ReadDisk(BCNameDB,"$Outpt/Dmd") # [Enduse,Tech,EC,Area,Year] Demand (TBtu/Yr)

  PEERef::VariableArray{5} = ReadDisk(BCNameDB,"$Outpt/PEE") # [Enduse,Tech,EC,Area,Year] Base Year Process Efficiency ($/Btu)

  PEE::VariableArray{5} = ReadDisk(db,"$Outpt/PEE") # [Enduse,Tech,EC,Area,Year] Process Efficiency ($/Btu)

  PEM::VariableArray{3} = ReadDisk(db,"$CalDB/PEM") # Maximum Process Efficiency ($/Btu) [Enduse,EC,Area]

  PEMM::VariableArray{5} = ReadDisk(db,"$CalDB/PEMM") # [Enduse,Tech,EC,Area,Year] Process Efficiency Max. Mult. ($/Btu/$/Btu)

  PEMMRef::VariableArray{5} = ReadDisk(BCNameDB,"$CalDB/PEMM") # [Enduse,Tech,EC,Area,Year] Base Year Process Efficiency Max. Mult. ($/Btu/$/Btu)

  PERRRExo::VariableArray{5} = ReadDisk(db,"$Outpt/PERRRExo") # [Enduse,Tech,EC,Area,Year] Process Energy Exogenous Retrofits ((mmBtu/Yr)/Yr)

  PEStd::VariableArray{5} = ReadDisk(db,"$Input/PEStd") # [Enduse,Tech,EC,Area,Year] Process Efficiency Standard ($/Btu)

  PEStdP::VariableArray{5} = ReadDisk(db,"$Input/PEStdP") # [Enduse,Tech,EC,Area,Year] Process Efficiency Standard Policy ($/Btu)

  PInvExo::VariableArray{5} = ReadDisk(db,"$Input/PInvExo") # [Enduse,Tech,EC,Area,Year] Process Exogenous Investments (M$/Yr)

  xInflation::VariableArray{2} = ReadDisk(db,"MInput/xInflation") # [Area,Year] Inflation Index ($/$)


  # Scratch Variables

  CCC::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Variable for Displaying Outputs

  Change::VariableArray{2} = zeros(Float32,length(EC),length(Year)) # [EC,Year] Change in Policy Variable

  DDD::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Variable for Displaying Outputs

  DmdFrac::VariableArray{5} = zeros(Float32,length(Enduse),length(Tech),length(EC),length(Area),length(Year)) # [Enduse,Tech,EC,Area,Year] Device Energy Requirement (mmBtu/Yr)

  DmdTotal::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Total Demand (TBtu/Yr)

  PEENew::VariableArray{5} = zeros(Float32,length(Enduse),length(Tech),length(EC),length(Area),length(Year)) # [Enduse,Tech,EC,Area,Year] New PEE

  PERRRExoTotal::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Total Process Energy Removed (mmBtu/Yr)

  PEStd1::VariableArray{5} = zeros(Float32,length(Enduse),length(Tech),length(EC),length(Area),length(Year)) # [Enduse,Tech,EC,Area,Year] Process Efficiency Standard Policy ($/Btu)

  PolicyCost::VariableArray{1} = zeros(Float32,length(Year)) # [Year] Policy Cost (M$/Yr)

end


function ComPolicy(db)

  data = CControl(; db)

  (; CalDB,Input) = data

  (; EC) = data 

  (; Enduse,Enduses,Nation) = data

  (; Techs) = data

  (; ANMap,Change,DmdFrac,DmdRef,DmdTotal) = data

  (; PEENew,PEERef,PEM,PEMM,PEMMRef) = data

  (; PEStd,PEStdP,PEStd1,PInvExo) = data

  (; PolicyCost,xInflation) = data


  CN = Select(Nation,"CN")

  areas = findall(ANMap[:,CN] .== 1)


  #

  # Store Orignal PEStdP

  #

  @. PEStd1 = PEStdP


  #

  # New facilities are x% more efficient/year beginning in 2022

  #

  @. Change = 1.0


  years = collect(Yr(2024):Yr(2026))

  ecs = Select(EC,(from="Wholesale", to="OtherCommercial"))

  for year in years, ec in ecs

    Change[ec,year] = 1.02

  end


  for year in years, area in areas, ec in ecs, tech in Techs, eu in Enduses

    PEENew[eu,tech,ec,area,year] = PEERef[eu,tech,ec,area,Yr(2017)]*Change[ec,year]

  end


  for year in years, area in areas, ec in ecs, tech in Techs, eu in Enduses

    PEMM[eu,tech,ec,area,year] = max(PEMM[eu,tech,ec,area,year],

      PEMM[eu,tech,ec,area,Yr(2017)]*Change[ec,year],PEMMRef[eu,tech,ec,area,Yr(2017)]*

        Change[ec,year])

    PEStdP[eu,tech,ec,area,year] = min(PEM[eu,ec,area]*PEMM[eu,tech,ec,area,year]*

      .98,max(PEStd[eu,tech,ec,area,year],PEStdP[eu,tech,ec,area,year],

        PEERef[eu,tech,ec,area,year],PEENew[eu,tech,ec,area,year]))

  end


  #

  # Adjust PEMM to account for growth of PEE in forecast

  #  

  for year in years, area in areas, ec in ecs, tech in Techs, eu in Enduses

    @finite_math PEMM[eu,tech,ec,area,year] = PEMM[eu,tech,ec,area,year]/

      (PEERef[eu,tech,ec,area,year]/PEERef[eu,tech,ec,area,Yr(2017)])

  end


  WriteDisk(db,"$Input/PEStdP",PEStdP)

  WriteDisk(db,"$CalDB/PEMM",PEMM)


  #

  # Program Costs are $11.4 million (CN$) spent equally between 2022 and 2026

 

  for year in years

    PolicyCost[year] = 2.28

  end


  #

  # Split out PolicyCost using reference Dmd values. PInv only uses Process Heat.

  #  

  Heat = Select(Enduse,"Heat")


  for year in years

    DmdTotal[year] = 

      sum(DmdRef[Heat,tech,ec,area,year] for area in areas, ec in ecs, tech in Techs)

  end


  for year in years, area in areas, ec in ecs, tech in Techs

    DmdFrac[Heat,tech,ec,area,year] = DmdRef[Heat,tech,ec,area,year]/DmdTotal[year]

  end


  for year in years, area in areas, ec in ecs, tech in Techs

    PInvExo[Heat,tech,ec,area,year] = PInvExo[Heat,tech,ec,area,year]+PolicyCost[year]/

      xInflation[area,Yr(2018)]*DmdFrac[Heat,tech,ec,area,year]

  end


  WriteDisk(db,"$Input/PInvExo",PInvExo)

end


function PolicyControl(db)

  @info "ResCom_EIP.jl - PolicyControl"

  ResPolicy(db)

  ComPolicy(db)

end


if abspath(PROGRAM_FILE) == @__FILE__

  PolicyControl(DB)

end


end