R/reportDemand.R

Defines functions reportDemand

Documented in reportDemand

#' Read in GDX and calculate (net and gross) annual demand, used in convGDX2MIF.R for the reporting
#'
#' Read in (net and gross) demand data from GDX file, information used in convGDX2MIF.R
#' for the reporting
#'
#' @param gdx a GDX object as created by readGDX, or the path to a gdx
#' @param output a magpie object containing all needed variables generated by other report*.R functions
#' @param reporting_tau boolean determining whether to generate the tau reports
#'  reporting at the time slice level (TRUE) or at the yearly level (FALSE, default)
#' @return MAgPIE object - contains the capacity variables
#' @author Sebastian Osorio, Renato Rodrigues
#' @seealso \code{\link{convGDX2MIF}}
#' @examples
#' \dontrun{
#' reportDemand(gdx, output = NULL)
#' }
#'
#' @importFrom gdx readGDX
#' @importFrom magclass mbind setNames dimSums getSets getSets<- as.magpie getItems collapseDim
#' @export
#'
reportDemand <- function(gdx, output = NULL, reporting_tau = FALSE) {

  if (is.null(output) && !reporting_tau) {
    stop("argument `output` is NULL. Please provide a file containing all needed information")
  }

  # Loading parameters from convGDX2MIF parent function
  c_demandscale <- readGDX(gdx, name = "c_demandscale", field = "l", format = "first_found") # factor for scaling net demand
  c_LIMESversion <- readGDX(gdx, name = "c_LIMESversion", field = "l", format = "first_found")
  tau <- readGDX(gdx, name = "tau") # set of time slices
  te <- readGDX(gdx, name = "te") # set of technologies

  # Loading parameters and variables
  p_taulength <- readGDX(gdx, name = c("p_taulength", "pm_taulength"), field = "l", format = "first_found", restore_zeros = FALSE)[, , tau] # number of hours/year per tau
  v_exdemand <- readGDX(gdx, name = "v_exdemand", field = "l", format = "first_found", restore_zeros = FALSE) # demand

  # Make sure only the "right" tau are taken -> to avoid info from gdx that might be stuck in the file
  v_exdemand <- v_exdemand[, , tau]
  p_taulength <- p_taulength[, , tau]

  # create MagPie object of demand with iso3 regions
  v_exdemand <- limesMapping(v_exdemand)
  p_hedemand <- new.magpie(cells_and_regions = getItems(v_exdemand, dim = 1), years = getYears(v_exdemand), names = tau,
                           fill = NA, sort = FALSE, sets = NULL)
  p_DH_losses <- new.magpie(cells_and_regions = getItems(v_exdemand, dim = 1), years = NULL, names = NULL,
                            fill = NA, sort = FALSE, sets = NULL)
  p_etah <- new.magpie(cells_and_regions = getItems(v_exdemand, dim = 1), years = NULL, names = te,
                       fill = NA, sort = FALSE, sets = NULL)

  # Check the version so to choose the electricity-related variables
  if (c_LIMESversion >= 2.28) {
    heating <- .readHeatingCfg(gdx)
    if (heating == "fullDH") {
      p_eldemand <- v_exdemand[, , "seel"]

      p_DH_losses <- readGDX(gdx, name = "p_DH_losses", field = "l", format = "first_found")
      p_DH_losses <- limesMapping(p_DH_losses)

      p_tedata <- readGDX(gdx, name = "p_tedata", field = "l", format = "first_found")
      p_etah <- p_tedata[, , "etah"]
      p_etah <- limesMapping(p_etah)

      ##Read variables related to heat prices:
      #heat demand was split into the one to be covered by DH and decentral P2H
      #Check if the new variables/equations already exist in the model
      v_exdemand_DH <- readGDX(gdx, name = "v_exdemand_DH", field = "l", format = "first_found",  restore_zeros  =  FALSE)[, , tau]
      if(is.null(v_exdemand_DH)) { #No split of heat demand

        split_DH_decP2H <- 0

        #Heat demand
        # This contains all heat production covered (directly or indirectly) by EU ETS (i.e., DH and decentraliced electric-based heating)
        p_hedemand <- v_exdemand[, , "sehe"]
        p_hedemand <- collapseDim(p_hedemand, dim = 3.2)

        # Wasted heat
        v_heatwaste <- readGDX(gdx, name = "v_heatwaste", field = "l", format = "first_found")[, , tau]
        v_heatwaste <- limesMapping(v_heatwaste)

      } else { #split of heat demand between DH and decentral P2H

        split_DH_decP2H <- 1

        #Load required equations
        v_exdemand_decP2H <- readGDX(gdx, name = "v_exdemand_decP2H", field = "l", format = "first_found",  restore_zeros  =  FALSE)[, , tau]
        v_heatwaste_DH <- readGDX(gdx, name = "v_heatwaste_DH", field = "l", format = "first_found",  restore_zeros  =  FALSE)[, , tau]
        v_heatwaste_decP2H <- readGDX(gdx, name = "v_heatwaste_decP2H", field = "l", format = "first_found",  restore_zeros  =  FALSE)[, , tau]


        # create MagPie object with iso3 regions
        v_exdemand_DH <- limesMapping(v_exdemand_DH) #[GWh]
        v_exdemand_decP2H <- limesMapping(v_exdemand_decP2H) #[GWh]
        v_heatwaste_DH <- limesMapping(v_heatwaste_DH) #[GWh]
        v_heatwaste_decP2H <- limesMapping(v_heatwaste_decP2H) #[GWh]

        #Collapse dimensions to avoid errors
        v_exdemand_DH <- collapseDim(v_exdemand_DH, dim = 3.2)
        v_exdemand_decP2H <- collapseDim(v_exdemand_decP2H, dim = 3.2)

        #end of if regarding splitting of ETS between DH and decP2H
      }


    } else {
      p_eldemand <- v_exdemand
    }
  } else {
    p_eldemand <- v_exdemand

  }

  # Collapse names of demand (just in case)
  p_eldemand <- collapseDim(p_eldemand, dim = 3.2)

  #Years
  y <- getYears(p_eldemand)

  #Use of electricity for transport
  p_exdem_trans <- readGDX(gdx, name = "p_exdem_trans", field = "l", format = "first_found", react = 'silent')[,y,]
  if(!is.null(p_exdem_trans)) {
    p_exdem_trans <- limesMapping(p_exdem_trans)
  }

  #Electricity input for heating
  o_seprodinputP2H <- readGDX(gdx, name = "o_seprodinputP2H", field = "l", format = "first_found", react = 'silent')[,y,"seel"]
  if(!is.null(o_seprodinputP2H)) {
    o_seprodinputP2H <- limesMapping(o_seprodinputP2H)
    o_seprodinputP2H <- collapseDim(o_seprodinputP2H)
  }


  # Standard Reporting ------------------------------------------------------
  if (!reporting_tau) { # for normal reporting

    # electricity-related
    tmp1 <- NULL

    # Peak demand
    tmp1 <- mbind(tmp1, setNames(as.magpie(apply(p_eldemand, 1:2, max)), "Capacity|Electricity|Peak Demand (GW)"))

    #Electricity demand in this case comprises all consumption
    tmp1 <- mbind(tmp1, setNames(dimSums(p_eldemand * p_taulength / c_demandscale, dim = 3) / 1000, "Final Energy|Electricity (TWh/yr)"))
    tmp1 <- mbind(tmp1, setNames(dimSums(p_eldemand * p_taulength / c_demandscale, dim = 3) * (c_demandscale - 1) / 1000, "Final Energy|Electricity|Losses (TWh/yr)"))

    if(c_LIMESversion >= 2.38) {

      if(!is.null(p_exdem_trans)) {
        #Use of electricity for transport
        tmp1 <- mbind(tmp1, setNames(dimSums(p_exdem_trans * p_taulength, dim = 3) / 1000,
                                     "Secondary Energy Input|Electricity|Transport (TWh/yr)"))
      }

      #Use of electricity for Hydrogen production
      tmp1 <- mbind(tmp1, setNames(output[,, "Primary Energy|Electricity|Hydrogen (TWh/yr)"],
                                   "Secondary Energy Input|Electricity|Hydrogen (TWh/yr)"))
    }


    # heating-related
    tmp2 <- NULL
    if (c_LIMESversion >= 2.28) {
      if (heating == "fullDH") {

        c_buildings <- readGDX(gdx, name = c("c_buildings", "report_c_buildings"),
                               field = "l", format = "first_found") #switch on buildings module

        #Peak demand
        if(c_buildings == 1) {
          p_bd_peakdemand <- readGDX(gdx, name = c("p_bd_peakdemand"), field = "l", format = "first_found", react = 'silent') #heat peak demand in buildings
          p_bd_peakdemand <- limesMapping(p_bd_peakdemand)[ ,y,"sehe"]
          tmp2 <- mbind(tmp2, setNames(p_bd_peakdemand, "Useful Energy|Heating|Buildings|Peak Demand (GW)"))
        }

        #Electricity peak demand due to P2H
        o_PeakDemP2H <- readGDX(gdx, name = "o_PeakDemP2H", field = "l", format = "first_found", react = 'silent') #electricity peak demand from P2H

        if(!is.null(o_PeakDemP2H)) {
          o_PeakDemP2H <- limesMapping(o_PeakDemP2H)[ ,y,"seel"]
          tmp2 <- mbind(tmp2, setNames(o_PeakDemP2H, "Capacity|Electricity|Peak Demand|Power to heat (GW)"))

          o_demP2H_PeakElec <- readGDX(gdx, name = c("o_demP2H_PeakElec"), field = "l", format = "first_found", react = 'silent') #P2H demand when electricity peak
          o_demP2H_PeakElec <- limesMapping(o_demP2H_PeakElec)[ ,y,"seel"]
          tmp2 <- mbind(tmp2, setNames(o_demP2H_PeakElec, "Capacity|Electricity|Power to heat when peak demand (GW)"))
        }

        #Report wasted heat
        if(split_DH_decP2H == 0) {

          tmp2 <- mbind(tmp2, setNames(dimSums(v_heatwaste * p_taulength, dim = 3) / 1000, "Useful Energy|Heating|Heat waste (TWh/yr)"))

        } else {

          tmp2 <- mbind(tmp2, setNames(dimSums(v_heatwaste_DH * p_taulength, dim = 3) / 1000, "Useful Energy|Heating|Heat waste|Heat (TWh/yr)"))
          tmp2 <- mbind(tmp2, setNames(dimSums(v_heatwaste_decP2H * p_taulength, dim = 3) / 1000, "Useful Energy|Heating|Heat waste|Decentral|Electricity (TWh/yr)"))
        }

      }
    }

    ##DACCS
    c_DACCS <- readGDX(gdx, name = c("c_DACCS"), field = "l", format = "first_found", react = 'silent') #heat peak demand in buildings
    if(!is.null(c_DACCS)) {
      if(c_DACCS >= 1) {
        #Load sets, parameters and variables
        tedaccs <- readGDX(gdx, name = "tedaccs")
        v_SECons_DACCS <- readGDX(gdx, name = c("v_SECons_DACCS"), field = "l", format = "first_found", restore_zeros = FALSE)[, , tau] # SE consumption from DACCS

        # create MagPie object of demand with iso3 regions
        v_SECons_DACCS <- limesMapping(v_SECons_DACCS)

        varList_daccs <- list(
          "Final Energy|Electricity|DACCS (TWh/yr)"                           = c(tedaccs),
          "Final Energy|Electricity|DACCS|Liquid solvent (TWh/yr)"            = "liquid_daccs",
          "Final Energy|Electricity|DACCS|Solid sorbent (TWh/yr)"             = "solid_daccs",
          "Final Energy|Electricity|DACCS|CaO ambient weathering (TWh/yr)"    = "caow_daccs"
        )

        for (var in names(varList_daccs)){ #Data is in GWh, convert to TWh
          tmp2 <- mbind(tmp2, setNames(dimSums(v_SECons_DACCS[, , varList_daccs[[var]]] * p_taulength / 1000,  dim = 3),  var))
        }

      }
    }

    # concatenating net and gross demand data
    tmp <- mbind(tmp1, tmp2)

  } else { #if not the reportTau
    # TAU reporting -----------------------------------------------------------

    rename_tau <- function(name, data) {
      .tau_nb <- getNames(data)
      .nm <- paste0(name, "|", .tau_nb, " (GW)")
      out <- setNames(data, .nm)
      return(out)
    }

    tmp <- rename_tau("Demand Load|Electricity", p_eldemand)

    if(!is.null(o_seprodinputP2H)) {
      tmp <- mbind(tmp, rename_tau("Demand Load|Electricity|Transport", p_exdem_trans) )
    }

    #Heating
    if (heating == "fullDH") {

      if(!is.null(o_seprodinputP2H)) {
        tmp <- mbind(tmp, rename_tau("Demand Load|Electricity|Heating", o_seprodinputP2H) )
        tmp <- mbind(tmp, rename_tau("Demand Load|Electricity|non-Heating", p_eldemand - o_seprodinputP2H) )
      }

      if(split_DH_decP2H == 0) {

        tmp <- mbind(tmp, rename_tau("Demand Load|Heating|ETS-covered", p_hedemand) )

      } else {

        tmp <- mbind(tmp, rename_tau("Demand Load|Heating|Heat", v_exdemand_DH) )
        tmp <- mbind(tmp, rename_tau("Demand Load|Heating|Decentral|Electricity", v_exdemand_decP2H) )
        tmp <- mbind(tmp, rename_tau("Demand Load|Heating|ETS-covered", v_exdemand_DH + v_exdemand_decP2H) )

        #Include also demand in buildings supplied by DH
        p_othersec_exdemand_DH <- readGDX(gdx, name = "p_othersec_exdemand_DH", field = "l", format = "first_found") # heat that is provided by DH to other sectors (industry and agriculture) [annual data per sector]
        p_othersec_exdemand_DH <- limesMapping(p_othersec_exdemand_DH)[,getYears(v_exdemand_DH),]
        tmp <- mbind(tmp, rename_tau("Demand Load|Heating|Buildings|Heat", v_exdemand_DH - p_othersec_exdemand_DH) )
        tmp <- mbind(tmp, rename_tau("Demand Load|Heating|Buildings|ETS-covered", v_exdemand_decP2H + v_exdemand_DH - p_othersec_exdemand_DH) )

      }
    }
  }

  return(tmp)
}
pik-piam/limes documentation built on Jan. 27, 2024, 4:45 a.m.