def test_constructor(self): """Tests different valid and invalid constructor values. """ with self.assertRaises(ValueError): SineMatrix(n_atoms_max=5, permutation="unknown") with self.assertRaises(ValueError): SineMatrix(n_atoms_max=-1)
def test_features(self): """Tests that the correct features are present in the desciptor. """ desc = SineMatrix(n_atoms_max=2, permutation="none", flatten=False) # Test that without cell the matrix cannot be calculated system = Atoms( positions=[[0, 0, 0], [1.0, 1.0, 1.0]], symbols=["H", "H"], ) with self.assertRaises(ValueError): desc.create(system) # Test that periodic boundaries are considered by seeing that an atom # in the origin is replicated to the corners system = Atoms( cell=[ [10, 10, 0], [0, 10, 0], [0, 0, 10], ], scaled_positions=[[0, 0, 0], [1.0, 1.0, 1.0]], symbols=["H", "H"], pbc=True, ) # from ase.visualize import view # view(system) matrix = desc.create(system) # The interaction between atoms 1 and 2 should be infinite due to # periodic boundaries. self.assertEqual(matrix[0, 1], float("Inf")) # The interaction of an atom with itself is always 0.5*Z**2.4 atomic_numbers = system.get_atomic_numbers() for i, i_diag in enumerate(np.diag(matrix)): self.assertEqual(i_diag, 0.5 * atomic_numbers[i]**2.4)
def test_flatten(self): """Tests the flattening.""" # Unflattened desc = SineMatrix(n_atoms_max=5, permutation="none", flatten=False) cm = desc.create(H2O) self.assertEqual(cm.shape, (5, 5)) # Flattened desc = SineMatrix(n_atoms_max=5, permutation="none", flatten=True) cm = desc.create(H2O) self.assertEqual(cm.shape, (25, ))
def test_exceptions(self): """Tests different invalid parameters that should raise an exception. """ with self.assertRaises(ValueError): SineMatrix(n_atoms_max=5, permutation="unknown") with self.assertRaises(ValueError): SineMatrix(n_atoms_max=-1) with self.assertRaises(ValueError): sm = SineMatrix(n_atoms_max=2) sm.create([HHe, H2O])
def test_sparse(self): """Tests the sparse matrix creation.""" # Dense desc = SineMatrix(n_atoms_max=5, permutation="none", flatten=True, sparse=False) vec = desc.create(H2O) self.assertTrue(type(vec) == np.ndarray) # Sparse desc = SineMatrix(n_atoms_max=5, permutation="none", flatten=True, sparse=True) vec = desc.create(H2O) self.assertTrue(type(vec) == sparse.COO)
def test_unit_cells(self): """Tests if arbitrary unit cells are accepted""" desc = SineMatrix(n_atoms_max=3, permutation="none", flatten=False) molecule = H2O.copy() molecule.set_cell([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]) with self.assertRaises(ValueError): nocell = desc.create(molecule) molecule.set_pbc(True) molecule.set_cell([[20.0, 0.0, 0.0], [0.0, 30.0, 0.0], [0.0, 0.0, 40.0]]) largecell = desc.create(molecule) molecule.set_cell([[2.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 2.0]]) cubic_cell = desc.create(molecule) molecule.set_cell([[0.0, 2.0, 2.0], [2.0, 0.0, 2.0], [2.0, 2.0, 0.0]]) triclinic_smallcell = desc.create(molecule)
""" from functional.streams import ParallelStream as pseq from collections import namedtuple import ase.build.bulk from dscribe.descriptors import CoulombMatrix from dscribe.descriptors import SineMatrix from dscribe.descriptors import EwaldMatrix # Setup the descriptors n_atoms_max = 4 n_proc = 4 coulombmatrix = CoulombMatrix(n_atoms_max=n_atoms_max) sinematrix = SineMatrix(n_atoms_max=n_atoms_max) ewaldmatrix = EwaldMatrix(n_atoms_max=n_atoms_max) # Define a dataset data = { "NaCl": ase.build.bulk("NaCl", "rocksalt", 5.64), "Diamond": ase.build.bulk("C", "diamond", 3.567), "Al": ase.build.bulk("Al", "fcc", 4.046), "GaAs": ase.build.bulk("GaAs", "zincblende", 5.653), } # Setup an iterable that runs through the samples. Result = namedtuple("Result", "cm sm em") Sample = namedtuple("Sample", "key value") samples = [Sample(key, value) for key, value in data.items()]
# "https://wiki.fysik.dtu.dk/ase/ase/io/io.html" for a list of supported file # formats. atoms = ase.io.read("nacl.xyz") atoms.set_cell([5.640200, 5.640200, 5.640200]) atoms.set_initial_charges(atoms.get_atomic_numbers()) # There are utilities for automatically detecting statistics for ASE Atoms # objects. Typically some statistics are needed for the descriptors in order to # e.g. define a proper zero-padding stats = system_stats([atoms]) n_atoms_max = stats["n_atoms_max"] atomic_numbers = stats["atomic_numbers"] # Create descriptors for this system directly from the ASE atoms cm = CoulombMatrix(n_atoms_max, permutation="sorted_l2").create(atoms) sm = SineMatrix(n_atoms_max, permutation="sorted_l2").create(atoms) mbtr = MBTR(atomic_numbers, k=[1, 2, 3], periodic=True, weighting={ "k2": { "function": "exponential", "scale": 0.5, "cutoff": 1e-3 }, "k3": { "function": "exponential", "scale": 0.5, "cutoff": 1e-3 }, }).create(atoms)
from dscribe.descriptors import SineMatrix # Setting up the sine matrix descriptor sm = SineMatrix(n_atoms_max=6, permutation="sorted_l2", sparse=False, flatten=True) # Creation from ase.build import bulk # NaCl crystal created as an ASE.Atoms nacl = bulk("NaCl", "rocksalt", a=5.64) # Create output for the system nacl_sine = sm.create(nacl) # Create output for multiple system al = bulk("Al", "fcc", a=4.046) fe = bulk("Fe", "bcc", a=2.856) samples = [nacl, al, fe] sine_matrices = sm.create(samples) # Serial sine_matrices = sm.create(samples, n_jobs=2) # Parallel # Visualization import numpy as np from ase import Atoms import matplotlib.pyplot as mpl from mpl_toolkits.axes_grid1 import make_axes_locatable # FCC aluminum crystal
from ase.spacegroup import crystal from dscribe.descriptors import SineMatrix # Define atomic structures skutterudite = crystal(('Co', 'Sb'), basis=[(0.25, 0.25, 0.25), (0.0, 0.335, 0.158)], spacegroup=204, cellpar=[9.04, 9.04, 9.04, 90, 90, 90]) nacl = bulk("NaCl", "rocksalt", a=5.64) al = bulk("Al", "fcc", a=4.046) fe = bulk("Fe", "bcc", a=2.856) samples_bulk = [skutterudite, nacl, al, fe] # Setup descriptor sm_desc = SineMatrix(n_atoms_max=35, permutation="sorted_l2", sparse=False, flatten=True) # Create single descriptor sine_matrix = sm_desc.create(skutterudite) print("Sine matrix for skutterudite:\n", sine_matrix) # Create multiple descriptors sine_matrices = sm_desc.create(samples_bulk) print("List of Sine matrices:\n", sine_matrices)
def test_parallel_dense(self): """Tests creating dense output parallelly. """ samples = [bulk("NaCl", "rocksalt", a=5.64), bulk('Cu', 'fcc', a=3.6)] desc = SineMatrix(n_atoms_max=5, permutation="none", flatten=True, sparse=False) n_features = desc.get_number_of_features() # Multiple systems, serial job output = desc.create( system=samples, n_jobs=1, ) assumed = np.empty((2, n_features)) assumed[0, :] = desc.create(samples[0]) assumed[1, :] = desc.create(samples[1]) self.assertTrue(np.allclose(output, assumed)) # Multiple systems, parallel job output = desc.create( system=samples, n_jobs=2, ) assumed = np.empty((2, n_features)) assumed[0, :] = desc.create(samples[0]) assumed[1, :] = desc.create(samples[1]) self.assertTrue(np.allclose(output, assumed)) # Non-flattened output desc = SineMatrix(n_atoms_max=5, permutation="none", flatten=False, sparse=False) output = desc.create( system=samples, n_jobs=2, ) assumed = np.empty((2, 5, 5)) assumed[0] = desc.create(samples[0]) assumed[1] = desc.create(samples[1]) self.assertTrue(np.allclose(np.array(output), assumed))
def test_number_of_features(self): """Tests that the reported number of features is correct. """ desc = SineMatrix(n_atoms_max=5, permutation="none", flatten=False) n_features = desc.get_number_of_features() self.assertEqual(n_features, 25)
def create(system): desc = SineMatrix(n_atoms_max=3, permutation="sorted_l2", flatten=True) return desc.create(system)