def loadData(filename, parent=None, gui=True): """ Loads material data from an ERANOS output file. Returns a list 'cycles' with all the Cycle instances. """ # Open file eranosFile = open(filename, "r") cycles = [] # Find the names of all the fuel regions fuelNames = [] m = fileReSeek(eranosFile, "^->LISTE_MILIEUX.*") fuelNames += re.findall("'(FUEL\d+)'", m.group()) while True: line = eranosFile.readline().strip() fuelNames += re.findall("'(FUEL\d+)'", line) if line[-1] == ";": break # Determine if there is a blanket material m = fileReSeek(eranosFile, "^->BLANKET.*") if m: fuelNames += ["BLANK"] else: eranosFile.seek(0) # Determine default cooling period position = eranosFile.tell() m = fileReSeek(eranosFile, "^->COOLINGTIME\s+(\S+).*") if m: try: if m.groups()[0][:6] == "(PASSE": auto_cooling = True else: auto_cooling = False cooling_time = float(m.groups()[0]) except: cooling_time = 30 else: cooling_time = None eranosFile.seek(position) # Determine cycle information while True: m = fileReSeek(eranosFile, ".*->CYCLE\s+(\d+).*") if not m: break n = int(m.groups()[0]) m = fileReSeek(eranosFile, "^->PASSE\s\((\d+)\).*") if not m: break timestep = int(m.groups()[0]) m = fileReSeek(eranosFile, "^->ITER\s(\d+).*") iterations = int(m.groups()[0]) # Determine cooling period if auto_cooling: cooling_time = timestep*iterations*0.15/0.85 cycles.append(Cycle(n, timestep, iterations, cooling_time)) eranosFile.seek(0) # Determine how many materials to read total n_materials = 0 for cycle in cycles: n_materials += len(cycle.times())*len(fuelNames) # Create progress bar if gui: progress = QProgressDialog("Loading ERANOS Data...", "Cancel", 0, n_materials, parent) progress.setWindowModality(Qt.WindowModal) progress.setWindowTitle("Loading...") progress.setMinimumDuration(0) progress.setValue(0) pValue = 0 for cycle in cycles: print("Loading Cycle {0}...".format(cycle.n)) # Determine critical mass fileReSeek(eranosFile, " ECCO6.*") xsDict = {} for i in fuelNames: m = fileReSeek(eranosFile, "\sREGION :(FUEL\d+|BLANK)\s*") name = m.groups()[0] m = fileReSeek(eranosFile, "\s*TOTAL\s+(\S+)\s+(\S+)\s+\S+\s+(\S+).*") nuSigmaF = float(m.groups()[0]) SigmaA = float(m.groups()[1]) Diff = float(m.groups()[2]) xsDict[name] = (nuSigmaF, SigmaA, Diff) # Find beginning of cycle m = fileReSeek(eranosFile, ".*M A T E R I A L B A L A N C E.*") # Find TIME block and set time for node, time in enumerate(cycle.times()): # Progress bar if gui: QCoreApplication.processEvents() if (progress.wasCanceled()): return None # Loop over fuel names for i in fuelNames: m = fileReSeek(eranosFile,"\s+MATERIAL\s(FUEL\d+|BLANK)\s+") name = m.groups()[0] volume = float(eranosFile.readline().split()[-1]) for n in range(5): eranosFile.readline() # Read in material data material = readMaterial(eranosFile) material.volume = volume if time == 0: material.nuFissionRate = xsDict[name][0] material.absorptionRate = xsDict[name][1] material.diffRate = xsDict[name][2] cycle.materials[(node,name)] = material #print (node,name) # Set progress bar value pValue += 1 if gui: progress.setValue(pValue) #print((cycle.n, time, name)) # Only for debugging # Read uranium added/required feed for i in range(3): # Determine if there is additional mass or not enough regexList = [" 'REQUIRED FEED FOR FUEL (\d).*", " 'ADDITIONAL FEED FOR FUEL (\d).*"] m, index = fileReSeekList(eranosFile,regexList) if index == 0: # We don't have enough fissile material cycle.extraMass = False mat = "FUEL{0}".format(m.groups()[0]) m = fileReSeek(eranosFile," ->REPLMASS2\s+(\S+).*") cycle.requiredFeed += float(m.groups()[0]) m = fileReSeek(eranosFile," ->REPLMASS1\s+(\S+).*") cycle.uraniumAdded[mat] = float(m.groups()[0]) m = fileReSeek(eranosFile," ->POWER\d\s+(\S+).*") cycle.materials[(5,mat)].power = float(m.groups()[0]) else: # Additional mass was produced cycle.extraMass = True mat = "FUEL{0}".format(m.groups()[0]) m = fileReSeek(eranosFile," ->EXTRA\s+(\S+).*") cycle.additionalFeed[mat] = float(m.groups()[0]) m = fileReSeek(eranosFile," ->REPLMASS\s+(\S+).*") cycle.uraniumAdded[mat] = float(m.groups()[0]) m = fileReSeek(eranosFile," ->POWER\d\s+(\S+).*") cycle.materials[(5,mat)].power = float(m.groups()[0]) posb = eranosFile.tell() for i in range(4): # Get DPA information regexList = [" 'DPA of FUEL (\d).*", " 'DPA of BLANKET'.*"] m, index = fileReSeekList(eranosFile,regexList) if index == 0: # We don't have enough fissile material mat = "FUEL{0}".format(m.groups()[0]) m = fileReSeek(eranosFile," ->DPA\dC\s+(\S+).*") #print (m.group(), m.groups()) #print (mat) cycle.materials[(5,mat)].dpa = float(m.groups()[0]) else: # Additional mass was produced mat = "BLANK" m = fileReSeek(eranosFile," ->DPABC\s+(\S+).*") #print (m.group(), m.groups()) cycle.materials[(5,mat)].dpa = float(m.groups()[0]) #cycle.materials[(0,mat)].dpa = float(m.groups()[0]) eranosFile.seek(posb) # Read charge and discharge vectors at end of ERANOS output file charge = Material() discharge = Material() onestreamch = Material() onestreamdis = Material() listeiso = ['Th232','Pa231','Pa233','U232','U233','U234','U235','U236','U238','Np237', 'Np239','Np238','Pu238','Pu239','Pu240','Pu241','Pu242','Am241','Am242g', 'Am242m','Am243','Cm242','Cm243','Cm244','Cm245','Cm246','Cm247','Cm248', 'Bk249','Cf249','Cf250','Cf251','Cf252','sfpU234','sfpU235','sfpU236', 'sfpU238','sfpNp237','sfpPu238','sfpPu239','sfpPu240','sfpPu241','sfpPu242', 'sfpAm241','sfpAm242m','sfpAm243','sfpCm243','sfpCm244','sfpCm245'] m = fileReSeek(eranosFile," ->CHARGE\s+(\S+).*") words = m.group().split() words.pop(0) value = [float(val) for val in words] for i in range(10): words = eranosFile.readline().split() value.extend([float(val) for val in words]) for iso in range(33): charge.addMass(listeiso[iso],value[iso]) onestreamch.addMass(listeiso[iso],value[iso]) for iso in range(16): charge.addMass(listeiso[iso+33],value[iso+33],True) onestreamch.addMass(listeiso[iso+33],value[iso+33],True) charge.expandFPs() m = fileReSeek(eranosFile," ->DISCHARGE\s+(\S+).*") words = m.group().split() words.pop(0) value = [float(val) for val in words] for i in range(10): words = eranosFile.readline().split() value.extend([float(val) for val in words]) for iso in range(33): discharge.addMass(listeiso[iso],value[iso]) onestreamdis.addMass(listeiso[iso],value[iso]) for iso in range(16): discharge.addMass(listeiso[iso+33],value[iso+33],True) onestreamdis.addMass(listeiso[iso+33],value[iso+33],True) discharge.expandFPs() chblank = Material() disblank = Material() m = fileReSeek(eranosFile," ->CHBLANK\s+(\S+).*") words = m.group().split() words.pop(0) value = [float(val) for val in words] for i in range(10): words = eranosFile.readline().split() value.extend([float(val) for val in words]) for iso in range(33): chblank.addMass(listeiso[iso],value[iso]) onestreamch.addMass(listeiso[iso],value[iso]) for iso in range(16): chblank.addMass(listeiso[iso+33],value[iso+33],True) onestreamch.addMass(listeiso[iso+33],value[iso+33],True) chblank.expandFPs() onestreamch.expandFPs() m = fileReSeek(eranosFile," ->DISBLANK\s+(\S+).*") words = m.group().split() words.pop(0) value = [float(val) for val in words] for i in range(10): words = eranosFile.readline().split() value.extend([float(val) for val in words]) for iso in range(33): disblank.addMass(listeiso[iso],value[iso]) onestreamdis.addMass(listeiso[iso],value[iso]) for iso in range(16): disblank.addMass(listeiso[iso+33],value[iso+33],True) onestreamdis.addMass(listeiso[iso+33],value[iso+33],True) disblank.expandFPs() onestreamdis.expandFPs() #posb = eranosFile.tell() eranosFile.seek(posb) try: mat = "BLANK" m = fileReSeek(eranosFile," ->POWERB\s+(\S+).*") n = len(cycles) #print (n, float(m.groups()[0])) cycle.materials[(5,mat)].power = float(m.groups()[0]) except: print('WARNING: No Blanket Discharge Power') eranosFile.seek(posb) try: # Determine reaction rates for FUEL3, FUEL6, FUEL9, and # BLANK. First we need to load material balance data. Is this # just reading the same data as the last timestep of the last # cycle??? n = len(cycles) + 1 cycle = Cycle(n, 0, 0, 0) cycles.append(cycle) for i in fuelNames: m = fileReSeek(eranosFile,"\s+MATERIAL\s(FUEL\d+|BLANK)\s+") name = m.groups()[0] volume = float(eranosFile.readline().split()[-1]) for n in range(5): eranosFile.readline() # Read in material data material = readMaterial(eranosFile) material.volume = volume cycle.materials[(0,name)] = material # Now read fission, absorption, and diffusion rates to be able to # determine the critical mass fuelNames = ['FUEL3', 'FUEL6', 'FUEL9', 'BLANK'] fileReSeek(eranosFile, " ECCO6.*") for name in fuelNames: m = fileReSeek(eranosFile, "\sREGION :(FUEL\d+|BLANK)\s*") name = m.groups()[0] m = fileReSeek(eranosFile, "\s*TOTAL\s+(\S+)\s+(\S+)\s+\S+\s+(\S+).*") cycle.materials[(0,name)].nuFissionRate = float(m.groups()[0]) cycle.materials[(0,name)].absorptionRate = float(m.groups()[1]) cycle.materials[(0,name)].diffRate = float(m.groups()[2]) m = fileReSeek(eranosFile, "\s*TOTAL FLUX =\s+(\S+)\s*") cycle.materials[(0,name)].flux = float(m.groups()[0]) #print(m.groups()[0]) except: # No ECCO calculation at end? print('WARNING: No ECCO_BLANK calculation at end of run?') # Create progress bar if gui: progress = QProgressDialog("Expanding fission products...", "Cancel", 0, n_materials, parent) progress.setWindowModality(Qt.WindowModal) progress.setWindowTitle("Loading...") progress.setMinimumDuration(0) progress.setValue(0) pValue = 0 # Expand all fission products for cycle in cycles: # Progress bar if gui: QCoreApplication.processEvents() if (progress.wasCanceled()): return None print("Expanding fission products for Cycle {0}...".format(cycle.n)) for mat in cycle.materials.values(): mat.expandFPs() # Set progress bar value pValue += 1 if gui: progress.setValue(pValue) # Close file and return eranosFile.close() return cycles, charge, discharge, chblank, disblank, onestreamch, onestreamdis
def writeInput(filename, charge, discharge): """ Formats data from a charge Material and a discharge Material into a form suitable for VISION input. Two files are written out: vision.txt -- list of isotopes for VISION summary.txt -- summary of equations for calculating total mass The equations for total masses are based on the list of isotopes in isoprocess.txt. """ #extrapath = "Rebuscode/postprocess/" visionFile = open(filename,"w") visionFile.write("ISOTOPE CHARGE DISCHARGE\n") summaryFile = open("summary.txt","w") # Open Output/summary.txt isoFile = open("isoprocess.txt", "r") m = fileReSeek(isoFile, "^NOISOTOPES\s+(\d+).*") n_total = eval(m.groups()[0]) for i in range(1,n_total+1): isoFile.seek(0) # Read isotopes m = fileReSeek(isoFile, "^ISOTOPE{0:03}\s(\d+)\s(.*)".format(i)) if not m: print("ISOTOPE{0} not found!".format(i)) return 1 n_isotopes = eval(m.groups()[0]) isotopes = m.groups()[1].split() # Determine name for grouped isotope if len(isotopes) > n_isotopes: name = isotopes[-1] else: name = isotopes[0] # Special treatment for FPs and Lanthanides if isotopes[0] == "FP": isotopes = fissionProducts elif isotopes[0] == "LA": isotopes = lanthanides # Determine weighting coefficients m = fileReSeek(isoFile, "^WEIGHTS{0:03}(.*)/.*".format(i)) if m: weights = [eval(j) for j in m.groups()[0].split()] else: weights = [1 for isotope in isotopes] # Print summary information if n_isotopes >= 2 and n_isotopes < 50: equation = name + " = " for index in range(n_isotopes): if index != 0: equation += " + " if weights[index] != 1: equation += "{0!s} * ".format(weights[index]) equation += isotopes[index] summaryFile.write(equation + "\n") # Calculate charge and discharge masses chargeMass = 0.0 dischargeMass = 0.0 for index, isotope in enumerate(isotopes): # If isotope is in charge material, add its mass iso = charge.find(isotope) if iso: chargeMass += iso.mass*weights[index] # If isotope is in discharge material, add its mass iso = discharge.find(isotope) if iso: dischargeMass += iso.mass*weights[index] # Write masses to visionFile if isotopes: visionFile.write("{0:12}{1:<12.4E}{2:<12.4E}\n".format( name, chargeMass, dischargeMass)) isoFile.close() visionFile.close() summaryFile.close()