Dragonfruit Setup
The traditional dragonfruit workflow works in a git-like repository in the pyOS framework, within a database as configured by minkipy.
Dragonfruit was first developped to be used together with the CLEASE cluster expansion code, so the example here will be constructing a project to be used with CLEASE, but that is just for the sake of example.
Your First Project
First we need to have some imports in order. Once minkipy has been configured to a project, let’s try and access the database. In this example, we’ll be working on a locally configured project called dragonfruit-slab (XXX: This needs to be changed…). First we import some packages we will be needing along the way.
[1]:
import minkipy # For accessing our database
from pyos.pyos import * # Navigate the DB like it's a file system
import dragonfruit as df
import dragonfruit.clease as mc
import clease
Welcome to
____ ____
/ __ \/ __ /
____ __ __/ / / / /_
/ __ \/ / / / / / /\__ \
/ /_/ / /_/ / /_/ /___/ /
/ .___/\__, /\____//____/
/_/ /____/ v0.7.14
Select the project database you want to work on.
[2]:
minkipy.workon('alexty') # XXX: Change this project name
[2]:
Project('alexty')
Let’s check where we are in our database:
[3]:
pwd()
[3]:
Path('/alexty/')
For now, this will point to where ever pyOS considers your “home” directory. Let’s make a new project, and start doing things with dragonfruit. pyOS has no “actual” concept of folders, so we can enter folders which doesn’t exist yet. A folder is just considered as “existing” if any file is located within that path. So move into a folder, and let’s start a new repo there.
[4]:
cd('my-awesome-project')
[5]:
print('Current directory:', pwd())
print('Contents:', ls())
Current directory: /alexty/my-awesome-project/
Contents: _clease/
initial/
As you can see, we are now in a sub-folder, but the directory is empty. Let’s initialize a repository with a new CLEASE repo.
[6]:
try:
mc.init_bulk(crystalstructure='fcc', a=3.8)
except RuntimeError:
# Just in case we try to initialize the same project multiple times
# e.g. if we run the command multiple times.
print('The project already exists.')
print('Contents:')
print(ls())
The project already exists.
Contents:
_clease/
initial/
Of course, using CLEASE here is optional. You could instead have used the mc.init() method, to just construct an empty repo. But we will be using CLEASE to construct our structures in a bit, so we utilize the built-in CLEASE calls.
We now created a new folder called _clease, which is the root folder which will contain our VASP settings. Let’s take a look inside the _clease folder.
[7]:
ls('_clease/')
[7]:
README
structure_settings
group_settings
general_settings
The structure_settings contains the information on the CLEASE settings which we will use.
[8]:
cat('_clease/structure_settings')
[8]:
╭────────────────┬──────╮
│type │CEBulk│
│crystalstructure│fcc │
│a │3.8 │
╰────────────────┴──────╯
The DFT settings
We can now go ahead and construct our settings for our DFT calculations. We will be using two different settings types: A general settings, and a group specific settings object. The general will be shared settings among all different groups in this repo, and group will be a dictionary containing settings for individual groups.
In this example, we’ll just be using one group, which we will call relax. The general settings will contain the DFT settings, and we will put any settings related to a structure relaxation into the group settings, in case we want to change our relaxation criteria for example.
First we construct our non-relaxation related settings object. We will use some very crude settings here, just for demonstration purposes.
[9]:
settings = dict(xc='LDA', encut=300, kpts=(2, 2, 2))
mc.save_settings(settings, mc.paths.GENERAL_SETTINGS)
ls('_clease/')
[9]:
README
structure_settings
group_settings
general_settings
If we take a look in the _clease folder, we can see we now find an object called general_settings. Let’s print the contents, to verify it is what we expect.
[10]:
cat('_clease/general_settings')
[10]:
╭─────┬─────────╮
│xc │LDA │
│encut│300 │
│kpts │╭─┬─╮ │
│ ││0│2│ │
│ ││1│2│ │
│ ││2│2│ │
│ │╰─┴─╯ │
╰─────┴─────────╯
We can now add our structure relaxation parameters into a group settings object.
[11]:
group_name = 'relax'
group_settings = mc.get_settings(mc.paths.GROUP_SETTINGS)
group_settings[group_name] = dict(ediffg=-0.05, isif=3, ibrion=0, nsw=50)
group_settings.save()
ls('_clease/')
[11]:
README
structure_settings
group_settings
general_settings
This created a group_settings object in our _clease/ folder. Let’s verify it looks as we would expect.
[12]:
cat('_clease/group_settings')
[12]:
╭─────┬──────────────╮
│relax│╭──────┬─────╮│
│ ││ediffg│-0.05││
│ ││isif │3 ││
│ ││ibrion│0 ││
│ ││nsw │50 ││
│ │╰──────┴─────╯│
╰─────┴──────────────╯
Next, we need to construct some structures. To do this, we leverage the structure generation capabilities of CLEASE.
Structure Generation with CLEASE
The dragonfruit workflow has built-in support for CLEASE. As we initialized our repo with CLEASE settings, we can utilize the capabilities of CLEASE directly from dragonfruit.
[13]:
conc = clease.settings.Concentration(basis_elements=[['Au', 'Cu']])
[14]:
mc.new_endpoints(conc, directory='initial')
Supplied structure already exists in DB. The structure will not be inserted.
Supplied structure already exists in DB. The structure will not be inserted.
[14]:
[]
[15]:
mc.new_random_structures(conc, num_to_generate=20, directory='initial')
[15]:
[Atoms(symbols='AuCuAu2', pbc=True, cell=[[1.9, 3.8, 1.9], [3.8, 0.0, 3.8], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='Au2CuAu2Cu2Au7CuAu3', pbc=True, cell=[[5.699999999999999, 7.6, 9.5], [5.699999999999999, 0.0, 5.699999999999999], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='CuAuCuAuCu2Au2Cu6Au2Cu2Au2CuAuCu2', pbc=True, cell=[[0.0, 7.6, 7.6], [3.8, 0.0, 3.8], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Au3CuAu8', pbc=True, cell=[[0.0, 3.8, 3.8], [3.8, 0.0, 3.8], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Au6CuAu9', pbc=True, cell=[[0.0, 1.9, 1.9], [3.8, 0.0, 3.8], [15.2, 15.2, 0.0]], tags=...),
Atoms(symbols='Cu2AuCu7AuCu10Au2Cu4', pbc=True, cell=[[5.699999999999999, 7.6, 9.5], [7.6, 1.9, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu10Au2Cu6', pbc=True, cell=[[5.699999999999999, 5.699999999999999, 7.6], [7.6, 1.9, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='CuAu2Cu4AuCu7', pbc=True, cell=[[9.5, 17.1, 11.4], [3.8, 1.9, 1.9], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu2Au2Cu4', pbc=True, cell=[[1.9, 5.699999999999999, 3.8], [9.5, 1.9, 7.6], [1.9, 1.9, 0.0]], tags=...),
Atoms(symbols='CuAuCuAuCuAuCu2', pbc=True, cell=[[0.0, 3.8, 3.8], [5.699999999999999, 1.9, 3.8], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='Cu3AuCuAu2Cu2AuCu8AuCu2Au3', pbc=True, cell=[[0.0, 3.8, 3.8], [9.5, 1.9, 7.6], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='CuAuCuAu3Cu2Au6', pbc=True, cell=[[7.6, 7.6, 7.6], [1.9, 0.0, 1.9], [13.299999999999999, 13.299999999999999, 0.0]], tags=...),
Atoms(symbols='Cu3AuCuAuCuAuCuAuCuAu3Cu2', pbc=True, cell=[[1.9, 3.8, 5.699999999999999], [5.699999999999999, 1.9, 3.8], [7.6, 7.6, 0.0]], tags=...),
Atoms(symbols='AuCuAu2Cu2Au3', pbc=True, cell=[[1.9, 5.699999999999999, 7.6], [1.9, 0.0, 1.9], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu5Au2Cu20', pbc=True, cell=[[3.8, 9.5, 5.699999999999999], [11.399999999999999, 5.699999999999999, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Au2Cu2Au4CuAu5CuAu2Cu2AuCu2Au2', pbc=True, cell=[[1.9, 7.6, 9.5], [5.699999999999999, 1.9, 3.8], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu5AuCuAuCu', pbc=True, cell=[[1.9, 1.9, 3.8], [9.5, 3.8, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='CuAu13CuAu4CuAuCuAu2', pbc=True, cell=[[1.9, 11.399999999999999, 13.299999999999999], [3.8, 1.9, 1.9], [7.6, 7.6, 0.0]], tags=...),
Atoms(symbols='CuAu2Cu', pbc=True, cell=[[5.699999999999999, 7.6, 5.699999999999999], [1.9, 0.0, 1.9], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='CuAuCuAu2Cu3AuCu2AuCuAuCuAu3', pbc=True, cell=[[5.699999999999999, 15.2, 13.299999999999999], [1.9, 0.0, 1.9], [5.699999999999999, 5.699999999999999, 0.0]], tags=...)]
[16]:
all_initial = mc.get_atoms()
[19]:
all_initial
[19]:
[Atoms(symbols='Au', pbc=True, cell=[[0.0, 1.9, 1.9], [1.9, 0.0, 1.9], [1.9, 1.9, 0.0]], tags=...),
Atoms(symbols='Cu', pbc=True, cell=[[0.0, 1.9, 1.9], [1.9, 0.0, 1.9], [1.9, 1.9, 0.0]], tags=...),
Atoms(symbols='AuCuAu2', pbc=True, cell=[[1.9, 3.8, 1.9], [3.8, 0.0, 3.8], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='Au2CuAu2Cu2Au7CuAu3', pbc=True, cell=[[5.699999999999999, 7.6, 9.5], [5.699999999999999, 0.0, 5.699999999999999], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='CuAuCuAuCu2Au2Cu6Au2Cu2Au2CuAuCu2', pbc=True, cell=[[0.0, 7.6, 7.6], [3.8, 0.0, 3.8], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Au3CuAu8', pbc=True, cell=[[0.0, 3.8, 3.8], [3.8, 0.0, 3.8], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Au6CuAu9', pbc=True, cell=[[0.0, 1.9, 1.9], [3.8, 0.0, 3.8], [15.2, 15.2, 0.0]], tags=...),
Atoms(symbols='Cu2AuCu7AuCu10Au2Cu4', pbc=True, cell=[[5.699999999999999, 7.6, 9.5], [7.6, 1.9, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu10Au2Cu6', pbc=True, cell=[[5.699999999999999, 5.699999999999999, 7.6], [7.6, 1.9, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='CuAu2Cu4AuCu7', pbc=True, cell=[[9.5, 17.1, 11.4], [3.8, 1.9, 1.9], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu2Au2Cu4', pbc=True, cell=[[1.9, 5.699999999999999, 3.8], [9.5, 1.9, 7.6], [1.9, 1.9, 0.0]], tags=...),
Atoms(symbols='CuAuCuAuCuAuCu2', pbc=True, cell=[[0.0, 3.8, 3.8], [5.699999999999999, 1.9, 3.8], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='Cu3AuCuAu2Cu2AuCu8AuCu2Au3', pbc=True, cell=[[0.0, 3.8, 3.8], [9.5, 1.9, 7.6], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='CuAuCuAu3Cu2Au6', pbc=True, cell=[[7.6, 7.6, 7.6], [1.9, 0.0, 1.9], [13.299999999999999, 13.299999999999999, 0.0]], tags=...),
Atoms(symbols='Cu3AuCuAuCuAuCuAuCuAu3Cu2', pbc=True, cell=[[1.9, 3.8, 5.699999999999999], [5.699999999999999, 1.9, 3.8], [7.6, 7.6, 0.0]], tags=...),
Atoms(symbols='AuCuAu2Cu2Au3', pbc=True, cell=[[1.9, 5.699999999999999, 7.6], [1.9, 0.0, 1.9], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu5Au2Cu20', pbc=True, cell=[[3.8, 9.5, 5.699999999999999], [11.399999999999999, 5.699999999999999, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Au2Cu2Au4CuAu5CuAu2Cu2AuCu2Au2', pbc=True, cell=[[1.9, 7.6, 9.5], [5.699999999999999, 1.9, 3.8], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='Cu5AuCuAuCu', pbc=True, cell=[[1.9, 1.9, 3.8], [9.5, 3.8, 5.699999999999999], [5.699999999999999, 5.699999999999999, 0.0]], tags=...),
Atoms(symbols='CuAu13CuAu4CuAuCuAu2', pbc=True, cell=[[1.9, 11.399999999999999, 13.299999999999999], [3.8, 1.9, 1.9], [7.6, 7.6, 0.0]], tags=...),
Atoms(symbols='CuAu2Cu', pbc=True, cell=[[5.699999999999999, 7.6, 5.699999999999999], [1.9, 0.0, 1.9], [3.8, 3.8, 0.0]], tags=...),
Atoms(symbols='CuAuCuAu2Cu3AuCu2AuCuAuCuAu3', pbc=True, cell=[[5.699999999999999, 15.2, 13.299999999999999], [1.9, 0.0, 1.9], [5.699999999999999, 5.699999999999999, 0.0]], tags=...)]
[ ]: