diff --git a/README.md b/README.md index 0de7906..46f1d27 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # BiCrystal -``BiCrystal`` is a Python program that builds commensurate and incommensurate crystal structures of layered materials. The current version reads CIF files and writes the new structure to a QUANTUM ESPRESSO input file. The program also provides additional information such as the bond distance between atoms, lattice vectors in Bohr and Angstrom, and a simple 3D plot of each layer. +``BiCrystal`` is a Python program that builds incommensurate crystal structures of layered materials. The current version reads CIF files and writes the new structure to a QUANTUM ESPRESSO input file. The program also provides additional information such as the bond distance between atoms, lattice vectors in Bohr and Angstrom, and a simple 3D plot of each layer. Contents ========== @@ -20,12 +20,13 @@ Building unit cells of arbitrary size is often an inevitable task when studying # Download The latest version of ``BiCrystal`` can be found on github: -https://github.com/tilaskabengele/BiCrystal +https://github.com/tilaskabengele/BiCrystal/tree/stable + **Contact**: Tilas Kabengele tilas.kabengele@dal.ca # Packages -`BiCrystal` is a python-based program that uses Scipy and Shapely libraries. Additionally, the Crystal package, which is not part of the standard Python packages, should be installed. i.e Install via pip or conda: +`BiCrystal` is a python-based program that uses Scipy and Shapely libraries. Additionally, the Crystal and shapely packages, which is not part of the standard Python packages, should be installed. i.e Install via pip or conda: pip install crystals or @@ -38,7 +39,6 @@ and For more information on crystals and shapely, visit: https://pypi.org/project/crystals/ and https://pypi.org/project/Shapely/ respectively. # Files - **bicrystal** - Bash script which runs the python program \ **cifs/** - Directory with sample cif files \ **examples/** - Directory with 33 examples of QUANTUM ESPRESSO input files generated by BiCrystal \ @@ -48,7 +48,7 @@ For more information on crystals and shapely, visit: https://pypi.org/project/cr # Installation After downloading the files from the github repository to the directory of your choice (_recommended: /usr/bin/_), make `bicrystal` and `program.py` into executables: - chmod u+x bicrystal program.py + chmod r+x bicrystal program.py Next, add this directory to your $PATH variable. In Bash, adding the following lines to your `.bashrc file`: @@ -75,13 +75,11 @@ The first thing you will be required to do is input your cif file, e.g. graphite ***Input cif file*** graphite.cif -Next, enter input parameters m and n, and rotation angle in degrees (_zero if you want both layers unperturbed_). -Parameter m and n correspond to the scale of the lattice vectors along the x and y directions, respectively. As an example, let's take m = 2, n = 1 and rotation angle 21.79 degrees. +Next, input scaling parameters m and n, which correspond to the scale of the lattice vectors along the x and y directions, respectively. As an example, let's take m = 2, n = 1. Bicrystal caculates the relative rotation angle for the given m and n. In this case, the rotation angle will be 21.79 degrees. ***Rotation parameters*** Enter m 2 Enter n 1 - Enter rotation_angle 0 After that, you will be required to pick a zeroeth atom from the top and bottom layer. If we were picking the atoms by hand using a visualization software such as Xcrysden, this would be the atom we start from when creating the new cell vectors. @@ -110,7 +108,10 @@ After that, you will be required to pick a zeroeth atom from the top and bottom Finally, you can save your output as a QUANTUM ESPRESSO file and visualize with Xcrysden for a more sophisticated look. ********************* SUMMARY REPORT *********************** - + + Rotation angle (deg) = 19.107 + Relative Rotation (deg) = 21.787 + Top atoms(rotated) = 14 Bottom atoms = 14 @@ -122,7 +123,6 @@ After that, you will be required to pick a zeroeth atom from the top and bottom Would you like to write Espresso file?[Y/n] # Examples - Let's say we saved our output in the example given above as graphite28.scf.in, we can visualize this with Xcrysden. xcrysden --pwi graphite28.scf.in @@ -134,17 +134,17 @@ Looking from the top view, we can see that for this rotation, a Moire pattern wa The **examples/** folder has over 30 examples of Moire patterns graphite, Molebdenum Disulfide and blue Phosphorene generated from `bicrystal`. Below are some examples. # Graphite 364-atom unit cell -The unit cell of graphite with 364 atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view. +The unit cell of graphite with 364 atoms can be generated by using parameters: m = 6, n = 5. Shown below is the top view. ![cc364](https://user-images.githubusercontent.com/62076249/87933970-98f5b000-ca64-11ea-906b-15a1036989a1.PNG) # Blue phosphorene 172-atom unit cell -The unit cell of blue phosphorene with 172 atoms can be generated by using parameters: m = 6, n = 1, and rotation angle of 44.82 degrees. Shown below is the top view. +The unit cell of blue phosphorene with 172 atoms can be generated by using parameters: m = 6, n = 1. Shown below is the top view. ![bluep172](https://user-images.githubusercontent.com/62076249/87934152-e245ff80-ca64-11ea-8f36-b69b5799e3fa.PNG) # Molybdenun Disulfide 546-atom unit cell -The unit cell of MoS2 with 546 atoms atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view. +The unit cell of MoS2 with 546 atoms atoms can be generated by using parameters: m = 6, n = 5. Shown below is the top view. ![mos546](https://user-images.githubusercontent.com/62076249/87934312-2fc26c80-ca65-11ea-97a2-c9cdb3068a9d.PNG) diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 2f7efbe..0000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-minimal \ No newline at end of file diff --git a/bicrystal/README.md b/bicrystal/README.md index c70093a..1b9e68c 100644 --- a/bicrystal/README.md +++ b/bicrystal/README.md @@ -1,5 +1,5 @@ # BiCrystal -``BiCrystal`` is a Python program that builds commensurate and incommensurate crystal structures of layered materials. The current version reads CIF files and writes the new structure to a QUANTUM ESPRESSO input file. The program also provides additional information such as the bond distance between atoms, lattice vectors in Bohr and Angstrom, and a simple 3D plot of each layer. +``BiCrystal`` is a Python program that builds incommensurate crystal structures of layered materials. The current version reads CIF files and writes the new structure to a QUANTUM ESPRESSO input file. The program also provides additional information such as the bond distance between atoms, lattice vectors in Bohr and Angstrom, and a simple 3D plot of each layer. Contents ========== @@ -26,7 +26,7 @@ https://github.com/tilaskabengele/BiCrystal/ **Contact**: Tilas Kabengele tilas.kabengele@dal.ca # Packages -`BiCrystal` is a python-based program that uses Scipy and Shapely libraries. Additionally, the Crystal package, which is not part of the standard Python packages, should be installed. i.e Install via pip or conda: +`BiCrystal` is a python-based program that uses Scipy and Shapely libraries. Additionally, the Crystal and shapely packages, which is not part of the standard Python packages, should be installed. i.e Install via pip or conda: pip install crystals or @@ -39,7 +39,6 @@ and For more information on crystals and shapely, visit: https://pypi.org/project/crystals/ and https://pypi.org/project/Shapely/ respectively. # Files - **bicrystal** - Bash script which runs the python program \ **cifs/** - Directory with sample cif files \ **examples/** - Directory with 33 examples of QUANTUM ESPRESSO input files generated by BiCrystal \ @@ -49,7 +48,7 @@ For more information on crystals and shapely, visit: https://pypi.org/project/cr # Installation After downloading the files from the github repository to the directory of your choice (_recommended: /usr/bin/_), make `bicrystal` and `program.py` into executables: - chmod u+x bicrystal program.py + chmod r+x bicrystal program.py Next, add this directory to your $PATH variable. In Bash, adding the following lines to your `.bashrc file`: @@ -76,13 +75,11 @@ The first thing you will be required to do is input your cif file, e.g. graphite ***Input cif file*** graphite.cif -Next, enter input parameters m and n, and rotation angle in degrees (_zero if you want both layers unperturbed_). -Parameter m and n correspond to the scale of the lattice vectors along the x and y directions, respectively. As an example, let's take m = 2, n = 1 and rotation angle 21.79 degrees. +Next, input scaling parameters m and n, which correspond to the scale of the lattice vectors along the x and y directions, respectively. As an example, let's take m = 2, n = 1. Bicrystal caculates the relative rotation angle for the given m and n. In this case, the rotation angle will be 21.79 degrees. ***Rotation parameters*** Enter m 2 Enter n 1 - Enter rotation_angle 0 After that, you will be required to pick a zeroeth atom from the top and bottom layer. If we were picking the atoms by hand using a visualization software such as Xcrysden, this would be the atom we start from when creating the new cell vectors. @@ -111,7 +108,10 @@ After that, you will be required to pick a zeroeth atom from the top and bottom Finally, you can save your output as a QUANTUM ESPRESSO file and visualize with Xcrysden for a more sophisticated look. ********************* SUMMARY REPORT *********************** - + + Rotation angle (deg) = 19.107 + Relative Rotation (deg) = 21.787 + Top atoms(rotated) = 14 Bottom atoms = 14 @@ -123,7 +123,6 @@ After that, you will be required to pick a zeroeth atom from the top and bottom Would you like to write Espresso file?[Y/n] # Examples - Let's say we saved our output in the example given above as graphite28.scf.in, we can visualize this with Xcrysden. xcrysden --pwi graphite28.scf.in @@ -135,17 +134,17 @@ Looking from the top view, we can see that for this rotation, a Moire pattern wa The **examples/** folder has over 30 examples of Moire patterns graphite, Molebdenum Disulfide and blue Phosphorene generated from `bicrystal`. Below are some examples. # Graphite 364-atom unit cell -The unit cell of graphite with 364 atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view. +The unit cell of graphite with 364 atoms can be generated by using parameters: m = 6, n = 5. Shown below is the top view. ![cc364](https://user-images.githubusercontent.com/62076249/87933970-98f5b000-ca64-11ea-906b-15a1036989a1.PNG) # Blue phosphorene 172-atom unit cell -The unit cell of blue phosphorene with 172 atoms can be generated by using parameters: m = 6, n = 1, and rotation angle of 44.82 degrees. Shown below is the top view. +The unit cell of blue phosphorene with 172 atoms can be generated by using parameters: m = 6, n = 1. Shown below is the top view. ![bluep172](https://user-images.githubusercontent.com/62076249/87934152-e245ff80-ca64-11ea-8f36-b69b5799e3fa.PNG) # Molybdenun Disulfide 546-atom unit cell -The unit cell of MoS2 with 546 atoms atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view. +The unit cell of MoS2 with 546 atoms atoms can be generated by using parameters: m = 6, n = 5. Shown below is the top view. ![mos546](https://user-images.githubusercontent.com/62076249/87934312-2fc26c80-ca65-11ea-97a2-c9cdb3068a9d.PNG) diff --git a/bicrystal/program.py b/bicrystal/program.py index 2b5a463..b5ced85 100644 --- a/bicrystal/program.py +++ b/bicrystal/program.py @@ -1,8 +1,8 @@ -#!/bin/python +#!/bin/python3 # PROGRAM: BiCRYSTAL -# VERSION: 1.0.6 +# VERSION: 1.0.8 # DESCRIPTION: This program buildscommensurate and incommensurate crystal structures of layered materials. Current version reads CIF files and writes the new structure to a QUANTUM ESPRESSO input file. @@ -31,13 +31,13 @@ from sklearn.neighbors import KNeighborsRegressor import numpy as np import decimal -from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from matplotlib import colors as mcolors from matplotlib.collections import PolyCollection from mpl_toolkits.mplot3d.art3d import Poly3DCollection from matplotlib import path from datetime import date, datetime +import time # FUNCTIONS: @@ -47,21 +47,21 @@ # Description: Isolates the z-coordinates (fractional) from CRYSTAL and stores them in an array # Inputs: Python CRYSTAL structure. i.e. don't use a supercell in SEPERATE # Output: Array with z-coordinates of bottom layer atoms - + def seperate(my_crystal): - nat = 0 - z_frac = [] + nat = 0 + z_frac = [] + + for atm in my_crystal: + nat = nat + 1 + z_frac.append(atm.coords_fractional[2]) - for atm in my_crystal: - nat = nat + 1 - z_frac.append(atm.coords_fractional[2]) + z_sorted = sorted(z_frac) + bottom_z = round(nat/2) + answer = z_sorted[0:bottom_z] - z_sorted = sorted(z_frac) - bottom_z = round(nat/2) - answer = z_sorted[0:bottom_z] - - return answer + return answer # *********************************** @@ -101,7 +101,6 @@ def highest(my_crystal): return max(z_cart) - #************************************** # Function name: LOCATE(TEST_ATM,Z_BOT) # Description: Checks if a given atom is from the bottom or top layer @@ -109,21 +108,43 @@ def highest(my_crystal): # Output: True if atom is from bottom layer; false if it isn't def locate(test_atm,z_bot): - - z = [] - - test_atm = round(test_atm,2) - for atm in z_bot: - z.append(round(atm,2)) + z = [] + + test_atm = round(test_atm,2) + + for atm in z_bot: + z.append(round(atm,2)) + + if test_atm in z: + answer = True + else: + answer = False + + return answer + + +# *********************************** +# Function Name: INTERLAYER(atm_top,atm_bottom) +# Description: Finds the interlayer seperation bettwen the layers +# Inputs: Python crystal +# Output: Interlayer seperation in bohr + +def interlayer(my_crystal): + + atmz = [] + for atm in my_crystal: + atmz.append(atm.coords_cartesian[2]) + + z = sorted(atmz) + z_bot = z[:len(z)//2] + z_top = z[len(z)//2:] + seperation = min(z_top) - max(z_bot) + + return seperation*0.529177249 + - if test_atm in z: - answer = True - else: - answer = False - return answer - #*********************************** # Function name: NEWCELL(MY_CRYSTAL,M,N) # Description: This function creates lattice vectors of a rotated layer @@ -131,19 +152,35 @@ def locate(test_atm,z_bot): # Outputs: supercell lattice vectors new_a; new_b .i.e the c-vector remains unchanged def newcell(my_crystal,atoms,m,n): - - a, b, c = my_crystal.lattice_vectors - v1 = atoms[0] + (m+n)*a + (m+n)*b - v2 = np.add(np.add(v1,(m+n)*a),n*b) - v3 = np.add(np.add(v2,(m+n)*b),m*a) - v4 = np.subtract(np.subtract(v3,(m+n)*a),n*b) - - new_a = v2 - v1 - new_b = v3 - v2 - + +# a, b, c = my_crystal.lattice_vectors + a1, a2, a3, alpha, beta, gamma = my_crystal.lattice_parameters +# v1 = atoms[0] + (m+n)*a + (m+n)*b +# v2 = np.add(np.add(v1,(m+n)*a),n*b) +# v3 = np.add(np.add(v2,(m+n)*b),m*a) +# v4 = np.subtract(np.subtract(v3,(m+n)*a),n*b) + + old_a = np.array([0.5*a1*np.sqrt(3), -0.5*a2, 0]) + old_b = np.array([0, a2, 0]) + + v1 = atoms[0] + (m+n)*old_a + (m+n)*old_b + v2 = np.add(np.add(v1,(m+n)*old_a),n*old_b) + v3 = np.add(np.add(v2,(m+n)*old_b),m*old_a) + v4 = np.subtract(np.subtract(v3,(m+n)*old_a),n*old_b) + +# old_a = np.array([a1*0.5*np.sqrt(3), -0.5*a2, 0]) +# old_b = np.array([0, a2, 0]) +# old_c = np.array([0, 0, a3]) + +# new_a = n*old_b - m*old_a +# new_b = m*old_b - n*old_a + + new_a = v3 - v2 + new_b = v2 - v1 + # ang to bohr mytiply by 1.8897259886 - return new_a, new_b, v1, v2, v3, v4 + return new_a, new_b, v1, v2, v3, v4 @@ -183,7 +220,7 @@ def poly(v1,v2,v3,v4): coords = [(p1), (p2), (p3), (p4)] ply = Polygon(coords) - + return ply, p1, p2, p3, p4 @@ -214,9 +251,9 @@ def inpoly(atz,ply): def central(ply): - center = ply.centroid + center = ply.centroid - return center + return center #*************************************** @@ -226,17 +263,17 @@ def central(ply): # Output: True if the rotation is correct, False if it isn't def swaped(layer): - pos_count = 0 - neg_count = 0 - for atm in layer: - if atm >= 0: - pos_count += 1 - else: - neg_count += 1 - if pos_count > neg_count: - return True - else: - return False + pos_count = 0 + neg_count = 0 + for atm in layer: + if atm >= 0: + pos_count += 1 + else: + neg_count += 1 + if pos_count > neg_count: + return True + else: + return False #*************************************** @@ -246,10 +283,10 @@ def swaped(layer): # Output: Number of atoms ---> Integer def ntype(my_crystal): - nat = 0 - for atm in my_crystal.chemical_composition: - nat+=1 - return nat + nat = 0 + for atm in my_crystal.chemical_composition: + nat+=1 + return nat @@ -260,26 +297,26 @@ def ntype(my_crystal): # Output: top and bottom atoms ---> np arrays; chemical symbols for top and bottom atoms ---> lists def bulk(my_crystal): - - atoms_bot = [] - atoms_top = [] - atmxyz = [] - ele_bot = [] - ele_top = [] - z_bot = seperate(my_crystal) - for atm in my_crystal: - atm_frac = atm.coords_fractional - atm_cart = atm.coords_cartesian - atmxyz = atm_cart[0], atm_cart[1], atm_cart[2] - if locate(atm_frac[2],z_bot) == True: - atoms_bot.append(atmxyz) - ELE = str(atm).lower() - ele_bot.append(ELE) - else: - atoms_top.append(atmxyz) - ELE = str(atm).lower() - ele_top.append(ELE) - return np.array(atoms_top), np.array(atoms_bot), ele_top, ele_bot + + atoms_bot = [] + atoms_top = [] + atmxyz = [] + ele_bot = [] + ele_top = [] + z_bot = seperate(my_crystal) + for atm in my_crystal: + atm_frac = atm.coords_fractional + atm_cart = atm.coords_cartesian + atmxyz = atm_cart[0], atm_cart[1], atm_cart[2] + if locate(atm_frac[2],z_bot) == True: + atoms_bot.append(atmxyz) + ELE = str(atm).lower() + ele_bot.append(ELE) + else: + atoms_top.append(atmxyz) + ELE = str(atm).lower() + ele_top.append(ELE) + return np.array(atoms_top), np.array(atoms_bot), ele_top, ele_bot @@ -297,7 +334,7 @@ def bulk(my_crystal): print ('* BiCRYSTAL--', now,'\n\n') print ('**************************************************************************\n \n') -# reading csv with elements from workspace +# reading csv with elements from workspace # i.e. directory where you installed bicrystal with open('workspace') as f: line = f.readline() @@ -316,19 +353,29 @@ def bulk(my_crystal): print ('\n***Rotation parameters*** ') m = int(input('Enter m ')) n = int(input('Enter n ')) -rotation_angle = float(input('Enter rotation_angle ')) -#rotation_angle = -180 + rotation_angle +#rotation_angle = float(input('Enter rotation angle ')) + +# lattice parameters +a, b, c, alpha, beta, gamma = my_crystal.lattice_parameters + +# specify vacuum size in bohr +#print('\n***Specify z-coordinate in cell parameter***') +#print ('(Default = ', c*1.8897259886,' Bohr)') +#vacuum = float(input('Enter z value [Bohr] ')) #### Initializing top and bottom layers #### tt_top,tt_bot,elt_top,elt_bot = bulk(my_crystal) -print ('\n\nIntializing atoms...\n\n') +# Interlayer seperation # +#d = interlayer(my_crystal) # lattice vectors a1, a2, a3 = my_crystal.lattice_vectors uc = a1,a2,a3 uc = np.array(uc) +print ('\n\nIntializing atoms...\n\n') + print ('Initial TOP atoms..') for i in range(0,len(elt_top)): s = np.array(tt_top[i]) @@ -350,33 +397,14 @@ def bulk(my_crystal): # correct array indices for zeroeth atoms idx1 = zeroeth1-1 idx2 = (zeroeth2-1)-len(elt_top) -print ('\nZeroeth TOP (angstrom)', elt_top[idx1], tt_top[idx1]) +print ('\nZeroeth TOP (angstrom)', elt_top[idx1], tt_top[idx1]) print ('\nZeroeth BOTTOM (angstrom)', elt_bot[idx2], tt_bot[idx2]) -#idx1 = min(tt_top, key=lambda x: (x[0], -x[1])) -#idx2 = min(tt_bot, key=lambda x: (x[0], -x[1])) -#print ('\nZeroeth TOP (angstrom)', elt_top[idx1], tt_top[idx1]) -#print ('\nZeroeth BOTTOM (angstrom)', elt_bot[idx2], tt_bot[idx2]) - - # finding the bond length lengths = pdist(tt_bot, 'euclidean') bond_distance = round(min(lengths),3) print ('\nBond distance = ', bond_distance) -# Rotation matrix -phi = np.deg2rad(rotation_angle) -print ('\nRotation angle (radians) = ', phi) -print ('\nRotation matrix') -R = np.array([[np.cos(phi), -np.sin(phi), 0], [np.sin(phi), np.cos(phi), 0], [0, 0, 1]]) -#print (' ','{:12.6f}'.format(R[0])) -#print (' ','{:12.6f}'.format(R[1])) -#print (' ','{:12.6f}'.format(R[2])) -print(R[0]) -print(R[1]) -print(R[2]) - - # lattice parameters print ('\nLattice Vectors (Angstrom)') print (' ','{:12.6f} {:12.6f} {:12.6f}'.format(a1[0],a1[1],a1[2])) @@ -388,11 +416,24 @@ def bulk(my_crystal): print (' ','{:12.6f} {:12.6f} {:12.6f}'.format(a2[0]*a2b,a2[1]*a2b,a2[2]*a2b)) print (' ','{:12.6f} {:12.6f} {:12.6f}'.format(a3[0]*a2b,a3[1]*a2b,a3[2]*a2b)) +# rotation angle +A = np.array([1,0,0]) +B = np.array([np.cos(np.deg2rad(60)),np.sin(np.deg2rad(60)),0]) +V = m*A + n*B +rotation_angle = np.arccos((np.dot(A,V.T))/(np.linalg.norm(A)*np.linalg.norm(V))) +rotation_angle = np.rad2deg(rotation_angle) + +# Rotation matrix +theta = np.deg2rad(rotation_angle) +phi = np.deg2rad(60) - 2*theta +R = np.array([[np.cos(phi), -np.sin(phi), 0], [np.sin(phi), np.cos(phi), 0], [0, 0, 1]]) +print ('\nRotation angle theta (degrees) = ', rotation_angle) +print ('\nMoire angle gamma (degrees) = ',np.rad2deg(phi)) print ("\n\nCALCULATING ATOMIC POSITIONS...") for i in range(1,2): - print ('\n\nPlease wait...\n\n') - sys.stdout.flush() + print ('\n\nPlease wait...\n\n') + sys.stdout.flush() print ("&control") print ( " title='crystal',") @@ -427,6 +468,10 @@ def bulk(my_crystal): ################### loops for bottom layer ################## ############################################################# +bt0 = time.time() +bt1 = time.time() + + tt1 = [] tt2 = [] atoms_bot = [] @@ -443,15 +488,16 @@ def bulk(my_crystal): k = 0 for atm in tt1: u = symb1[k] - k = k + 1 + k = k + 1 for i in range(1,(n+m)*15): tty = atm + i*a2 tt2.append(tty) symb2.append(u) -symb_bot = symb1 + symb2 +symb_bot = symb1 + symb2 atoms_bot = list(tt1) + list (tt2) #atoms_bot = np.array(atoms_bot) +elbt1 = time.time() - bt1 ### Initializing new unit cell ### @@ -538,14 +584,17 @@ def bulk(my_crystal): i = 0 nat_bot=0 for atm in bot_frac: - print ('{} {:12.6f} {:12.6f} {:12.6f}'.format(symbot[i], atm[0], atm[1], atm[2])) + print ('{:2} {:12.6f} {:12.6f} {:12.6f}'.format(symbot[i], atm[0], atm[1], atm[2])) i+=1 nat_bot+=1 +elbt = time.time() - bt0 +#0.5-(atm[2]*c*1.8897259886)/vacuum ####################### loops for top layer ################## ############################################################## +tp0 = time.time() tt1 = [] tt2 = [] @@ -563,12 +612,12 @@ def bulk(my_crystal): k = 0 for atm in tt1: u = symb1[k] - k = k + 1 + k = k + 1 for i in range(1,(n+m)*15): tty = atm + i*a2 tt2.append(tty) symb2.append(u) -symb_top = symb1 + symb2 +symb_top = symb1 + symb2 atoms_top = list(tt1) + list (tt2) #atoms_top = np.array(atoms_top) @@ -659,11 +708,12 @@ def bulk(my_crystal): i = 0 nat_top=0 for atm in top_frac: - print ('{} {:12.6f} {:12.6f} {:12.6f}'.format(symtop[i], atm[0], atm[1], atm[2])) + print ('{:2} {:12.6f} {:12.6f} {:12.6f}'.format(symtop[i], atm[0], atm[1], atm[2])) i+=1 nat_top+=1 - +#0.5+(atm[2]*c*1.8897259886)/vacuum +eltp = time.time() - tp0 ######################################################## ############## closing part of scf.in file ############# @@ -672,46 +722,62 @@ def bulk(my_crystal): print ('\nK_POINTS automatic') print ('8 8 1 1 1 1') +#new_a = np.linalg.norm(newa1b) +old_a = np.array([a*0.5*np.sqrt(3), -0.5*b, 0]) +old_b = np.array([0, b, 0]) +old_c = np.array([0, 0, c]) + +newa1 = -m*old_a + n*old_b +newa2 = -m*old_b + n*old_a + # cell parameters in bohr -uc1 = np.around(newa1b*1.8897259886, decimals=8) -uc2 = np.around(newa2b*1.8897259886, decimals=8) -uc3 = np.around(a3*1.8897259886, decimals=8) +uc1 = np.around(newa1b*1.8897259886, decimals=12) +uc2 = np.around(newa2b*1.8897259886, decimals=12) +uc3 = np.around(a3*1.8897259886, decimals=12) uc1 = list(uc1) uc2 = list(uc2) uc3 = list(uc3) #unit_cell = ' '.join([str(elem) for elem in uc]) print ('\nCELL_PARAMETERS bohr') -print (' ','{:12.6f} {:12.6f} {:12.6f}'.format(uc1[0],uc1[1],uc1[2])) -print (' ','{:12.6f} {:12.6f} {:12.6f}'.format(uc2[0],uc2[1],uc2[2])) -print (' ','{:12.6f} {:12.6f} {:12.6f}'.format(uc3[0],uc3[1],uc3[2])) - +print (' ','{:17.12f} {:17.12f} {:17.12f}'.format(uc1[0],uc1[1],uc1[2])) +print (' ','{:17.12f} {:17.12f} {:17.12f}'.format(uc2[0],uc2[1],uc2[2])) +print (' ','{:17.12f} {:17.12f} {:17.12f}'.format(uc3[0],uc3[1],uc3[2])) ############################################################# ##################### PLOTTING RESULTS ###################### +pt1 = time.time() ## figure settings ## fig = plt.figure(figsize = (8, 8)) ax = fig.add_subplot(111, projection='3d') -fig.set_facecolor('black') -ax.set_facecolor('black') +fig.set_facecolor('white') +ax.set_facecolor('white') ax.grid(False) -ax.w_xaxis.set_pane_color((0.0, 0.0, 0.0, 0.0)) -ax.w_yaxis.set_pane_color((0.0, 0.0, 0.0, 0.0)) -ax.w_zaxis.set_pane_color((0.0, 0.0, 0.0, 0.0)) +ax.set_xticks([]) +ax.set_yticks([]) +ax.set_zticks([]) +plt.axis('off') +plt.grid(b=None) +#ax.w_xaxis.set_pane_color((0.0, 0.0, 0.0, 0.0)) +#ax.w_yaxis.set_pane_color((0.0, 0.0, 0.0, 0.0)) +#ax.w_zaxis.set_pane_color((0.0, 0.0, 0.0, 0.0)) # Initializing bottom coordinates for new unitcell plotting coord = [p1b, p2b, p3b, p4b] coord.append(coord[0]) xb, yb = zip(*coord) -plt.plot(xb,yb) + +# plotting boundary at lowest z position +zb = lowest(my_crystal) +plt.plot(xb,yb,zb) # plotting bottom layer atoms bot = bot.T supx,supy,supz = list(bot) -ax.scatter(supx, supy, supz, s=10*num, c='tab:green', alpha=0.4) +ax.scatter(supx, supy, supz, s=5*num, c='tab:green', alpha=0.4) ax.scatter(supx, supy, supz, c='tab:blue') # Adding bonds to bottom layer @@ -732,15 +798,18 @@ def bulk(my_crystal): # Initializing TOP coordinates for new unitcell plotting -#coord = [p1t, p2t, p3t, p4t] -#coord.append(coord[0]) -#xt, yt = zip(*coord) -#plt.plot(xt,yt) +coord = [p1t, p2t, p3t, p4t] +coord.append(coord[0]) +xt, yt = zip(*coord) + +# plotting the boundary at hiest z position +zt = highest(my_crystal) +plt.plot(xt,yt,zt) # plotting TOP layer atoms top = top.T supx,supy,supz = list(top) -ax.scatter(supx, supy, supz, s=10*num, c='tab:red', alpha=0.4) +ax.scatter(supx, supy, supz, s=5*num, c='tab:red', alpha=0.4) ax.scatter(supx, supy, supz, c='tab:blue') # Adding bonds to TOP layer @@ -763,21 +832,26 @@ def bulk(my_crystal): plt.show() +elplt = time.time() - pt1 + +j2 = 90 + np.rad2deg(phi/2) +mk = 1/(2*(np.abs(np.sin((phi/2))))) ########################## SUMMARY REPORT ############################### print ("\n********************* SUMMARY REPORT ***********************") +#print ('\nRotation angle (deg) = ', np.round(rotation_angle,3)) +#print ('Relative Rotation (deg) = ',np.round(np.rad2deg(phi),3)) +print ('\nHermann moire rotation = ', j2) +print ('Hermann moire constant = ', mk) print ('\nTop atoms(rotated) = ',len(top_frac)) -print ('Bottom atoms = ',len(bot_frac)) +print ('Bottom atoms = ',len(bot_frac)) print ('\nTotal atoms \n=', len(bot_frac)+len(top_frac)) -print ('\n*************************** Done! **************************\n') - - - - - - - - - - +#print ('\n Gamma = ', j2 + np.round(rotation_angle,3)) +#print ( '\n lattice vectors = ',1.8897259886*a, 1.8897259886*b, 1.8897259886*c) +#print ('\n Erin method lattice vectors = ',1.8897259886*old_a,1.8897259886*old_b) +#print ('time for replication', elbt1) +#print ('time for plotting', elplt) +#print ('\ntotal time top layer',eltp) +#print ('total time bottom layer',elbt) +print ('\n*************************** Done!! **************************\n') diff --git a/images/arrow-down.png b/images/arrow-down.png deleted file mode 100644 index 5c55c6a..0000000 Binary files a/images/arrow-down.png and /dev/null differ diff --git a/images/bg_hr.png b/images/bg_hr.png deleted file mode 100644 index 514aee5..0000000 Binary files a/images/bg_hr.png and /dev/null differ diff --git a/images/blacktocat.png b/images/blacktocat.png deleted file mode 100644 index e160053..0000000 Binary files a/images/blacktocat.png and /dev/null differ diff --git a/images/icon_download.png b/images/icon_download.png deleted file mode 100644 index 5a793f1..0000000 Binary files a/images/icon_download.png and /dev/null differ diff --git a/images/octocat-small.png b/images/octocat-small.png deleted file mode 100644 index 57c1e44..0000000 Binary files a/images/octocat-small.png and /dev/null differ diff --git a/images/sprite_download.png b/images/sprite_download.png deleted file mode 100644 index f9f8de2..0000000 Binary files a/images/sprite_download.png and /dev/null differ diff --git a/index.html b/index.html deleted file mode 100644 index 45f7cba..0000000 --- a/index.html +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - BiCrystal - - - - - -
-
- View on GitHub - -

BiCrystal

-

BiCrystal is a Python program that builds commensurate and incommensurate crystal structures of layered materials.

- -
- Download this project as a .zip file - Download this project as a tar.gz file -
-
-
- - -
-
-

-BiCrystal

-

BiCrystal is a Python program that builds commensurate and incommensurate crystal structures of layered materials. The current version reads CIF files and writes the new structure to a QUANTUM ESPRESSO input file. The program also provides additional information such as the bond distance between atoms, lattice vectors in Bohr and Angstrom, and a simple 3D plot of each layer.

-

-Contents

-

Overview
-Download
-Packages
-Files
-Installation
-Usage
-Examples
-Summary Table
-References
-License

-

-Overview

-

Building unit cells of arbitrary size is often an inevitable task when studying the physical and mechanical properties of layered materials such as graphene, hexagonal Boron Nitride, transition metal dichalcogenides. Although most visualzation software such as Xcrysden, VESTA or Avogadro provide very powerful tools for analysing and manipulating periodic crystal structures, constructing large unit cells in bilayers with one of the layers perturbed can be very daunting. BiCrystal provides a convinient and easy way of creating new crystal structures of arbitrary size from CIF files.

-

-Download

-

The latest version of BiCrystal can be found on github:

-

https://github.com/tilaskabengele/BiCrystal

-

Contact: Tilas Kabengele tilas.kabengele@dal.ca

-

-Packages

-

BiCrystal is a python-based program that uses Scipy and Shapely libraries. Additionally, the Crystal package, which is not part of the standard Python packages, should be installed. i.e Install via pip or conda:

-
 pip install crystals
-
-

or

-
conda install -c conda-forge crystals
-
-

and

-
pip install shapely
-
-

For more information on crystals and shapely, visit: https://pypi.org/project/crystals/ and https://pypi.org/project/Shapely/ respectively.

-

-Files

-

bicrystal - Bash script which runs the python program
-cifs/ - Directory with sample cif files
-examples/ - Directory with 33 examples of QUANTUM ESPRESSO input files generated by BiCrystal
-periodic_table.csv - Periodic table of elements
-program.py - Python program to be called from bicrystal script

-

-Installation

-

After downloading the files from the github repository to the directory of your choice (recommended: /usr/bin/), make bicrystal and program.py into executables:

-
chmod u+x bicrystal program.py
-
-

Next, add this directory to your $PATH variable. In Bash, adding the following lines to your .bashrc file:

-
vi ~/.bashrc
-
-

Add:

-
export PATH="$/path/to/your/directory/with/bicrysal/:$PATH"
-export PYTHONPATH="${PYTHONPATH}:/path/to/your/directory/with/bicrysal/"
-
-

Save, close then source your .bashrc file to activate the changes:

-
source ~/.bashrc
-
-

Restart your terminal window to start using bicrystal.

-

-Usage

-

BiCrystal is an interactive program that instructs the user every step of the way. To start BiCrystal, in the terminal type:

-
bicrystal
-
-

The first thing you will be required to do is input your cif file, e.g. graphite.cif:

-
***Input cif file***
-graphite.cif
-
-

Next, enter input parameters m and n, and rotation angle in degrees (zero if you want both layers unperturbed). -Parameter m and n correspond to the scale of the lattice vectors along the x and y directions, respectively. As an example, let's take m = 2, n = 1 and rotation angle 21.79 degrees.

-
***Rotation parameters***
-Enter m 2
-Enter n 1
-Enter rotation_angle 0
-
-

After that, you will be required to pick a zeroeth atom from the top and bottom layer. If we were picking the atoms by hand using a visualization software such as Xcrysden, this would be the atom we start from when creating the new cell vectors.

-
Intializing atoms...
-
-
-Initial TOP atoms..
-Atom No. 1   c   [0.  0.  0.5]
-Atom No. 2   c   [0.66667 0.33334 0.505  ]
-
-Initial BOTTOM atoms..
-Atom No. 3   c   [0. 0. 0.]
-Atom No. 4   c   [0.33333 0.66667 0.005  ]
-
-

For a good symmetrical structure, always pick atoms such that the zeroeth TOP and BOTTOM atoms align. In this example, that would be Atom No. 1 and Atom No. 3. After picking your zeroeth atoms, a window with a simple 3D will then open.

-
Select zeroeth TOP atom
-Enter Atom No. 1
-
-Select zeroeth BOTTOM atom
-Enter Atom No. 3
-
-

cc28

-

Finally, you can save your output as a QUANTUM ESPRESSO file and visualize with Xcrysden for a more sophisticated look.

-
 ********************* SUMMARY REPORT ***********************
-
-Top atoms(rotated) =  14
-Bottom atoms  =  14
-
-Total atoms
-= 28
-
-*************************** Done! **************************
-
-Would you like to write Espresso file?[Y/n]
-
-

-Examples

-

Let's say we saved our output in the example given above as graphite28.scf.in, we can visualize this with Xcrysden.

-
   xcrysden --pwi graphite28.scf.in
-
-

ccmoire28

-

Looking from the top view, we can see that for this rotation, a Moire pattern was created. Really neat! This was not apparent from the simple 3D plot because BiCrystal plots cartesian coordinates of the atoms where the top and bottom layer do not necessarily align. Before writing the QUANTUM ESPRESSO file, BiCrystal removes symmetrically equivalent atoms and maps back those atoms that fell outside the unit cell due to rotation.

-

The examples/ folder has over 30 examples of Moire patterns graphite, Molebdenum Disulfide and blue Phosphorene generated from bicrystal. Below are some examples.

-

-Graphite 364-atom unit cell

-

The unit cell of graphite with 364 atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view.

-

cc364

-

-Blue phosphorene 172-atom unit cell

-

The unit cell of blue phosphorene with 172 atoms can be generated by using parameters: m = 6, n = 1, and rotation angle of 44.82 degrees. Shown below is the top view.

-

bluep172

-

-Molybdenun Disulfide 546-atom unit cell

-

The unit cell of MoS2 with 546 atoms atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view.

-

mos546

-

-Summary Table

-

All the examples in the examples folder can be summarized in the table below:

-

example_table

-

-References

-

For a detailed analysis of Moire patterns and angles:

-

Density functional calculations on the intricacies of Moiré patterns on graphite, J. M. Campanera, G. Savini, I. Suarez-Martinez, and M. I. Heggie, Phys. Rev. B 75, 235449 – Published 28 June 2007

-

Crystals package authors:

-

L. P. René de Cotret, M. R. Otto, M. J. Stern. and B. J. Siwick, An open-source software ecosystem for the interactive exploration of ultrafast electron scattering data, Advanced Structural and Chemical Imaging 4:11 (2018) DOI:10.1186/s40679-018-0060-y.

-

For further reading and related projects, visit Johnson Group wiki: http://schooner.chem.dal.ca/wiki/Johnson_Group_Wiki

-

-License

-

Copyright (c) 2020 Tilas Kabengele, Johnson Chemistry Group, Dalhousie University.

-

BiCrystal is a free program: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

-

BiCrystal is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

-

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

-
-
- - - - - - - - diff --git a/javascripts/main.js b/javascripts/main.js deleted file mode 100644 index d8135d3..0000000 --- a/javascripts/main.js +++ /dev/null @@ -1 +0,0 @@ -console.log('This would be the main JS file.'); diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js deleted file mode 100644 index 08716c0..0000000 --- a/javascripts/scale.fix.js +++ /dev/null @@ -1,20 +0,0 @@ -fixScale = function(doc) { - - var addEvent = 'addEventListener', - type = 'gesturestart', - qsa = 'querySelectorAll', - scales = [1, 1], - meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; - - function fix() { - meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; - doc.removeEventListener(type, fix, true); - } - - if ((meta = meta[meta.length - 1]) && addEvent in doc) { - fix(); - scales = [.25, 1.6]; - doc[addEvent](type, fix, true); - } - -}; \ No newline at end of file diff --git a/params.json b/params.json deleted file mode 100644 index e0396a4..0000000 --- a/params.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"BiCrystal","tagline":"BiCrystal is a Python program that builds commensurate and incommensurate crystal structures of layered materials. ","body":"# BiCrystal\r\n``BiCrystal`` is a Python program that builds commensurate and incommensurate crystal structures of layered materials. The current version reads CIF files and writes the new structure to a QUANTUM ESPRESSO input file. The program also provides additional information such as the bond distance between atoms, lattice vectors in Bohr and Angstrom, and a simple 3D plot of each layer.\r\n\r\nContents\r\n==========\r\n**Overview** \\\r\n**Download** \\\r\n**Packages** \\\r\n**Files** \\\r\n**Installation** \\\r\n**Usage** \\\r\n**Examples** \\\r\n**Summary Table** \\\r\n**References** \\\r\n**License** \r\n\r\n# Overview\r\nBuilding unit cells of arbitrary size is often an inevitable task when studying the physical and mechanical properties of layered materials such as graphene, hexagonal Boron Nitride, transition metal dichalcogenides. Although most visualzation software such as Xcrysden, VESTA or Avogadro provide very powerful tools for analysing and manipulating periodic crystal structures, constructing large unit cells in bilayers with one of the layers perturbed can be very daunting. ``BiCrystal`` provides a convinient and easy way of creating new crystal structures of arbitrary size from CIF files.\r\n\r\n# Download\r\nThe latest version of ``BiCrystal`` can be found on github:\r\n\r\nhttps://github.com/tilaskabengele/BiCrystal\r\n\r\n**Contact**: Tilas Kabengele tilas.kabengele@dal.ca\r\n\r\n# Packages\r\n`BiCrystal` is a python-based program that uses Scipy and Shapely libraries. Additionally, the Crystal package, which is not part of the standard Python packages, should be installed. i.e Install via pip or conda:\r\n\r\n pip install crystals\r\nor\r\n\r\n conda install -c conda-forge crystals\r\nand\r\n\r\n pip install shapely\r\n \r\nFor more information on crystals and shapely, visit: https://pypi.org/project/crystals/ and https://pypi.org/project/Shapely/ respectively.\r\n \r\n # Files\r\n\r\n**bicrystal** - Bash script which runs the python program \\\r\n**cifs/** - Directory with sample cif files \\\r\n**examples/** - Directory with 33 examples of QUANTUM ESPRESSO input files generated by BiCrystal \\\r\n**periodic_table.csv** - Periodic table of elements \\\r\n**program.py** - Python program to be called from bicrystal script\r\n\r\n# Installation\r\nAfter downloading the files from the github repository to the directory of your choice (_recommended: /usr/bin/_), make `bicrystal` and `program.py` into executables:\r\n\r\n chmod u+x bicrystal program.py\r\n\r\nNext, add this directory to your $PATH variable. In Bash, adding the following lines to your `.bashrc file`:\r\n\r\n vi ~/.bashrc\r\n\r\nAdd:\r\n\r\n export PATH=\"$/path/to/your/directory/with/bicrysal/:$PATH\"\r\n export PYTHONPATH=\"${PYTHONPATH}:/path/to/your/directory/with/bicrysal/\"\r\n\r\nSave, close then source your `.bashrc` file to activate the changes:\r\n \r\n source ~/.bashrc\r\n\r\nRestart your terminal window to start using `bicrystal`.\r\n\r\n# Usage\r\nBiCrystal is an interactive program that instructs the user every step of the way. To start BiCrystal, in the terminal type:\r\n\r\n bicrystal\r\n \r\nThe first thing you will be required to do is input your cif file, e.g. graphite.cif:\r\n\r\n ***Input cif file***\r\n graphite.cif\r\n\r\nNext, enter input parameters m and n, and rotation angle in degrees (_zero if you want both layers unperturbed_).\r\nParameter m and n correspond to the scale of the lattice vectors along the x and y directions, respectively. As an example, let's take m = 2, n = 1 and rotation angle 21.79 degrees.\r\n \r\n ***Rotation parameters***\r\n Enter m 2\r\n Enter n 1\r\n Enter rotation_angle 0\r\n\r\nAfter that, you will be required to pick a zeroeth atom from the top and bottom layer. If we were picking the atoms by hand using a visualization software such as Xcrysden, this would be the atom we start from when creating the new cell vectors. \r\n\r\n Intializing atoms...\r\n\r\n\r\n Initial TOP atoms..\r\n Atom No. 1 c [0. 0. 0.5]\r\n Atom No. 2 c [0.66667 0.33334 0.505 ]\r\n\r\n Initial BOTTOM atoms..\r\n Atom No. 3 c [0. 0. 0.]\r\n Atom No. 4 c [0.33333 0.66667 0.005 ]\r\n \r\n For a good symmetrical structure, always pick atoms such that the zeroeth TOP and BOTTOM atoms align. In this example, that would be Atom No. 1 and Atom No. 3. After picking your zeroeth atoms, a window with a simple 3D will then open.\r\n \r\n Select zeroeth TOP atom\r\n Enter Atom No. 1\r\n\r\n Select zeroeth BOTTOM atom\r\n Enter Atom No. 3\r\n\r\n \r\n ![cc28](https://user-images.githubusercontent.com/62076249/87927879-48795500-ca5a-11ea-98c1-b2949bb672e3.PNG)\r\n \r\n Finally, you can save your output as a QUANTUM ESPRESSO file and visualize with Xcrysden for a more sophisticated look.\r\n \r\n ********************* SUMMARY REPORT ***********************\r\n\r\n Top atoms(rotated) = 14\r\n Bottom atoms = 14\r\n\r\n Total atoms\r\n = 28\r\n\r\n *************************** Done! **************************\r\n\r\n Would you like to write Espresso file?[Y/n]\r\n\r\n # Examples\r\n \r\n Let's say we saved our output in the example given above as graphite28.scf.in, we can visualize this with Xcrysden.\r\n \r\n xcrysden --pwi graphite28.scf.in\r\n \r\n ![ccmoire28](https://user-images.githubusercontent.com/62076249/87929694-377e1300-ca5d-11ea-80e3-76417f34a5e4.PNG)\r\n \r\nLooking from the top view, we can see that for this rotation, a Moire pattern was created. Really neat! This was not apparent from the simple 3D plot because BiCrystal plots cartesian coordinates of the atoms where the top and bottom layer do not necessarily align. Before writing the QUANTUM ESPRESSO file, `BiCrystal` removes symmetrically equivalent atoms and maps back those atoms that fell outside the unit cell due to rotation. \r\n\r\nThe **examples/** folder has over 30 examples of Moire patterns graphite, Molebdenum Disulfide and blue Phosphorene generated from `bicrystal`. Below are some examples.\r\n\r\n# Graphite 364-atom unit cell\r\nThe unit cell of graphite with 364 atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view.\r\n\r\n![cc364](https://user-images.githubusercontent.com/62076249/87933970-98f5b000-ca64-11ea-906b-15a1036989a1.PNG)\r\n\r\n# Blue phosphorene 172-atom unit cell\r\nThe unit cell of blue phosphorene with 172 atoms can be generated by using parameters: m = 6, n = 1, and rotation angle of 44.82 degrees. Shown below is the top view.\r\n\r\n![bluep172](https://user-images.githubusercontent.com/62076249/87934152-e245ff80-ca64-11ea-8f36-b69b5799e3fa.PNG)\r\n\r\n# Molybdenun Disulfide 546-atom unit cell\r\nThe unit cell of MoS2 with 546 atoms atoms can be generated by using parameters: m = 6, n = 5, and rotation angle of 6.01 degrees. Shown below is the top view.\r\n\r\n![mos546](https://user-images.githubusercontent.com/62076249/87934312-2fc26c80-ca65-11ea-97a2-c9cdb3068a9d.PNG)\r\n\r\n# Summary Table\r\nAll the examples in the examples folder can be summarized in the table below:\r\n\r\n![example_table](https://user-images.githubusercontent.com/62076249/87934662-dc045300-ca65-11ea-8f54-818b7183d6e1.PNG)\r\n \r\n # References\r\n For a detailed analysis of Moire patterns and angles:\r\n \r\n **Density functional calculations on the intricacies of Moiré patterns on graphite**, J. M. Campanera, G. Savini, I. Suarez-Martinez, and M. I. Heggie, _Phys. Rev. B 75, 235449 – Published 28 June 2007_\r\n \r\n Crystals package authors:\r\n \r\n L. P. René de Cotret, M. R. Otto, M. J. Stern. and B. J. Siwick, An open-source software ecosystem for the interactive exploration of ultrafast electron scattering data, Advanced Structural and Chemical Imaging 4:11 (2018) DOI:10.1186/s40679-018-0060-y.\r\n \r\n For further reading and related projects, visit **Johnson Group wiki**: http://schooner.chem.dal.ca/wiki/Johnson_Group_Wiki \r\n \r\n # License\r\n Copyright (c) 2020 Tilas Kabengele, Johnson Chemistry Group, Dalhousie University.\r\n\r\nBiCrystal is a free program: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r\n\r\nBiCrystal is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.\r\n\r\n\r\n\r\n","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/stylesheets/github-light.css b/stylesheets/github-light.css deleted file mode 100644 index 68b86c1..0000000 --- a/stylesheets/github-light.css +++ /dev/null @@ -1,130 +0,0 @@ -/*! - * GitHub Light v0.4.1 - * Copyright (c) 2012 - 2017 GitHub, Inc. - * Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE) - */ - -.pl-c /* comment, punctuation.definition.comment, string.comment */ { - color: #6a737d; -} - -.pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header, meta.output */, -.pl-s .pl-v /* string variable */ { - color: #005cc5; -} - -.pl-e /* entity */, -.pl-en /* entity.name */ { - color: #6f42c1; -} - -.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */, -.pl-s .pl-s1 /* string source */ { - color: #24292e; -} - -.pl-ent /* entity.name.tag, markup.quote */ { - color: #22863a; -} - -.pl-k /* keyword, storage, storage.type */ { - color: #d73a49; -} - -.pl-s /* string */, -.pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */, -.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, -.pl-sr /* string.regexp */, -.pl-sr .pl-cce /* string.regexp constant.character.escape */, -.pl-sr .pl-sre /* string.regexp source.ruby.embedded */, -.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ { - color: #032f62; -} - -.pl-v /* variable */, -.pl-smw /* sublimelinter.mark.warning */ { - color: #e36209; -} - -.pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ { - color: #b31d28; -} - -.pl-ii /* invalid.illegal */ { - color: #fafbfc; - background-color: #b31d28; -} - -.pl-c2 /* carriage-return */ { - color: #fafbfc; - background-color: #d73a49; -} - -.pl-c2::before /* carriage-return */ { - content: "^M"; -} - -.pl-sr .pl-cce /* string.regexp constant.character.escape */ { - font-weight: bold; - color: #22863a; -} - -.pl-ml /* markup.list */ { - color: #735c0f; -} - -.pl-mh /* markup.heading */, -.pl-mh .pl-en /* markup.heading entity.name */, -.pl-ms /* meta.separator */ { - font-weight: bold; - color: #005cc5; -} - -.pl-mi /* markup.italic */ { - font-style: italic; - color: #24292e; -} - -.pl-mb /* markup.bold */ { - font-weight: bold; - color: #24292e; -} - -.pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ { - color: #b31d28; - background-color: #ffeef0; -} - -.pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ { - color: #22863a; - background-color: #f0fff4; -} - -.pl-mc /* markup.changed, punctuation.definition.changed */ { - color: #e36209; - background-color: #ffebda; -} - -.pl-mi2 /* markup.ignored, markup.untracked */ { - color: #f6f8fa; - background-color: #005cc5; -} - -.pl-mdr /* meta.diff.range */ { - font-weight: bold; - color: #6f42c1; -} - -.pl-ba /* brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote */ { - color: #586069; -} - -.pl-sg /* sublimelinter.gutter-mark */ { - color: #959da5; -} - -.pl-corl /* constant.other.reference.link, string.other.link */ { - text-decoration: underline; - color: #032f62; -} - diff --git a/stylesheets/styles.css b/stylesheets/styles.css deleted file mode 100644 index 647f08d..0000000 --- a/stylesheets/styles.css +++ /dev/null @@ -1,423 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Arvo:400,700,400italic); - -/* MeyerWeb Reset */ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font: inherit; - vertical-align: baseline; -} - - -/* Base text styles */ - -body { - padding:10px 50px 0 0; - font-family:"Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - color: #232323; - background-color: #FBFAF7; - margin: 0; - line-height: 1.8em; - -webkit-font-smoothing: antialiased; - -} - -h1, h2, h3, h4, h5, h6 { - color:#232323; - margin:36px 0 10px; -} - -p, ul, ol, table, dl { - margin:0 0 22px; -} - -h1, h2, h3 { - font-family: Arvo, Monaco, serif; - line-height:1.3; - font-weight: normal; -} - -h1,h2, h3 { - display: block; - border-bottom: 1px solid #ccc; - padding-bottom: 5px; -} - -h1 { - font-size: 30px; -} - -h2 { - font-size: 24px; -} - -h3 { - font-size: 18px; -} - -h4, h5, h6 { - font-family: Arvo, Monaco, serif; - font-weight: 700; -} - -a { - color:#C30000; - font-weight:200; - text-decoration:none; -} - -a:hover { - text-decoration: underline; -} - -a small { - font-size: 12px; -} - -em { - font-style: italic; -} - -strong { - font-weight:700; -} - -ul { - list-style-position: inside; - list-style: disc; - padding-left: 25px; -} - -ol { - list-style-position: inside; - list-style: decimal; - padding-left: 25px; -} - -blockquote { - margin: 0; - padding: 0 0 0 20px; - font-style: italic; -} - -dl, dt, dd, dl p { - font-color: #444; -} - -dl dt { - font-weight: bold; -} - -dl dd { - padding-left: 20px; - font-style: italic; -} - -dl p { - padding-left: 20px; - font-style: italic; -} - -hr { - border:0; - background:#ccc; - height:1px; - margin:0 0 24px; -} - -/* Images */ - -img { - position: relative; - margin: 0 auto; - max-width: 650px; - padding: 5px; - margin: 10px 0 32px 0; - border: 1px solid #ccc; -} - -p img { - display: inline; - margin: 0; - padding: 0; - vertical-align: middle; - text-align: center; - border: none; -} - -/* Code blocks */ - -code, pre { - font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; - color:#000; - font-size:14px; -} - -pre { - padding: 4px 12px; - background: #FDFEFB; - border-radius:4px; - border:1px solid #D7D8C8; - overflow: auto; - overflow-y: hidden; - margin-bottom: 32px; -} - - -/* Tables */ - -table { - width:100%; -} - -table { - border: 1px solid #ccc; - margin-bottom: 32px; - text-align: left; - } - -th { - font-family: 'Arvo', Helvetica, Arial, sans-serif; - font-size: 18px; - font-weight: normal; - padding: 10px; - background: #232323; - color: #FDFEFB; - } - -td { - padding: 10px; - background: #ccc; - } - - -/* Wrapper */ -.wrapper { - width:960px; -} - - -/* Header */ - -header { - background-color: #171717; - color: #FDFDFB; - width:170px; - float:left; - position:fixed; - border: 1px solid #000; - -webkit-border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 4px; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - padding: 34px 25px 22px 50px; - margin: 30px 25px 0 0; - -webkit-font-smoothing: antialiased; -} - -p.header { - font-size: 16px; -} - -h1.header { - font-family: Arvo, sans-serif; - font-size: 30px; - font-weight: 300; - line-height: 1.3em; - border-bottom: none; - margin-top: 0; -} - - -h1.header, a.header, a.name, header a{ - color: #fff; -} - -a.header { - text-decoration: underline; -} - -a.name { - white-space: nowrap; -} - -header ul { - list-style:none; - padding:0; -} - -header li { - list-style-type: none; - width:132px; - height:15px; - margin-bottom: 12px; - line-height: 1em; - padding: 6px 6px 6px 7px; - - background: #AF0011; - background: -moz-linear-gradient(top, #AF0011 0%, #820011 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); - background: -webkit-linear-gradient(top, #AF0011 0%,#820011 100%); - background: -o-linear-gradient(top, #AF0011 0%,#820011 100%); - background: -ms-linear-gradient(top, #AF0011 0%,#820011 100%); - background: linear-gradient(top, #AF0011 0%,#820011 100%); - - border-radius:4px; - border:1px solid #0D0D0D; - - -webkit-box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); - box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); - -} - -header li:hover { - background: #C3001D; - background: -moz-linear-gradient(top, #C3001D 0%, #950119 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); - background: -webkit-linear-gradient(top, #C3001D 0%,#950119 100%); - background: -o-linear-gradient(top, #C3001D 0%,#950119 100%); - background: -ms-linear-gradient(top, #C3001D 0%,#950119 100%); - background: linear-gradient(top, #C3001D 0%,#950119 100%); -} - -a.buttons { - -webkit-font-smoothing: antialiased; - background: url(../images/arrow-down.png) no-repeat; - font-weight: normal; - text-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0; - padding: 2px 2px 2px 22px; - height: 30px; -} - -a.github { - background: url(../images/octocat-small.png) no-repeat 1px; -} - -a.buttons:hover { - color: #fff; - text-decoration: none; -} - - -/* Section - for main page content */ - -section { - width:650px; - float:right; - padding-bottom:50px; -} - - -/* Footer */ - -footer { - width:170px; - float:left; - position:fixed; - bottom:10px; - padding-left: 50px; -} - -@media print, screen and (max-width: 960px) { - - div.wrapper { - width:auto; - margin:0; - } - - header, section, footer { - float:none; - position:static; - width:auto; - } - - footer { - border-top: 1px solid #ccc; - margin:0 84px 0 50px; - padding:0; - } - - header { - padding-right:320px; - } - - section { - padding:20px 84px 20px 50px; - margin:0 0 20px; - } - - header a small { - display:inline; - } - - header ul { - position:absolute; - right:130px; - top:84px; - } -} - -@media print, screen and (max-width: 720px) { - body { - word-wrap:break-word; - } - - header { - padding:10px 20px 0; - margin-right: 0; - } - - section { - padding:10px 0 10px 20px; - margin:0 0 30px; - } - - footer { - margin: 0 0 0 30px; - } - - header ul, header p.view { - position:static; - } -} - -@media print, screen and (max-width: 480px) { - - header ul li.download { - display:none; - } - - footer { - margin: 0 0 0 20px; - } - - footer a{ - display:block; - } - -} - -@media print { - body { - padding:0.4in; - font-size:12pt; - color:#444; - } -} \ No newline at end of file diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css deleted file mode 100644 index 3da3485..0000000 --- a/stylesheets/stylesheet.css +++ /dev/null @@ -1,425 +0,0 @@ -/******************************************************************************* -Slate Theme for GitHub Pages -by Jason Costello, @jsncostello -*******************************************************************************/ - -@import url(github-light.css); - -/******************************************************************************* -MeyerWeb Reset -*******************************************************************************/ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font: inherit; - vertical-align: baseline; -} - -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} - -ol, ul { - list-style: none; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -/******************************************************************************* -Theme Styles -*******************************************************************************/ - -body { - box-sizing: border-box; - color:#373737; - background: #212121; - font-size: 16px; - font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; - line-height: 1.5; - -webkit-font-smoothing: antialiased; -} - -h1, h2, h3, h4, h5, h6 { - margin: 10px 0; - font-weight: 700; - color:#222222; - font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif; - letter-spacing: -1px; -} - -h1 { - font-size: 36px; - font-weight: 700; -} - -h2 { - padding-bottom: 10px; - font-size: 32px; - background: url('../images/bg_hr.png') repeat-x bottom; -} - -h3 { - font-size: 24px; -} - -h4 { - font-size: 21px; -} - -h5 { - font-size: 18px; -} - -h6 { - font-size: 16px; -} - -p { - margin: 10px 0 15px 0; -} - -footer p { - color: #f2f2f2; -} - -a { - text-decoration: none; - color: #007edf; - text-shadow: none; - - transition: color 0.5s ease; - transition: text-shadow 0.5s ease; - -webkit-transition: color 0.5s ease; - -webkit-transition: text-shadow 0.5s ease; - -moz-transition: color 0.5s ease; - -moz-transition: text-shadow 0.5s ease; - -o-transition: color 0.5s ease; - -o-transition: text-shadow 0.5s ease; - -ms-transition: color 0.5s ease; - -ms-transition: text-shadow 0.5s ease; -} - -a:hover, a:focus {text-decoration: underline;} - -footer a { - color: #F2F2F2; - text-decoration: underline; -} - -em { - font-style: italic; -} - -strong { - font-weight: bold; -} - -img { - position: relative; - margin: 0 auto; - max-width: 739px; - padding: 5px; - margin: 10px 0 10px 0; - border: 1px solid #ebebeb; - - box-shadow: 0 0 5px #ebebeb; - -webkit-box-shadow: 0 0 5px #ebebeb; - -moz-box-shadow: 0 0 5px #ebebeb; - -o-box-shadow: 0 0 5px #ebebeb; - -ms-box-shadow: 0 0 5px #ebebeb; -} - -p img { - display: inline; - margin: 0; - padding: 0; - vertical-align: middle; - text-align: center; - border: none; -} - -pre, code { - width: 100%; - color: #222; - background-color: #fff; - - font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; - font-size: 14px; - - border-radius: 2px; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; -} - -pre { - width: 100%; - padding: 10px; - box-shadow: 0 0 10px rgba(0,0,0,.1); - overflow: auto; -} - -code { - padding: 3px; - margin: 0 3px; - box-shadow: 0 0 10px rgba(0,0,0,.1); -} - -pre code { - display: block; - box-shadow: none; -} - -blockquote { - color: #666; - margin-bottom: 20px; - padding: 0 0 0 20px; - border-left: 3px solid #bbb; -} - - -ul, ol, dl { - margin-bottom: 15px -} - -ul { - list-style-position: inside; - list-style: disc; - padding-left: 20px; -} - -ol { - list-style-position: inside; - list-style: decimal; - padding-left: 20px; -} - -dl dt { - font-weight: bold; -} - -dl dd { - padding-left: 20px; - font-style: italic; -} - -dl p { - padding-left: 20px; - font-style: italic; -} - -hr { - height: 1px; - margin-bottom: 5px; - border: none; - background: url('../images/bg_hr.png') repeat-x center; -} - -table { - border: 1px solid #373737; - margin-bottom: 20px; - text-align: left; - } - -th { - font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; - padding: 10px; - background: #373737; - color: #fff; - } - -td { - padding: 10px; - border: 1px solid #373737; - } - -form { - background: #f2f2f2; - padding: 20px; -} - -/******************************************************************************* -Full-Width Styles -*******************************************************************************/ - -.outer { - width: 100%; -} - -.inner { - position: relative; - max-width: 640px; - padding: 20px 10px; - margin: 0 auto; -} - -#forkme_banner { - display: block; - position: absolute; - top:0; - right: 10px; - z-index: 10; - padding: 10px 50px 10px 10px; - color: #fff; - background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%; - font-weight: 700; - box-shadow: 0 0 10px rgba(0,0,0,.5); - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; -} - -#header_wrap { - background: #212121; - background: -moz-linear-gradient(top, #373737, #212121); - background: -webkit-linear-gradient(top, #373737, #212121); - background: -ms-linear-gradient(top, #373737, #212121); - background: -o-linear-gradient(top, #373737, #212121); - background: linear-gradient(top, #373737, #212121); -} - -#header_wrap .inner { - padding: 50px 10px 30px 10px; -} - -#project_title { - margin: 0; - color: #fff; - font-size: 42px; - font-weight: 700; - text-shadow: #111 0px 0px 10px; -} - -#project_tagline { - color: #fff; - font-size: 24px; - font-weight: 300; - background: none; - text-shadow: #111 0px 0px 10px; -} - -#downloads { - position: absolute; - width: 210px; - z-index: 10; - bottom: -40px; - right: 0; - height: 70px; - background: url('../images/icon_download.png') no-repeat 0% 90%; -} - -.zip_download_link { - display: block; - float: right; - width: 90px; - height:70px; - text-indent: -5000px; - overflow: hidden; - background: url(../images/sprite_download.png) no-repeat bottom left; -} - -.tar_download_link { - display: block; - float: right; - width: 90px; - height:70px; - text-indent: -5000px; - overflow: hidden; - background: url(../images/sprite_download.png) no-repeat bottom right; - margin-left: 10px; -} - -.zip_download_link:hover { - background: url(../images/sprite_download.png) no-repeat top left; -} - -.tar_download_link:hover { - background: url(../images/sprite_download.png) no-repeat top right; -} - -#main_content_wrap { - background: #f2f2f2; - border-top: 1px solid #111; - border-bottom: 1px solid #111; -} - -#main_content { - padding-top: 40px; -} - -#footer_wrap { - background: #212121; -} - - - -/******************************************************************************* -Small Device Styles -*******************************************************************************/ - -@media screen and (max-width: 480px) { - body { - font-size:14px; - } - - #downloads { - display: none; - } - - .inner { - min-width: 320px; - max-width: 480px; - } - - #project_title { - font-size: 32px; - } - - h1 { - font-size: 28px; - } - - h2 { - font-size: 24px; - } - - h3 { - font-size: 21px; - } - - h4 { - font-size: 18px; - } - - h5 { - font-size: 14px; - } - - h6 { - font-size: 12px; - } - - code, pre { - min-width: 320px; - max-width: 480px; - font-size: 11px; - } - -}