def _featurize(self, struct: PymatgenStructure) -> np.ndarray: """Calculate SOAP descriptor from pymatgen structure. Parameters ---------- struct: pymatgen.Structure A periodic crystal composed of a lattice and a sequence of atomic sites with 3D coordinates and elements. Returns ------- features: np.ndarray soap descriptor """ soap = SOAP( periodic=self.periodic, species=self.species, rcut=self.rcut, nmax=self.nmax, lmax=self.lmax, rbf=self.rbf, sigma=self.sigma, average=self.average, ) if self.convert: adaptor = AseAtomsAdaptor() struct = adaptor.get_atoms(struct) features = soap.create(struct) features = np.asarray(features) return features
def extract_descriptor(rows): soaps, targets = [], [] for row in rows: atoms_Au_Fe = row.toatoms() atoms_all_Fe = Atoms() atoms_all_Fe.set_cell(atoms_Au_Fe.get_cell()) atoms_all_Fe.set_pbc(atoms_Au_Fe.get_pbc()) Au_idx_lst = [] for idx, at in enumerate(atoms_Au_Fe): if at.symbol == 'Fe': atoms_all_Fe.append(Atom(at.symbol, at.position)) elif at.symbol == 'Au': atoms_all_Fe.append(Atom('Fe', at.position)) Au_idx_lst.append(idx) else: atoms_all_Fe.append(Atom(at.symbol, at.position)) species = [] for at in atoms_all_Fe: species.append(at.symbol) species = list(set(species)) periodic_soap = SOAP( species=species, rcut=rcut, nmax=nmax, lmax=nmax, periodic=True, sparse=False) # print(Au_idx_lst, atoms_all_Fe.get_pbc(), species) soap_crystal = periodic_soap.create(atoms_all_Fe, positions=Au_idx_lst) # print(soap_crystal.shape, periodic_soap.get_number_of_features()) soaps.append(np.mean(soap_crystal, axis=0)) targets.append(([(row.data[predict_item])])) # print(soaps[-1].shape[0], targets[-1]) # print('-' * 100) return soaps, targets
def test_metrics(self): """Tests that different metrics as defined by scikit-learn can be used. """ # Create SOAP features for a system desc = SOAP([1, 8], 5.0, 2, 2, sigma=0.2, periodic=False, crossover=True, sparse=False) a = molecule('H2O') a_features = desc.create(a) # Linear dot-product kernel kernel = REMatchKernel(metric="linear", alpha=0.1, threshold=1e-6) K = kernel.create([a_features, a_features]) # Gaussian kernel kernel = REMatchKernel(metric="rbf", gamma=1, alpha=0.1, threshold=1e-6) K = kernel.create([a_features, a_features]) # Laplacian kernel kernel = REMatchKernel(metric="laplacian", gamma=1, alpha=0.1, threshold=1e-6) K = kernel.create([a_features, a_features])
def getSOAPs(geometries, species, rcut, sigma, nmax = 10, lmax = 9, periodic = True, crossover = True, sparse = False): """ Takes a Series of geometries with one He present, returns SOAP representation of the chemical environment of He for each item Assumes any given structure in ``geometries`` has the same collection of elements as all the other structures Assumes any given structure in ``geometries`` has the same number of atoms as all the other structures Input: geometries: Series of Atoms objects; each must contain exactly 1 He atom rcut, nmax, lmax, sigma, periodic, crossover, sparse: SOAP parameters Output: output: Series of SOAP matrices, each corresponding to the appropriate index """ # refgeom = geometries.iloc[0] #use the first geometry as a reference geometry ## set up descriptor # species = np.unique([i.symbol for i in refgeom]) desc = SOAP(species=species, rcut = rcut, nmax = nmax, lmax = lmax, sigma = sigma, periodic = periodic, crossover = crossover, sparse = sparse) ## apply descriptor soaps = {} for i, geom in geometries.iteritems(): HeLoc = len(geom) - 1 # assume He atom is last one in Atoms list tempSOAP = preprocessing.normalize( desc.create(geom, positions = [HeLoc], n_jobs = 4)) # SOAP representation of temp soaps[i] = tempSOAP[0] return pd.Series(soaps,name = 'SOAP')
def test_exclude(self): soap = SOAP( species=[1, 6, 8], rcut=3, nmax=2, lmax=1, rbf="gto", sparse=False, periodic=False, ) for method in ["numerical", "analytical"]: # Invalid exclude options with self.assertRaises(ValueError): soap.derivatives(H2O, exclude=[3], method=method) with self.assertRaises(ValueError): soap.derivatives(H2O, exclude=[-1], method=method) # Test that correct atoms are excluded and in the correct order D1, d1 = soap.derivatives(H2O, exclude=[1], method=method) D2, d2 = soap.derivatives(H2O, method=method) self.assertTrue(np.array_equal(D1[:, 0], D2[:, 0])) self.assertTrue(np.array_equal(D1[:, 1], D2[:, 2])) # Test that using single list and multiple samples works D1, d1 = soap.derivatives([H2O, CO2], exclude=[1], method=method) D2, d2 = soap.derivatives([H2O, CO2], method=method) self.assertTrue(np.array_equal(D1[:, :, 0], D2[:, :, 0])) self.assertTrue(np.array_equal(D1[:, :, 1], D2[:, :, 2]))
def test_xy(self): """Tests that the kernel can be also calculated between two different sets, which is necessary for making predictions with kernel-based methods. """ # Create SOAP features for a system desc = SOAP([1, 8], 5.0, 2, 2, sigma=0.2, periodic=False, crossover=True, sparse=False) a = molecule('H2O') b = molecule('O2') c = molecule('H2O2') a_feat = desc.create(a) b_feat = desc.create(b) c_feat = desc.create(c) # Linear dot-product kernel kernel = REMatchKernel(metric="linear", alpha=0.1, threshold=1e-6) K = kernel.create([a_feat, b_feat], [c_feat]) self.assertEqual(K.shape, (2, 1))
def createDescriptorsAllSOAP(data, species, sigma_SOAP, cutoff_SOAP, nmax_SOAP, lmax_SOAP, periodic, sparse_SOAP=default_sparse_SOAP): # Initialize SOAP soap = SOAP(species=species, sigma=sigma_SOAP, periodic=periodic, rcut=cutoff_SOAP, nmax=nmax_SOAP, lmax=lmax_SOAP, sparse=sparse_SOAP) # Compute number of features n_features = soap.get_number_of_features() n_atoms = np.shape(data[0])[0] n_steps = len(data) # Computing descriptors descriptors = np.empty((n_atoms, n_steps, n_features), dtype=object) for index_structure in tqdm.tqdm(range(n_steps)): descriptors[:, index_structure, :] = soap.create(data[index_structure]) descriptors_ = [] for atom in range(n_atoms): descriptors_.append(descriptors[atom, :, :]) return descriptors_
def test_convergence_infinity(self): """Tests that the REMatch kernel correctly converges to the average kernel at the the limit of infinite alpha. """ # Create SOAP features for a system desc = SOAP( species=[1, 8], rcut=5.0, nmax=2, lmax=2, sigma=0.2, periodic=False, crossover=True, sparse=False, ) a = molecule("H2O") b = molecule("H2O2") a_features = desc.create(a) b_features = desc.create(b) # REMatch kernel with very high alpha kernel_re = REMatchKernel(metric="linear", alpha=1e20, threshold=1e-6) K_re = kernel_re.create([a_features, b_features]) # Average kernel kernel_ave = AverageKernel(metric="linear") K_ave = kernel_ave.create([a_features, b_features]) # Test approximate equality self.assertTrue(np.allclose(K_re, K_ave))
def test_metrics(self): """Tests that different metrics as defined by scikit-learn can be used.""" # Create SOAP features for a system desc = SOAP( species=[1, 8], rcut=5.0, nmax=2, lmax=2, sigma=0.2, periodic=False, crossover=True, sparse=False, ) a = molecule("H2O") a_features = desc.create(a) # Linear dot-product kernel kernel = AverageKernel(metric="linear") K = kernel.create([a_features, a_features]) # Gaussian kernel kernel = AverageKernel(metric="rbf", gamma=1) K = kernel.create([a_features, a_features]) # Laplacian kernel kernel = AverageKernel(metric="laplacian", gamma=1) K = kernel.create([a_features, a_features])
def coefficients_gto(system, centers, args): """Used to numerically calculate the inner product coefficients of SOAP with GTO radial basis. """ nmax = args["nmax"] lmax = args["lmax"] rcut = args["rcut"] sigma = args["sigma"] weighting = args.get("weighting") positions = system.get_positions() symbols = system.get_chemical_symbols() atomic_numbers = system.get_atomic_numbers() species_ordered = sorted(list(set(atomic_numbers))) n_elems = len(species_ordered) # Calculate the weights and decays of the radial basis functions. soap = SOAP(**args) soap.create(system, positions=centers) alphas = np.reshape(soap._alphas, [lmax + 1, nmax]) betas = np.reshape(soap._betas, [lmax + 1, nmax, nmax]) def rbf_gto(r, n, l): i_alpha = alphas[l, 0:nmax] i_beta = betas[l, n, 0:nmax] return (i_beta * r ** l * np.exp(-i_alpha * r ** 2)).sum() return soap_integration(system, centers, args, rbf_gto)
def update_soap_analysis(struct, all_kwargs): if not struct: raise PreventUpdate struct = self.from_data(struct) kwargs = self.reconstruct_kwargs_from_state( callback_context.inputs) # TODO: make sure is_int kwarg information is enforced so that int() conversion is unnecessary desc = SOAP( species=[e.number for e in struct.composition.elements], sigma=kwargs["sigma"], rcut=kwargs["rcut"], nmax=int(kwargs["nmax"]), lmax=int(kwargs["lmax"]), periodic=True, crossover=kwargs["crossover"], sparse=False, average=kwargs["average"], ) adaptor = AseAtomsAdaptor() atoms = adaptor.get_atoms(struct) feature = normalize(desc.create(atoms, n_jobs=cpu_count())) return _get_soap_graph(feature, "SOAP vector for this material")
def test_difference(self): """Tests that the similarity is correct. """ # Create SOAP features for a system desc = SOAP(species=[1, 6, 7, 8], rcut=5.0, nmax=2, lmax=2, sigma=0.2, periodic=False, crossover=True, sparse=False) # Calculate that identical molecules are identical. a = molecule("H2O") a_features = desc.create(a) kernel = AverageKernel(metric="linear") K = kernel.create([a_features, a_features]) self.assertTrue(np.all(np.abs(K - 1) < 1e-3)) # Check that completely different molecules are completely different a = molecule("N2") b = molecule("H2O") a_features = desc.create(a) b_features = desc.create(b) K = kernel.create([a_features, b_features]) self.assertTrue(np.all(np.abs(K - np.eye(2)) < 1e-3)) # Check that somewhat similar molecules are somewhat similar a = molecule("H2O") b = molecule("H2O2") a_features = desc.create(a) b_features = desc.create(b) K = kernel.create([a_features, b_features]) self.assertTrue(K[0, 1] > 0.9)
def soap_gto_vs_polynomial(version): """GTO vs polynomial RBF scaling. """ nmax = 4 lmax = 4 fig = mpl.figure(figsize=[9, 7]) ax = fig.add_subplot(111) ax.set_title("SOAP nmax={}, lmax={}, version={}".format( nmax, lmax, version)) ax.set_xlabel("Number of atoms") ax.set_ylabel("Time (s)") for rbf in ["gto", "polynomial"]: N = [] t = [] for ncells in tqdm(range(5, 15)): soap_generator = SOAP(rcut=3.0, nmax=nmax, lmax=lmax, species=["Ni", "Ti"], rbf=rbf, crossover=True, periodic=True) i_system = system_periodic.copy() * ncells t0 = time() soap_generator.create(i_system) t1 = time() N.append(len(i_system)) t.append(t1 - t0) ax.plot(N, t, "o--", label="{}".format(rbf)) mpl.legend() mpl.show()
def test_poly_integration(self): """Tests that the partial power spectrum with the polynomial basis done with C corresponds to the easier-to-code but less performant integration done with python. """ # Calculate mostly analytical (radial part is integrated numerically) # power spectrum system, centers, args = get_soap_polynomial_lmax_setup() soap = SOAP(**args, rbf="polynomial", dtype="float64") analytical_power_spectrum = soap.create(system, positions=centers) # Calculate numerical power spectrum coeffs = load_polynomial_coefficients(args) numerical_power_spectrum = self.get_power_spectrum( coeffs, crossover=args["crossover"] ) # print("Numerical: {}".format(numerical_power_spectrum)) # print("Analytical: {}".format(analytical_power_spectrum)) # print(analytical_power_spectrum.dtype) self.assertTrue( np.allclose( numerical_power_spectrum, analytical_power_spectrum, atol=1e-15, rtol=0.01, ) )
def test_constructor(self): """Tests different valid and invalid constructor values. """ # Invalid gaussian width with self.assertRaises(ValueError): SOAP(species=[-1, 2], rcut=5, sigma=0, nmax=5, lmax=5, periodic=True) with self.assertRaises(ValueError): SOAP(species=[-1, 2], rcut=5, sigma=-1, nmax=5, lmax=5, periodic=True) # Invalid rcut with self.assertRaises(ValueError): SOAP(species=[-1, 2], rcut=0.5, sigma=0, nmax=5, lmax=5, periodic=True)
def create_soap(nmax, lmax, rcut, procs): species = ['Au'] soap = SOAP( species=species, periodic=False, rcut=rcut, nmax=nmax, lmax=lmax, ) print('Calculating SOAPs on', procs, 'procs') print('nmax, lmax, rcut =', nmax, lmax, rcut) start = time.time() soap_struc = soap.create(struc, grid, n_jobs=procs) elapsed = time.time() - start print('DONE in ', elapsed, '\n') print('Shape of SOAPs:', soap_struc.shape) print('Writing SOAPs to disk...') start = time.time() write_pickle( soap_struc, path + 'soap_n_' + str(nmax) + '_l_' + str(lmax) + '_r_' + str(rcut) + '_p_' + str(procs)) elapsed = time.time() - start print('DONE in ', elapsed, '\n') print('ALL DONE')
def test_multiple_species(self): """Tests multiple species are handled correctly. """ lmax = 5 nmax = 5 species = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] desc = SOAP(species=species, rcut=5, nmax=nmax, lmax=lmax, periodic=False, sparse=False) pos = np.expand_dims(np.linspace(0, 8, 8), 1) pos = np.hstack((pos, pos, pos)) sys = Atoms(symbols=species[0:8], positions=pos, pbc=False) vec1 = desc.create(sys) sys2 = Atoms(symbols=species[8:], positions=pos, pbc=False) vec2 = desc.create(sys2) sys3 = Atoms(symbols=species[4:12], positions=pos, pbc=False) vec3 = desc.create(sys3) dot1 = np.dot(vec1[6, :], vec2[6, :]) dot2 = np.dot(vec1[3, :], vec3[3, :]) dot3 = np.dot(vec2[3, :], vec3[3, :]) # The dot product for systems without overlap in species should be zero self.assertTrue(abs(dot1) <= 1e-8) # The systems with overlap in the elements should have onerlap in the # dot product self.assertTrue(abs(dot2) > 1e-3) self.assertTrue(abs(dot3) > 1e-3)
def test_xy(self): """Tests that the kernel can be also calculated between two different sets, which is necessary for making predictions with kernel-based methods. """ # Create SOAP features for a system desc = SOAP( species=[1, 8], rcut=5.0, nmax=2, lmax=2, sigma=0.2, periodic=False, crossover=True, sparse=False, ) a = molecule("H2O") b = molecule("O2") c = molecule("H2O2") a_feat = desc.create(a) b_feat = desc.create(b) c_feat = desc.create(c) # Linear dot-product kernel kernel = AverageKernel(metric="linear") K = kernel.create([a_feat, b_feat], [c_feat]) self.assertEqual(K.shape, (2, 1))
def calc_soap_dscribe(atoms, parameters, atomic_numbers=None, periodic=True, sparse=False, rbf="polynomial"): """ Calculate the SOAP vector for the structure. Args ---- parameters: list SOAP parameters (r, sigma, n, l, zeta). r: radial cut-off. sigma: broadness of the Gaussian functions (smoothness). n: order to which the radial basis set is expanded to. l: order to which the angular basis set is expanded to. zeta: power to which the normalised SOAP kernel is raised. atomic_numbers: list Atomic numbers to include in the SOAP analysis. All elements that will be encountered need to be included. If None, will just include all elements in the structure. Note, undesirable behaviour may occur if comparing structures with differnet species if not all elements are included for both structures. periodic: bool Whether to construct a perioidic SOAP. sparse: rbf: str Radial basis function to use ("poylnomial" or DScribe's custom "gto" basis set). """ from dscribe.descriptors import SOAP # build for all atoms in structure. if atomic_numbers is None: atomic_numbers = atoms.get_atomic_numbers() # unpack the SOAP parameters. r, sigma, n, l, _ = parameters # using DScribe implementation of SOAP, create periodic calculator. p_soap = SOAP(species=np.unique(atomic_numbers), rcut=r, sigma=sigma, nmax=n, lmax=l, periodic=periodic, sparse=sparse, rbf=rbf) return p_soap.create(atoms)
def create_poly(system): desc = SOAP(species=system.get_atomic_numbers(), rcut=8.0, lmax=2, nmax=1, rbf="polynomial", periodic=False, crossover=True) return desc.create(system)
def create_gto(system): desc = SOAP(species=system.get_atomic_numbers(), rcut=8.0, lmax=5, nmax=5, rbf="gto", periodic=False, crossover=True) return desc.create(system)
def test_verbose_create(self): """Tests the verbose flag in create. """ lmax = 5 nmax = 5 n_elems = 2 desc = SOAP(species=[1, 8], rcut=3, nmax=nmax, lmax=lmax, periodic=True) vec = desc.create([H2O, H2O], verbose = True)
def test_soap_structure(self): """Tests that when no positions are given, the SOAP for the full structure is calculated. """ lmax = 5 nmax = 5 desc = SOAP(atomic_numbers=[1, 8], rcut=5, nmax=nmax, lmax=lmax, periodic=True) vec = desc.create(H2O) self.assertTrue(vec.shape[0] == 3)
def test_periodic_images(self): """Tests the periodic images seen by the descriptor""" desc = SOAP( species=[1, 6, 8], rcut=10.0, nmax=2, lmax=0, periodic=False, crossover=True ) molecule = H2O.copy() # Non-periodic for comparison molecule.set_cell([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]) nocell = desc.create(molecule, positions=[[0, 0, 0]]) # Make periodic desc = SOAP( species=[1, 6, 8], rcut=10.0, nmax=2, lmax=0, periodic=True, crossover=True ) molecule.set_pbc(True) # Cubic molecule.set_cell([[3.0, 0.0, 0.0], [0.0, 3.0, 0.0], [0.0, 0.0, 3.0]]) cubic_cell = desc.create(molecule, positions=[[0, 0, 0]]) suce = molecule * (2, 1, 1) cubic_suce = desc.create(suce, positions=[[0, 0, 0]]) # Triclinic molecule.set_cell([[0.0, 2.0, 2.0], [2.0, 0.0, 2.0], [2.0, 2.0, 0.0]]) triclinic_cell = desc.create(molecule, positions=[[0, 0, 0]]) suce = molecule * (2, 1, 1) triclinic_suce = desc.create(suce, positions=[[0, 0, 0]]) self.assertTrue(np.sum(np.abs((nocell[:3] - cubic_suce[:3]))) > 0.1) self.assertAlmostEqual(np.sum(cubic_cell[:3] - cubic_suce[:3]), 0) self.assertAlmostEqual(np.sum(triclinic_cell[:3] - triclinic_suce[:3]), 0)
def test_soap(version): """Tests how the SOAP descriptor calculation scales with system size. """ nmax = 4 lmax = 4 fig = mpl.figure(figsize=[9, 7]) ax = fig.add_subplot(111) ax.set_title("SOAP nmax={}, lmax={}, version={}".format( nmax, lmax, version)) ax.set_xlabel("Number of atoms") ax.set_ylabel("Time (s)") for rbf in ["gto", "polynomial"]: N = [] t = [] # Loop over different system sizes for ncells in tqdm(range(5, 20)): natoms = 2 * ncells**3 soap_generator = SOAP(rcut=3.0, nmax=nmax, lmax=lmax, species=["Ni", "Ti"], rbf=rbf, crossover=True, periodic=True) a = 2.993 niti = Atoms( "NiTi", positions=[[0.0, 0.0, 0.0], [a / 2, a / 2, a / 2]], cell=[a, a, a], pbc=[1, 1, 1], ) # Replicate system niti = niti * ncells a *= ncells t0 = time() soap_generator.create(niti) t1 = time() N.append(natoms) t.append(t1 - t0) N = np.array(N) t = np.array(t) ax.plot(N, t, "o--", label="{}".format(rbf)) mpl.legend() mpl.savefig("soap_scaling_{}.pdf".format(version))
def test_system_input(self): """Tests that create takes internal system object. """ system = System.from_atoms(H2O) lmax = 5 nmax = 5 n_elems = 2 desc = SOAP(species=[1, 8], rcut=3, nmax=nmax, lmax=lmax, periodic=True) vec = desc.create(system)
def __init__(self, desc_spec): """ make a DScribe SOAP object """ from dscribe.descriptors import SOAP if "type" not in desc_spec.keys() or desc_spec["type"] != "SOAP": raise ValueError( "Type is not SOAP or cannot find the type of the descriptor") # required try: self.species = desc_spec['species'] self.cutoff = desc_spec['cutoff'] self.g = desc_spec['atom_gaussian_width'] self.n = desc_spec['n'] self.l = desc_spec['l'] except: raise ValueError( "Not enough information to intialize the `Atomic_Descriptor_SOAP` object" ) # we have defaults here if 'rbf' in desc_spec.keys(): self.rbf = desc_spec['rbf'] else: self.rbf = 'gto' if 'crossover' in desc_spec.keys(): self.crossover = bool(desc_spec['crossover']) else: self.crossover = False if 'periodic' in desc_spec.keys(): self.periodic = bool(desc_spec['periodic']) else: self.periodic = True self.soap = SOAP(species=self.species, rcut=self.cutoff, nmax=self.n, lmax=self.l, sigma=self.g, rbf=self.rbf, crossover=self.crossover, average='off', periodic=self.periodic) print("Using SOAP Descriptors ...") # make an acronym self.acronym = "SOAP-n" + str(self.n) + "-l" + str( self.l) + "-c" + str(self.cutoff) + "-g" + str(self.g)
def test_infer_rcut(self): """Tests that the rcut is correctly inferred from the weighting function. """ # poly weighting = { "function": "poly", "c": 2, "m": 3, "r0": 4, } soap = SOAP( nmax=1, lmax=1, weighting=weighting, species=[1, 8], sparse=True, ) rcut = weighting["r0"] self.assertAlmostEqual(soap._rcut, rcut) # pow weighting = { "function": "pow", "threshold": 1e-3, "c": 1, "d": 1, "m": 1, "r0": 1, } soap = SOAP( nmax=1, lmax=1, weighting=weighting, species=[1, 8], sparse=True, ) rcut = weighting["c"] * (1 / weighting["threshold"] - 1) self.assertAlmostEqual(soap._rcut, rcut) # exp weighting = { "c": 2, "d": 1, "r0": 2, "function": "exp", "threshold": 1e-3, } soap = SOAP(species=[1, 8], nmax=1, lmax=1, sparse=True, weighting=weighting) rcut = weighting["r0"] * np.log( weighting["c"] / weighting["threshold"] - weighting["d"] ) self.assertAlmostEqual(soap._rcut, rcut)
def test_weighting(self): """Tests that the weighting done with C corresponds to the easier-to-code but less performant python version. """ system, centers, args = get_soap_default_setup() for rbf in ["gto", "polynomial"]: for weighting in [ {"function": "poly", "r0": 2, "c": 3, "m": 4}, {"function": "pow", "r0": 2, "c": 3, "d": 4, "m": 5}, {"function": "exp", "r0": 2, "c": 3, "d": 4}, ]: # Calculate the analytical power spectrum soap = SOAP(**args, rbf=rbf, weighting=weighting) analytical_power_spectrum = soap.create(system, positions=centers) # Calculate and save the numerical power spectrum to disk filename = ( "{rbf}_coefficients_{nmax}_{lmax}_{rcut}_{sigma}_{func}.npy".format( **args, rbf=rbf, func=weighting["function"] ) ) # coeffs = getattr(self, "coefficients_{}".format(rbf))( # system_num, # soap_centers_num, # nmax_num, # lmax_num, # rcut_num, # sigma_num, # weighting, # ) # np.save(filename, coeffs) # Load coefficients from disk coeffs = np.load(filename) numerical_power_spectrum = self.get_power_spectrum( coeffs, crossover=args["crossover"] ) # print("Numerical: {}".format(numerical_power_spectrum)) # print("Analytical: {}".format(analytical_power_spectrum)) self.assertTrue( np.allclose( numerical_power_spectrum, analytical_power_spectrum, atol=1e-15, rtol=0.01, ) )
def test_unit_cells(self): """Tests if arbitrary unit cells are accepted""" desc = SOAP([1, 6, 8], 10.0, 2, 0, periodic=False, crossover=True,) molecule = H2O.copy() molecule.set_cell([ [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ]) nocell = desc.create(molecule, positions=[[0, 0, 0]]) desc = SOAP([1, 6, 8], 10.0, 2, 0, periodic=True, crossover=True,) # Invalid unit cell 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): desc.create(molecule, positions=[[0, 0, 0]]) 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, positions=[[0, 0, 0]]) 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, positions=[[0, 0, 0]]) 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, positions=[[0, 0, 0]])