Ejemplo n.º 1
0
def main(args=None):
    """The CLI main entry point function.

    The optional argument args, can be used to
    directly supply command line argument like

    $ kmcos <args>

    otherwise args will be taken from STDIN.

    """

    from glob import glob

    options, args, parser = get_options(args, get_parser=True)

    global model, pt, np, cm_model

    if not args[0] in list(usage.keys()):
        args[0] = match_keys(args[0], usage, parser)

    if args[0] == 'benchmark':
        from sys import path
        path.append(os.path.abspath(os.curdir))
        nsteps = 1000000
        from time import time
        from kmcos.run import KMC_Model
        model = KMC_Model(print_rates=False, banner=False)
        accelerated = model.can_accelerate
        if not accelerated:
            time0 = time()
            try:
                model.proclist.do_kmc_steps(nsteps)
            except:  # kmos < 0.3 had no model.proclist.do_kmc_steps
                model.do_steps(nsteps)

            needed_time = time() - time0
            print('Using the [%s] backend.' % model.get_backend())
            print('%s steps took %.2f seconds' % (nsteps, needed_time))
            print('Or %.2e steps/s' % (1e6 / needed_time))
            model.deallocate()
        else:
            time0 = time()
            model.do_steps(nsteps)
            needed_time = time() - time0
            print('Using the [%s] backend.' % model.get_backend())
            print('Using the temporal acceleration scheme')
            print('%s normal steps took %.2f seconds' % (nsteps, needed_time))
            print('Or %.2e steps/s' % (1e6 / needed_time))
            print('')
            model.deallocate()
            model = KMC_Model(print_rates=False, banner=False)
            time0 = time()
            model.do_acc_steps(nsteps)
            needed_time = time() - time0
            print('%s accelerated steps took %.2f seconds' % (nsteps, needed_time))
            print('Or %.2e steps/s' % (1e6 / needed_time))
            model.deallocate()

    elif args[0] == 'build':
        from kmcos.utils import build
        build(options)
    elif args[0] == 'edit':
        from kmcos import gui
        gui.main()
    elif args[0] == 'settings-export':
        import kmcos.types
        import kmcos.io
        from kmcos.io import ProcListWriter

        if len(args) < 2:
            parser.error('XML file and export path expected.')
        if len(args) < 3:
            out_dir = '%s_%s' % (os.path.splitext(args[1])[0], options.backend)
            print('No export path provided. Exporting to %s' % out_dir)
            args.append(out_dir)

        xml_file = args[1]
        export_dir = args[2]
        project = kmcos.types.Project()
        project.import_file(xml_file)

        writer = ProcListWriter(project, export_dir)
        writer.write_settings()

    elif args[0] == 'export':
        import kmcos.types
        import kmcos.io
        from kmcos.utils import build
        if len(args) < 2:
            parser.error('XML file and export path expected.')
        if len(args) < 3:
            out_dir = '%s_%s' % (os.path.splitext(args[1])[0], options.backend)

            print('No export path provided. Exporting to %s' % out_dir)
            args.append(out_dir)

        xml_file = args[1]
        export_dir = os.path.join(args[2], 'src')

        project = kmcos.types.Project()
        project.import_file(xml_file)

        project.shorten_names(max_length=options.variable_length)

        kmcos.io.export_source(project,
                               export_dir,
                               options=options,
                               accelerated=options.temp_acc)

        if ((os.name == 'posix'
           and os.uname()[0] in ['Linux', 'Darwin'])
           or os.name == 'nt') \
           and not options.source_only:
            os.chdir(export_dir)
            build(options)
            for out in glob('kmc_*'):
                if os.path.exists('../%s' % out) :
                    if options.overwrite :
                        overwrite = 'y'
                    else:
                        overwrite = input(('Should I overwrite existing %s ?'
                                               '[y/N]  ') % out).lower()
                    if overwrite.startswith('y') :
                        print('Overwriting {out}'.format(**locals()))
                        os.remove('../%s' % out)
                        shutil.move(out, '..')
                    else :
                        print('Skipping {out}'.format(**locals()))
                else:
                    shutil.move(out, '..')

    elif args[0] == 'settings-export':
        import kmcos.io
        pt = kmcos.io.import_file(args[1])
        if len(args) < 3:
            out_dir = os.path.splitext(args[1])[0]
            print('No export path provided. Exporting kmc_settings.py to %s'
                  % out_dir)
            args.append(out_dir)

        if not os.path.exists(args[2]):
            os.mkdir(args[2])
        elif not os.path.isdir(args[2]):
            raise UserWarning("Cannot overwrite %s; Exiting;" % args[2])
        writer = kmcos.io.ProcListWriter(pt, args[2])
        writer.write_settings()

    elif args[0] == 'help':
        if len(args) < 2:
            parser.error('Which help do you  want?')
        if args[1] == 'all':
            for command in sorted(usage):
                print(usage[command])
        elif args[1] in usage:
            print('Usage: %s\n' % usage[args[1]])
        else:
            arg = match_keys(args[1], usage, parser)
            print('Usage: %s\n' % usage[arg])

    elif args[0] == 'import':
        import kmcos.io
        if not len(args) >= 2:
            raise UserWarning('XML file name expected.')
        pt = kmcos.io.import_xml_file(args[1])
        if len(args) == 2:
            sh(banner='Note: pt = kmcos.io.import_xml(\'%s\')' % args[1])
        elif len(args) == 3: # if optional 3rd argument is given, store model there and exit
            pt.save(args[2])

    elif args[0] == 'rebuild':
        from time import sleep
        print('Will rebuild model from kmc_settings.py in current directory')
        print('Please do not interrupt,'
              ' build process, as you will most likely')
        print('loose the current model files.')
        sleep(2.)
        from sys import path
        path.append(os.path.abspath(os.curdir))
        from tempfile import mktemp
        if not os.path.exists('kmc_model.so') \
           and not os.path.exists('kmc_model.pyd'):
            raise Exception('No kmc_model.so found.')
        if not os.path.exists('kmc_settings.py'):
            raise Exception('No kmc_settings.py found.')

        from kmcos.run import KMC_Model

        model = KMC_Model(print_rates=False, banner=False)
        tempfile = mktemp()
        f = file(tempfile, 'w')
        f.write(model.xml())
        f.close()

        for kmc_model in glob('kmc_model.*'):
            os.remove(kmc_model)
        os.remove('kmc_settings.py')
        main('export %s -b %s .' % (tempfile, options.backend))
        os.remove(tempfile)
        model.deallocate()

    elif args[0] in ['run', 'shell']:
        from sys import path
        path.append(os.path.abspath(os.curdir))
        from kmcos.run import KMC_Model

        # useful to have in interactive mode
        import numpy as np
        try:
            from matplotlib import pyplot as plt
        except:
            plt = None

        if options.catmap:
            import catmap
            import catmap.cli.kmc_runner
            seed = catmap.cli.kmc_runner.get_seed_from_path('.')
            cm_model = catmap.ReactionModel(setup_file='{seed}.mkm'.format(**locals()))
            catmap_message = '\nSide-loaded catmap_model {seed}.mkm into cm_model = ReactionModel(setup_file="{seed}.mkm")'.format(**locals())
        else:
            catmap_message = ''

        try:
            model = KMC_Model(print_rates=False)
        except:
            print("Warning: could not import kmc_model!"
                  " Please make sure you are in the right directory")
        sh(banner='Note: model = KMC_Model(print_rates=False){catmap_message}'.format(**locals()))
        try:
            model.deallocate()
        except:
            print("Warning: could not deallocate model. Was is allocated?")

    elif args[0] == 'version':
        from kmcos import VERSION
        print(VERSION)

    elif args[0] == 'view':
        from sys import path
        path.append(os.path.abspath(os.curdir))
        from kmcos import view
        view.main(steps_per_frame=options.steps_per_frame)

    elif args[0] == 'xml':
        from sys import path
        path.append(os.path.abspath(os.curdir))
        from kmcos.run import KMC_Model
        model = KMC_Model(banner=False, print_rates=False)
        print(model.xml())

    else:
        parser.error('Command "%s" not understood.' % args[0])
Ejemplo n.º 2
0
def simulate_tpd(Tinitial, Tfinal, beta, cov, species, element, maxstp,
                 minstp):

    #******************************Initiating & opening*******************************
    # In this section, the files to be exported to are created and opened. Then, some of the initial conditions and headers are exported to files. The size and number of sites of the model are calculated. Then, the initial 		coverage is produced using the random seed and coverage that was set in the main() function.

    path = 'tpd_info_{0}_{1}'.format(cov, element)
    prefix = "*****" + str(path) + "***** "
    print(prefix, "Starting run of", cov, species, "coverage at", Tinitial,
          "Kelvin...")

    os.mkdir(path)
    cov1 = open(path + '/site_coverages.txt', 'w')
    des = open(path + '/desorptions.txt', 'w')
    representation = open(path + '/representation.txt', 'w')
    cov2 = open(path + '/total_coverages.txt', 'w')

    info = open(path + '/info.txt', 'w')
    info.write(
        "Starting temperature = {0} \nFinal temperature = {1} \nHeating rate = {2}\n"
        .format(Tinitial, Tfinal, beta))
    info.write("Initial coverage = {0} of {1}\n".format(cov, species))
    info.write("Pseudo-random generator seed = {0}\n".format(element))

    cov1.write(
        "Temperature[K]\tTime[s]\tDesorption_events\tSite_coverage_filled\tSite_coverage_empty\tDesorption_TOF\n"
    )
    cov2.write(
        "Temperature[K]\tTime[s]\tDesorption_events\tTotal_sitecoverage_filled\tTotal_sitecoverage_empty\n"
    )

    model = KMC_Model(print_rates=False, banner=False)
    kmc_settings.random_seed = element  #set the random seed to the seed that was generated
    model.parameters.T = Tinitial  #the temperature parameter is set so that the processes' rate contstants reflect the temperature changes
    representation.write(str(model.__repr__) + '\n')
    representation.close()

    des.write("Temperature[K]\tTime[s]\tDesorption_events" + '\n')

    nsites = model.lattice.spuck  #sets the number of sites per cell
    vol = model.base.get_volume(
    )  #sets the volume of the model(num of sites * num of cells)

    # dictionary of {species_name : corresponding int}
    reps = {}
    for i, spec in enumerate(sorted(kmc_settings.representations)):
        reps[spec] = i

    # initial coverage:
    print(prefix, "Producing initial coverage...")
    nadsorbed = 0
    nads = int(round(cov * vol))  #changed this temporarily(cov)

    X, Y, Z = model.lattice.system_size
    sites = [
        [x, y, z,
         n + 1] for (x, y, z, n) in product(list(range(X)), list(range(
             Y)), list(range(Z)), list(range(nsites)))
    ]  # for loop to populate an array with every possible cell/site combination in the model; the range function excludes the last 														#number; for x,y,z the indices work out but for n, 1 has to be added for it to be correct
    random.seed(element)  #sets the random seed to the random seed passed in
    for i in range(
            nads
    ):  #for loop for producing the coverage that was set previously
        while True:
            site = random.choice(sites)
            if model.lattice.get_species(site) == reps['empty']:
                model._put(site, model.proclist.co)
                nadsorbed += 1
                break

    model._adjust_database()
    info.write('Initial number of CO atoms = {0} (total of {1} sites)'.format(
        nadsorbed, vol))
    info.close()
    config = model._get_configuration()

    #*******************************Start*******************************
    #The initial temperature, min and max steps are set. The initial temperature is set according the the number passed into the simulate_tpd function. The min and max steps are set according to user input information. Then the 	model does a set number of steps to 'warm' the model up. Then, a for loop is entered until the final temperature is reached or the number desorbed is equal to the number adsorbed. In this loop, the model does steps and 		increments the temperature between snapshots. Then, it exports information if a molecule has been desorbed

    print(prefix, "Starting TPD...\n")

    atoms = model.get_atoms(geometry=True)
    write(path + '/initial.traj', atoms)

    ################################################################## User Set Parameters 2 of 2 ####################################################################

    ndesorbed = 0
    maxsteps = maxstp  # max number of steps that should be in a snapshot
    minsteps = minstp  # min number of steps that should be in a snap shot
    steps = minsteps

    max_covChange = 0.5  # max percent of coverage change that should occur
    min_covChange = 0.0001  # min percent of coverage change that should occur
    covForDecSteps = .03  # percent coverage left, used for slowing the model down towards the end of the sim
    cov_final = .01  # the lowest amount of coverage before the simulation needs to stop
    curr_cov = (atoms.occupation[0])[0]  # the current amount of coverage
    prev_cov = curr_cov  # the previous coverage, used for determining coverage change

    T = Tinitial  # the starting temperature
    prev_T = T  # the previous temperature, used in exporting data
    maxDeltaTpersnapshot = 5  # max number the temperature can increase by between snapshots

    prev_config = model._get_configuration(
    )  # previous configuration, used for reseting the model
    prev_t = atoms.kmc_time  # previous kmc_time, used for reseting the model

    ##################################################################################################################################################################

    while T < Tfinal and ndesorbed < nadsorbed and curr_cov > cov_final:  #while the temperature hasn't reached the final temp, and all the molecules haven't desorbed

        desorbed = False
        model.parameters.T = T
        model.do_steps(steps)

        atoms = model.get_atoms(geometry=False)
        t = atoms.kmc_time
        curr_cov = (atoms.occupation[0])[0]
        prev_T = T

        Tincr = beta * (
            t - prev_t
        )  # calculate the value to increment the temperature by(if it passes all the checks)
        T_incremented = T + Tincr
        cov_change = (
            prev_cov - curr_cov
        )  # coverage change, used to see if any molecules have desorbed

        if Tincr > maxDeltaTpersnapshot:  # if the value to increment the temperature is too large, reset the model and decrease the steps by half
            model._set_configuration(prev_config)
            model.base.set_kmc_time(prev_t)
            model._adjust_database()
            steps = steps / 2
            successfulresolution = False

            if ndesorbed == 0:
                T = T + maxDeltaTpersnapshot

            atoms = model.get_atoms(geometry=False)

        elif cov_change > max_covChange:  # if the coverage change is too large, reset the model and decrease the steps by half
            model._set_configuration(prev_config)
            model.base.set_kmc_time(prev_t)
            model._adjust_database()
            steps = steps / 2
            successfulresolution = False
            atoms = model.get_atoms(geometry=False)

        elif cov_change < min_covChange:  # if the coverage change is too small, double the steps
            successfulresolution = True
            T = T_incremented
            steps = steps * 2
            prev_cov = curr_cov
            prev_t = atoms.kmc_time
        else:  # if the checks have been passed, increment the temperature using the calculated T_incremented value
            successfulresolution = True
            T = T_incremented
            prev_cov = curr_cov
            prev_t = atoms.kmc_time

        if curr_cov < covForDecSteps:  # if the current coverage is lower than the set amount, decrease the steps by half and set minsteps to 1. This prevents the simulation crashing from too many steps
            minsteps = 1
            steps = steps / 2

        if successfulresolution:  # if the snapshot passed all of the tests
            desorbed = False
            avg_T = (T + prev_T) / 2

            print(prefix, "Avg Temp:", avg_T, "Time:", t,
                  "\nSteps per update:", steps, "Coverage change:", cov_change,
                  "Tincr:", Tincr, '\n')

            if cov_change != 0:  # if the coverage change was zero, no molecules desorbed, don't export the data
                desorbed = True
                recentdesorbed = cov_change * vol
                ndesorbed += recentdesorbed  #counter for total number desorbed

            if desorbed:  # if a molecule did desorb, export the data
                entry = str(avg_T) + '\t' + str(t) + '\t' + str(
                    recentdesorbed
                ) + '\t'  #temp could be exported by linear fitting the tof calculations and picking whether to export curr or prev temp based on those calcs
                print(prefix, "DESORBED", ndesorbed, 'out of', nadsorbed,
                      "Total sites:", model.base.get_volume(), '\n')
                des.write(entry + '\n')
                cov1.write(entry)
                cov2.write(entry)

                for spec in atoms.occupation:
                    tot = 0.0
                    for site in range(nsites):
                        cov1.write(str(spec[site]) + '\t')
                        tot += spec[site]
                    cov2.write(str(tot / nsites) + '\t')
                cov1.write(str(atoms.tof_integ[0]) + '\t')
                cov1.write('\n')
                cov2.write('\n')

        if steps < minsteps:
            steps = minsteps  # if the steps are lower than the min amount of steps, set equal to the minsteps
        elif steps > maxsteps:
            steps = maxsteps  # if the steps are higher than the max amount of steps, set equal to the maxsteps

        prev_config = model._get_configuration()

        sys.stdout.flush()

    cov1.close()
    cov2.close()
    des.close()

    #*************************Finalize*******************************
    model.deallocate()
    print(prefix, "Finished!")
    status.close()
    return
Ejemplo n.º 3
0
import pickle
from kmcos.run import KMC_Model

model = KMC_Model()
NSTEPS = 1e6
model.do_steps(NSTEPS)
model.pickle_export_atoms("MyFirstDiffusion_atoms_" + str(NSTEPS) + ".pkl")
Ejemplo n.º 4
0
simulation_size = model.size[0] # model.size gives you the size of the arrays which would be [3,3] for a model
totalsites = simulation_size*simulation_size#with a sim_size of 3. 

spt = 20 # total number of steps
sps = 1 # total number of steps per "snapshot"
SNI = int(spt/sps) # number of s iterations  
Step = 0

SimulationName = 'MyFirstDiffusion' # Change to current simulation name for each run
filename1 = '%s_OccupationPopulations.csv' %(SimulationName) 
with open(filename1, 'a') as f1:
	# headers for file1
	f1.write('Step;')
	f1.write('Time;')
	f1.write('SiteA_SiteOccupation;')
	f1.write('SiteB_SiteOccupation;')
	f1.write('SiteC_SiteOccupation\n')
	for s in range(0,SNI+1): # snapshot iterations plus 1 because range always excludes the last number
		
		
		f1.write('%s;'%(Step))
		f1.write('%s;'%(atoms.kmc_time))
		f1.write('%s;'%(atoms.occupation[0])[0])
		f1.write('%s;'%(atoms.occupation[0])[1])	
		f1.write('%s\n'%(atoms.occupation[0])[2])

		model.do_steps(sps)
		Step += sps
		atoms = model.get_atoms(geometry=False) # Have to recall it everytime or it will not refresh atoms
        
print("Finished with Custom Runfile!")