Esempio n. 1
0
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
Esempio n. 2
0
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()