Example #1
0
    def ParseXMLNode(self, mineDataNode):
        """
      Generate Mine Data Manager data from xml tree node. 
      """

        # Location
        if (HasChild(mineDataNode, "Location")):
            locNode = GetChild(mineDataNode, "Location")
            self.mineLatLong[0] = GetAttributeValue(locNode, "lat")
            self.mineLatLong[1] = GetAttributeValue(locNode, "long")

        # Orebody
        if (HasChild(mineDataNode, "Orebody")):
            orebodyNode = GetChild(mineDataNode, "Orebody")
            self.theOreBody.ParseXMLNode(orebodyNode)

        theFunctionManager = FunctionManager()
        if ((self.theOreBody.cover < 0.0)
                and (theFunctionManager.HasFunction("DepthOfCover"))):
            self.theOreBody.cover = theFunctionManager.GetFunction(
                "DepthOfCover").f(self.mineLatLong)
            print "Cover set to: ", self.theOreBody.cover

        # Infrastructure
        if (HasChild(mineDataNode, "Infrastructure")):
            infrastructureNode = GetChild(mineDataNode, "Infrastructure")
            self.theInfrastructureManager.ParseXMLNode(infrastructureNode)

        # Economics
        if (HasChild(mineDataNode, "Economics")):
            economicsNode = GetChild(mineDataNode, "Economics")
            self.theEconomicDataManager.ParseXMLNode(economicsNode)
    def CalculateOpex(self, hydrogenManager):
        """Calculate the ongoing costs for the power plant"""

        #  no distinction between opex and sustaining capital (adjust tax calculation)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        opexFunc = theFunctionManager.GetFunction("EnergyOpex_" + self.type)

        opexPerAnnumPerMW = opexFunc.f(
            [self.plantCapacity * theUnitManager.ConvertTo("MW")])

        #print "Power plant type: ", self.type
        #print "Power plant capacity (MW)", self.plantCapacity  *  theUnitManager.ConvertTo("MW")
        #print "Capacity factor", self.capacityFactor
        #print "Power plant Opex Per Annum", opexPerAnnum

        self.opex = np.zeros(self.projectLife)
        self.opex[
            self.
            startupTime:] = opexPerAnnumPerMW * self.capacityFactor * self.plantCapacity * theUnitManager.ConvertTo(
                "MW")

        #print "self.plantCapacity",self.plantCapacity
        #print "power opex", self.opex

        rv = np.array(self.opex)

        if (self.secondaryPowerSource):
            rv += self.secondaryPowerSource.CalculateOpex(hydrogenManager)

        return rv
    def CalculateMineCapacityFromMass(self, orebodyMass):
        """
      Determine the maximum annual extraction for the mine using Taylor's rule from orebodyMass given in tonnes. 
      """
        theUnitManager = UnitManager()

        #orebodyMass =  mineManager.theOreBody.CalculateDepositMass()*theUnitManager.ConvertTo("tonne")

        theFunctionManager = FunctionManager()

        if (self.miningMethod == "OCUG"):
            taylorsRuleFunc = theFunctionManager.GetFunction(
                "TaylorsRule_" + self.miningMethod[:2])
        else:
            taylorsRuleFunc = theFunctionManager.GetFunction("TaylorsRule_" +
                                                             self.miningMethod)
        daysPerYear = 350
        #Todo("Check operating days per year - assuming 350 days")
        mineProductionCapacity = daysPerYear * taylorsRuleFunc.f(
            [orebodyMass]) * theUnitManager.ConvertToBaseUnits("tonne")

        #self.mineOreProductionCapacity = self.mineCapacity
        #print "Mine ore capacity from Taylor's rule in Mt/year", self.mineCapacity* theUnitManager.ConvertTo("1e6 tonne")
        #print "Mine ore capacity from Taylor's rule in Mt/day", self.mineCapacity* theUnitManager.ConvertTo("1e6 tonne")/350.

        return mineProductionCapacity
Example #4
0
 def WriteXMLNode(self, root,recordSha=True):
   """
   Write problem to xml node
   """
   if(recordSha):
     theGitSha = GetGitSha()
     SetAttributeString(root,"sha",theGitSha)
   
   #Functions
   theFunctionManager = FunctionManager()  
   funcMngrNode = AddChild(root,"Functions")
   theFunctionManager.WriteXMLNode(funcMngrNode) 
   
   # Mine data
   mineNode = AddChild(root,"MineData")
   self.theMineDataManager.WriteXMLNode(mineNode)
   
   # Output
   outputNode = AddChild(root,"Output")
   SetAttributeString(outputNode,"prefix",self.outputPrefix)
   
   # Actions
   #theActionManager = ActionManager()        
   actnMngrNode = AddChild(root,"Actions")
   self.theActionManager.WriteXMLNode(actnMngrNode) 
   
   return root
    def CalculateMineCapacity(self, problemManager, mineManager):
        """
      Determine the maximum annual extraction for the mine using Taylor's rule
      """
        theUnitManager = UnitManager()

        orebodyMass = mineManager.theOreBody.CalculateDepositMass(
        ) * theUnitManager.ConvertTo("tonne")

        theFunctionManager = FunctionManager()

        if (self.miningMethod == "OCUG"):
            taylorsRuleFunc = theFunctionManager.GetFunction(
                "TaylorsRule_" + self.miningMethod[:2])
        else:
            taylorsRuleFunc = theFunctionManager.GetFunction("TaylorsRule_" +
                                                             self.miningMethod)
        daysPerYear = 350
        # operating days per year - assuming 350 days
        self.mineCapacity = daysPerYear * taylorsRuleFunc.f(
            [orebodyMass]) * theUnitManager.ConvertToBaseUnits("tonne")
        self.mineOreProductionCapacity = self.mineCapacity

        print("Mine ore capacity from Taylor's rule in Mt/year",
              self.mineCapacity * theUnitManager.ConvertTo("1e6 tonne"))

        return self.mineCapacity
Example #6
0
    def CalculateRehabilitationExpenses(self, problemManager, mineDataManager):
        """
      Calculate rehabilitation costs.
      """

        self.rehabilitationCosts = np.zeros(
            mineDataManager.theMiningSystem.mineLife)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        processingCapacity = mineDataManager.theProcessingSystem.processingCapacity * theUnitManager.ConvertTo(
            "1e6 tonne")
        rehabSecurityFunc = theFunctionManager.GetFunction(
            "RehabilitationSecurity_" +
            mineDataManager.theProcessingSystem.processingMethod)

        self.rehabSecurityCost = rehabSecurityFunc.f([processingCapacity])

        # NT model: 1% of rehabSecurity paid each year of operation
        self.rehabilitationCosts = np.ones(
            mineDataManager.theMiningSystem.mineLife
        ) * self.rehabSecurityCost * 0.01

        self.rehabilitationCosts[0] = self.rehabSecurityCost

        self.rehabilitationNPC = self.CalculateRehabilitationBondNPC(
            problemManager, mineDataManager)

        return self.rehabilitationCosts
    def CalculateProcessingOpex(self, problemManager, mineDataManager):

        self.processingOpex = np.zeros(
            mineDataManager.theMiningSystem.mineLife)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        self.processingOpex = self.oreProcessed * theUnitManager.ConvertTo(
            "tonne")  # tonnes processed per year

        processingOpexFunc = theFunctionManager.GetFunction(
            "ProcessingOpex_" + self.processingMethod)
        opexPerTonne = processingOpexFunc.f(
            [self.processingCapacity * theUnitManager.ConvertTo("1e6 tonne")])

        print("Processing method: ", self.processingMethod)
        #print "Processing capacity (kg ore)", self.processingCapacity
        print("Processing capacity (Mt ore)",
              self.processingCapacity * theUnitManager.ConvertTo("1e6 tonne"))
        print("Processing Opex Per Tonne ", opexPerTonne)

        self.processingOpex *= opexPerTonne

        if (self.secondaryProcessingSystem):
            secondaryOpex = self.secondaryProcessingSystem.CalculateProcessingOpex(
                problemManager, mineDataManager)
            self.processingOpex += secondaryOpex

        return self.processingOpex
Example #8
0
    def DetermineDistanceToInfrastructure(self, problemManager,
                                          mineDataManager):
        """
      Use available data to determine the distance to infrastructure (single site calculation only).
      """
        theUnitManager = UnitManager()
        theFunctionManager = FunctionManager()

        oneKm = theUnitManager.ConvertToBaseUnits(
            "km")  # assumed that distances are given in km
        self.distanceToRoad = theFunctionManager.GetFunction(
            "DistanceToRoad").f(mineDataManager.mineLatLong[::-1]) * oneKm
        self.distanceToRail = theFunctionManager.GetFunction(
            "DistanceToRail").f(mineDataManager.mineLatLong[::-1]) * oneKm
        self.distanceToWater = theFunctionManager.GetFunction(
            "DistanceToWater").f(mineDataManager.mineLatLong[::-1]) * oneKm
        self.distanceToPower = theFunctionManager.GetFunction(
            "DistanceToPower").f(mineDataManager.mineLatLong[::-1]) * oneKm

        self.roadTransportationDistance = theFunctionManager.GetFunction(
            "RoadTransportationDistance").f(
                mineDataManager.mineLatLong[::-1]) * oneKm
        self.railTransportationDistance = theFunctionManager.GetFunction(
            "RailTransportationDistance").f(
                mineDataManager.mineLatLong[::-1]) * oneKm

        if (self.calculateGas):
            self.distanceToGas = theFunctionManager.GetFunction(
                "DistanceToGas").f(mineDataManager.mineLatLong[::-1]) * oneKm
Example #9
0
 def CalculateOpex(self, hydrogenManager):
   """Calculate opex costs for energy storage facility."""
   
   theFunctionManager =  FunctionManager()
   theUnitManager = UnitManager()
   
   opexFunc = theFunctionManager.GetFunction("StorageOpex_" + self.type)
   
   # opex Per MWh stored as a function of output capacity in MW
   opexPerMWh =  opexFunc.f( [self.storageOutputCapacity *theUnitManager.ConvertTo("MW")] )
   self.opex = opexPerMWh*self.energyStored*theUnitManager.ConvertTo("MWh")
   
   return self.opex
    def CalculateMiningOpex(self, mineManager):
        """Calculating ongoing costs for mining operation. Note that all costs before production, and later a proportion of these costs is assumed to be capitalized (sustaining capital)."""

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        if (self.miningMethod == "K2SO4"):
            # need to distinguish brine mining from other forms.
            miningOpexFunc = theFunctionManager.GetFunction("MiningOpex_" +
                                                            self.miningMethod)
        else:
            miningOpexFunc = theFunctionManager.GetFunction(
                "MiningOpex_" +
                self.miningMethod[:2])  #  NB. just opencut or underground
        opexPerTonne = miningOpexFunc.f(
            [self.mineCapacity * theUnitManager.ConvertTo("1e6 tonne")])
        ugOpexPerTonnePerMDepth = self.ugHaulCostPerDepth * theUnitManager.ConvertTo(
            "AUD/tonne/m")

        #print "Mining method: ", self.miningMethod
        #print "Mining capacity (Mt material)", self.mineCapacity  *  theUnitManager.ConvertTo("1e6 tonne")
        #print "Mining Opex Per Tonne ", opexPerTonne

        if (self.miningMethod == "OCUG"):

            #print "self.ugOpexPerTonne",self.ugOpexPerTonne
            self.miningOpex = (self.materialMined - self.ugMaterialMined
                               ) * theUnitManager.ConvertTo(
                                   "tonne")  # tonnes mined per year
            self.miningOpex *= opexPerTonne

            self.miningOpex += self.ugMaterialMined * theUnitManager.ConvertTo(
                "tonne") * (self.ugOpexPerTonne + ugOpexPerTonnePerMDepth *
                            (self.depths - 60))

        else:
            self.miningOpex = self.materialMined * theUnitManager.ConvertTo(
                "tonne")  # tonnes mined per year
            if (self.miningMethod[:2] == "UG"):
                self.miningOpex *= opexPerTonne + ugOpexPerTonnePerMDepth * (
                    self.depths - 60)
            else:
                self.miningOpex *= opexPerTonne

        # pre-production expenses are capitalized
        self.miningCapex[:self.
                         mineStartupTime] += self.miningOpex[:self.
                                                             mineStartupTime]
        self.miningOpex[:self.mineStartupTime] = 0.0

        return self.miningOpex
Example #11
0
 def ParseXMLNode(self, rootNode):
   """
   Generate Problem Manager data from xml tree node. 
   """
   
   # remove "Problem" branch if present
   if(HasChild(rootNode,"Problem")):
     root = GetChild(rootNode,"Problem")
     
   # load parameters not set from command line
   # done here to prevent recursion
   theParameterManager = ParameterManager()  
   if(HasChild(rootNode,"Parameters")):
     parameterNode = GetChild(rootNode,"Parameters")
     
     for child in GetChildren(parameterNode):
     
       name = GetAttributeString(child,"name")
       
       if(not theParameterManager.HasParameter(name) ):
         paramString = GetAttributeString(child,"value")
         theParameterManager.SetParameter(name,paramString)
         print "param: ", name, " value:",paramString
     
   # create functions before other classes (after UnitManager & Parameter Manager)
   theFunctionManager = FunctionManager()  
   if(HasChild(rootNode,"Functions")):
     functionNode = GetChild(rootNode,"Functions")
     theFunctionManager.ParseXMLNode(functionNode,self) 
   
   # Mine data
   if(HasChild(rootNode,"MineData")):
     mineDataNode = GetChild(rootNode,"MineData")
     self.theMineDataManager.ParseXMLNode(mineDataNode) 
     
    
   # Output - eventually will make into a manager
   if(HasChild(rootNode,"Output")):
     outputNode = GetChild(rootNode,"Output")
     self.outputPrefix = GetAttributeFileString(outputNode,"prefix")
     self.outputType = GetAttributeStringOrDefault(outputNode,"type","")
     
     self.recordRange = GetAttributeValueOrDefault(outputNode,"recordRange",False)
     
   # Regional calculation - optional
   if(HasChild(rootNode,"RegionalCalculation")):
     regionalCalculationNode = GetChild(rootNode,"RegionalCalculation")
     self.theRegionalCalculationManager.ParseXMLNode(regionalCalculationNode) 
Example #12
0
    def CalculateCapex(self, hydrogenManager):
        """ Calculate hydrogen plant startup costs. NB all costs are assumed capitalized."""

        self.capex = np.zeros(self.projectLife)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        capexFunc = theFunctionManager.GetFunction("HydrogenCapex_" +
                                                   self.type)

        self.capex[0] = capexFunc.f([
            self.hydrogenPlantCapacity * theUnitManager.ConvertTo("1e6 tonne")
        ])

        return self.capex
Example #13
0
    def CalculateCapex(self, hydrogenManager):
      """Calculate capex costs for energy storage facility."""

      self.capex = np.zeros(hydrogenManager.thePowerPlant.projectLife)
      
      theFunctionManager =  FunctionManager()
      theUnitManager =  UnitManager()
      
      capexFunc = theFunctionManager.GetFunction("StorageCapex_" + self.type)
        
      # Capex as a function of output capacity in MW
      self.capex[0] =  capexFunc.f( [self.storageOutputCapacity*theUnitManager.ConvertTo("MW")] )
      
      #print("self.capex", self.capex)
      
      return self.capex
Example #14
0
    def CalculateProcessingCapex(self, problemManager, mineDataManager):

        self.processingCapex = np.zeros(
            mineDataManager.theMiningSystem.mineLife)

        theFunctionManager = FunctionManager()

        processingCapexFunc = theFunctionManager.GetFunction(
            "ProcessingCapex_" + self.processingMethod)

        theUnitManager = UnitManager()
        self.processingCapex[0] = processingCapexFunc.f(
            [self.processingCapacity * theUnitManager.ConvertTo("1e6 tonne")])
        print "Processing Capex ", self.processingCapex[0]

        return self.processingCapex
    def CalculateMiningOpex(self, mineManager):
        #  no distinction between opex and sustaining capital (adjust tax calculation)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        miningOpexFunc = theFunctionManager.GetFunction(
            "MiningOpex_" +
            self.miningMethod[:2])  #  NB. just opencut or underground
        opexPerTonne = miningOpexFunc.f(
            [self.mineCapacity * theUnitManager.ConvertTo("1e6 tonne")])
        ugOpexPerTonnePerMDepth = self.ugHaulCostPerDepth * theUnitManager.ConvertTo(
            "AUD/tonne/m")

        print("Mining method: ", self.miningMethod)
        print("Mining capacity (Mt material)",
              self.mineCapacity * theUnitManager.ConvertTo("1e6 tonne"))
        print("Mining Opex Per Tonne ", opexPerTonne)

        if (self.miningMethod == "OCUG"):

            #print "self.ugOpexPerTonne",self.ugOpexPerTonne
            self.miningOpex = (self.materialMined - self.ugMaterialMined
                               ) * theUnitManager.ConvertTo(
                                   "tonne")  # tonnes mined per year
            self.miningOpex *= opexPerTonne

            self.miningOpex += self.ugMaterialMined * theUnitManager.ConvertTo(
                "tonne") * (self.ugOpexPerTonne + ugOpexPerTonnePerMDepth *
                            (self.depths - 60))

        else:
            self.miningOpex = self.materialMined * theUnitManager.ConvertTo(
                "tonne")  # tonnes mined per year
            if (self.miningMethod[:2] == "UG"):
                self.miningOpex *= opexPerTonne + ugOpexPerTonnePerMDepth * (
                    self.depths - 60)
            else:
                self.miningOpex *= opexPerTonne

        # pre-production expenses are capitalized
        self.miningCapex[:self.
                         mineStartupTime] = self.miningOpex[:self.
                                                            mineStartupTime]
        self.miningOpex[:self.mineStartupTime] = 0.0

        return self.miningOpex
Example #16
0
    def CalculateOpex(self, hydrogenManager):
        """ Calculate hydrogen plant opex. NB no distinction between opex and sustaining capital."""

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        opexFunc = theFunctionManager.GetFunction("HydrogenOpex_" + self.type)

        opexPerTonne = opexFunc.f([
            self.hydrogenPlantCapacity * theUnitManager.ConvertTo("1e6 tonne")
        ])

        if (self.type == "SteamMethane"
                and hydrogenManager.theEconomicDataManager.calculateGasCosts):
            AUD2018 = 1.0
            gasPrice = hydrogenManager.theEconomicDataManager.commodityPrices[
                "gas"] * theUnitManager.ConvertTo("1/GJ") * AUD2018

            opexPerTonne += (gasPrice - 8) * 0.1726 * 1000

            # 0.1726 = change in LCOH/kg per $AUD/GJ price for gas. Based on CSIRO estimate and $8/GJ gas price.

        if (self.type == "BlackCoalGasification" and
                hydrogenManager.theEconomicDataManager.calculateBlackCoalCosts
            ):
            AUD2018 = 1.0
            coalPrice = hydrogenManager.theEconomicDataManager.commodityPrices[
                "blackCoal"] * theUnitManager.ConvertTo("1/GJ") * AUD2018

            opexPerTonne += (coalPrice - 3) * 0.2248 * 1000
            # 0.2248 = change in LCOH/kg per $AUD/GJ price for black coal. Based on CSIRO estimate and $3/GJ coal price.

        if (self.type == "BrownCoalGasification" and
                hydrogenManager.theEconomicDataManager.calculateBrownCoalCosts
            ):
            # NB brown coal estimates use CSIRO estimated price for brown coal ($1.50/GJ) but estimate relative change based on black coal price due to a lack of data.
            AUD2018 = 1.0
            coalPrice = hydrogenManager.theEconomicDataManager.commodityPrices[
                "brownCoal"] * theUnitManager.ConvertTo("1/GJ") * AUD2018

            opexPerTonne += (coalPrice - 1.5) * 0.2248 * 1000
            # 0.2248 = change in LCOH/kg per $AUD/GJ price for *black* coal (no equivalent information available for brown coal). Based on CSIRO estimate and $1.5/GJ brown coal price.

        self.opex = opexPerTonne * self.hydrogenProduced * theUnitManager.ConvertTo(
            "tonne")

        return self.opex
    def CalculateMiningCapex(self, mineManager):

        self.miningCapex = np.zeros(self.mineLife)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        if (self.miningMethod == "OCUG"):
            miningCapexFunc = theFunctionManager.GetFunction(
                "MiningCapex_" + self.miningMethod[:2])
        else:
            miningCapexFunc = theFunctionManager.GetFunction("MiningCapex_" +
                                                             self.miningMethod)

        self.miningCapex[0] = miningCapexFunc.f(
            [self.mineCapacity * theUnitManager.ConvertTo("1e6 tonne")])

        return self.miningCapex
    def CalculateMiningCapex(self, mineManager):
        """Calculating startup costs for the mining operation."""

        self.miningCapex = np.zeros(self.mineLife)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        if (self.miningMethod == "OCUG"):
            miningCapexFunc = theFunctionManager.GetFunction(
                "MiningCapex_" + self.miningMethod[:2])
        else:
            miningCapexFunc = theFunctionManager.GetFunction("MiningCapex_" +
                                                             self.miningMethod)

        self.miningCapex[0] = miningCapexFunc.f(
            [self.mineCapacity * theUnitManager.ConvertTo("1e6 tonne")])

        if (self.doProvingCostCalculation):
            self.miningCapex[0] += self.CalculateProvingCosts(mineManager)

        return self.miningCapex
    def CalculateCapex(self, hydrogenManager):
        """Calculate the startup costs for the power plant"""

        self.capex = np.zeros(self.projectLife)

        theFunctionManager = FunctionManager()
        theUnitManager = UnitManager()

        capexFunc = theFunctionManager.GetFunction("EnergyCapex_" + self.type)

        self.capex[0] = capexFunc.f(
            [self.plantCapacity * theUnitManager.ConvertTo("MW")])

        #print "self.capex", self.capex

        rv = np.array(self.capex)

        #print "power capex", self.capex

        if (self.secondaryPowerSource):
            rv += self.secondaryPowerSource.CalculateCapex(hydrogenManager)

        return self.capex
Example #20
0
 def DetermineDistanceToInfrastructure(self, problemManager, mineDataManager):
   """
   Use available data to determine the most likely processing method/capacity/opex etc.
   """
   theUnitManager = UnitManager()
   theFunctionManager = FunctionManager()
   
   oneKm = theUnitManager.ConvertToBaseUnits("km")  # assumed that distances are given in km
   self.distanceToRoad = theFunctionManager.GetFunction("DistanceToRoad").f( mineDataManager.mineLatLong  ) *oneKm
   self.distanceToRail = theFunctionManager.GetFunction("DistanceToRail").f( mineDataManager.mineLatLong  )   *oneKm
   self.distanceToWater = theFunctionManager.GetFunction("DistanceToWater").f( mineDataManager.mineLatLong  )  *oneKm
   self.distanceToPower = theFunctionManager.GetFunction("DistanceToPower").f( mineDataManager.mineLatLong  )  *oneKm
        
   self.roadTransportationDistance = theFunctionManager.GetFunction("RoadTransportationDistance").f( mineDataManager.mineLatLong  )  *oneKm
   self.railTransportationDistance = theFunctionManager.GetFunction("RailTransportationDistance").f( mineDataManager.mineLatLong  )  *oneKm 
 
   if(self.calculateGas): 
     self.distanceToGas = theFunctionManager.GetFunction("DistanceToGas").f( mineDataManager.mineLatLong  ) *oneKm
    def CalculateOreMined(self, mineManager):

        self.materialMined = np.zeros(self.mineLife)
        self.oreMined = np.zeros(self.mineLife)
        self.wasteMined = np.zeros(self.mineLife)
        self.depths = np.zeros(self.mineLife)

        if (self.actualMineStartupTime > 1):
            tt = int(np.floor(self.actualMineStartupTime))
            self.materialMined[:tt - 1] = self.mineCapacity
            self.materialMined[
                tt - 1] = self.mineCapacity * (self.actualMineStartupTime - tt)
        else:
            self.materialMined[
                0] = self.mineCapacity * self.actualMineStartupTime

        self.materialMined[
            self.mineStartupTime:
            -1] = self.mineCapacity  # constant in all years but last
        self.materialMined[-1] = self.orebodyMass - self.mineCapacity * (
            self.mineLife - self.mineStartupTime - 1)  # remainder in last year

        # assuming all material mined is ore in underground mines

        if (self.miningMethod[:2] == "OC"):  # open cut

            self.oreMined = np.array(self.materialMined)
            self.oreMined[:self.mineStartupTime] = 0.0
            #self.wasteMined =  (1 - oreFraction)*self.oreMined
            #self.oreMined *=  oreFraction

            theUnitManager = UnitManager()
            theFunctionManager = FunctionManager()

            ugMiningOpexFunc = theFunctionManager.GetFunction(
                "MiningOpex_UG_ST"
            )  # underground stoping assumed as alternative mining method
            ugOpexPerTonne = ugMiningOpexFunc.f(
                [self.mineCapacity * theUnitManager.ConvertTo("1e6 tonne")])
            ugOpexPerTonneMDepth = self.ugHaulCostPerDepth * theUnitManager.ConvertTo(
                "AUD/tonne/m")

            ocMiningOpexFunc = theFunctionManager.GetFunction("MiningOpex_OC")

            oreProductionRate = self.mineOreProductionCapacity  # taylor's rule gives average ore produced not total material

            minD = mineManager.theOreBody.cover
            maxD = mineManager.theOreBody.cover + mineManager.theOreBody.height
            w = mineManager.theOreBody.length
            l = mineManager.theOreBody.width
            alpha = self.alpha

            switchingDepth = self.FindOpUgSwitchingDepth(
                oreProductionRate, w, l, minD, maxD, alpha, ocMiningOpexFunc,
                ugOpexPerTonne, ugOpexPerTonneMDepth
            ) + 1e-3  # add a mm to prevent roundoff error

            print("OC/UG Switching Depth", switchingDepth)
            print("minD", minD)
            print("maxD", maxD)

            if (switchingDepth > minD):

                maxOCdepth = np.minimum(switchingDepth, maxD)

                ocTotalMaterialProductionRate = self.RequiredTotalCapacity(
                    oreProductionRate, w, l, minD, maxOCdepth,
                    alpha)  # total material produced (mass Rate)
                self.mineCapacity = ocTotalMaterialProductionRate
                rho = mineManager.theOreBody.orebodyMass / mineManager.theOreBody.orebodyVolume
                ocTotalMaterialProductionVolume = ocTotalMaterialProductionRate / rho  # assumes ore body density = material density

                if (switchingDepth >= maxD):

                    #print "Open cut only"
                    # all open cut
                    self.materialMined[:self.
                                       mineStartupTime] = self.mineCapacity
                    self.materialMined[0] = self.mineCapacity * (
                        self.actualMineStartupTime -
                        np.floor(self.actualMineStartupTime))
                    self.materialMined[
                        self.mineStartupTime:] = ocTotalMaterialProductionRate

                    # ore mined varies over the years (but on average is equal to the mine ore production capacity) - this may not be needed.
                    d = minD
                    dd = minD  # maxD # establish default for when mineLife == mineStartupTime (i.e. no loop)

                    self.depths[self.mineStartupTime - 1] = minD
                    for year in range(self.mineStartupTime, self.mineLife - 1):
                        dd = self.UpdateOpenPitDepth(
                            w, l, d, ocTotalMaterialProductionVolume, alpha)
                        self.oreMined[year] = (
                            (dd - d) / mineManager.theOreBody.height
                        ) * mineManager.theOreBody.orebodyMass
                        d = dd
                        self.depths[year] = dd

                    self.oreMined[
                        -1] = mineManager.theOreBody.orebodyMass - np.sum(
                            self.oreMined[:-1]
                        )  # add any remaining ore to the last year ore
                    self.depths[-1] = maxD

                    fractionOre = self.OpenPitOreFraction(
                        w, l, dd, maxD, self.alpha)

                    self.materialMined[-1] = self.oreMined[-1] / fractionOre
                    #print "self.materialMined[-1]",self.materialMined[-1],dd,maxD

                else:

                    #print "Mixed opencut and underground"

                    self.miningMethod = "OCUG"
                    self.ugMaterialMined = np.zeros(self.mineLife)
                    self.ugOpexPerTonne = ugOpexPerTonne

                    switchingTime = (
                        (switchingDepth - minD) / mineManager.theOreBody.height
                    ) * mineManager.theOreBody.orebodyMass / oreProductionRate
                    switchingTime += self.mineStartupTime
                    theSwitchingYear = int(np.floor(switchingTime))

                    print("Op/UG Switching Time,year", switchingTime,
                          theSwitchingYear)

                    print(
                        "OC opex",
                        ocMiningOpexFunc.f([
                            self.mineCapacity *
                            theUnitManager.ConvertTo("1e6 tonne")
                        ]))
                    print("UG opex", ugOpexPerTonne)
                    print(
                        "OC capacity (Mt)",
                        self.mineCapacity *
                        theUnitManager.ConvertTo("1e6 tonne"))
                    print(
                        "UG capacity (Mt)",
                        self.mineOreProductionCapacity *
                        theUnitManager.ConvertTo("1e6 tonne"))

                    firstUGYear = theSwitchingYear + 1
                    if (firstUGYear < self.mineLife):
                        self.materialMined[firstUGYear:] = self.oreMined[
                            firstUGYear:]  # already true
                        self.ugMaterialMined[firstUGYear:] = self.oreMined[
                            firstUGYear:]

                        self.depths[theSwitchingYear:] = np.linspace(
                            switchingDepth, maxD,
                            self.mineLife - theSwitchingYear)

                    if (theSwitchingYear < self.mineLife):
                        self.materialMined[
                            theSwitchingYear] = ocTotalMaterialProductionRate * (
                                switchingTime - theSwitchingYear
                            ) + self.mineOreProductionCapacity * (
                                1 - switchingTime + theSwitchingYear)
                        #self.oreMined[theSwitchingYear] = self.mineOreProductionCapacity*(switchingTime-theSwitchingYear)   # we will add OC contribution later
                    self.materialMined[:
                                       theSwitchingYear] = ocTotalMaterialProductionRate  # oc material production up to time of switch

                    # ore mined varies over the years (but on average is equal to the mine ore production capacity) - this may not be needed.
                    d = minD
                    self.depths[self.mineStartupTime - 1] = minD
                    for year in range(self.mineStartupTime, theSwitchingYear):
                        dd = self.UpdateOpenPitDepth(
                            w, l, d, ocTotalMaterialProductionVolume, alpha)
                        self.oreMined[year] = (
                            (dd - d) / mineManager.theOreBody.height
                        ) * mineManager.theOreBody.orebodyMass
                        #print "dd",dd,ocTotalMaterialProductionVolume, (dd-d)*w*l, alpha
                        d = dd
                        self.depths[year] = dd

                    self.oreMined[
                        theSwitchingYear] = self.mineOreProductionCapacity * (
                            switchingTime - self.mineStartupTime
                        ) - np.sum(
                            self.oreMined[:theSwitchingYear]
                        )  # add any remaining oc ore to the switching year ore

                    self.ugMaterialMined[
                        theSwitchingYear] = self.mineOreProductionCapacity * (
                            1 - switchingTime + theSwitchingYear
                        )  # ug component
                    self.oreMined[theSwitchingYear] += self.ugMaterialMined[
                        theSwitchingYear]  # ug component
                    self.depths[theSwitchingYear] = switchingDepth
                    self.depths[-1] = maxD
                # account for

            else:
                print(
                    "Open cut mining is less economic than underground mining")
                self.materialMined[:] = 0.0  # ug is better at all depths
                self.oreMined[:] = 0.0

        else:
            # assuming all material mined is ore in underground mines

            minD = mineManager.theOreBody.cover
            maxD = mineManager.theOreBody.cover + mineManager.theOreBody.height

            self.oreMined[self.mineStartupTime:] = self.materialMined[
                self.mineStartupTime:]
            self.depths[self.mineStartupTime - 1:] = np.linspace(
                minD, maxD, self.mineLife + 1 - self.mineStartupTime)

        self.wasteMined = self.materialMined - self.oreMined

        return self.oreMined
Example #22
0
 def ParseXMLNode(self, mineDataNode):
   """
   Generate Mine Data Manager data from xml tree node. 
   """
   
   # Location
   if(HasChild(mineDataNode,"Location")):
     locNode = GetChild(mineDataNode,"Location")
     self.mineLatLong[0] = GetAttributeValue(locNode,"lat")
     self.mineLatLong[1] = GetAttributeValue(locNode,"long")
   
   # Orebody
   if(HasChild(mineDataNode,"Orebody")):
     orebodyNode = GetChild(mineDataNode,"Orebody")
     orebodyName = GetAttributeStringOrDefault(orebodyNode,"name","unnamed")
     self.theOrebodies[orebodyName] = OreBodyDataManager(orebodyName)
     self.theOrebodies[orebodyName].ParseXMLNode(orebodyNode)
     self.theOrebodies["Active"] = self.theOrebodies[orebodyName]
     self.theOreBody = self.theOrebodies[orebodyName]
     self.theMines[orebodyName] = MiningSystemDataManager(orebodyName)
     self.theMiningSystem = self.theMines[orebodyName]
     
   # Orebody Set
   if(HasChild(mineDataNode,"OrebodyList")):
     orebodyList = GetChild(mineDataNode,"OrebodyList")
     setActive = True
     for orebodyNode in GetChildren(orebodyList):
     
       if(GetXMLTag(orebodyNode) != "note"):
         
         orebodyName = GetAttributeString(orebodyNode,"name")
         self.theOrebodies[orebodyName] = OreBodyDataManager(orebodyName)
         self.theOrebodies[orebodyName].latLong = np.array(self.mineLatLong)  # set global lat long as orebody lat long as default
         self.theOrebodies[orebodyName].ParseXMLNode(orebodyNode)
       
         self.theMines[orebodyName] = MiningSystemDataManager(orebodyName)
       
         if(setActive):
           self.theOrebodies["Active"] = self.theOrebodies[orebodyName]
           self.theOreBody = self.theOrebodies[orebodyName]
           self.theMiningSystem = self.theMines[orebodyName]
           setActive = False
         
       
   
   theFunctionManager = FunctionManager()
   if( (self.theOreBody.cover < 0.0 ) and (theFunctionManager.HasFunction("DepthOfCover") ) ):
     self.theOreBody.cover = theFunctionManager.GetFunction("DepthOfCover").f( self.mineLatLong[::-1]  )
     print("Cover set to: ", self.theOreBody.cover )
     
     
   
   if(HasChild(mineDataNode,"Mining")):
     miningNode = GetChild(mineDataNode,"Mining")
     # pass XML settings to all orebodies
     self.theMines["Active"].ParseXMLNode(miningNode)
     for orebodyName in self.theOrebodies:
       self.theMines[orebodyName].ParseXMLNode(miningNode)
     
   # Infrastructure
   if(HasChild(mineDataNode,"Infrastructure")):
     infrastructureNode = GetChild(mineDataNode,"Infrastructure")
     self.theInfrastructureManager.ParseXMLNode(infrastructureNode)      
 
   # Rehabilitation
   if(HasChild(mineDataNode,"Rehabilitation")):
     rehabNode = GetChild(mineDataNode,"Rehabilitation")
     self.theRehabilitationManager = RehabilitationDataManager()
     self.theRehabilitationManager.ParseXMLNode(rehabNode)    
     
   # Economics
   if(HasChild(mineDataNode,"Economics")):
     economicsNode = GetChild(mineDataNode,"Economics")
     self.theEconomicDataManager.ParseXMLNode(economicsNode)
Example #23
0
 def ParseXMLNode(self, rootNode):
   """
   Generate Problem Manager data from xml tree node. 
   """
   
   # remove "Problem" branch if present
   if(HasChild(rootNode,"Problem")):
     root = GetChild(rootNode,"Problem")
     
   # load parameters not set from command line
   # done here to prevent recursion
   theParameterManager = ParameterManager()  
   if(HasChild(rootNode,"Parameters")):
     parameterNode = GetChild(rootNode,"Parameters")
     
     for child in GetChildren(parameterNode):
     
       name = GetAttributeString(child,"name")
       
       if(not theParameterManager.HasParameter(name) ):
         paramString = GetAttributeString(child,"value")
         theParameterManager.SetParameter(name,paramString)
         print("param: ", name, " value:",paramString)
     
   # create functions before other classes (after UnitManager & Parameter Manager)
   theFunctionManager = FunctionManager()  
   if(HasChild(rootNode,"Functions")):
     functionNode = GetChild(rootNode,"Functions")
     theFunctionManager.ParseXMLNode(functionNode,self) 
   
   # Mine data
   if(HasChild(rootNode,"MineData")):
     mineDataNode = GetChild(rootNode,"MineData")
     self.theMineDataManager.ParseXMLNode(mineDataNode) 
   
   # Processing data
   if(HasChild(rootNode,"Processing")):
     processingNode = GetChild(rootNode,"Processing")
     self.theMineDataManager.theProcessingSystem.ParseXMLNode(processingNode)
    
   # Hydrogen data
   if(HasChild(rootNode,"HydrogenData")):
     hydrogenDataNode = GetChild(rootNode,"HydrogenData")
     self.theHydrogenDataManager.ParseXMLNode(hydrogenDataNode) 
     
   # Output - eventually will make into a manager
   if(HasChild(rootNode,"Output")):
     outputNode = GetChild(rootNode,"Output")
     self.outputPrefix = GetAttributeFileString(outputNode,"prefix")
     self.outputType = GetAttributeStringOrDefault(outputNode,"type","")
     
     self.recordRange = GetAttributeValueOrDefault(outputNode,"recordRange",False)
     
   # Regional calculation - optional - eventually will make into a solver
   if(HasChild(rootNode,"RegionalCalculation")):
     regionalCalculationNode = GetChild(rootNode,"RegionalCalculation")
     self.theRegionalCalculationManager.ParseXMLNode(regionalCalculationNode) 
 
   # Solver manager (after UnitManager & Parameter Manager & Function Manager)
   if(HasChild(rootNode,"Solvers")):
     solversNode = GetChild(rootNode,"Solvers")
     theSolverManager = SolverManager()
     theSolverManager.ParseXMLNode(self,solversNode) 
 
   # Create actions after other classes (after UnitManager & Parameter & Solver Manager)
   self.theActionManager = ActionManager()  
   if(HasChild(rootNode,"Actions")):
     actionNode = GetChild(rootNode,"Actions")
     self.theActionManager.ParseXMLNode(actionNode,self)   
   else:
   
     # Add actions for backwards compatibility
     # A) If regional manager present - run regional calculation
     # B) Otherwise add single site calculation
     
     # This will be depreciated (need to issue warning)
     if(self.theRegionalCalculationManager.type):
         self.theActionManager.actions.append( RegionalCalculationAction() )
     else:
         self.theActionManager.actions.append( SingleSiteEvaluationAction() )