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
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
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
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
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 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 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 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
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 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 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 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 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 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
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
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
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 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
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)
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