diff --git a/README.rst b/README.rst index 9be12f1ed019627bad89a38cf3880892ec1d557e..6025d1f3b253c1730c74c353df0dbe1e53cdb1ac 100644 --- a/README.rst +++ b/README.rst @@ -137,7 +137,7 @@ FILES COPYRIGHT AND LICENSE ##################### -Copyright (C) 2009-13 Max J. Hoffmann <mjhoffmann@gmail.com> +Copyright (C) 2009-13 Max J. Hoffmann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/doc/build/html/_sources/reference/cli.txt b/doc/build/html/_sources/reference/cli.txt index 51bacb455786cd99316dc89ffcb06847370dfdac..ff04004875ffadc45d8ee29a9d59e1b0a111cb70 100644 --- a/doc/build/html/_sources/reference/cli.txt +++ b/doc/build/html/_sources/reference/cli.txt @@ -36,7 +36,7 @@ ``kmcos import <xml-file>`` Take a kmcos xml-file and open an ipython shell - with the project_tree imported as pt. + with the project_tree imported as kmc_model. ``kmcos rebuild`` diff --git a/doc/build/html/_sources/topic_guides/coord_minilanguage.txt b/doc/build/html/_sources/topic_guides/coord_minilanguage.txt index de416a64bbe30079f2aa8fa705f2a2ce45702b77..8944a975e48a41b9d67da77f0efec7a5b3d0697c 100644 --- a/doc/build/html/_sources/topic_guides/coord_minilanguage.txt +++ b/doc/build/html/_sources/topic_guides/coord_minilanguage.txt @@ -12,5 +12,5 @@ Manual generation Autogeneration of sets ^^^^^^^^^^^^^^^^^^^^^^ -.. TODO:: describe pt.lattice.generate_coord_set +.. TODO:: describe kmc_model.lattice.generate_coord_set and other ways using e.g. list expressions diff --git a/doc/build/html/_sources/topic_guides/coord_syntax.txt b/doc/build/html/_sources/topic_guides/coord_syntax.txt index 32e44f6e3f3761ff6264f10804bb23d27e6c0744..fb75ac710c7ae975abbf167e03fbecfc8180df18 100644 --- a/doc/build/html/_sources/topic_guides/coord_syntax.txt +++ b/doc/build/html/_sources/topic_guides/coord_syntax.txt @@ -57,7 +57,7 @@ Manual generation To quickly generate single coordinates you can generate it from a Project like so :: - pt.lattice.generate_coord('hollow.(0,0,0).layer_name') + kmc_model.lattice.generate_coord('hollow.(0,0,0).layer_name') Let's look at the generation string. The general syntax is :: @@ -85,7 +85,7 @@ Often times it is handier (less typing) to generate a larger set of coordinates at first and then select different subsets from it in a process definition. For this purpose you can use :: - pset = pt.lattice.generate_coord_set(size=[x,y,z], layer_name='layer_name') + pset = kmc_model.lattice.generate_coord_set(size=[x,y,z], layer_name='layer_name') This collects all sites from the given layer and generates diff --git a/doc/build/html/_sources/topic_guides/proc_syntax.txt b/doc/build/html/_sources/topic_guides/proc_syntax.txt index 555c535dea618b29185d0e11b9fbb04569966cd8..681008030c8066d9d7a523959a4617b2c774a24b 100644 --- a/doc/build/html/_sources/topic_guides/proc_syntax.txt +++ b/doc/build/html/_sources/topic_guides/proc_syntax.txt @@ -46,21 +46,21 @@ adsorption of a gas phase species, let call it ``A`` on a surface site. For this we need a species :: from kmcos.types import * - pt = Project() + kmc_model = kmcos.create_kmc_model() A = Species(name='A') - pt.add_species(A) + kmc_model.add_species(A) empty = Species(name='empty') - pt.add_species(empty) + kmc_model.add_species(empty) and the coordinate of a surface site :: layer = Layer(name='default') - pt.add_layer(layer) + kmc_model.add_layer(layer) layer.sites.append(Site(name='a')) - coord = pt.lattice.generate_coord('a.(0,0,0).default') + coord = kmc_model.lattice.generate_coord('a.(0,0,0).default') which is for now all we need to define an adsorption process:: @@ -70,7 +70,7 @@ process:: species='empty')], action_list=[Action(coord=coord, species='A')]) - pt.add_process(adsorption) + kmc_model.add_process(adsorption) Now this wasn't hard, was it? @@ -82,7 +82,7 @@ Let's move to another example, namely the `diffusion` of a particle to the next unit cell in the y-direction. You first need the coordinate of the final site :: - final = pt.lattice.generate_coord('a.(0,1,0).default') + final = kmc_model.lattice.generate_coord('a.(0,1,0).default') and you are good to go :: @@ -95,7 +95,7 @@ and you are good to go :: species='empty'), Condition(coord=final, species='A')], - pt.add_process(diffusion_up) + kmc_model.add_process(diffusion_up) You can complicated this `ad infinitum` but you know all elements needed to define processes. diff --git a/doc/build/html/_sources/tutorials/first_model_api.txt b/doc/build/html/_sources/tutorials/first_model_api.txt index f679eb31485274ecfa15109eecdc70ab541e79ab..5409e81f82b3bfe7ab1c9daadb0e83f9c2429d8c 100644 --- a/doc/build/html/_sources/tutorials/first_model_api.txt +++ b/doc/build/html/_sources/tutorials/first_model_api.txt @@ -34,8 +34,8 @@ this hardly excites surface scientists but we need to start somewhere, right? First you should instantiate a new project and fill in meta information :: - pt = Project() - pt.set_meta(author = 'Your Name', + kmc_model = kmcos.create_kmc_model() + kmc_model.set_meta(author = 'Your Name', email = 'your.name@server.com', model_name = 'MyFirstModel', model_dimension = 2,) @@ -48,12 +48,12 @@ system will be initialized. Of course this can be changed later For surface science simulations it is useful to define an *empty* state, so we add :: - pt.add_species(name='empty') + kmc_model.add_species(name='empty') and some surface species. Given you want to simulate CO adsorption and desorption on a single crystal surface you would say :: - pt.add_species(name='CO', + kmc_model.add_species(name='CO', representation="Atoms('CO',[[0,0,0],[0,0,1.2]])") where the string passed as `representation` is a string representing @@ -64,7 +64,7 @@ To keep it simple we will stick with a simple-cubic lattice in 2D which could for example represent the (100) surface of a fcc crystal with only one adsorption site per unit cell. You start by giving your layer a name :: - layer = pt.add_layer(name='simple_cubic') + layer = kmc_model.add_layer(name='simple_cubic') and adding a site :: @@ -85,7 +85,7 @@ to allow a graphical representation of the simulation one can add geometry as you have already done for the site. You set the size of the unit cell via :: - pt.lattice.cell = np.diag([3.5, 3.5, 10]) + kmc_model.lattice.cell = np.diag([3.5, 3.5, 10]) which are prototypical dimensions for a single-crystal surface in Angstrom. @@ -118,8 +118,8 @@ First of all you want to define the external parameters to which our model is coupled. Here we use the temperature and the CO partial pressure:: - pt.add_parameter(name='T', value=600., adjustable=True, min=400, max=800) - pt.add_parameter(name='p_CO', value=1., adjustable=True, min=1e-10, max=1.e2) + kmc_model.add_parameter(name='T', value=600., adjustable=True, min=400, max=800) + kmc_model.add_parameter(name='p_CO', value=1., adjustable=True, min=1e-10, max=1.e2) You can also set a default value and a minimum and maximum value set defines how the scrollbars a behave later in the runtime GUI. @@ -127,19 +127,19 @@ set defines how the scrollbars a behave later in the runtime GUI. To describe the adsorption rate constant you will need the area of the unit cell:: - pt.add_parameter(name='A', value='(3.5*angstrom)**2') + kmc_model.add_parameter(name='A', value='(3.5*angstrom)**2') Last but not least you need a binding energy of the particle on the surface. Since without further ado we have no value for the gas phase chemical potential, we'll just call it deltaG and keep it adjustable :: - pt.add_parameter(name='deltaG', value='-0.5', adjustable=True, + kmc_model.add_parameter(name='deltaG', value='-0.5', adjustable=True, min=-1.3, max=0.3) To define processes we first need a coordinate [#coord_minilanguage]_ :: - coord = pt.lattice.generate_coord('hollow.(0,0,0).simple_cubic') + coord = kmc_model.lattice.generate_coord('hollow.(0,0,0).simple_cubic') Then you need to have at least two processes. A process or elementary step in kMC @@ -150,7 +150,7 @@ So for example an adsorption requires at least one site to be empty (condition). Then this site can be occupied by CO (action) with a rate constant. Written down in code this looks as follows :: - pt.add_process(name='CO_adsorption', + kmc_model.add_process(name='CO_adsorption', conditions=[Condition(coord=coord, species='empty')], actions=[Action(coord=coord, species='CO')], rate_constant='p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)') @@ -164,7 +164,7 @@ that we need conversion factors of bar and umass. Then the desorption process is almost the same, except the reverse:: - pt.add_process(name='CO_desorption', + kmc_model.add_process(name='CO_desorption', conditions=[Condition(coord=coord, species='CO')], actions=[Action(coord=coord, species='empty')], rate_constant='p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') @@ -173,19 +173,19 @@ Then the desorption process is almost the same, except the reverse:: To reduce typing, kmcos also knows a shorthand notation for processes. In order to produce the same process you could also type :: - pt.parse_process('CO_desorption; CO@hollow->empty@hollow ; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') + kmc_model.parse_process('CO_desorption; CO@hollow->empty@hollow ; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') and since any non-existing on either the left or the right side of the `->` symbol is replaced by a corresponding term with the `default_species` (in this case `empty`) you could as well type :: - pt.parse_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') + kmc_model.parse_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') and to make it even shorter you can parse and add the process on one line :: - pt.parse_and_add_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') + kmc_model.parse_and_add_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') In order to add processes on more than one site possible spanning across unit @@ -201,8 +201,8 @@ Export, save, compile Next, it's a good idea to save your work :: - pt.filename = 'myfirst_kmc.xml' - pt.save() + kmc_model.filename = 'myfirst_kmc.xml' + kmc_model.save() Now is the time to leave the python shell. In the current directory you should see a `myfirst_kmc.xml`. diff --git a/doc/build/html/reference/cli.html b/doc/build/html/reference/cli.html index 9e95dd6eb8da58f5c91ef8fda6fcdb57495cd3b5..37a19ee06be9be230836ac6de7944a88c16ab685 100644 --- a/doc/build/html/reference/cli.html +++ b/doc/build/html/reference/cli.html @@ -94,7 +94,7 @@ to the export-path.</dd> <dd>Display documentation for all commands.</dd> <dt><tt class="docutils literal"><span class="pre">kmcos</span> <span class="pre">import</span> <span class="pre"><xml-file></span></tt></dt> <dd>Take a kmcos xml-file and open an ipython shell -with the project_tree imported as pt.</dd> +with the project_tree imported as kmc_model.</dd> <dt><tt class="docutils literal"><span class="pre">kmcos</span> <span class="pre">rebuild</span></tt></dt> <dd>Export code and rebuild binary module from XML information included in kmc_settings.py in diff --git a/doc/build/html/reference/index.html b/doc/build/html/reference/index.html index 0818ef63d61218fa524fb1220d5fc84053647317..2ca76c8363d52ed9eae54d34f2fabb7e41ad70a6 100644 --- a/doc/build/html/reference/index.html +++ b/doc/build/html/reference/index.html @@ -203,7 +203,7 @@ to the export-path.</dd> <dd>Display documentation for all commands.</dd> <dt><tt class="docutils literal"><span class="pre">kmcos</span> <span class="pre">import</span> <span class="pre"><xml-file></span></tt></dt> <dd>Take a kmcos xml-file and open an ipython shell -with the project_tree imported as pt.</dd> +with the project_tree imported as kmc_model.</dd> <dt><tt class="docutils literal"><span class="pre">kmcos</span> <span class="pre">rebuild</span></tt></dt> <dd>Export code and rebuild binary module from XML information included in kmc_settings.py in diff --git a/doc/build/html/topic_guides/coord_minilanguage.html b/doc/build/html/topic_guides/coord_minilanguage.html index cdb9bce0e4066a9221144e03efc7beb84e346051..08f19621a937cda0099bc635b0642ae2f2fabe09 100644 --- a/doc/build/html/topic_guides/coord_minilanguage.html +++ b/doc/build/html/topic_guides/coord_minilanguage.html @@ -103,7 +103,7 @@ <h2>Autogeneration of sets<a class="headerlink" href="#autogeneration-of-sets" title="Permalink to this headline">¶</a></h2> <div class="admonition-todo admonition " id="index-1"> <p class="first admonition-title">Todo</p> -<p class="last">describe pt.lattice.generate_coord_set +<p class="last">describe kmc_model.lattice.generate_coord_set and other ways using e.g. list expressions</p> </div> </div> diff --git a/doc/build/html/topic_guides/proc_syntax.html b/doc/build/html/topic_guides/proc_syntax.html index 5644fefa34e5e321d2f60283c373bc1f5775393a..5334688d9b699994c08843c5187d47aa133d8477 100644 --- a/doc/build/html/topic_guides/proc_syntax.html +++ b/doc/build/html/topic_guides/proc_syntax.html @@ -185,7 +185,7 @@ You first need the coordinate of the final site</p> species='empty'), Condition(coord=final, species='A')], -pt.add_process(diffusion_up)</pre> +kmc_model.add_process(diffusion_up)</pre> </div> <p>You can complicated this <cite>ad infinitum</cite> but you know all elements needed to define processes.</p> diff --git a/doc/source/installation/installation.rst b/doc/source/installation/installation.rst index 4b3bfd34ea7f0f842b4e18d0666c6937652be2a8..f5ea04c11a9e1dfedd97c41372fff2816d2440ce 100644 --- a/doc/source/installation/installation.rst +++ b/doc/source/installation/installation.rst @@ -172,31 +172,8 @@ There is more than one way to get required dependencies. I have tested MacPorts Installation on windows ^^^^^^^^^^^^^^^^^^^^^^^^^ -Direct installation on windows is currently not supported. It is recommended to download virtualbox, to install Ubuntu, and then follow the Ubuntu installation instructions. You may need to adjust the resolution to work effectively. -For direct installin on windows, partial instructions have been written below. In the future, an "Ubuntu on Windows 10 via Windows Subsystem" set of instructions will be provided (and would be welcomed as a contribution). - -*** - -If a virtual ubuntu machine is used, the below instructions may be useful for allowing sharing of files and copy and paste between the virtual machine and windows. - -Open the virtual machine, and use the file menu at the top of the window. - -1) Devices --> Shared Folders --> + icon on right --> Folder Path (navigate to shared folder) --> auto mount --> Make permanent -2) Devices --> Insert Guest Additions CD Image --> Run - -Now the folder shows up. - -Now add your user account to the group of vboxsf, otherwise won't have folder access permissions: - -sudo usermod -a -G vboxsf "$USER" - -Then restart virtual machine (from inside machine). - -Now can access shared folder. - -Devices --> Shared Clipboard --> Bidirectional -Devices --> Shared Drag and Drop --> Bidrectional (only works for dragging to/from shared folder) - +Direct installation on windows is currently not supported. It is recommended to download virtualbox, to install Ubuntu, and then follow the Ubuntu installation instructions in the intro2kmcos pdf file here: https://github.com/kmcos/intro2kmcos. You may need to adjust the resolution to work effectively. +For direct installion on windows, partial instructions have been written below. In the future, an "Ubuntu on Windows 10 via Windows Subsystem" set of instructions will be provided (and would be welcomed as a contribution). *** diff --git a/doc/source/reference/cli.rst b/doc/source/reference/cli.rst index 2927389cec2b29a37feaf4e6c8b6c5fdeafd34aa..75572abc46c78ffa17ea2feab317c6d02f1496e5 100644 --- a/doc/source/reference/cli.rst +++ b/doc/source/reference/cli.rst @@ -84,7 +84,7 @@ List of commands ``kmcos import <xml-file>`` Take a kmcos xml-file and open an ipython shell - with the project_tree imported as pt. + with the project_tree imported as kmc_model. ``kmcos rebuild`` diff --git a/doc/source/reference/generate_backend_reference.py b/doc/source/reference/generate_backend_reference.py index 87d14f258ad08c2f33244cc80f1bcdc2aca0ce57..ef6bd646bfa5f084f53183ab5c743c3ecebd3be9 100755 --- a/doc/source/reference/generate_backend_reference.py +++ b/doc/source/reference/generate_backend_reference.py @@ -20,31 +20,31 @@ shutil.copy(os.path.join(os.path.dirname(kmcos.__file__), for backend in ['local_smart', 'lat_int', 'otf']: print("Backend {backend}".format(**locals())) - pt = Project() + kmc_model = kmcos.create_kmc_model() outdir = tempfile.mkdtemp() outdir = 'outdir' outdir - pt.meta.model_dimension = 2 - pt.species_list.default_species = 'default' + kmc_model.meta.model_dimension = 2 + kmc_model.species_list.default_species = 'default' - pt.meta.model_name = 'example' - pt.meta.model_name = 'some_model' - pt.meta.author = 'some guy' - pt.meta.email = 'some.guy@server.org' + kmc_model.meta.model_name = 'example' + kmc_model.meta.model_name = 'some_model' + kmc_model.meta.author = 'some guy' + kmc_model.meta.email = 'some.guy@server.org' - pt.add_layer(name='default') - pt.get_layers()[0].add_site(Site(name='default')) - pt.add_species(name='a', representation='') - pt.add_species(name='b', representation='') + kmc_model.add_layer(name='default') + kmc_model.get_layers()[0].add_site(Site(name='default')) + kmc_model.add_species(name='a', representation='') + kmc_model.add_species(name='b', representation='') - pt.species_list.default_species = 'a' - coord = pt.layer_list.generate_coord('default.(0,0,0).default') + kmc_model.species_list.default_species = 'a' + coord = kmc_model.layer_list.generate_coord('default.(0,0,0).default') - pt.add_process(name='ab', + kmc_model.add_process(name='ab', condition_list=[Condition(coord=coord, species='a')], action_list=[Condition(coord=coord, species='b')], ) - pt.add_process(name='ba', + kmc_model.add_process(name='ba', condition_list=[Condition(coord=coord, species='b')], action_list=[Condition(coord=coord, species='a')], ) diff --git a/doc/source/topic_guides/coord_syntax.rst b/doc/source/topic_guides/coord_syntax.rst index 32e44f6e3f3761ff6264f10804bb23d27e6c0744..fb75ac710c7ae975abbf167e03fbecfc8180df18 100644 --- a/doc/source/topic_guides/coord_syntax.rst +++ b/doc/source/topic_guides/coord_syntax.rst @@ -57,7 +57,7 @@ Manual generation To quickly generate single coordinates you can generate it from a Project like so :: - pt.lattice.generate_coord('hollow.(0,0,0).layer_name') + kmc_model.lattice.generate_coord('hollow.(0,0,0).layer_name') Let's look at the generation string. The general syntax is :: @@ -85,7 +85,7 @@ Often times it is handier (less typing) to generate a larger set of coordinates at first and then select different subsets from it in a process definition. For this purpose you can use :: - pset = pt.lattice.generate_coord_set(size=[x,y,z], layer_name='layer_name') + pset = kmc_model.lattice.generate_coord_set(size=[x,y,z], layer_name='layer_name') This collects all sites from the given layer and generates diff --git a/doc/source/topic_guides/developers_guide.rst b/doc/source/topic_guides/developers_guide.rst index a3f91a041c69d1892dee06f108be3e468b56639c..b838df0620147b8ce155c398ff7cb4517dd45d2b 100644 --- a/doc/source/topic_guides/developers_guide.rst +++ b/doc/source/topic_guides/developers_guide.rst @@ -22,7 +22,22 @@ effectively add functionality to kmcos. For developers of the project, branch management will follow `this flowchart <https://github.com/kmcos/kmcos/tree/master/doc/source/topic_guides/GithubGuideKmcos.pptx>`__ -Some nomenclature. +How to edit, install, and test your changes locally +--------------------------------------------------- + +With every change made to the kmcos source code (within the kmcos directory), kmcos needs to be reinstalled for the changes to take place. +Before re-installing kmcos, to ensure the re-installation occurs correctly, it's best to delete any past kmcos installation files in your python environment. To do so, locate the site-package directory for whichever python environment you're using (typically this would be located in a directory that looks something like ~/VENV/kmcos/lib/python3/site-packages/). Within the site-packages directory, delete any subdirectories that have the name kmcos as well as any other files you see with the name kmcos (typically egg or zip files). +Next, using the terminal, navigate the kmcos source code directory that you have edited, and make sure you are in the directory where setup.py is located. Run the following commands to reinstall kmcos with changes :: + + source ~/VENV/kmcos/bin/activate #this is the command to enter the python virtual environment + python3 setup.py build + python3 setup.py install + +Now that the kmcos dependencies are updated, you can start testing your latest changes. + +Before pushing to github, you should enter the the tests directory and run the unit tests. + +Some nomenclature ------------------ For some terms used frequently in this guide, there might exist some diff --git a/doc/source/topic_guides/otf_backend.rst b/doc/source/topic_guides/otf_backend.rst index 56407832cb73aab5725c69fb6be1d16fa1f37514..19632f706de0def032b37221e0c5fb590a39ad66 100644 --- a/doc/source/topic_guides/otf_backend.rst +++ b/doc/source/topic_guides/otf_backend.rst @@ -107,7 +107,7 @@ need any changes. We also need to collect a set of all interacting coordinates which will affect CO desorption rate:: # fetch a lot of coordinates - coords = pt.lattice.generate_coord_set(size=[2, 2, 2], + coords = kmc_model.lattice.generate_coord_set(size=[2, 2, 2], layer_name='simplecubic_2d') # fetch all nearest neighbor coordinates nn_coords = [nn_coord for i, nn_coord in enumerate(coords) @@ -152,7 +152,7 @@ All of this comes together in the process definition:: bystander_list = bystander_list, rate_constant=rate_constant, otf_rate=otf_rate) - pt.add_process(proc) + kmc_model.add_process(proc) Advanced OTF rate expressions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/topic_guides/proc_syntax.rst b/doc/source/topic_guides/proc_syntax.rst index 555c535dea618b29185d0e11b9fbb04569966cd8..681008030c8066d9d7a523959a4617b2c774a24b 100644 --- a/doc/source/topic_guides/proc_syntax.rst +++ b/doc/source/topic_guides/proc_syntax.rst @@ -46,21 +46,21 @@ adsorption of a gas phase species, let call it ``A`` on a surface site. For this we need a species :: from kmcos.types import * - pt = Project() + kmc_model = kmcos.create_kmc_model() A = Species(name='A') - pt.add_species(A) + kmc_model.add_species(A) empty = Species(name='empty') - pt.add_species(empty) + kmc_model.add_species(empty) and the coordinate of a surface site :: layer = Layer(name='default') - pt.add_layer(layer) + kmc_model.add_layer(layer) layer.sites.append(Site(name='a')) - coord = pt.lattice.generate_coord('a.(0,0,0).default') + coord = kmc_model.lattice.generate_coord('a.(0,0,0).default') which is for now all we need to define an adsorption process:: @@ -70,7 +70,7 @@ process:: species='empty')], action_list=[Action(coord=coord, species='A')]) - pt.add_process(adsorption) + kmc_model.add_process(adsorption) Now this wasn't hard, was it? @@ -82,7 +82,7 @@ Let's move to another example, namely the `diffusion` of a particle to the next unit cell in the y-direction. You first need the coordinate of the final site :: - final = pt.lattice.generate_coord('a.(0,1,0).default') + final = kmc_model.lattice.generate_coord('a.(0,1,0).default') and you are good to go :: @@ -95,7 +95,7 @@ and you are good to go :: species='empty'), Condition(coord=final, species='A')], - pt.add_process(diffusion_up) + kmc_model.add_process(diffusion_up) You can complicated this `ad infinitum` but you know all elements needed to define processes. diff --git a/doc/source/tutorials/first_model_api.rst b/doc/source/tutorials/first_model_api.rst index 224082bb9f1374325aa88be1fdef3cc9516310d5..8231d3d83b4baf7a0307575d4070cb7c41e3997c 100644 --- a/doc/source/tutorials/first_model_api.rst +++ b/doc/source/tutorials/first_model_api.rst @@ -35,8 +35,8 @@ The example sketched out here leads you to a kMC model for CO adsorption and desorption on Pd(100). First you should instantiate a new project and fill in meta information :: - pt = Project() - pt.set_meta(author = 'Your Name', + kmc_model = kmcos.create_kmc_model() + kmc_model.set_meta(author = 'Your Name', email = 'your.name@server.com', model_name = 'MyFirstModel', model_dimension = 2,) @@ -49,12 +49,12 @@ system will be initialized. Of course this can be changed later For surface science simulations it is useful to define an *empty* state, so we add :: - pt.add_species(name='empty') + kmc_model.add_species(name='empty') and some surface species. Given you want to simulate CO adsorption and desorption on a single crystal surface you would say :: - pt.add_species(name='CO', + kmc_model.add_species(name='CO', representation="Atoms('CO',[[0,0,0],[0,0,1.2]])") where the string passed as `representation` is a string representing @@ -65,7 +65,7 @@ To keep it simple we will stick with a simple-cubic lattice in 2D which could for example represent the (100) surface of a fcc crystal with only one adsorption site per unit cell. You start by giving your layer a name :: - layer = pt.add_layer(name='simple_cubic') + layer = kmc_model.add_layer(name='simple_cubic') and adding a site :: @@ -86,7 +86,7 @@ to allow a graphical representation of the simulation one can add geometry as you have already done for the site. You set the size of the unit cell via :: - pt.lattice.cell = np.diag([3.5, 3.5, 10]) + kmc_model.lattice.cell = np.diag([3.5, 3.5, 10]) which are prototypical dimensions for a single-crystal surface in Angstrom. @@ -119,8 +119,8 @@ First of all you want to define the external parameters to which our model is coupled. Here we use the temperature and the CO partial pressure:: - pt.add_parameter(name='T', value=600., adjustable=True, min=400, max=800) - pt.add_parameter(name='p_CO', value=1., adjustable=True, min=1e-10, max=1.e2) + kmc_model.add_parameter(name='T', value=600., adjustable=True, min=400, max=800) + kmc_model.add_parameter(name='p_CO', value=1., adjustable=True, min=1e-10, max=1.e2) You can also set a default value and a minimum and maximum value set defines how the scrollbars a behave later in the runtime GUI. @@ -128,19 +128,19 @@ set defines how the scrollbars a behave later in the runtime GUI. To describe the adsorption rate constant you will need the area of the unit cell:: - pt.add_parameter(name='A', value='(3.5*angstrom)**2') + kmc_model.add_parameter(name='A', value='(3.5*angstrom)**2') Last but not least you need a binding energy of the particle on the surface. Since without further ado we have no value for the gas phase chemical potential, we'll just call it deltaG and keep it adjustable :: - pt.add_parameter(name='deltaG', value='-0.5', adjustable=True, + kmc_model.add_parameter(name='deltaG', value='-0.5', adjustable=True, min=-1.3, max=0.3) To define processes we first need a coordinate [#coord_minilanguage]_ :: - coord = pt.lattice.generate_coord('hollow.(0,0,0).simple_cubic') + coord = kmc_model.lattice.generate_coord('hollow.(0,0,0).simple_cubic') Then you need to have at least two processes. A process or elementary step in kMC @@ -151,7 +151,7 @@ So for example an adsorption requires at least one site to be empty (condition). Then this site can be occupied by CO (action) with a rate constant. Written down in code this looks as follows :: - pt.add_process(name='CO_adsorption', + kmc_model.add_process(name='CO_adsorption', conditions=[Condition(coord=coord, species='empty')], actions=[Action(coord=coord, species='CO')], rate_constant='p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)') @@ -169,7 +169,7 @@ that we need conversion factors of `bar` and `umass`. Then the desorption process is almost the same, except the reverse:: - pt.add_process(name='CO_desorption', + kmc_model.add_process(name='CO_desorption', conditions=[Condition(coord=coord, species='CO')], actions=[Action(coord=coord, species='empty')], rate_constant='p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') @@ -178,19 +178,19 @@ Then the desorption process is almost the same, except the reverse:: To reduce typing, kmcos also knows a shorthand notation for processes. In order to produce the same process you could also type :: - pt.parse_process('CO_desorption; CO@hollow->empty@hollow ; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') + kmc_model.parse_process('CO_desorption; CO@hollow->empty@hollow ; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') and since any non-existing on either the left or the right side of the `->` symbol is replaced by a corresponding term with the `default_species` (in this case `empty`) you could as well type :: - pt.parse_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') + kmc_model.parse_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') and to make it even shorter you can parse and add the process on one line :: - pt.parse_and_add_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') + kmc_model.parse_and_add_process('CO_desorption; CO@hollow->; p_CO*bar*A/sqrt(2*pi*umass*m_CO/beta)*exp(beta*deltaG*eV)') In order to add processes on more than one site possible spanning across unit @@ -204,23 +204,31 @@ check :ref:`manual_coord_generation` for details. Export, save, compile ===================== -Next, it's a good idea to save your work :: +Before we compile the model, we should specify and understand the various backends that are involved. - pt.filename = 'myfirst_kmc.xml' - pt.save() +local_smart backend (default) for models with <100 processes. +lat_int backend for models with >100 processes. (build the model same ways local_smart but different backend for compile step) +otf backend requires custom model (build requires different process definitions compared to local_smart) and can work for models which require >10000 processes, since each process rate is calculated on the fly instead of being held in memory. -This creates an XML file with the full definition of your model. -Finally, you will export the the model to compiled code. :: +Here is how we specify the model's backend :: - import kmcos.cli - kmcos.cli.main('export myfirst_kmc.xml') + kmc_model.backend = 'local_smart' + kmc_model.backend = 'lat_int' + kmc_model.backend = 'otf' + +Next, it's a good idea to save and compile your work :: + + kmc_model.save_model() + kmcos.compile(kmc_model) + +This creates an XML file with the full definition of your model and exports the model to compiled code. Now is the time to leave the python shell. In the current directory you should see a `myfirst_kmc.xml`. You will also see a directory ending with _local_smart, this directory includes your compiled model. -You can also skip the model exporting and do it later: +You can also skip the model exporting and do it later by removing kmcos.compile(kmc_model): you can use a separate python file later, or from the command line can run `kmcos export myfirst_kmc.xml` in the same directory as the XML. @@ -228,6 +236,9 @@ During troubleshooting, exporting separately can be useful to make sure the compiling occurs gracefully without any line containining an error. +Running and viewing the model +----------------------------- + If you now `cd` to that folder `myfirst_kmc_local_smart` and run :: python3 kmc_settings.py benchmark @@ -238,7 +249,9 @@ Next, let's try seeing how it looks visually with :: python3 kmc_settings.py view ... and dada! Your first running kMC model right there! -For some installations, one can type `kmcos benchmark` and `kmcos view`. +For some installations, one can type `kmcos benchmark` and `kmcos view.` + +For running the model, you should use a runfile. If you wonder why the CO molecules are basically just dangling there in mid-air that is because you have no background setup, yet. @@ -252,6 +265,13 @@ I suggest you take a look at the `examples folder <https://github.com/mhoffman/k for some hints. To learn more about the kmcos approach and methods you should into :ref:`topic guides <topic-guides>`. +In technical terms, kmcos is run an API via the kmcos python module. + +Additionally, though now discouraged, kmcos can be invoked directly from the command line in one of the following +ways:: + + kmcos [help] (all|benchmark|build|edit|export|help|import|rebuild|run|settings-export|shell|version|view|xml) [options] + Taking it home ============== diff --git a/doc/source/tutorials/introduction.rst b/doc/source/tutorials/introduction.rst index 02f75f7bb218ab13edc8435c4d6090ebbd133649..3698caa113d920bcc930dd2d337e1f7afecdbd55 100644 --- a/doc/source/tutorials/introduction.rst +++ b/doc/source/tutorials/introduction.rst @@ -9,15 +9,15 @@ If you do not have that directory, but have kmcos installed, go to https://githu Inside /examples/, run the following commands :: - python3 MyFirstSnapshots.py + python3 MyFirstSnapshots__build.py cd MyFirstSnapshots_local_smart python3 runfile.py The first command uses a python file to create a chemical model (process definitions) and a KMC modeling executable as well. The "local_smart" is the default backend (default "KMC Engine", kmcos has several). -After the simulation has run, you will see a csv file named runfile_TOFs_and_Coverages.csv , open this file to see your first KMC output! +After the simulation has run, you will see a csv file named runfile_TOFs_and_Coverages.csv, open this file to see your first KMC output! -Various examples exist. More features and a thorough tutorial are forthcoming. Please join the kmcos-users group https://groups.google.com/g/kmcos-users and email any questions if you get stuck. +Various examples exist. More features and a thorough tutorial are forthcoming. Please join the kmcos-users group https://groups.google.com/g/kmcos-users and email any questions if you get stuck. .. automodule:: kmcos diff --git a/examples/AB_model.py b/examples/AB_model.py index 2135a50a1f49b769c841ef300df83020e407e91e..31bde4641fc3c438920d2bdb0ed83b67fcd9bec7 100755 --- a/examples/AB_model.py +++ b/examples/AB_model.py @@ -4,8 +4,7 @@ from kmcos.types import * import kmcos def main(): - model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. - model_name = model_name.replace("__build", "") + model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) # Meta kmc_model.meta.author = 'Max J. Hoffmann' diff --git a/examples/Lotka_Volterra_model__build.py b/examples/Lotka_Volterra_model__build.py index f9d086f0395403125b29bec828fc66d891b4aaef..310d7c0783c4aee3a9bc92c2e2b7c7b7a0b43444 100644 --- a/examples/Lotka_Volterra_model__build.py +++ b/examples/Lotka_Volterra_model__build.py @@ -5,8 +5,7 @@ import numpy as np from kmcos.types import Site, Condition, Action import kmcos -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author="LotkaVolterra", diff --git a/examples/MyFirstDiffusion__build.py b/examples/MyFirstDiffusion__build.py index 21826a8d5209decde74c276f59fcc296d71b50da..e724810eea1e2356b2a3c04273f4c3bb712a0440 100644 --- a/examples/MyFirstDiffusion__build.py +++ b/examples/MyFirstDiffusion__build.py @@ -5,8 +5,7 @@ from itertools import product import numpy as np import kmcos.cli #not needed. -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Zachary Coin', diff --git a/examples/MyFirstDiffusion_local_smart/runfile_atoms_export.py b/examples/MyFirstDiffusion_local_smart/runfile_atoms_export.py new file mode 100644 index 0000000000000000000000000000000000000000..4d628ffbd209e6a89e3785e249f8d25101dcd28a --- /dev/null +++ b/examples/MyFirstDiffusion_local_smart/runfile_atoms_export.py @@ -0,0 +1,7 @@ +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") \ No newline at end of file diff --git a/examples/MyFirstDiffusion_local_smart/runfile_atoms_import.py b/examples/MyFirstDiffusion_local_smart/runfile_atoms_import.py new file mode 100644 index 0000000000000000000000000000000000000000..8a8c3a082b990f734304cb4ba24187b7908df6f7 --- /dev/null +++ b/examples/MyFirstDiffusion_local_smart/runfile_atoms_import.py @@ -0,0 +1,7 @@ +from ase.io import write +import pickle + +filehandler = open('MyFirstDiffusion_atoms_1000000.0.pkl', 'rb') +loaded_atoms_object = pickle.load(filehandler) +filehandler.close() +write('MyFirstDiffusion_atoms_1000000.0.png', loaded_atoms_object) diff --git a/examples/MyFirstModel_AB.py b/examples/MyFirstModel_AB.py index 4fd8bd12c7f71050b0ad1902c7255aa7d6c848a8..c7af97064025aa03bc3f49a4ea5da13858735940 100644 --- a/examples/MyFirstModel_AB.py +++ b/examples/MyFirstModel_AB.py @@ -4,8 +4,7 @@ from kmcos.types import * import kmcos def main(): - model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. - model_name = model_name.replace("__build", "") + model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) # Meta kmc_model.meta.author = 'Max J. Hoffmann' diff --git a/examples/MyFirstSnapshots__build.py b/examples/MyFirstSnapshots__build.py index 65d9bc7d8a32f84d5f46fa25c81284e949fcfbae..0f5ad12a513630b5a7b48937fc0f702fe54efe96 100644 --- a/examples/MyFirstSnapshots__build.py +++ b/examples/MyFirstSnapshots__build.py @@ -5,8 +5,7 @@ from kmcos.io import * from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Aditya (Ashi) Savara', email='savaraa@ornl.gov', diff --git a/examples/MyFirstSnapshots_local_smart/runfile.py b/examples/MyFirstSnapshots_local_smart/runfile.py index 7974c45e7c33d2b6da3dcf56912725ff8b39306f..eb4d19c16bc36e718b05963cd751f21951c33d1b 100644 --- a/examples/MyFirstSnapshots_local_smart/runfile.py +++ b/examples/MyFirstSnapshots_local_smart/runfile.py @@ -42,8 +42,15 @@ do_snapshots(sps, n_snapshots) #The final command below writes the simulation details to the logfile create_log() +# plot_configuration(self, filename = '', resolution = 150, scale = 20, representation = '', plot_settings = {}): + #The first plot_configuration will use default arguments to construct the plot and export as "plottedConfiguration.png" -sg.model.plot_configuration() +#sg.model.plot_configuration() + +#The second plot_configuration will use the atomic argument to contruct the plot and export as "atomic_view.png" +#for the filename, you can specify with or without the .png at the end. This function will automatically convert to .png file +sg.model.plot_configuration(filename='MyFirstSnapshots_atomic_view', resolution=100, scale=20, representation='atomic') + plot_settings = { "y_label": "y_direction", @@ -58,4 +65,7 @@ plot_settings = { "num_y_ticks": 3, } #the second plot_configuration here will construct the plot using the above dictionary and export the file as "Plot.png" -sg.model.plot_configuration(plot_settings) +# Note that the spatial representation plots by default, but you can always specify in representation +sg.model.plot_configuration(representation='spatial', plot_settings=plot_settings) + +sg.model.export_movie() \ No newline at end of file diff --git a/examples/MyFirstTPD_DesorptionOnly_Comparison__build.py b/examples/MyFirstTPD_DesorptionOnly_Comparison__build.py index 41b4ed0362d16150a35f9749c77287bc8f1e5e68..d25783ef068a21619e90f0f9b617d22f64ff4012 100644 --- a/examples/MyFirstTPD_DesorptionOnly_Comparison__build.py +++ b/examples/MyFirstTPD_DesorptionOnly_Comparison__build.py @@ -6,8 +6,7 @@ from kmcos.io import * from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Christa Cody', email='codycn@ornl.gov', diff --git a/examples/MyFirstTPD_DesorptionOnly__build.py b/examples/MyFirstTPD_DesorptionOnly__build.py index fad2a9235e42cad4bfa7bb546f81642e612b559f..0045cfc7515bb5260375422adb9c2cdf81b3be8d 100644 --- a/examples/MyFirstTPD_DesorptionOnly__build.py +++ b/examples/MyFirstTPD_DesorptionOnly__build.py @@ -6,8 +6,7 @@ from kmcos.io import * from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Christa Cody', email='codycn@ornl.gov', diff --git a/examples/MyFirstTPD_Precovered__build.py b/examples/MyFirstTPD_Precovered__build.py index 41e0d9587c54b552585187c4a22c40916b82d8b2..fe4ffa2d5be4b10b8df1f1f2c2c9ac1abbc0f5f2 100644 --- a/examples/MyFirstTPD_Precovered__build.py +++ b/examples/MyFirstTPD_Precovered__build.py @@ -6,8 +6,7 @@ from kmcos.io import * from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) diff --git a/examples/MyFirstThrottling/MyFirstThrottling.py b/examples/MyFirstThrottling/MyFirstThrottling.py index 4322f0e6528c83715f3c69a20d3698047cab716b..41cc3be1029045840d746dd5116c45873bfc8887 100644 --- a/examples/MyFirstThrottling/MyFirstThrottling.py +++ b/examples/MyFirstThrottling/MyFirstThrottling.py @@ -7,7 +7,7 @@ import numpy as np #from math import exp #from math import sqrt -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. +model_name = str(__file__[+0:-3]) # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Thomas Danielson', email='thomasd1@vt.edu', diff --git a/examples/MySecondTPR__build.py b/examples/MySecondTPR__build.py index b6e50ac8c9b6a3eb9d822d1535dc001af512eee3..bacbf60a5aac801fd1634758c39b12c94ef0d87e 100644 --- a/examples/MySecondTPR__build.py +++ b/examples/MySecondTPR__build.py @@ -9,8 +9,7 @@ from kmcos.types import * from kmcos.io import * import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Max J. Hoffmann', diff --git a/examples/MyThirdTPR__build.py b/examples/MyThirdTPR__build.py index 3944d93929dcc8dbdc1e03964461e72eed81e683..495dbc2087cdadd0ca8d90d4db5809f0a5c8932f 100644 --- a/examples/MyThirdTPR__build.py +++ b/examples/MyThirdTPR__build.py @@ -14,8 +14,7 @@ import numpy as np #from math import exp #from math import sqrt -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Thomas Danielson', email='thomasd1@vt.edu', diff --git a/examples/Pt_111__build.py b/examples/Pt_111__build.py index d144046cd7bbc9db96d00067e4908272fddb25b1..87ee75c1b96bad7571c3d6c9250c8c4eee272abe 100644 --- a/examples/Pt_111__build.py +++ b/examples/Pt_111__build.py @@ -11,8 +11,7 @@ from kmcos.io import * import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Max J. Hoffmann', model_name='pt111', diff --git a/examples/ZGB_model__build.py b/examples/ZGB_model__build.py index ad91dcb0b1db7f2e9e3f5c08303006f9c41c990a..be341a57911c6962ebd6656692a519cc8a511e55 100644 --- a/examples/ZGB_model__build.py +++ b/examples/ZGB_model__build.py @@ -5,8 +5,7 @@ import numpy as np import kmcos from kmcos.types import Project, Site, Condition, Action -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author="Ziff,Gulari,Barshad", diff --git a/examples/bigcell__build.py b/examples/bigcell__build.py index 81d0c70d9e66cb4d19f57da1600849adbc871580..6855ff2ad5e31b05ce16bf5812f7ad0875b822d6 100644 --- a/examples/bigcell__build.py +++ b/examples/bigcell__build.py @@ -6,8 +6,7 @@ import kmcos from kmcos.types import * -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Max J. Hoffmann', email='mjhoffmann@gmail.com', diff --git a/examples/co_oxidation_ruo2__build.py b/examples/co_oxidation_ruo2__build.py index 0898a6ce23ff05a68ac956a30c34116bedb840e7..e744005170f021ddfdda32abfcc8ccfd2f8592b4 100644 --- a/examples/co_oxidation_ruo2__build.py +++ b/examples/co_oxidation_ruo2__build.py @@ -9,8 +9,7 @@ from kmcos.io import * import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Max J. Hoffmann', diff --git a/examples/co_oxidation_ruo2_processes_paired__build.py b/examples/co_oxidation_ruo2_processes_paired__build.py index 75b9229f68bc6f9bb90ee84dc80c0e1115d5cdd9..c367ce32f887d553d039582b4fee8650d694e2a2 100644 --- a/examples/co_oxidation_ruo2_processes_paired__build.py +++ b/examples/co_oxidation_ruo2_processes_paired__build.py @@ -8,8 +8,7 @@ from kmcos.types import * from kmcos.io import * import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Mie Andersen', diff --git a/examples/diffusion_model__build.py b/examples/diffusion_model__build.py index 2ef749be8f7eab649715fd8e888b9a08d1b140a2..86380e0ba98e91114955e6e4a925cd1aa88fa797 100644 --- a/examples/diffusion_model__build.py +++ b/examples/diffusion_model__build.py @@ -5,8 +5,7 @@ from kmcos.types import * from kmcos.io import * import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) # Meta information kmc_model.set_meta(author='Max J. Hoffmann', diff --git a/examples/einsD__build.py b/examples/einsD__build.py index 432ece3bb8a6debc8edac6b3e42dc740296af17c..6b4b5cc58e2a3659c8a5413a84e21383fc9b2314 100644 --- a/examples/einsD__build.py +++ b/examples/einsD__build.py @@ -4,8 +4,7 @@ import kmcos from kmcos.types import Condition, Action import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) diff --git a/examples/model_Pt111_surface__build.py b/examples/model_Pt111_surface__build.py index 8080f0fd7fa74f2030bd83edd845995c87aa03be..e8bd0a372cc115656c95cc8f1419812e49419874 100644 --- a/examples/model_Pt111_surface__build.py +++ b/examples/model_Pt111_surface__build.py @@ -12,7 +12,7 @@ import numpy as np slab = fcc111('Pt', [1,1,4], vacuum=10) positions = slab.get_scaled_positions() -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(model_name='pt111', model_dimension='2', diff --git a/examples/multidentate__build.py b/examples/multidentate__build.py index a718a6e356b1e5ded5fe37a1f9e2558d1ef813ba..b900eb461edba8fa87371d4f976f5ce62d500a37 100644 --- a/examples/multidentate__build.py +++ b/examples/multidentate__build.py @@ -10,8 +10,7 @@ from kmcos.types import * import kmcos -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.add_species(name='empty') diff --git a/examples/multispecies__build.py b/examples/multispecies__build.py index a964bd2980d9c2308dc8409e7ce65c56c02d951b..1d71536cc1e5b1d8e61bdba73e2e531091d93461 100644 --- a/examples/multispecies__build.py +++ b/examples/multispecies__build.py @@ -8,8 +8,7 @@ import kmcos from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Max J. Hoffmann', email='mjhoffmann@gmail.com', @@ -80,7 +79,7 @@ for species_name in species_names: # Save the model to an xml file ###It's good to simply copy and paste the below lines between model creation files. kmc_model.print_statistics() -kmc_model.backend = 'local_smart' #specifying is optional. 'local_smart' is the default. Currently, the other options are 'lat_int' and 'otf' +kmc_model.backend = 'lat_int' #specifying is optional. 'local_smart' is the default. Currently, the other options are 'lat_int' and 'otf' kmc_model.clear_model() #This line is optional: if you are updating a model, this line will remove the old model files (including compiled files) before exporting the new one. It is convenient to always include this line because then you don't need to 'confirm' removing/overwriting the old model during the compile step. kmc_model.save_model() print("For this example, we are not using the compile step because it takes more than 30 minutes. To do the compile step, the user should uncomment the kmcos.compile(kmc_model) line or should type in 'kmcos export multispecies.xml' in the terminal") diff --git a/examples/pairwise_interaction__build.py b/examples/pairwise_interaction__build.py index 6cb48af88d04e05b7157d6017b88bb8a0a5d904c..878c3051b0a4ef256380eb0a41eef2d59b37d059 100644 --- a/examples/pairwise_interaction__build.py +++ b/examples/pairwise_interaction__build.py @@ -5,8 +5,7 @@ import kmcos from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Max J. Hoffmann', email='mjhoffmann@gmail.com', diff --git a/examples/pairwise_interaction_otf__build.py b/examples/pairwise_interaction_otf__build.py index 48919fe9521ccc9c335c5342794463a66b59f894..48c3c3644259644200e3baf5eeb7a5b639fa1c3a 100644 --- a/examples/pairwise_interaction_otf__build.py +++ b/examples/pairwise_interaction_otf__build.py @@ -5,8 +5,7 @@ import kmcos from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Juan M. Lorenzi', email='jmlorenzi@gmail.com', diff --git a/examples/pairwise_interaction_otf_no_JANAF__build.py b/examples/pairwise_interaction_otf_no_JANAF__build.py index a31d95648c4b14ba639a3e9a7c44511903478657..93f6fc02c1cdfd632bd772aaa07c0a264f051a3d 100644 --- a/examples/pairwise_interaction_otf_no_JANAF__build.py +++ b/examples/pairwise_interaction_otf_no_JANAF__build.py @@ -5,8 +5,7 @@ from itertools import product import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) kmc_model.set_meta(author='Juan M. Lorenzi', email='jmlorenzi@gmail.com', diff --git a/examples/sand_model__build.py b/examples/sand_model__build.py index 37c8d8ee9731b3e50fc839762700e322521aaf20..59edb143c11af83d679afb7a1b685fa76a34de0a 100644 --- a/examples/sand_model__build.py +++ b/examples/sand_model__build.py @@ -6,8 +6,7 @@ from kmcos.io import * import numpy as np -model_name = __file__[+0:-3] # This is the python file name, the brackets cut off zero characters from the beginning and three character from the end (".py"). To manually name the model just place a string here. -model_name = model_name.replace("__build", "") +model_name = str(__file__[+0:-3]).replace("__build", "") # This line automatically names the model based on the python file’s name. The brackets cut off zero characters from the beginning and three character from the end (".py"). The replace command removes the ‘__build’ part of the string. If you want to override this automatic naming, just set the variable ‘model_name’ equal to the string that you would like to use. kmc_model = kmcos.create_kmc_model(model_name) # Meta information kmc_model.set_meta(author='Max J. Hoffmann', diff --git a/kmcos/__init__.py b/kmcos/__init__.py index 8906ac5d5a852b34018c3cfd9042bdd8eb226c96..6af6c90d4c92a91b0e35bbbf311aea79a9e7867b 100644 --- a/kmcos/__init__.py +++ b/kmcos/__init__.py @@ -20,13 +20,6 @@ you plan the model. Typical users will run kmcos entirely from python code by following the examples. -In technical terms, kmcos is run an API via the kmcos python module. - -Additionally, though now discouraged, kmcos can be invoked directly from the command line in one of the following -ways:: - - kmcos [help] (all|benchmark|build|edit|export|help|import|rebuild|run|settings-export|shell|version|view|xml) [options] - .. rubric:: Footnotes @@ -56,7 +49,8 @@ from __future__ import print_function #import kmcos.io -__version__ = "0.0.64" + +__version__ = "0.0.67" VERSION = __version__ def evaluate_param_expression(param, parameters={}): diff --git a/kmcos/run/__init__.py b/kmcos/run/__init__.py index 509f7893d4364197c5b3216c25041998415bef1d..ebab9f265f5723e5d7ed0185737720f1b8b10e41 100644 --- a/kmcos/run/__init__.py +++ b/kmcos/run/__init__.py @@ -797,146 +797,50 @@ class KMC_Model(Process): settings.parameters.update(parameters) set_rate_constants(parameters, self.print_rates, self.can_accelerate) - def export_movie(self, - frames=30, - skip=1, - prefix='movie', - rotation='15z,-70x', - suffix='png', - verbose=False, - **kwargs): - """Export series of snapshots of model instance to an image - file in the current directory which allows for easy post-processing - of images, e.g. using `ffmpeg` :: - - avconv -i movie_%06d.png -r 24 movie.avi - - or :: - - ffmpeg -i movie_%06d.png -f image2 -r 24 movie.avi - - Allows suffixes are png, pov, and eps. Additional keyword arguments - (kwargs) are passed directly the ase.io.write of the ASE library. - - When exporting to *.pov, one has to manually povray each *.pov file in - the directory which is as simple as typing :: - - for pov_file in *.pov - do - povray ${pov_file} - done - - using bash. - - :param frames: Number of frames to records (Default: 30). - :type frames: int - :param skip: Number of kMC steps between frames (Default: 1). - :type skip: int - :param prefix: Prefix for filename (Default: movie). - :type -#@ !------ A. Garhammer 2015------ -#@ !subroutine update_clocks_acf(ran_time) -#@ !****f* base/update_clocks_acf -#@ ! FUNCTION -#@ ! Updates walltime, kmc_step, kmc_step_acf, time_intervalls and kmc_time. -#@ ! -#@ ! ARGUMENTS -#@ ! -#@ ! * ``ran_time`` Random real number :math:`\in [0,1]` -#@ !****** -#@ !real(kind=rsingle), intent(in) :: ran_time -#@ !real(kind=rsingle) :: runtime -#@ -#@ -#@ ! Make sure ran_time is in the right interval -#@ !ASSERT(ran_time.ge.0.,"base/update_clocks: ran_time variable has to be positive.") -#@ !ASSERT(ran_time.le.1.,"base/update_clocks: ran_time variable has to be less than 1.") -#@ -#@ !kmc_time_step = -log(ran_time)/accum_rates(nr_of_proc) -#@ ! Make sure the difference is not so small, that it is rounded off -#@ ! ASSERT(kmc_time+kmc_time_step>kmc_time,"base/update_clocks: precision of kmc_time is not sufficient") -#@ -#@ !call CPU_TIME(runtime) -#@ -#@ ! Make sure we are not dividing by zeroprefix: str - :param rotation: Angle from which movie is recorded - (only useful if suffix is png). - String to be interpreted by ASE (Default: '15x,-70x') - :type rotation: str - :param suffix: File suffix (type) of exported file (Default: png). - :type suffix: str - - """ - - import ase.io - import ase.data.colors - jmol_colors = ase.data.colors.jmol_colors - + def export_movie(self, filename = "", resolution = 150, scale = 20, fps=1, frames = 30, steps = 1e6): + """Exports a series of atomic view snapshots of model instance to a subdirectory, creating png files + in the folder_with_movie_images directory and then creates a .webm video file of all the images + of the images into a video + 'filename' sets the filename for the images in the image directory and the video + 'scale' increases the size of each species in the structure (currently not working as desired) + 'resolution' changes the dpi of the images (currently not working as desired) + 'fps' sets how long each image will stay in the video + 'frames' sets the total video length + 'steps' is the amount of steps the model does between each image + """ + + import os + import moviepy.video.io.ImageSequenceClip + + if filename == '': + filename = 'atoms_image' + video_filename = 'atoms_video.webm' + else: + video_filename = filename + '.webm' + if not os.path.exists('folder_with_movie_images'): + os.mkdir('folder_with_movie_images') + image_folder = 'folder_with_movie_images' + os.chdir(image_folder) for i in range(frames): - atoms = self.get_atoms(reset_time_overrun=False) - filename = '{prefix:s}_{i:06d}.{suffix:s}'.format(**locals()) - #write('%s_%06i.%s' % (prefix, i, suffix), - #atoms, - #show_unit_cell=True, - #rotation=rotation, - #**kwargs) - - if suffix == 'png': - writer = kmcos.run.png.MyPNG(atoms, show_unit_cell=True, scale=20, model=self, **kwargs).write(filename, resolution=150) - elif suffix == 'pov': - rescale = 0.5 - radii_dict2 = {'Ni':0.9*rescale, - 'O': 1.0*rescale, - 'H': 0.5*rescale} - - radii2 = [] - water_radii_dict2 = {'O':1.0*rescale, 'H': 0.5*rescale, 'Ni':0.9*rescale} - colors = [] - colors2 = [] - for atom in atoms: - radii2+=[water_radii_dict2[atom.symbol]] - colors+=[(jmol_colors[atom.number][0],jmol_colors[atom.number][1],jmol_colors[atom.number][2],0.00,0.00)] - colors2+=[(jmol_colors[atom.number][0],jmol_colors[atom.number][1],jmol_colors[atom.number][2])] - - BA = [] - distances = atoms.get_all_distances() - for i, j in zip(*np.where(distances<2.2)): - if distances[i, j] < 0.1 : - continue - if not (atoms[i].symbol=='H' or atoms[j].symbol=='H') : - BA += [[i, j]] - elif distances[i, j] < 1.5: - BA += [[i, j]] - - ase.io.write(filename, atoms, run_povray=False,display=False,pause=False, - #rotation='-90x,30y', - #rotation='-90x,30y', - show_unit_cell=1, - #bbox=(-7,17,0,20), - #bbox=(-8,12,8,28), - bbox=(-(3.0*20 + 2) ,-2,7*20,5.5*20), - textures=['ase3' for atom in atoms], - canvas_height=500, - camera_type='orthographic', - bondatoms=BA, - radii=radii2, - colors=colors2) - elif suffix == 'traj': - write(filename, atoms) - else: - writer = kmcos.run.png.MyPNG(atoms, show_unit_cell=True, scale=20, model=self, **kwargs).write(filename, resolution=150) + self.do_steps(steps) + self.export_picture(filename = filename + str(i), resolution = resolution, scale = scale) + os.chdir("..") + image_files = [os.path.join(image_folder,img) for img in os.listdir(image_folder) if img.endswith(".png")] + clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps) + clip.write_videofile(video_filename) + clip.close() - if verbose: - print('Wrote {filename}'.format(**locals())) - self.do_steps(skip) - def show(self, *args, **kwargs): + def peek(self, *args, **kwargs): """Visualize the current configuration of the model using ASE ag.""" tag = kwargs.pop('tag', None) ase = import_ase() ase.visualize.view(self.get_atoms(tag=tag), *args, **kwargs) + def show(self): + return self.peek() + def view(self, scaleA = None): """Start current model in live view mode.""" from kmcos import view @@ -1478,6 +1382,9 @@ class KMC_Model(Process): @staticmethod def get_species_coordinates(config, species): + """ + Gets the species coordinates from a 4d list and appends it into a 2d array that's then returned + """ species_coords = [] for k in range(len(species)): species_coords.append([]) @@ -1488,7 +1395,24 @@ class KMC_Model(Process): return species_coords @staticmethod - def create_plot(coords, species, plot_settings={}, showFigure=True, directory=''): + def create_configuration_plot(coords, species, plot_settings={}, showFigure=True, directory=''): + """ + coords is expected to be the results from get_species_coordinates(config, species) + Ex: + species is expected to be the results from get_coords(), which is a dictionary that contains the names of the species + Ex: {"CO" : "carbon"} + plot_settings is a dictionary that allows for the plot to change given the arguements + EX: + "y_label": "test", + "x_label": "test", + "legendLabel": "Species", + "legendExport": False, + "legend": True, + "figure_name": "Plot", + "dpi": 220, + "speciesName": False + create_configuration_plot will return the spatial view of the kmc_model and make a graph named 'plottedConfiguration.png,' unless specified by 'figure_name' in plot_settings + """ import matplotlib.pyplot as plt exportFigure = True #This variable should be moved to an argument or something in plot_settings. #First put some defaults in if not already defined. @@ -1515,7 +1439,7 @@ class KMC_Model(Process): ax0.set_xlabel(plot_settings['x_label'], fontdict=fontdict) ax0.set_ylabel(plot_settings['y_label'], fontdict=fontdict) #TODO: THis is not yet generalized (will be a function) - for (i, key) in zip(list(range(len(coords))), list(species.keys())): + for (i, key) in zip(list(range(len(coords))), list(species.keys())): #goes through each species and plots their coordinates x, y = list(zip(*coords[i])) if plot_settings['legend'] == True: if plot_settings['speciesName'] == False: @@ -1523,32 +1447,32 @@ class KMC_Model(Process): else: ax0.scatter(x,y,label=key) - if plot_settings['legend'] == True: + if plot_settings['legend'] == True: #creates the configuration's legend if 'legendLabel' in plot_settings: ax0.legend(title = plot_settings['legendLabel'], bbox_to_anchor=(1.05,1.0), loc="upper left") else: ax0.legend(bbox_to_anchor=(1.05,1.0), loc="upper left") - if plot_settings['legendExport'] == True: + if plot_settings['legendExport'] == True: #exports the legend into a separate text file with open(plot_settings['figure_name'] + "Legend.txt", 'w') as f: for key, value in list(species.items()): f.write('%s\n' % (key)) - if str(plot_settings['num_x_ticks']) != 'auto': + if str(plot_settings['num_x_ticks']) != 'auto': #sets the tick locator for the x-axis plot_settings['num_x_ticks'] = int(plot_settings['num_x_ticks']) from matplotlib.ticker import MaxNLocator ax0.xaxis.set_major_locator(MaxNLocator(nbins = plot_settings['num_x_ticks'])) - if str(plot_settings['num_y_ticks']) != 'auto': + if str(plot_settings['num_y_ticks']) != 'auto': #sets the tick locator for the y-axis plot_settings['num_y_ticks'] = int(plot_settings['num_y_ticks']) from matplotlib.ticker import MaxNLocator ax0.yaxis.set_major_locator(MaxNLocator(nbins = plot_settings['num_y_ticks'])) - if 'x_ticks' in plot_settings: + if 'x_ticks' in plot_settings: #sets the ticker for the x-axis if str(plot_settings['x_ticks']).lower != 'auto': ax0.set_xticks(plot_settings['x_ticks']) - if 'y_ticks' in plot_settings: + if 'y_ticks' in plot_settings: #sets the ticker for the y-axis if str(plot_settings['y_ticks']).lower != 'auto': ax0.set_yticks(plot_settings['y_ticks']) @@ -1558,9 +1482,25 @@ class KMC_Model(Process): if showFigure==False: plt.close(fig0) return fig0, ax0 + + def export_picture(self, resolution, scale, filename="", **kwargs): + """ + Gets the atoms objects of the kmc_model and returns a atomic view of the configuration and make a file named 'atomic_view.png' unless specified by 'filename' in the function's argument + 'filename' sets the filename for the images in the image directory and the video + 'scale' increases the size of each species in the structure (currently not working as desired) + 'resolution' changes the dpi of the images (currently not working as desired) + """ + atoms = self.get_atoms(reset_time_overrun = False) #here, the self is the KMC_Model object + kmcos.run.png.MyPNG(atoms, show_unit_cell=False, scale=scale, model=self, **kwargs).write(filename=filename, resolution=resolution) + return - def plot_configuration(self, plot_settings = {}): + def plot_configuration(self, filename = '', resolution = 150, scale = 20, representation = 'spatial', plot_settings = {}): """ + representation is an optional argument for spatial and atomic view + resolution and scale are strictly for the atomic view + resolution changes the plot's + You should specify as 'atomic' to see the atomic view. Leaving representation empty returns spatial view by default. + plot_settings is a dictionary that allows for the plot to change given the arguements EX: "y_label": "test", @@ -1571,13 +1511,25 @@ class KMC_Model(Process): "figure_name": "Plot", "dpi": 220, "speciesName": False - plot_configuration will make a graph named 'plottedConfiguration.png,' unless specified by 'figure_name' in plot_settings - """ - config = self._get_configuration().tolist() - species = self.species_tags - species_coordinates = self.get_species_coordinates(config, species) - self.create_plot(species_coordinates, species, plot_settings) - + plot_configuration either calls create_configuration_plot to create the spatial representation of the model, or calls export_picture to create the atomic representation of the model + """ + if representation == 'atomic': + if 'show_unit_cell' in plot_settings: + show_unit_cell = plot_settings['show_unit_cell'] + else: + show_unit_cell = True + if 'kwargs' in plot_settings: + kwargs = plot_settings['kwargs'] + else: + kwargs = {} #default for kwargs is a blank dictionary + self.export_picture(resolution = resolution, scale = scale, filename = filename) + + if (representation == 'spatial') or (representation == 'circles'): + config = self._get_configuration().tolist() + species = self.species_tags + species_coordinates = self.get_species_coordinates(config, species) + self.create_configuration_plot(species_coordinates, species, plot_settings) + def _put(self, site, new_species, reduce=False): """ Works exactly like put, but without updating the database of @@ -1983,6 +1935,21 @@ class KMC_Model(Process): self._set_configuration(config) self._adjust_database() + def pickle_export_atoms(self, filename = ""): + # takes atoms object in filename and turns it into a .pkl file + import pickle + if filename == "": + filename = "atoms_export.pkl" + else: + if filename[-4:] == '.pkl': + filename.replace('.pkl', '.pkl') + else: + filename = filename + '.pkl' + filehandler = open(filename, 'wb') + pickle.dump(self.get_atoms(), filehandler) + filehandler.close() + + class Model_Parameters(object): """Holds all user defined parameters of a model in concise form. All user defined parameters can be diff --git a/kmcos/run/png.py b/kmcos/run/png.py index 39e6d93d045582d68dd313d90326a9ebfefaa30c..f2030c34eb354bd1653b4d7b5d0ba9c88bed870f 100644 --- a/kmcos/run/png.py +++ b/kmcos/run/png.py @@ -16,6 +16,7 @@ class MyPNG(PNG): model=None, scale=20) : + self.atoms = atoms self.numbers = atoms.get_atomic_numbers() self.colors = colors self.model = model @@ -114,7 +115,6 @@ class MyPNG(PNG): self.filename = filename self.write_header(resolution=resolution) self.write_info() - self.write_body() self.write_trailer(resolution=resolution) def write_info(self): @@ -140,8 +140,9 @@ class MyPNG(PNG): text.draw(self.renderer) def write_header(self, resolution=72): - from matplotlib.backends.backend_agg import RendererAgg, Figure + from matplotlib.backends.backend_agg import RendererAgg from matplotlib.backend_bases import GraphicsContextBase + from matplotlib.figure import Figure try: from matplotlib.transforms import Value @@ -157,23 +158,20 @@ class MyPNG(PNG): self.gc.set_linewidth(.2) def write_trailer(self, resolution=72): + import matplotlib renderer = self.renderer if hasattr(renderer._renderer, 'write_png'): # Old version of matplotlib: renderer._renderer.write_png(self.filename) else: - from matplotlib import _png - # buffer_rgba does not accept arguments from version 1.2.0 - # https://github.com/matplotlib/matplotlib/commit/f4fee350f9fbc639853bee76472d8089a10b40bd - import matplotlib - if matplotlib.__version__ < '1.2.0': - x = renderer._renderer.buffer_rgba(0, 0) - _png.write_png(renderer._renderer.buffer_rgba(0, 0), - renderer.width, renderer.height, - self.filename, resolution) + from ase.io import write + #self.atoms.rotate(a=0.5, (0,1,0), rotate_self=True) + if self.filename == "": + write('atomic_view.png', self.atoms) else: - x = renderer._renderer.buffer_rgba() - _png.write_png(renderer._renderer.buffer_rgba(), - #renderer.width, renderer.height, - self.filename, resolution) + if self.filename[-4:] == '.png': + self.filename.replace('.png', '.png') + else: + self.filename = self.filename + '.png' + write(self.filename, self.atoms)