GithubHelp home page GithubHelp logo

qzhu2017 / pyxtal Goto Github PK

View Code? Open in Web Editor NEW
228.0 12.0 59.0 25 MB

A code to generate atomic structure with symmetry

License: MIT License

Python 98.72% CSS 0.12% JavaScript 0.08% HTML 1.07% Shell 0.01%
crystallography nanoparticles 2d-materials symmetry

pyxtal's Introduction

PyXtal

Documentation Status Test Status Download Status Download Status Downloads DOI Gitter

Table of content

Introduction

PyXtal is an open source Python package which was initiated by Qiang Zhu and Scott Fredericks at department of Physics and Astronomy, University of Nevada Las Vegas. The goal of PyXtal is to develop a fundamental library to allow one to design the material structure with a certain symmetry constraint. These structures can exported to various structural formats for further study. See the documentation for more information.

To contribute to this project, please check How to contribute?.

Quick Start

Current Features

  • Generation of atomic structures for a given symmetry and stoichiometry (0-3D)
  • Generation of molecular crystals (1-3D) with the support of special Wyckoff positions.
  • Structure manipulation via subgroup/supergroup symmetry relation
  • Geometry optimization from built-in and external optimization methods.
  • Internal support of cif file and many other formats via pymatgen or ASE.
  • Easy access to symmetry information (e.g., Wyckoff, site symmetry and international symbols).
  • X-ray diffraction analysis and its online application

Installation

To install the code, one just needs to do

pip install pyxtal

or

pip install --upgrade git+https://github.com/qzhu2017/PyXtal.git@master

Citation

Fredericks S, Parrish K, Sayre D, Zhu Q*(2020) PyXtal: a Python Library for Crystal Structure Generation and Symmetry Analysis. [arXiv link]

@article{pyxtal,
title = "PyXtal: A Python library for crystal structure generation and symmetry analysis",
journal = "Computer Physics Communications",
volume = "261",
pages = "107810",
year = "2021",
issn = "0010-4655",
doi = "https://doi.org/10.1016/j.cpc.2020.107810",
url = "http://www.sciencedirect.com/science/article/pii/S0010465520304057",
author = "Scott Fredericks and Kevin Parrish and Dean Sayre and Qiang Zhu",
}

How to contribute?

This is an open-source project. Its growth depends on the community. To contribute to PyXtal, you don't necessarily have to write the code. Any contributions from the following list will be helpful.

  • Star on GitHub the PyXtal project and recommend it to your colleagues/friends
  • Open an GitHub issues to report the bug or address your wishlist or improve our documentation
  • GitHub forks the repository and send us the pull request

pyxtal's People

Contributors

comprhys avatar dee-y avatar dependabot[bot] avatar gpetretto avatar janosh avatar kevinparrish1 avatar kyledmiller avatar pmrv avatar qzhu2017 avatar rmcgibbo avatar sabaronett avatar scottfredericks avatar setchatuan avatar somerandomguy10111 avatar ubikpt avatar yanxon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyxtal's Issues

a bug

@scottfredericks
try to execute the following code. It looks like there is a bug when the input molecule has C1 symmetry.

from pyxtal.molecular_crystal import molecular_crystal
from random import randint
from time import time 
from pymatgen.io.cif import CifWriter
import os

mols = ['CH4', 'H2O', 'NH3', 'benzene', 'C60', 'pentacene', 'roy', 'aspirin']
filename = 'out.cif'
if os.path.isfile(filename):
    os.remove(filename)

for mol in mols:
    for i in range(10):
        run = True
        while run:
            sg = 19 #randint(4, 191)
            start = time()
            rand_crystal = molecular_crystal(sg, [mol], [4], 2.0)
            if rand_crystal.valid:
                run = False
                print('SG: {0:d} Time: {1:.3f} seconds'.format(sg, time()-start))
                content = str(CifWriter(rand_crystal.struct, symprec=0.1))
                with open(filename, 'a+') as f:
                    f.writelines(content)
SG: 19 Time: 0.768 seconds
SG: 19 Time: 0.445 seconds
Traceback (most recent call last):
  File "1.py", line 18, in <module>
    rand_crystal = molecular_crystal(sg, [mol], [4], 2.0)
  File "/Users/qiangzhu/Desktop/github/PyXtal/pyxtal/molecular_crystal.py", line 772, in __init__
    self.get_orientations()
  File "/Users/qiangzhu/Desktop/github/PyXtal/pyxtal/molecular_crystal.py", line 813, in get_orientations
    allowed = orientation_in_wyckoff_position(mol, self.wyckoffs, self.w_symm, wp_index, already_oriented=True, allow_inversion=self.allow_inversion)
  File "/Users/qiangzhu/Desktop/github/PyXtal/pyxtal/molecule.py", line 314, in orientation_in_wyckoff_position
    for op in gen_pos:
NameError: name 'gen_pos' is not defined

[bug]structure generation failed

Sometimes, the program will fail without outputting anything useful.

qiangzhu@u-10-240-0-27:~/Desktop/github/crystallography$ python molecular_crystal.py -n 4 -s 61
/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/pymatgen/io/cif.py:44: UserWarning: Please install optional dependency pybtex if youwant to extract references from CIF files.
  warnings.warn("Please install optional dependency pybtex if you"
Error: the stoichiometry is incompatible with the wyckoff sites choice
something is wrong
Traceback (most recent call last):
  File "molecular_crystal.py", line 591, in <module>
    print(len(rand_crystal.coordinates))
AttributeError: 'molecular_crystal' object has no attribute 'coordinates'

Atomic 2D and 1D Symmetry

@qzhu2017
It seems there are still some 2D and 1D space groups which do not have the correct symmetry for atomic structures. The 2D groups are all monoclinic, while the 1D are not. I will look into this.

Omission of Wyckoff Positions for 2d crystals

@qzhu2017
In the function get_wyckoffs, if a Wyckoff position is incompatible with the defined value of PB, it will not include that Wyckoff position into the returned list. As a result, the length of the list can change depending on the value of PB, and thus the indices used for the list might not match up with get_wyckoff_symmetry, get_wyckoff_generators, letter_from_index, index_from_letter, etc.

This has caused various issues for the use of check_wyckoff_position and find_generating_point. I am currently working on syncing up all of these functions so that the correct index will be passed/used. I have made some progress, but it seems there are still a few problems. I will upload the new code once the functions work correctly.

unit test script

@scottfredericks
When I tried to follow the tutorial to run the script, it returned some annoying messages. It would be good to create a simple test script and make sure you run it every time after you updated the code.

qiangzhu@Qiangs-MacBook-Pro:~/Desktop/github/pyXtal$ python -m pyxtal.crystal
/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/pymatgen/io/cif.py:44: UserWarning: Please install optional dependency pybtex if youwant to extract references from CIF files.
  warnings.warn("Please install optional dependency pybtex if you"
Space group  requested:  206 generated 230
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
Space group  requested:  206 generated 206
    Could not write cif file.
qiangzhu@Qiangs-MacBook-Pro:~/Desktop/github/pyXtal$ python -m pyxtal.molecular_crystal
/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/pymatgen/io/cif.py:44: UserWarning: Please install optional dependency pybtex if youwant to extract references from CIF files.
  warnings.warn("Please install optional dependency pybtex if you"
Traceback (most recent call last):
  File "/Users/qiangzhu/miniconda3/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/Users/qiangzhu/miniconda3/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/qiangzhu/Desktop/github/pyXtal/pyxtal/molecular_crystal.py", line 1303, in <module>
    rand_crystal = molecular_crystal(options.sg, system, numMols0, options.factor, orientations=orientations, check_atomic_distances=checkatoms, allow_inversion=allowinversion)
  File "/Users/qiangzhu/Desktop/github/pyXtal/pyxtal/molecular_crystal.py", line 411, in __init__
    self.get_orientations()
  File "/Users/qiangzhu/Desktop/github/pyXtal/pyxtal/molecular_crystal.py", line 453, in get_orientations
    allowed = orientation_in_wyckoff_position(mol, self.sg, wp_index, already_oriented=True, allow_inversion=self.allow_inversion, PBC=self.PBC)
AttributeError: 'molecular_crystal' object has no attribute 'PBC'

bug in 2d crystal?

I tried the following script @scottfredericks

from crystallography import crystal

struc = crystal.random_crystal_2D(20, ['C'], [4], 2.0, 2.5)
print(struc.struct)

Thought it should be easy to generate a 2d crystal for carbon with 4 atoms. However, it returns the following,

Error: failed in the cycle of generating structures

Propose logo

Hello, i am a graphic designer and i would love to contribute a logo to your project. It's free of course.

Profiling

I am still not very happy about the efficiency. By running the tests on molecular_3D. It takes a lot of time for some space groups. We need to figure out which parts of the code need to be optimized.

generate_lattice loop

Need to add a loop when the generate_lattice function returns False.

                 #1, Generate a lattice
                 cell_para = generate_lattice(self.sg, self.volume, minvec=minvector)
                 cell_matrix = para2matrix(cell_para)

I will do it later.

Random generation of molecular crystals

@scottfredericks , I suggest you start with the code which we had for atomic crystals.

1, copy structure.py to a new file (structure_molecule.py?)
2, for a given molecule (like H2O), we still randomly pick a space group and wyckoff site, and then align the molecules with some random numbers.
3, In the structure class, we now have
numIons, space group, lattice, coordinates, wyckoffs
it would be good to add some parameters which represents the necessary information to reproduce the structure, like the followings,
molecular xyz
the alignment of molecules and random numbers.

I will come up with more suggestions later

Symbol interpretation

@qzhu2017
It would be useful to allow the user to input symbols instead of international numbers, since the numbers are not very well known without the use of Bilbao or the International Tables. Also, it would be nice to print the symbol for certain classes.

H-M symbols should be straightforward to implement. Hall symbols may be more complicated. I will worry about those around the time we start incorporating cell transformations.

Symbols will be especially important for 0D clusters, since the non-crystallographic point groups do not have official international numbers. In this case, the Schoenflies notation will probably be the most appropriate.

Wyckoff as a separate class

@scottfredericks

After reading the documents on wyckoff positions
https://github.com/qzhu2017/PyXtal/blob/master/doc/index.rst

I think a better way to organize it should make a separate class.

>>> from pyxtal.crystal import *
>>> sg = 35
>>> index = index_from_letter('b', sg)
>>> ops = get_wyckoff_symmetry(sg)[index][0]
>>> ss_string_from_ops(ops, sg)
'mm2'

A human way of doing this should be

>>> from pyxtal.wyckoff import wyckoff
>>> sg = 35
>>> test = wyckoff(sg)
>>> test.show_letters()
>>> ops = test.get_wyckoff_symmetry('4b')
>>> ops.point_group()
'mm2'

We should do it after fixing the issues in speeds

the variable of generators

@scottfredericks
I have created a simple test.py as follows

#from crystallography import molecular_crystal
#struc = molecular_crystal.molecular_crystal(36, ['H2O'], [4], 2.5)
#print(struc.struct)

from crystallography import crystal
struc = crystal.random_crystal(14, ['C'], [4], 1.5)
print(struc.struct)
#struc = crystal.random_crystal(36, ['C'], [4], 1.5)
#print(struc.struct)

If you execute this script for a couple of times, you will find sometimes python has the following complaints

qiangzhu@Qiangs-MBP:~/Desktop$ python 1.py 
/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/pymatgen/io/cif.py:44: UserWarning: Please install optional dependency pybtex if youwant to extract references from CIF files.
  warnings.warn("Please install optional dependency pybtex if you"
Traceback (most recent call last):
  File "1.py", line 6, in <module>
    struc = crystal.random_crystal(14, ['C'], [4], 1.5)
  File "/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/crystallography/crystal.py", line 1465, in __init__
    self.generate_crystal()
  File "/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/crystallography/crystal.py", line 1582, in generate_crystal
    coords_toadd, good_merge = merge_coordinate(coords, cell_matrix, self.wyckoffs, self.sg, tol)
  File "/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/crystallography/crystal.py", line 841, in merge_coordinate
    index = check_wyckoff_position(merged, sg, exact_translation=False, PBC=PBC, PB=PB)
  File "/Users/qiangzhu/miniconda3/lib/python3.6/site-packages/crystallography/crystal.py", line 1397, in check_wyckoff_position
    p = find_generating_point(points, generators, PBC=PBC)
NameError: name 'generators' is not defined

Needs to provide our own structure type

@scottfredericks

Right now, we directly use the structure module from pymatgen, which is good but sometimes not very convenient,

from crystallography.molecular_crystal import molecular_crystal
my_crystal = molecular_crystal(36, ['C60'], [2], 20.0)
my_crystal.struct.to(filename='c60.poscar',fmt='poscar')
my_crystal.struct.to(filename='c60.cif',fmt='cif')

the default cif writer does not symmetrize the structure. Pymatgen has a separate cifWriter class to do it. However, it would be better we build our own function inside the crystal class so that the user can directly get the cif file without knowing the functionality in Pymatgen.

I will discuss it with you later in person.

add distance check function

need to add a distance check function after placing the molecule in the crystal

                    #placing molecules here
                    if good_structure:
                        final_coor = []
                        final_site = []
                        final_number = []
                        final_lattice = cell_matrix
                        wyckoffs = get_wyckoffs(sg)
                        for center0, i, wp_index in zip(points_total, sites_total, wps_total):
                            mol = self.molecules[i]
                            mo = deepcopy(mol)
                            #get j, k from wp_index
                            num = 0
                            found = False
                            j, k = jkfromi(wp_index, self.wyckoffs)
                            op1 = choose(self.valid_orientations[i][j][k]).get_op()
                            mo.apply_operation(op1)
                            for op2 in get_wyckoff_generators(self.sg)[wp_index]:
                                for site in mo:
                                    #Place molecular coordinates in relative coordinates
                                    relative_coords = np.dot(np.linalg.inv(cell_matrix), site.coords)
                                    raw_vector = center0 + relative_coords
                                    new_vector = op2.operate(raw_vector)
                                    new_vector -= np.floor(new_vector)
                                    final_coor.append(new_vector)
                                    final_site.append(site.specie)
                                    final_number.append(site.specie.number)

Repository listed as HTML instead of Python

@qzhu2017
I was browsing a few forks of our project, and it seems that the repository is listed as HTML instead of Python. I am not sure if this is automatically detected based on the contents of doc, or if we can change it.

molecular library

Instead of using the molecular libraries in ASE, we need to build a library for our own studies. I will start to collect such examples later.

Primitive cell usage

@qzhu2017
Currently, we do not have a way to convert between conventional, primitive, and non-standard settings. I think outputting the conventional standard cell is fine, but working with the primitive cell should speed things up for I, C, and F space groups. For F groups especially, our distance matrices would be reduced in size by a factor of 4**2=16.

I need to research what the primitive cell is for these groups, and how to convert the Wyckoff positions, generators, and symmetry accordingly. Also, we need to convert the final structure to the conventional setting after the primitive structure is generated (with an option whether or not to do so).

For certain classes and functions, we can implement an option like setting='conventional' or setting='primitive'. These include Group, Wyckoff_position, random_crystal, get_wyckoffs, get_wyckoff_generators, get_wyckoff_symmetry, etc.

Further down the line, we could implement more alternative settings, but since we are only outputting structures instead of taking them in, I don't think this will be needed yet. spg and/or pymatgen should have some tools for handling these kinds of problems.

Needs new scheme to estimate the molecular volume

The current scheme absolutely fails to give correct estimation on the molecular volume. For C60, we need to use almost 20 times of volume factor to obtain the real volume.

from crystallography.molecular_crystal import molecular_crystal
my_crystal = molecular_crystal(36, ['C60'], [2], 20.0)
my_crystal.struct.to(filename='c60.cif',fmt='cif')

There should be a better scheme. Will look into some literature

needs to support the fix lattice mode

At present, we generate the crystal structure based on a random lattice. For practical crystal structure prediction, it is also useful to fix the lattice parameter. I will think about an optimum way to define this option.

Redesign it as a class

make it as an class like the followings,

class Random_crystal(object):
"""a class of crystal structure generation object.
Attributes:
space group: international number of space group, e.g., 206
species: list of elements, e.g., ['Li', 'Na']
numIons: the corresponding numbers for each specie, e.g, [16, 8]
volume_factor: the volume factor for estimation: e.g., 0.5
"""

def __init__(self, spacegroup, species, numIons, volume_factor=0.5):
    """Return a RDF object with the proper info"""
    self.sg = spacegroup
    self.species = species
    self.numIons = numIons
    self.generate_crystal(spacegroup, species, numIons, volume_factor)
   ......

The similar examples can be found at:
https://github.com/qzhu2017/RDF/blob/master/RDF.py

optimization

@scottfredericks
I just add a test code for optimization. It works fine. Now I need to implement the method for optimization under symmetry constraints. Please find me tomorrow. I need to know how to find the symmetry information for such task.

lattice assignment

Sometimes the program fails due to very unbalance lattice assignment.
Li8 Ca4 O10
1.0
101.924633 0.000000 0.000000
2.092458 1.699747 0.000000
0.901087 1.611128 1.139483
Ca Li O
4 8 10
direct
0.618499 0.026280 0.781551 Ca
0.381501 0.973720 0.218449 Ca
0.934161 0.947708 0.208905 Ca
0.065839 0.052292 0.791095 Ca
0.699432 0.589616 0.423058 Li
0.300568 0.410384 0.576942 Li
0.276588 0.174145 0.497114 Li
0.723412 0.825855 0.502886 Li
0.165347 0.126766 0.852747 Li
0.834653 0.873234 0.147253 Li
0.893754 0.494705 0.883722 Li
0.106246 0.505295 0.116278 Li
0.980766 0.937745 0.976306 O
0.019234 0.062255 0.023694 O
0.543600 0.986248 0.909981 O
0.456400 0.013752 0.090019 O
0.699099 0.094702 0.612930 O
0.300901 0.905298 0.387070 O
0.481797 0.128817 0.121688 O
0.518203 0.871183 0.878312 O
0.468908 0.946897 0.805108 O
0.531092 0.053103 0.194892 O

Documentation

Currently, a few items in the documentation need to be added/corrected

1, Regarding the use of molecule (how to read the molecule from the SMILES string?)
2, The use of random_cluster generation (the basic functionality and the list of supported points groups)
3, The updates on the use of symmetry class

make_sitesym.get_wyckoff_position_operators is slow

wyckoff_positions = make_sitesym.get_wyckoff_position_operators('database/Wyckoff.csv', hall_number)

I just did some profiler analysis on the code. It was found that the
Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)
93845 0.081 0.000 0.081 0.000 :0(append)
36989 0.096 0.000 0.096 0.000 :0(array)
60 0.000 0.000 0.000 0.000 :0(ascii_decode)
1 0.000 0.000 3.256 3.256 :0(exec)
441856 0.433 0.000 0.433 0.000 :0(find)
20236 0.022 0.000 0.022 0.000 :0(isdigit)
2 0.000 0.000 0.000 0.000 :0(items)
38130 0.030 0.000 0.030 0.000 :0(len)
2 0.000 0.000 0.000 0.000 :0(nl_langinfo)
2 0.000 0.000 0.000 0.000 :0(open)
552315 0.260 0.000 0.260 0.000 :0(ord)
2 0.000 0.000 0.000 0.000 :0(pop)
14 0.000 0.000 0.000 0.000 :0(replace)
94910 0.101 0.000 0.101 0.000 :0(split)
57972 0.065 0.000 0.065 0.000 :0(strip)
110463 0.119 0.000 0.119 0.000 :0(translate)
73699 0.177 0.000 0.177 0.000 :0(zeros)
1 0.000 0.000 3.256 3.256 :1()
2 0.000 0.000 0.000 0.000 _bootlocale.py:23(getpreferredencoding)
60 0.000 0.000 0.000 0.000 ascii.py:25(decode)
2 0.000 0.000 0.000 0.000 codecs.py:259(init)
2 0.000 0.000 0.000 0.000 element.py:2(init)
2 0.000 0.000 0.000 0.000 groups.py:36(get_symm_data)
2 0.000 0.000 0.000 0.000 groups.py:487(sg_symbol_from_int_number)
2 0.000 0.000 0.000 0.000 hall.py:239(hall_from_hm)
2 0.161 0.081 0.305 0.153 make_Wyckoff_db.py:153(read_wyckoff_csv)
2 0.336 0.168 2.943 1.471 make_Wyckoff_db.py:205(get_wyckoff_positions)
36822 0.999 0.000 2.402 0.000 make_Wyckoff_db.py:22(position2operation)
110463 0.368 0.000 0.628 0.000 make_Wyckoff_db.py:57()

2 0.000 0.000 3.248 1.624 make_sitesym.py:19(get_wyckoff_position_operators)
56 0.000 0.000 0.000 0.000 operations.py:43(init)
56 0.000 0.000 0.002 0.000 operations.py:61(from_rotation_and_translation)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 3.256 3.256 profile:0(random_crystal(sg, species, numIons, factor))
2 0.000 0.000 0.000 0.000 structure.py:149(cellsize)
2 0.000 0.000 0.000 0.000 structure.py:261(estimate_volume)
56 0.000 0.000 0.000 0.000 structure.py:318(filter_site)
2 0.005 0.003 3.255 1.628 structure.py:371(get_wyckoff_positions)
1 0.000 0.000 3.256 3.256 structure.py:459(init)
2 0.000 0.000 0.000 0.000 structure.py:477(Msgs)
56 0.001 0.000 0.001 0.000 twodim_base.py:140(eye)

The function of make_Wyckoff_db.py would be very time consuming if we repeat the code for many times.
We need to optimize this part!

test suites

After you are done with the random_crystal class, you can write a separate test.py to run the following tests.

  1. ['Li'], [8], 2-230
  2. ['Ca', 'Li'], [4, 8], 2-230
  3. ['Mg', 'Si', 'O'], [2, 2, 10], 2-230
  4. ['Li'], [8], 2-15, 143-167
  5. ['Li'], [4], 2-15, 143-167

Tolerance_matrix class

@qzhu2017
As discussed in person, I would like to create a tolerance matrix class for custom distance checking. This will allow users to use different inter-atomic distance tolerances, or check distances for specific systems like metals. Some desired features are:

  • Loading and saving from json file
  • Several default profiles for common cases ('atomic', 'molecular', 'metallic', etc.)
  • Customization of specific atom-atom bonds. For example, something like tol_m.set_tol('C', 'H', 1.2) would set the distance tolerance between Carbon and Hydrogen to 1.2 Angstroms.
  • A distance factor to pass to check_distances. A larger value will mean atoms must be further apart

Also, within the random_crystal and molecular_crystal classes, we should implement a custom print function which shows the used tolerances. We can have an attribute 'random_crystal.tolerances' that prints the tolerances for the atom-atom pairs which are present within the crystal.

Interface Module

For the purpose of test, it would be good to have our own energy models. I think the easiest model is the LJ potential. I will implement the general LJ model for any arbitrary dimension and periodic boundary conditions.

improve the check_compatible function

parameter set: 218 ['Ca', 'Li'] [4, 8] 1.0

If space group 218 has only 2a 6b as follows,
6 | b | 222 . . | (0,1/2,1/2)(1/2,0,1/2)(1/2,1/2,0)(0,1/2,0)(1/2,0,0)(0,0,1/2) | (0,1/2,1/2) | (1/2,0,1/2) |
2 | a | 23. | (0,0,0)(1/2,1/2,1/2) | (0,0,0) |

It is obviously impossible to make 4 atoms.

PBC list format

@qzhu2017
As you mentioned before, I will try to convert the values of PBC to use [0,0,0] or [1,1,1] instead of the current [1,2,3] style. I want to knock out all of the usage cases at once, so I will try to do this some time after implementing the new Wyckoff_position and Group classes.

bug

@scottfredericks
A bug after your recent commits

qiangzhu@Qiangs-MacBook-Pro:~/Desktop/github/PyXtal$ python pyxtal/test_cases/test_3D_molecule.py 
Mol:CH4         SG: 51 Time:0.69 seconds, N_attempts:   2 Vol: 216.51
Traceback (most recent call last):
  File "pyxtal/test_cases/test_3D_molecule.py", line 18, in <module>
    rand_crystal = molecular_crystal(sg, [mol], [4], 1.0)
  File "/Users/qiangzhu/Desktop/github/PyXtal/pyxtal/molecular_crystal.py", line 1013, in __init__
    self.init_common(molecules, numMols, volume_factor, allow_inversion, orientations, check_atomic_distances, group, lattice, tm)
  File "/Users/qiangzhu/Desktop/github/PyXtal/pyxtal/molecular_crystal.py", line 1001, in init_common
    self.generate_crystal()
  File "/Users/qiangzhu/Desktop/github/PyXtal/pyxtal/molecular_crystal.py", line 1178, in generate_crystal
    self.struct = Msg1
NameError: name 'Msg1' is not defined

Incorrect determination of Wyckoff position for merged coordinates

@qzhu2017
There is an issue in determining the Wyckoff position of merged coordinates. In certain cases, multiple possible Wyckoff positions are found. I think this is due to having exact_translation=False in check_wyckoff_position. We should be able to differentiate the possible WP's based on whether or not we can re-generate the coordinates using the Wyckoff generators. So, if we pass a set of coordinates to check_wyckoff_position, we should be able to re-generate those coordinates using 1) a specific coordinate in the list, and 2) the Wyckoff generators for some position (assuming the coordinates belong to that WP). However, in some cases the function is not able to re-generate the coordinates for any of the found Wyckoff positions.

I am not sure exactly where the issue is coming, but I will continue to look into it. I think the problem may be that having exact_translation=False allows for some false positives, meaning the possible WP's we check shouldn't work in the first place. I will look at some examples to check. I first noticed this issue while generating crystals for spacegroup 225, with 48 or 96 atoms/molecules in the primitive cell (which is quite slow).

Molecular Distance Check

@qzhu2017
In order to check the distance between molecules (without checking inter-atomic distances directly), I think minimal ellipsoids would be a good approximate solution. For a given molecule, we can calculate a minimum binding ellipsoid which contains the molecule, with some padding. We can store this ellipsoid as an affine matrix, where the 3x3 rotational/skew part corresponds to the a, b, c vectors of the ellipsoid, and the vector part corresponds to the ellipsoid's center:

[a1, a2, a3, v1]
[b1, b2, b3, v2]
[c1, c2, c2, v3]
[0,  0,  0,  1 ]

To compare two molecules, we use these two affine 4x4 matrices. We can apply a transformation so that one of the ellipsoids becomes a sphere; the other ellipsoid will be skewed, but will still be an ellipsoid. Then, we can use an approximate method for checking whether or not the sphere and ellipsoid intersect. A more detailed method is described here: https://www.geometrictools.com/Documentation/IntersectionOfEllipsoids.pdf

So, it seems the main challenge is calculating a binding ellipsoid in the first place. I am inexperienced with optimizing functionals computationally. But since we can define the ellipsoid as an affine matrix, I think we can just try to optimize the components of this matrix simultaneously, in such a way that all of our molecular coordinates are contained within the ellipsoid. I will try to look for existing algorithms for this. In the mean time, I will work on a less exact method which uses the binding boxes as a basis for the binding ellipsoid.

Also, there is the issue of doing these checks with periodic boundary conditions. This should be similar to the inter-atomic distance check, but we'll need to apply np.min at a different step in the process.

Because of the complexity of the process compared to direct distance checking, I think the method will likely be slower except for very large molecules. Still, it would be a nice feature to have a binding ellipsoid calculator as part of the package.

cluster distance check

@scottfredericks
I just quickly ran a test for LJ16, and quickly found a structure with quick high energy (>-9 eV). When I looked at the structure, it clearly show that there exist many rather small distances.
image

An automated script to update the doc file

@scottfredericks

Just realized that we need to create an automated script to update the sphinx documents. Remember you once showed us that you need to answer some questions when you execute the sphinx commend. So you just need to create a bash script that store all the default answers. This will make life easier.

molecular crystal with support from ASE

@scottfredericks it might be a good idea to take the advantage of ase for generating molecular crystal.
ASE provides a collection of small molecules which you can use for test.

from ase.build import molecule
c60 = molecule('C60')

Moreover, it has well designed class which can be very useful.

print(c60.get_positions())

check out my updates on github: https://github.com/qzhu2017/CMS/blob/master/ASE-scripts/Model_construction.ipynb

as well as the documentation of molecule class in ASE,
https://wiki.fysik.dtu.dk/ase/ase/atoms.html

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.