Source code for duo.core.material

import duo.core.element as duoelement
import duo.core.duo_exception as de
import duo.core.constant as constant

#------------------------------------------------------------
#------------------------------------------------------------
[docs]class ElementComponent: #------------------------------------------------------------ #------------------------------------------------------------ def __init__(self, Z): self.Z = Z self.weightFraction = 0.0 self.atomicFraction = 0.0
#------------------------------------------------------------ #------------------------------------------------------------
[docs]class Material: #------------------------------------------------------------ #------------------------------------------------------------ def __init__(self, name, elementTable): self.name = name self.elementList = {} self.elementTable = elementTable self.density = 0.0 self.isCommitted = False #------------------------------------------------------------ #------------------------------------------------------------
[docs] def AddElement(self, Z, **kwargs): # if Z exists in the material, accumulate if Z in self.elementList.keys(): for key, value in kwargs.items(): if "weightFraction" == key: self.elementList[Z].weightFraction += kwargs["weightFraction"] elif "atomicFraction" == key: self.elementList[Z].atomicFraction += kwargs["atomicFraction"] else: raise de.DuoException("--> Invalid argument.") else: ec = ElementComponent(Z) for key, value in kwargs.items(): if "weightFraction" == key: ec.weightFraction = kwargs["weightFraction"] elif "atomicFraction" == key: ec.atomicFraction = kwargs["atomicFraction"] else: raise de.DuoException("--> Invalid argument.") self.elementList[Z] = ec
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def Commit(self): # validate fraction values # the fraction values should be either all weight fractions or all atomic fraction # mix of both is not allowed useWeightFraction = False; useAtomicFraction = False; for Z, ec in self.elementList.items(): if (not useWeightFraction) and (ec.weightFraction != 0.0): useWeightFraction = True if (not useAtomicFraction) and (ec.atomicFraction != 0.0): useAtomicFraction = True if useWeightFraction and useAtomicFraction: raise de.DuoException("--> Mixing weight fraction and atomic fraction is not supported.") if (not useWeightFraction) and (not useAtomicFraction): raise de.DuoException("--> Wrong weight fraction or atomic fraction.") # convert between weight and atomic fraction # theory: w_i = n_i * A_i / A if useWeightFraction: for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) ec.atomicFraction = ec.weightFraction / element.A elif useAtomicFraction: for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) ec.weightFraction = ec.atomicFraction * element.A # normalize fraction values weightFractionSum = 0.0 atomicFractionSum = 0.0 for Z, ec in self.elementList.items(): weightFractionSum += ec.weightFraction atomicFractionSum += ec.atomicFraction for Z, ec in self.elementList.items(): ec.weightFraction /= weightFractionSum ec.atomicFraction /= atomicFractionSum self.isCommitted = True
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def Show(self): message = "--> material : {0:s}".format(self.name) print(message) for Z, ec in self.elementList.items(): message = " Z = {0:5d}, w = {1:10f}, n = {2:10f}".format(Z, ec.weightFraction, ec.atomicFraction) print(message)
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculateMacAtE(self, energy): if not self.isCommitted: raise de.DuoException("--> Material not committed.") mac = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) mac += ec.weightFraction / element.A * element.CalculateTotalMicroXSAtE(energy) mac *= constant.Endfb.Avogadro * 1e-24 return mac # unit: cm ^ 2 / g
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculatePEMacAtE(self, energy): if not self.isCommitted: raise de.DuoException("--> Material not committed.") mac = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) mac += ec.weightFraction / element.A * element.CalculatePEMicroXSAtE(energy) mac *= constant.Endfb.Avogadro * 1e-24 return mac # unit: cm ^ 2 / g
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculateCSMacAtE(self, energy): if not self.isCommitted: raise de.DuoException("--> Material not committed.") mac = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) mac += ec.weightFraction / element.A * element.CalculateCSMicroXSAtE(energy) mac *= constant.Endfb.Avogadro * 1e-24 return mac # unit: cm ^ 2 / g
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculateRLMacAtE(self, energy): if not self.isCommitted: raise de.DuoException("--> Material not committed.") mac = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) mac += ec.weightFraction / element.A * element.CalculateRLMicroXSAtE(energy) mac *= constant.Endfb.Avogadro * 1e-24 return mac # unit: cm ^ 2 / g
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculateZeffAtE(self, energy): if not self.isCommitted: raise de.DuoException("--> Material not committed.") Zeff = 0.0 up = 0.0 down = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) sigma = element.CalculateTotalMicroXSAtE(energy) temp = ec.atomicFraction * sigma up += temp down += temp / Z Zeff = up / down return Zeff
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculateElectronXSAtE(self, energy): if not self.isCommitted: raise de.DuoException("--> Material not committed.") up = 0.0 down = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) sigma_e = element.CalculateElectronXSAtE(energy) up += ec.weightFraction * element.Z * sigma_e / element.A down += ec.weightFraction * element.Z / element.A result = up / down return result
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def ShowInfo(self, energy): print("--> Material ShowInfo(): energy = {:f}".format(energy)) totalElectrons = 0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) totalElectrons += element.Z * ec.atomicFraction up = 0.0 down = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) sigma_e = element.CalculateElectronXSAtE(energy) up += ec.weightFraction * element.Z * sigma_e / element.A down += ec.weightFraction * element.Z / element.A currentElectrons = element.Z * ec.atomicFraction print(" Z = {:d}, lambda = {:f}, sigma_e = {:f}".format(element.Z, currentElectrons / totalElectrons, sigma_e)) result = up / down print(" electron xs = {:f}".format(result))
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculateTotalMicroXSAtEPerAtom(self, energy): up = 0.0 down = 0.0 for Z, ec in self.elementList.items(): element = self.elementTable.GetElementByZ(Z) temp = ec.weightFraction / element.A up += temp * element.CalculateTotalMicroXSAtE(energy) down += temp return up / down
#------------------------------------------------------------ #------------------------------------------------------------
[docs] def CalculateNumElectronPerAtom(self): result = 0.0 for Z, ec in self.elementList.items(): result += Z * ec.atomicFraction return result