To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit b275cb13 authored by psd's avatar psd
Browse files

Exercise-10

parent 6f005725
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"import itertools\n",
"import numpy as np\n",
"from numpy.linalg import norm\n",
"import spglib\n",
"from glob import glob\n",
"\n",
"from ase import Atoms\n",
"from ase.io import read\n",
"from ase.spacegroup import crystal\n",
"from ase.spacegroup import Spacegroup\n",
"from ase.data import atomic_numbers, atomic_names\n",
"import nglview"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Crystallographic point groups"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"14 P 21/c\n",
" setting 1\n",
" centrosymmetric 1\n",
" primitive vectors\n",
" 1.0000000000 0.0000000000 0.0000000000\n",
" 0.0000000000 1.0000000000 0.0000000000\n",
" 0.0000000000 0.0000000000 1.0000000000\n",
" reciprocal vectors\n",
" 1 0 0\n",
" 0 1 0\n",
" 0 0 1\n",
" 1 subtranslations\n",
" 0.0000000000 0.0000000000 0.0000000000\n",
" 2 symmetry operations (rot+trans)\n",
" 1 0 0 0 1 0 0 0 1 0.0000000000 0.0000000000 0.0000000000\n",
" -1 0 0 0 1 0 0 0 -1 0.0000000000 0.5000000000 0.5000000000\n",
"\n",
"\n"
]
}
],
"source": [
"a=5.117\n",
"b=5.175\n",
"c=5.291\n",
"alpha=90\n",
"beta=99.22\n",
"gamma=90\n",
"thespacegroup=14\n",
"print(Spacegroup(thespacegroup))\n",
"\n",
"hfo2 = crystal(symbols=['Hf','O','O'],\n",
" basis=[(0.276,0.04,0.208),(0.074,0.332,0.347),(0.449,0.758,0.480)],\n",
" spacegroup=thespacegroup, \n",
" cellpar=[a, b, c, alpha, beta, gamma])\n",
"#hfo2.write('hfo2.xyz')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"bondatoms = []\n",
"symbols = hfo2.get_chemical_symbols()\n",
"for i in range(len(hfo2)):\n",
" for j in range(i):\n",
" if (symbols[i] == 'Hf' and symbols[j] == 'O' and hfo2.get_distance(i, j) < 2.6):\n",
" bondatoms.append((i, j))\n",
" elif (symbols[i] == 'O' and symbols[j] == 'Hf' and hfo2.get_distance(i, j) < 2.6):\n",
" bondatoms.append((i, j))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "173ee9fd9ff14be7a76bdd69a69afbe2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"NGLWidget()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"nglview.show_ase(hfo2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Questions:\n",
"\n",
" -how many atoms are contained in the unit cell?\n",
" -compute the volume of the unit cell "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## "
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"def ase_to_spgcell(ase_atoms=None, cell=None, inverse=False):\n",
" if not inverse:\n",
" assert ase_atoms is not None\n",
" return (ase_atoms.get_cell(),\n",
" ase_atoms.get_scaled_positions(),\n",
" ase_atoms.get_atomic_numbers())\n",
" else:\n",
" assert cell is not None\n",
" return Atoms(cell=cell[0],\n",
" scaled_positions=cell[1],\n",
" numbers=cell[2])"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"def a_equiv_b(a,b):\n",
" \"\"\"Function that identifies whether two crystals are equivalent\"\"\"\n",
"\n",
" # getting symmetry datasets for both crystals\n",
" cryst_a = spglib.get_symmetry_dataset(ase_to_spgcell(ase_atoms=a), symprec=1e-5, angle_tolerance=-1.0, hall_number=0)\n",
" cryst_b = spglib.get_symmetry_dataset(ase_to_spgcell(ase_atoms=b), symprec=1e-5, angle_tolerance=-1.0, hall_number=0)\n",
"\n",
" samecell = np.allclose(cryst_a['std_lattice'], cryst_b['std_lattice'], atol=1e-5)\n",
" samenatoms = len(cryst_a['std_positions']) == len(cryst_b['std_positions'])\n",
" samespg = cryst_a['number'] == cryst_b['number']\n",
" \n",
" def test_rotations_translations(cryst_a, cryst_b, repeat):\n",
" cell = cryst_a['std_lattice']\n",
" pristine = crystal('Mg', [(0, 0., 0.)], \n",
" spacegroup=int(cryst_a['number']),\n",
" cellpar=[cell[0]/repeat[0], cell[1]/repeat[1], cell[2]/repeat[2]]).repeat(repeat)\n",
"\n",
" sym_set_p = spglib.get_symmetry_dataset(ase_to_spgcell(ase_atoms=pristine), symprec=1e-5,\n",
" angle_tolerance=-1.0, hall_number=0)\n",
"\n",
" for _,trans in enumerate(zip(sym_set_p['rotations'], sym_set_p['translations'])):\n",
" pnew=(np.matmul(trans[0],cryst_a['std_positions'].T).T + trans[1]) % 1.0\n",
" fulln = np.concatenate([cryst_a['std_types'][:, None], pnew], axis=1)\n",
" fullb = np.concatenate([cryst_b['std_types'][:, None], cryst_b['std_positions']], axis=1)\n",
" sorted_n = np.array(sorted([ list(row) for row in list(fulln) ]))\n",
" sorted_b = np.array(sorted([ list(row) for row in list(fullb) ]))\n",
" if np.allclose(sorted_n, sorted_b, atol=1e-5):\n",
" return True\n",
" return False\n",
"\n",
" if samecell and samenatoms and samespg:\n",
" cell = cryst_a['std_lattice']\n",
" rng1 = range(1, int(norm(cell[0])/2.))\n",
" rng2 = range(1, int(norm(cell[1])/2.))\n",
" rng3 = range(1, int(norm(cell[2])/2.))\n",
"\n",
" for repeat in itertools.product(rng1, rng2, rng3):\n",
" if test_rotations_translations(cryst_a, cryst_b, repeat):\n",
" return True\n",
"\n",
" return False"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task 1"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7261855ebc41485c8822834f33016a8d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"NGLWidget()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"atoms = read('./quartz_alpha.xyz')\n",
"nglview.show_ase(atoms)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"cell = ase_to_spgcell(ase_atoms=atoms)\n",
"lattice, scaled_positions, numbers = spglib.find_primitive(cell, symprec=1e-5)\n",
"reduced = ase_to_spgcell(cell=(lattice, scaled_positions, numbers),inverse=True)"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c0b014720e3d4c09b7430432c38b0056",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"NGLWidget()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"nglview.show_ase(reduced)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task 2"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"versions = [read(atoms) for atoms in glob('./quartz_alpha*')]\n",
"\n",
"for outer in range(len(versions)-1):\n",
" for inner in range(outer+1,len(versions)):\n",
" print('Comparing: ',outer,inner)\n",
" print('Equivalent: ',a_equiv_b(versions[outer],versions[inner]))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import itertools\n",
"import numpy as np\n",
"from numpy.linalg import norm\n",
"import spglib\n",
"from glob import glob\n",
"\n",
"from ase import Atoms\n",
"from ase.io import read\n",
"from ase.spacegroup import crystal\n",
"from ase.spacegroup import Spacegroup\n",
"from ase.data import atomic_numbers, atomic_names\n",
"import nglview"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Crystallographic point groups"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a=...\n",
"b=...\n",
"c=...\n",
"alpha=...\n",
"beta=...\n",
"gamma=...\n",
"thespacegroup=...\n",
"print Spacegroup(thespacegroup)\n",
"\n",
"hfo2 = crystal(['...','...','...'],basis=[(...,...,...),(...,...,...),(...,...,...)], \n",
" spacegroup=thespacegroup, cellpar=[a, b, c, alpha, beta, gamma])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"bondatoms = []\n",
"symbols = hfo2.get_chemical_symbols()\n",
"for i in range(len(hfo2)):\n",
" for j in range(i):\n",
" if (symbols[i] == 'Hf' and symbols[j] == 'O' and hfo2.get_distance(i, j) < 2.6):\n",
" bondatoms.append((i, j))\n",
" elif (symbols[i] == 'O' and symbols[j] == 'Hf' and hfo2.get_distance(i, j) < 2.6):\n",
" bondatoms.append((i, j))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Questions:\n",
"\n",
" -how many atoms are contained in the unit cell?\n",
" -compute the volume of the unit cell "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def ase_to_spgcell(ase_atoms=None, cell=None, inverse=False):\n",
" if not inverse:\n",
" assert ase_atoms is not None\n",
" return (ase_atoms.get_cell(),\n",
" ase_atoms.get_scaled_positions(),\n",
" ase_atoms.get_atomic_numbers())\n",
" else:\n",
" assert cell is not None\n",
" return Atoms(cell=cell[0],\n",
" scaled_positions=cell[1],\n",
" numbers=cell[2])"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def a_equiv_b(a,b):\n",
" \"\"\"Function that identifies whether two crystals are equivalent\"\"\"\n",
"\n",
" # getting symmetry datasets for both crystals\n",
" cryst_a = spglib.get_symmetry_dataset(ase_to_spgcell(ase_atoms=a), symprec=1e-5, angle_tolerance=-1.0, hall_number=0)\n",
" cryst_b = spglib.get_symmetry_dataset(ase_to_spgcell(ase_atoms=b), symprec=1e-5, angle_tolerance=-1.0, hall_number=0)\n",
"\n",
" samecell = np.allclose(cryst_a['std_lattice'], cryst_b['std_lattice'], atol=1e-5)\n",
" samenatoms = len(cryst_a['std_positions']) == len(cryst_b['std_positions'])\n",
" samespg = cryst_a['number'] == cryst_b['number']\n",
" \n",
" def test_rotations_translations(cryst_a, cryst_b, repeat):\n",
" cell = cryst_a['std_lattice']\n",
" pristine = crystal('Mg', [(0, 0., 0.)], \n",
" spacegroup=int(cryst_a['number']),\n",
" cellpar=[cell[0]/repeat[0], cell[1]/repeat[1], cell[2]/repeat[2]]).repeat(repeat)\n",
"\n",
" sym_set_p = spglib.get_symmetry_dataset(ase_to_spgcell(ase_atoms=pristine), symprec=1e-5,\n",
" angle_tolerance=-1.0, hall_number=0)\n",
"\n",
" for _,trans in enumerate(zip(sym_set_p['rotations'], sym_set_p['translations'])):\n",
" pnew=(np.matmul(trans[0],cryst_a['std_positions'].T).T + trans[1]) % 1.0\n",
" fulln = np.concatenate([cryst_a['std_types'][:, None], pnew], axis=1)\n",
" fullb = np.concatenate([cryst_b['std_types'][:, None], cryst_b['std_positions']], axis=1)\n",
" sorted_n = np.array(sorted([ list(row) for row in list(fulln) ]))\n",
" sorted_b = np.array(sorted([ list(row) for row in list(fullb) ]))\n",
" if np.allclose(sorted_n, sorted_b, atol=1e-5):\n",
" return True\n",
" return False\n",
"\n",
" if samecell and samenatoms and samespg:\n",
" cell = cryst_a['std_lattice']\n",
" rng1 = range(1, int(norm(cell[0])/2.))\n",
" rng2 = range(1, int(norm(cell[1])/2.))\n",
" rng3 = range(1, int(norm(cell[2])/2.))\n",
"\n",
" for repeat in itertools.product(rng1, rng2, rng3):\n",
" if test_rotations_translations(cryst_a, cryst_b, repeat):\n",
" return True\n",
"\n",
" return False"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"atoms = read('./quartz_alpha.xyz')"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"view(atoms)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"cell = ase_to_spgcell(ase_atoms=atoms)\n",
"lattice, scaled_positions, numbers = spglib.find_primitive(cell, symprec=1e-5)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"reduced = ase_to_spgcell(cell=(lattice, scaled_positions, numbers),inverse=True)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"versions = [read(atoms) for atoms in glob('./quartz_alpha*')]"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Comparing: 0 1\n",
"Equivalent: False\n",
"Comparing: 0 2\n",
"Equivalent: False\n",
"Comparing: 0 3\n",
"Equivalent: True\n",
"Comparing: 0 4\n",
"Equivalent: False\n",
"Comparing: 0 5\n",
"Equivalent: False\n",
"Comparing: 1 2\n",
"Equivalent: False\n",
"Comparing: 1 3\n",
"Equivalent: False\n",
"Comparing: 1 4\n",
"Equivalent: False\n",
"Comparing: 1 5\n",
"Equivalent: False\n",
"Comparing: 2 3\n",
"Equivalent: False\n",
"Comparing: 2 4\n",
"Equivalent: False\n",
"Comparing: 2 5\n",
"Equivalent: False\n",
"Comparing: 3 4\n",
"Equivalent: False\n",
"Comparing: 3 5\n",
"Equivalent: False\n",
"Comparing: 4 5\n",
"Equivalent: False\n"
]
}
],
"source": [
"for outer in range(len(versions)-1):\n",
" for inner in range(outer+1,len(versions)):\n",
" print('Comparing: ',outer,inner)\n",
" print('Equivalent: ',a_equiv_b(versions[outer],versions[inner]))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"import itertools\n",
"import numpy as np\n",
"from numpy.linalg import norm\n",
"import spglib\n",
"from glob import glob\n",
"\n",
"from ase import Atoms\n",
"from ase.io import read\n",
"from ase.spacegroup import crystal\n",
"from ase.spacegroup import Spacegroup\n",
"from ase.data import atomic_numbers, atomic_names\n",
"import nglview"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [