def run_task(self, fw_spec): user_incar_settings = self["user_incar_settings"] interpolation_type = self.get("interpolation_type", "IDPP") idpp_species = fw_spec.get("idpp_species") user_kpoints_settings = self.get("user_kpoints_settings") try: ep0 = Structure.from_dict(fw_spec["ep0"]) ep1 = Structure.from_dict(fw_spec["ep1"]) except: ep0 = fw_spec["ep0"] ep1 = fw_spec["ep1"] # Get number of images. nimages = user_incar_settings.get("IMAGES", self._get_nimages(ep0, ep1)) if interpolation_type == "IDPP": from pymatgen_diffusion.neb.pathfinder import IDPPSolver obj = IDPPSolver.from_endpoints([ep0, ep1], nimages=nimages) images = obj.run(species=idpp_species) images_dic_list = [image.as_dict() for image in images] elif interpolation_type == "linear": images = self._get_images_by_linear_interp(nimages, ep0, ep1) images_dic_list = [i.as_dict() for i in images] else: raise ValueError("The interpolation method must either be 'linear' or 'IDPP'!") write = WriteNEBFromImages(neb_label='1', user_incar_settings=user_incar_settings, user_kpoints_settings=user_kpoints_settings) fw_spec["neb"] = [images_dic_list] write.run_task(fw_spec=fw_spec)
def test_disordered_primitive_to_ordered_supercell(self): sm_atoms = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size = 'num_atoms', comparator=OrderDisorderElementComparator()) sm_sites = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size = 'num_sites', comparator=OrderDisorderElementComparator()) lp = Lattice.orthorhombic(10, 20, 30) pcoords = [[0, 0, 0], [0.5, 0.5, 0.5]] ls = Lattice.orthorhombic(20,20,30) scoords = [[0, 0, 0], [0.75, 0.5, 0.5]] prim = Structure(lp, [{'Na':0.5}, {'Cl':0.5}], pcoords) supercell = Structure(ls, ['Na', 'Cl'], scoords) supercell.make_supercell([[-1,1,0],[0,1,1],[1,0,0]]) self.assertFalse(sm_sites.fit(prim, supercell)) self.assertTrue(sm_atoms.fit(prim, supercell)) self.assertRaises(ValueError, sm_atoms.get_s2_like_s1, prim, supercell) self.assertEqual(len(sm_atoms.get_s2_like_s1(supercell, prim)), 4)
def setUp(self): c1 = [[0.5] * 3, [0.9] * 3] c2 = [[0.5] * 3, [0.9, 0.1, 0.1]] s1 = Structure(Lattice.cubic(5), ['Si', 'Si'], c1) s2 = Structure(Lattice.cubic(5), ['Si', 'Si'], c2) structs = [] for s in s1.interpolate(s2, 3, pbc=True): structs.append(Structure.from_sites(s.sites, to_unit_cell=True)) self.structures = structs self.vis = MITNEBSet(self.structures)
def test_supercell_fit(self): sm = StructureMatcher(attempt_supercell=False) s1 = Structure.from_file(os.path.join(test_dir, "Al3F9.json")) s2 = Structure.from_file(os.path.join(test_dir, "Al3F9_distorted.json")) self.assertFalse(sm.fit(s1, s2)) sm = StructureMatcher(attempt_supercell=True) self.assertTrue(sm.fit(s1, s2)) self.assertTrue(sm.fit(s2, s1))
def test_get_supercell_matrix(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0,0,0.1],[0,0,0.2],[.7,.4,.5]]) s1.make_supercell([2,1,1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0,0.1,0],[0,0.1,-0.95],[-.7,.5,.375]]) result = sm.get_supercell_matrix(s1, s2) self.assertTrue((result == [[-2,0,0],[0,1,0],[0,0,1]]).all())
def test_electronegativity(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5) s1 = Structure.from_file(os.path.join(test_dir, "Na2Fe2PAsO4S4.json")) s2 = Structure.from_file(os.path.join(test_dir, "Na2Fe2PNO4Se4.json")) self.assertEqual(sm.get_best_electronegativity_anonymous_mapping(s1, s2), {Element('S'): Element('Se'), Element('As'): Element('N'), Element('Fe'): Element('Fe'), Element('Na'): Element('Na'), Element('P'): Element('P'), Element('O'): Element('O'),}) self.assertEqual(len(sm.get_all_anonymous_mappings(s1, s2)), 2)
def test_predict(self): s = PymatgenTest.get_structure("CsCl") nacl = PymatgenTest.get_structure("CsCl") nacl.replace_species({"Cs": "Na"}) nacl.scale_lattice(184.384551033) p = RLSVolumePredictor(radii_type="ionic") self.assertAlmostEqual(p.predict(s, nacl), 342.84905395082535) p = RLSVolumePredictor(radii_type="atomic") self.assertAlmostEqual(p.predict(s, nacl), 391.884366481) lif = PymatgenTest.get_structure("CsCl") lif.replace_species({"Cs": "Li", "Cl": "F"}) p = RLSVolumePredictor(radii_type="ionic") self.assertAlmostEqual(p.predict(lif, nacl), 74.268402413690467) p = RLSVolumePredictor(radii_type="atomic") self.assertAlmostEqual(p.predict(lif, nacl), 62.2808125839) lfpo = PymatgenTest.get_structure("LiFePO4") lmpo = PymatgenTest.get_structure("LiFePO4") lmpo.replace_species({"Fe": "Mn"}) p = RLSVolumePredictor(radii_type="ionic") self.assertAlmostEqual(p.predict(lmpo, lfpo), 310.08253254420134) p = RLSVolumePredictor(radii_type="atomic") self.assertAlmostEqual(p.predict(lmpo, lfpo), 299.607967711) sto = PymatgenTest.get_structure("SrTiO3") scoo = PymatgenTest.get_structure("SrTiO3") scoo.replace_species({"Ti4+": "Co4+"}) p = RLSVolumePredictor(radii_type="ionic") self.assertAlmostEqual(p.predict(scoo, sto), 56.162534974936463) p = RLSVolumePredictor(radii_type="atomic") self.assertAlmostEqual(p.predict(scoo, sto), 57.4777835108) # Use Ag7P3S11 as a test case: # (i) no oxidation states are assigned and CVP-atomic scheme is selected. aps = Structure.from_file(os.path.join(dir_path, "Ag7P3S11_mp-683910_primitive.cif")) apo = Structure.from_file(os.path.join(dir_path, "Ag7P3S11_mp-683910_primitive.cif")) apo.replace_species({"S": "O"}) p = RLSVolumePredictor(radii_type="atomic", check_isostructural=False) self.assertAlmostEqual(p.predict(apo, aps), 1196.31384276) # (ii) Oxidation states are assigned. apo.add_oxidation_state_by_element({"Ag": 1, "P": 5, "O": -2}) aps.add_oxidation_state_by_element({"Ag": 1, "P": 5, "S": -2}) p = RLSVolumePredictor(radii_type="ionic") self.assertAlmostEqual(p.predict(apo, aps), 1165.23259079) p = RLSVolumePredictor(radii_type="atomic") self.assertAlmostEqual(p.predict(apo, aps), 1196.31384276)
def test_find_match2(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, attempt_supercell=False) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ["Si", "Si"], [[0, 0, 0.1], [0, 0, 0.2]]) s2 = Structure(l, ["Si", "Si"], [[0, 0.1, 0], [0, 0.1, -0.95]]) s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False) match = sm._strict_match(s1, s2, fu, s1_supercell=False, use_rms=True, break_on_match=False) scale_matrix = match[2] s2.make_supercell(scale_matrix) s2.translate_sites(range(len(s2)), match[3]) self.assertAlmostEqual(np.sum(s2.frac_coords), 0.3) self.assertAlmostEqual(np.sum(s2.frac_coords[:, :2]), 0)
def test_writebandstr(self): filepath = os.path.join(test_dir, 'CsI3Pb.cif') structure = Structure.from_file(filepath) excin = ExcitingInput(structure) string = excin.write_string('primitive', bandstr=True) bandstr = string.split('<properties>')[1].split('</properties>')[0] coord = [] label = [] coord_ref = [[0.0, 0.0, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.0, 0.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.5, 0.5]] label_ref = ['GAMMA', 'X', 'S', 'Y', 'GAMMA', 'Z', 'U', 'R', 'T', 'Z', 'Y', 'T', 'U', 'X', 'S', 'R'] root = ET.fromstring(bandstr) for plot1d in root.iter('plot1d'): for point in plot1d.iter('point'): coord.append([float(i) for i in point.get('coord').split()]) label.append(point.get('label')) self.assertEqual(label, label_ref) self.assertEqual(coord, coord_ref)
def test_find_match1(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, attempt_supercell=False) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ["Si", "Si", "Ag"], [[0, 0, 0.1], [0, 0, 0.2], [0.7, 0.4, 0.5]]) s2 = Structure(l, ["Si", "Si", "Ag"], [[0, 0.1, 0], [0, 0.1, -0.95], [0.7, 0.5, 0.375]]) s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False) match = sm._strict_match(s1, s2, fu, s1_supercell=True, use_rms=True, break_on_match=False) scale_matrix = match[2] s2.make_supercell(scale_matrix) fc = s2.frac_coords + match[3] fc -= np.round(fc) self.assertAlmostEqual(np.sum(fc), 0.9) self.assertAlmostEqual(np.sum(fc[:, :2]), 0.1) cart_dist = np.sum(match[1] * (l.volume / 3) ** (1 / 3)) self.assertAlmostEqual(cart_dist, 0.15)
def setUp(self): with open(os.path.join(test_dir, "TiO2_entries.json"), 'r') as fp: entries = json.load(fp, cls=MontyDecoder) self.struct_list = [e.structure for e in entries] self.oxi_structs = [self.get_structure("Li2O"), Structure.from_file(os.path.join( test_dir, "POSCAR.Li2O"))]
def from_dict(cls, d): structure = Structure.from_dict(d["structure"]) return cls(structure, np.array(d["displacements"]), specie=d["specie"], temperature=d["temperature"], time_step=d["time_step"], step_skip=d["step_skip"], min_obs=d["min_obs"], smoothed=d.get("smoothed", "max"), avg_nsteps=d.get("avg_nsteps", 1000))
def test_electronegativity(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5) s1 = Structure.from_file(os.path.join(test_dir, "Na2Fe2PAsO4S4.json")) s2 = Structure.from_file(os.path.join(test_dir, "Na2Fe2PNO4Se4.json")) self.assertEqual( sm.get_best_electronegativity_anonymous_mapping(s1, s2), { Element("S"): Element("Se"), Element("As"): Element("N"), Element("Fe"): Element("Fe"), Element("Na"): Element("Na"), Element("P"): Element("P"), Element("O"): Element("O"), }, ) self.assertEqual(len(sm.get_all_anonymous_mappings(s1, s2)), 2)
def from_dict(cls, d): """ As in :Class: `pymatgen.core.Structure` except restoring graphs using `from_dict_of_dicts` from NetworkX to restore graph information. """ s = Structure.from_dict(d['structure']) return cls(s, d['graphs'])
def test_ignore_species(self): s1 = Structure.from_file(os.path.join(test_dir, "LiFePO4.cif")) s2 = Structure.from_file(os.path.join(test_dir, "POSCAR")) m = StructureMatcher(ignored_species=["Li"], primitive_cell=False, attempt_supercell=True) self.assertTrue(m.fit(s1, s2)) self.assertTrue(m.fit_anonymous(s1, s2)) groups = m.group_structures([s1, s2]) self.assertEqual(len(groups), 1) s2.make_supercell((2, 1, 1)) ss1 = m.get_s2_like_s1(s2, s1, include_ignored_species=True) self.assertAlmostEqual(ss1.lattice.a, 20.820740000000001) self.assertEqual(ss1.composition.reduced_formula, "LiFePO4") self.assertEqual( {k.symbol: v.symbol for k, v in m.get_best_electronegativity_anonymous_mapping(s1, s2).items()}, {"Fe": "Fe", "P": "P", "O": "O"}, )
def test_find_match2(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, attempt_supercell=False) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si'], [[0,0,0.1],[0,0,0.2]]) s2 = Structure(l, ['Si', 'Si'], [[0,0.1,0],[0,0.1,-0.95]]) match = sm._find_match(s1, s2, break_on_match = False, use_rms = True, niggli = False) scale_matrix = np.round(np.dot(match[2].matrix, s2.lattice.inv_matrix)).astype('int') s2.make_supercell(scale_matrix) fc = s2.frac_coords + match[3] fc -= np.round(fc) self.assertAlmostEqual(np.sum(fc), 0.3) self.assertAlmostEqual(np.sum(fc[:,:2]), 0)
def setUp(self): """ 1) Basic check for pymatgen configurations. 2) Setup all test workflow. """ super(TestNudgedElasticBandWorkflow, self).setUp() # Structures used for test: parent = PymatgenTest.get_structure("Li2O") parent.remove_oxidation_states() parent.make_supercell(2) ep0, ep1 = get_endpoints_from_index(parent, [0, 1]) neb_dir = [os.path.join(module_dir, "..", "..", "test_files", "neb_wf", "4", "inputs", "{:02}", "POSCAR").format(i) for i in range(5)] self.structures = [Structure.from_file(n) for n in neb_dir] # Run fake vasp test_yaml = os.path.join(module_dir, "../../test_files/neb_wf/config/neb_unittest.yaml") with open(test_yaml, 'r') as stream: self.config = yaml.safe_load(stream) # Use scratch directory as destination directory for testing self.config["common_params"]["_fw_env"] = {"run_dest_root": self.scratch_dir} # Config 1: The parent structure & two endpoint indexes provided; need relaxation first. self.config_1 = copy.deepcopy(self.config) self.config_1["common_params"]["is_optimized"] = False self.config_1["common_params"]["wf_name"] = "NEB_test_1" # Config 2: The parent structure & two endpoint indexes provided; no need to relax. self.config_2 = copy.deepcopy(self.config) del self.config_2["fireworks"][0] self.config_2["common_params"]["is_optimized"] = True self.config_2["common_params"]["wf_name"] = "NEB_test_2" # Config 3: Two endpoints provided; need to relax two endpoints. self.config_3 = copy.deepcopy(self.config) del self.config_3["fireworks"][0] self.config_3["common_params"]["is_optimized"] = False self.config_3["common_params"]["wf_name"] = "NEB_test_3" # Config 4: Two relaxed endpoints provided; no need to relax two endpoints. self.config_4 = copy.deepcopy(self.config_3) del self.config_4["fireworks"][0] self.config_4["common_params"]["is_optimized"] = True self.config_4["common_params"]["wf_name"] = "NEB_test_4" # Config 5: All images including two endpoints are provided. self.config_5 = copy.deepcopy(self.config) del self.config_5["fireworks"][0: 2] self.config_5["common_params"]["wf_name"] = "NEB_test_5" self.wf_1 = wf_nudged_elastic_band([parent], parent, self.config_1) self.wf_2 = wf_nudged_elastic_band([parent], parent, self.config_2) self.wf_3 = wf_nudged_elastic_band([ep0, ep1], parent, self.config_3) self.wf_4 = wf_nudged_elastic_band([ep0, ep1], parent, self.config_4) self.wf_5 = wf_nudged_elastic_band(self.structures, parent, self.config_5) # Workflow without the config file self.wf_6 = wf_nudged_elastic_band(self.structures, parent)
def test_get_mapping(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=False, allow_subset = True) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Ag', 'Si', 'Si'], [[.7,.4,.5],[0,0,0.1],[0,0,0.2]]) s1.make_supercell([2,1,1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0,0.1,-0.95],[0,0.1,0],[-.7,.5,.375]]) shuffle = [2,0,1,3,5,4] s1 = Structure.from_sites([s1[i] for i in shuffle]) #test the mapping s2.make_supercell([2,1,1]) #equal sizes for i, x in enumerate(sm.get_mapping(s1, s2)): self.assertEqual(s1[x].species_and_occu, s2[i].species_and_occu) del s1[0] #s1 is subset of s2 for i, x in enumerate(sm.get_mapping(s2, s1)): self.assertEqual(s1[i].species_and_occu, s2[x].species_and_occu) #s2 is smaller than s1 del s2[0] del s2[1] self.assertRaises(ValueError, sm.get_mapping, s2, s1)
def test_get_s2_like_s1(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0,0,0.1],[0,0,0.2],[.7,.4,.5]]) s1.make_supercell([2,1,1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0,0.1,0],[0,0.1,-0.95],[-.7,.5,.375]]) result = sm.get_s2_like_s1(s1, s2) self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords, [0.35,0.4,0.5])), 1) self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords, [0,0,0.125])), 1) self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords, [0,0,0.175])), 1)
def test_electronegativity(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5) s1 = Structure.from_file(os.path.join(test_dir, "Na2Fe2PAsO4S4.json")) s2 = Structure.from_file(os.path.join(test_dir, "Na2Fe2PNO4Se4.json")) self.assertEqual(sm.get_best_electronegativity_anonymous_mapping(s1, s2), {Element('S'): Element('Se'), Element('As'): Element('N'), Element('Fe'): Element('Fe'), Element('Na'): Element('Na'), Element('P'): Element('P'), Element('O'): Element('O'),}) self.assertEqual(len(sm.get_all_anonymous_mappings(s1, s2)), 2) # test include_dist dists = {Element('N'): 0, Element('P'): 0.0010725064} for mapping, d in sm.get_all_anonymous_mappings(s1, s2, include_dist=True): self.assertAlmostEqual(dists[mapping[Element('As')]], d)
def setUp(self): filepath = os.path.join(test_dir, 'Li.cif') self.s = Structure.from_file(filepath) self.bulk = MVLGBSet(self.s) self.slab = MVLGBSet(self.s, slab_mode=True) self.d_bulk = self.bulk.all_input self.d_slab = self.slab.all_input
def setUp(self): filepath = self.TEST_FILES_DIR / 'Li.cif' self.s = Structure.from_file(filepath) self.bulk = MVLGBSet(self.s) self.slab = MVLGBSet(self.s, slab_mode=True) self.d_bulk = self.bulk.get_vasp_input() self.d_slab = self.slab.get_vasp_input() warnings.simplefilter("ignore")
def test_get_s2_large_s2(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=False, attempt_supercell=True, allow_subset=False, supercell_size='volume') l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Ag', 'Si', 'Si'], [[.7,.4,.5],[0,0,0.1],[0,0,0.2]]) l2 = Lattice.orthorhombic(1.01, 2.01, 3.01) s2 = Structure(l2, ['Si', 'Si', 'Ag'], [[0,0.1,-0.95],[0,0.1,0],[-.7,.5,.375]]) s2.make_supercell([[0,-1,0],[1,0,0],[0,0,1]]) result = sm.get_s2_like_s1(s1, s2) for x,y in zip(s1, result): self.assertLess(x.distance(y), 0.08)
def handle_subcommand_test_relax(args): default_commands = { 'lammps': 'lammps' } command = args.command if args.command else default_commands.get(args.software) predict = Predict(calculator=args.software, command=command, num_workers=1) potential = Potential.from_file(args.potential) structure = get_structure(args.structure) import warnings warnings.filterwarnings("ignore") # yes I have sinned sga = SpacegroupAnalyzer(structure) conventional_structure = sga.get_conventional_standard_structure() old_lattice, new_lattice = predict.lattice_constant(conventional_structure, potential) equilibrium_structure = Structure( new_lattice, [s.specie.element for s in conventional_structure.sites], [s.frac_coords for s in conventional_structure.sites]) equilibrium_structure.to(filename=args.output_filename)
def handle_input_event(self, abiinput, outdir, event): try: old_abiinput = abiinput.deepcopy() # Read the last structure dumped by ABINIT before aborting. filepath = outdir.has_abiext("DILATMX_STRUCT.nc") last_structure = Structure.from_file(filepath) abiinput.set_structure(last_structure) return Correction(self, self.compare_inputs(abiinput, old_abiinput), event, False) except Exception as exc: logger.warning('Error while trying to apply the handler {}.'.format(str(self)), exc) return None
def test_metal_check(self): structure = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3), ["Cu"], [[0, 0, 0]]) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") # Trigger a warning. vis = MITRelaxSet(structure) incar = vis.incar # Verify some things self.assertIn("ISMEAR", str(w[-1].message))
def test_mix(self): structures = [self.get_structure("Li2O"), self.get_structure("Li2O2"), self.get_structure("LiFePO4")] for fname in ["POSCAR.Li2O", "POSCAR.LiFePO4"]: structures.append(Structure.from_file(os.path.join(test_dir, fname))) sm = StructureMatcher(comparator=ElementComparator()) groups = sm.group_structures(structures) for g in groups: formula = g[0].composition.reduced_formula if formula in ["Li2O", "LiFePO4"]: self.assertEqual(len(g), 2) else: self.assertEqual(len(g), 1)
def test_get_supercell_matrix(self): sm = StructureMatcher(ltol=0.1, stol=0.3, angle_tol=2, primitive_cell=False, scale=True, attempt_supercell=True) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ["Si", "Si", "Ag"], [[0, 0, 0.1], [0, 0, 0.2], [0.7, 0.4, 0.5]]) s1.make_supercell([2, 1, 1]) s2 = Structure(l, ["Si", "Si", "Ag"], [[0, 0.1, 0], [0, 0.1, -0.95], [-0.7, 0.5, 0.375]]) result = sm.get_supercell_matrix(s1, s2) self.assertTrue((result == [[-2, 0, 0], [0, 1, 0], [0, 0, 1]]).all()) s1 = Structure(l, ["Si", "Si", "Ag"], [[0, 0, 0.1], [0, 0, 0.2], [0.7, 0.4, 0.5]]) s1.make_supercell([[1, -1, 0], [0, 0, -1], [0, 1, 0]]) s2 = Structure(l, ["Si", "Si", "Ag"], [[0, 0.1, 0], [0, 0.1, -0.95], [-0.7, 0.5, 0.375]]) result = sm.get_supercell_matrix(s1, s2) self.assertTrue((result == [[-1, -1, 0], [0, 0, -1], [0, 1, 0]]).all()) # test when the supercell is a subset sm = StructureMatcher( ltol=0.1, stol=0.3, angle_tol=2, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True ) del s1[0] result = sm.get_supercell_matrix(s1, s2) self.assertTrue((result == [[-1, -1, 0], [0, 0, -1], [0, 1, 0]]).all())
def test_ordering_enumeration(self): # simple afm structure = Structure.from_file( os.path.join(test_dir, "magnetic_orderings/LaMnO3.json")) enumerator = MagneticStructureEnumerator(structure) self.assertEqual(enumerator.input_origin, "afm") # ferrimagnetic (Cr produces net spin) structure = Structure.from_file( os.path.join(test_dir, "magnetic_orderings/Cr2NiO4.json")) enumerator = MagneticStructureEnumerator(structure) self.assertEqual(enumerator.input_origin, "ferri_by_Cr") # antiferromagnetic on single magnetic site structure = Structure.from_file( os.path.join(test_dir, "magnetic_orderings/Cr2WO6.json")) enumerator = MagneticStructureEnumerator(structure) self.assertEqual(enumerator.input_origin, "afm_by_Cr") # afm requiring large cell size # (enable for further development of workflow, too slow for CI) # structure = Structure.from_file(os.path.join(ref_dir, "CuO.json")) # enumerator = MagneticOrderingsenumerator(structure, default_magmoms={'Cu': 1.73}, # transformation_kwargs={'max_cell_size': 4}) # self.assertEqual(enumerator.input_origin, "afm") # antiferromagnetic by structural motif structure = Structure.from_file( os.path.join(test_dir, "magnetic_orderings/Ca3Co2O6.json")) enumerator = MagneticStructureEnumerator( structure, strategies=("antiferromagnetic_by_motif",), # this example just misses default cut-off, so do not truncate truncate_by_symmetry=False, transformation_kwargs={"max_cell_size": 2}, ) self.assertEqual(enumerator.input_origin, "afm_by_motif_2a")
def run_task(self, fw_spec): user_incar_settings = self.get("user_incar_settings", {}) user_kpoints_settings = self.get("user_kpoints_settings", {}) neb_label = self.get("neb_label") assert neb_label.isdigit() and int(neb_label) >= 1 images = fw_spec["neb"][int(neb_label) - 1] try: images = [Structure.from_dict(i) for i in images] except: images = images vis = MVLCINEBSet(images, user_incar_settings=user_incar_settings, user_kpoints_settings=user_kpoints_settings) vis.write_input(".")
def substrate(self) -> Structure: """ A pymatgen Structure for just the substrate """ return Structure.from_sites(self.substrate_sites)
# load data cif_path = path.normpath(path.join(getcwd(), args.cif_data)) cif_data = h5py.File(cif_path, "r") battery_table = pd.read_csv(args.battery_data, index_col=False) element_data = ElementDataSingleton.get_instance( element_data_path=args.element_data) # create features features = np.zeros((len(battery_table), NUM_OF_FEATURE)) for i, (id_charge, id_discharge, ion) in tqdm( enumerate( zip(battery_table['id_charge'], battery_table['id_discharge'], battery_table['working_ion']))): # load crystal object from cif charge_crystal = Structure.from_str(cif_data[id_charge].value, 'cif') discharge_crystal = Structure.from_str(cif_data[id_discharge].value, 'cif') # specific features finder = SpacegroupAnalyzer(charge_crystal) space_group_feat = np.array([finder.get_space_group_number()]) crystal_system_feat = create_feature_from_crystal_system( finder.get_crystal_system()) ion_feat = create_feature_from_wokring_ion(ion) dischr_comp = Composition(discharge_crystal.formula) ion_concentrate = np.array( [dischr_comp.get_atomic_fraction(Element(ion))]) # calculate features from element property charge_formula = charge_crystal.formula
class CollinearMagneticStructureAnalyzerTest(unittest.TestCase): def setUp(self): parser = CifParser(os.path.join(test_dir, 'Fe.cif')) self.Fe = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'LiFePO4.cif')) self.LiFePO4 = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'Fe3O4.cif')) self.Fe3O4 = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'magnetic.ncl.example.GdB4.mcif')) self.GdB4 = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'magnetic.example.NiO.mcif')) self.NiO_expt = parser.get_structures()[0] latt = Lattice.cubic(4.17) species = ["Ni", "O"] coords = [[0, 0, 0], [0.5, 0.5, 0.5]] self.NiO = Structure.from_spacegroup(225, latt, species, coords) latt = Lattice([[2.085, 2.085, 0.0], [0.0, -2.085, -2.085], [-2.085, 2.085, -4.17]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0, 0.5], [0, 0, 0], [0.25, 0.5, 0.25], [0.75, 0.5, 0.75]] self.NiO_AFM_111 = Structure(latt, species, coords, site_properties={'magmom': [-5, 5, 0, 0]}) latt = Lattice([[2.085, 2.085, 0], [0, 0, -4.17], [-2.085, 2.085, 0]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0.5, 0.5], [0, 0, 0], [0, 0.5, 0], [0.5, 0, 0.5]] self.NiO_AFM_001 = Structure(latt, species, coords, site_properties={'magmom': [-5, 5, 0, 0]}) latt = Lattice([[2.085, 2.085, 0], [0, 0, -4.17], [-2.085, 2.085, 0]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0.5, 0.5], [0, 0, 0], [0, 0.5, 0], [0.5, 0, 0.5]] self.NiO_AFM_001_opposite = Structure(latt, species, coords, site_properties={'magmom': [5, -5, 0, 0]}) latt = Lattice([[2.085, 2.085, 0], [0, 0, -4.17], [-2.085, 2.085, 0]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0.5, 0.5], [0, 0, 0], [0, 0.5, 0], [0.5, 0, 0.5]] self.NiO_unphysical = Structure(latt, species, coords, site_properties={'magmom': [-3, 0, 0, 0]}) warnings.simplefilter("ignore") def tearDown(self): warnings.simplefilter("default") def test_get_representations(self): # tests to convert between storing magnetic moment information # on site_properties or on Species 'spin' property # test we store magnetic moments on site properties self.Fe.add_site_property('magmom', [5]) msa = CollinearMagneticStructureAnalyzer(self.Fe) self.assertEqual(msa.structure.site_properties['magmom'][0], 5) # and that we can retrieve a spin representaiton Fe_spin = msa.get_structure_with_spin() self.assertFalse('magmom' in Fe_spin.site_properties) self.assertEqual(Fe_spin[0].specie.spin, 5) # test we can remove magnetic moment information Fe_none = msa.get_nonmagnetic_structure() self.assertFalse('magmom' in Fe_spin.site_properties) # test with disorder on magnetic site self.Fe[0] = {Species('Fe', oxidation_state=0, properties={'spin': 5}): 0.5, 'Ni': 0.5} self.assertRaises(NotImplementedError, CollinearMagneticStructureAnalyzer, self.Fe) def test_matches(self): self.assertTrue(self.NiO.matches(self.NiO_AFM_111)) self.assertTrue(self.NiO.matches(self.NiO_AFM_001)) # MSA adds magmoms to Structure, so not equal msa = CollinearMagneticStructureAnalyzer(self.NiO, overwrite_magmom_mode="replace_all") self.assertFalse(msa.matches_ordering(self.NiO)) self.assertFalse(msa.matches_ordering(self.NiO_AFM_111)) self.assertFalse(msa.matches_ordering(self.NiO_AFM_001)) msa = CollinearMagneticStructureAnalyzer(self.NiO_AFM_001, overwrite_magmom_mode="respect_sign") self.assertFalse(msa.matches_ordering(self.NiO)) self.assertFalse(msa.matches_ordering(self.NiO_AFM_111)) self.assertTrue(msa.matches_ordering(self.NiO_AFM_001)) self.assertTrue(msa.matches_ordering(self.NiO_AFM_001_opposite)) msa = CollinearMagneticStructureAnalyzer(self.NiO_AFM_111, overwrite_magmom_mode="respect_sign") self.assertFalse(msa.matches_ordering(self.NiO)) self.assertTrue(msa.matches_ordering(self.NiO_AFM_111)) self.assertFalse(msa.matches_ordering(self.NiO_AFM_001)) self.assertFalse(msa.matches_ordering(self.NiO_AFM_001_opposite)) def test_modes(self): mode = "none" msa = CollinearMagneticStructureAnalyzer(self.NiO, overwrite_magmom_mode=mode) magmoms = msa.structure.site_properties['magmom'] self.assertEqual(magmoms, [0, 0]) mode = "respect_sign" msa = CollinearMagneticStructureAnalyzer(self.NiO_unphysical, overwrite_magmom_mode=mode) magmoms = msa.structure.site_properties['magmom'] self.assertEqual(magmoms, [-5, 0, 0, 0]) mode = "respect_zeros" msa = CollinearMagneticStructureAnalyzer(self.NiO_unphysical, overwrite_magmom_mode=mode) magmoms = msa.structure.site_properties['magmom'] self.assertEqual(magmoms, [5, 0, 0, 0]) mode = "replace_all" msa = CollinearMagneticStructureAnalyzer(self.NiO_unphysical, overwrite_magmom_mode=mode, make_primitive=False) magmoms = msa.structure.site_properties['magmom'] self.assertEqual(magmoms, [5, 5, 0, 0]) mode = "replace_all_if_undefined" msa = CollinearMagneticStructureAnalyzer(self.NiO, overwrite_magmom_mode=mode) magmoms = msa.structure.site_properties['magmom'] self.assertEqual(magmoms, [5, 0]) mode = "normalize" msa = CollinearMagneticStructureAnalyzer(msa.structure, overwrite_magmom_mode='normalize') magmoms = msa.structure.site_properties['magmom'] self.assertEqual(magmoms, [1, 0]) def test_net_positive(self): msa = CollinearMagneticStructureAnalyzer(self.NiO_unphysical) magmoms = msa.structure.site_properties['magmom'] self.assertEqual(magmoms, [3, 0, 0, 0]) def test_get_ferromagnetic_structure(self): msa = CollinearMagneticStructureAnalyzer(self.NiO, overwrite_magmom_mode="replace_all_if_undefined") s1 = msa.get_ferromagnetic_structure() s1_magmoms = [float(m) for m in s1.site_properties['magmom']] s1_magmoms_ref = [5.0, 0.0] self.assertListEqual(s1_magmoms, s1_magmoms_ref) msa2 = CollinearMagneticStructureAnalyzer(self.NiO_AFM_111, overwrite_magmom_mode="replace_all_if_undefined") s2 = msa.get_ferromagnetic_structure(make_primitive=False) s2_magmoms = [float(m) for m in s2.site_properties['magmom']] s2_magmoms_ref = [5.0, 0.0] self.assertListEqual(s2_magmoms, s2_magmoms_ref) s2_prim = msa.get_ferromagnetic_structure(make_primitive=True) self.assertTrue(CollinearMagneticStructureAnalyzer(s1).matches_ordering(s2_prim)) def test_magnetic_properties(self): msa = CollinearMagneticStructureAnalyzer(self.GdB4) self.assertFalse(msa.is_collinear) msa = CollinearMagneticStructureAnalyzer(self.Fe) self.assertFalse(msa.is_magnetic) self.Fe.add_site_property('magmom', [5]) msa = CollinearMagneticStructureAnalyzer(self.Fe) self.assertTrue(msa.is_magnetic) self.assertTrue(msa.is_collinear) self.assertEqual(msa.ordering, Ordering.FM) msa = CollinearMagneticStructureAnalyzer(self.NiO, make_primitive=False, overwrite_magmom_mode="replace_all_if_undefined") self.assertEqual(msa.number_of_magnetic_sites, 4) self.assertEqual(msa.number_of_unique_magnetic_sites(), 1) self.assertEqual(msa.types_of_magnetic_species, (Element.Ni,)) self.assertEqual(msa.get_exchange_group_info(), ('Fm-3m', 225)) def test_str(self): msa = CollinearMagneticStructureAnalyzer(self.NiO_AFM_001) ref_msa_str = """Structure Summary Lattice abc : 2.948635277547903 4.17 2.948635277547903 angles : 90.0 90.0 90.0 volume : 36.2558565 A : 2.085 2.085 0.0 B : 0.0 0.0 -4.17 C : -2.085 2.085 0.0 Magmoms Sites +5.00 PeriodicSite: Ni (0.0000, 0.0000, 0.0000) [0.0000, 0.0000, 0.0000] PeriodicSite: O (0.0000, 0.0000, -2.0850) [0.0000, 0.5000, 0.0000] PeriodicSite: O (0.0000, 2.0850, 0.0000) [0.5000, 0.0000, 0.5000] -5.00 PeriodicSite: Ni (0.0000, 2.0850, -2.0850) [0.5000, 0.5000, 0.5000]""" # just compare lines form 'Magmoms Sites', # since lattice param string can vary based on machine precision self.assertEqual("\n".join(str(msa).split("\n")[-5:-1]), "\n".join(ref_msa_str.split("\n")[-5:-1])) def test_round_magmoms(self): struct = self.NiO_AFM_001.copy() struct.add_site_property('magmom', [-5.0143, -5.02, 0.147, 0.146]) msa = CollinearMagneticStructureAnalyzer(struct, round_magmoms=0.001, make_primitive=False) self.assertTrue(np.allclose(msa.magmoms, [5.0171, 5.0171, -0.1465, -0.1465])) self.assertAlmostEqual(msa.magnetic_species_and_magmoms['Ni'], 5.0171) self.assertAlmostEqual(msa.magnetic_species_and_magmoms['O'], 0.1465) struct.add_site_property('magmom', [-5.0143, 4.5, 0.147, 0.146]) msa = CollinearMagneticStructureAnalyzer(struct, round_magmoms=0.001, make_primitive=False) self.assertTrue(np.allclose(msa.magmoms, [5.0143, -4.5, -0.1465, -0.1465])) self.assertAlmostEqual(msa.magnetic_species_and_magmoms['Ni'][0], 4.5) self.assertAlmostEqual(msa.magnetic_species_and_magmoms['Ni'][1], 5.0143) self.assertAlmostEqual(msa.magnetic_species_and_magmoms['O'], 0.1465)
def setUp(self): parser = CifParser(os.path.join(test_dir, 'Fe.cif')) self.Fe = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'LiFePO4.cif')) self.LiFePO4 = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'Fe3O4.cif')) self.Fe3O4 = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'magnetic.ncl.example.GdB4.mcif')) self.GdB4 = parser.get_structures()[0] parser = CifParser(os.path.join(test_dir, 'magnetic.example.NiO.mcif')) self.NiO_expt = parser.get_structures()[0] latt = Lattice.cubic(4.17) species = ["Ni", "O"] coords = [[0, 0, 0], [0.5, 0.5, 0.5]] self.NiO = Structure.from_spacegroup(225, latt, species, coords) latt = Lattice([[2.085, 2.085, 0.0], [0.0, -2.085, -2.085], [-2.085, 2.085, -4.17]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0, 0.5], [0, 0, 0], [0.25, 0.5, 0.25], [0.75, 0.5, 0.75]] self.NiO_AFM_111 = Structure(latt, species, coords, site_properties={'magmom': [-5, 5, 0, 0]}) latt = Lattice([[2.085, 2.085, 0], [0, 0, -4.17], [-2.085, 2.085, 0]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0.5, 0.5], [0, 0, 0], [0, 0.5, 0], [0.5, 0, 0.5]] self.NiO_AFM_001 = Structure(latt, species, coords, site_properties={'magmom': [-5, 5, 0, 0]}) latt = Lattice([[2.085, 2.085, 0], [0, 0, -4.17], [-2.085, 2.085, 0]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0.5, 0.5], [0, 0, 0], [0, 0.5, 0], [0.5, 0, 0.5]] self.NiO_AFM_001_opposite = Structure(latt, species, coords, site_properties={'magmom': [5, -5, 0, 0]}) latt = Lattice([[2.085, 2.085, 0], [0, 0, -4.17], [-2.085, 2.085, 0]]) species = ["Ni", "Ni", "O", "O"] coords = [[0.5, 0.5, 0.5], [0, 0, 0], [0, 0.5, 0], [0.5, 0, 0.5]] self.NiO_unphysical = Structure(latt, species, coords, site_properties={'magmom': [-3, 0, 0, 0]}) warnings.simplefilter("ignore")
return {"-".join(sorted(c)) for c in [elements, elements - {self.working_ion}]} def _mat_doc2comp_entry(self, docs, store_struct=True): def get_prim_host(struct): """ Get the primitive structure with all of the lithiums removed """ structure = struct.copy() structure.remove_species([self.working_ion]) prim = PrimitiveCellTransformation() return prim.apply_transformation(structure) entries = [] for d in docs: <<<<<<< HEAD struct = Structure.from_dict(d["structure"]) en = ComputedStructureEntry( structure=struct, energy=d["thermo"]["energy"], parameters=d["calc_settings"], entry_id=d["task_id"], ) if "_sbxn" in d: en.data["_sbxn"] = d["_sbxn"] else: en.data["_sbxn"] = ["core"] ======= struct = Structure.from_dict(d['structure']) en = ComputedStructureEntry(structure=struct, energy=d['thermo']['energy'], parameters=d['calc_settings'],
def _structure(self): # avoid overlapping structure for e.g., phonon forces. if self.args.prev_dir and self.task.fine_to_inherit_structure_from_prev: return Structure.from_file(self.args.prev_dir / defaults.contcar) return Structure.from_file(self.args.poscar)
def film(self) -> Structure: """ A pymatgen Structure for just the film """ return Structure.from_sites(self.film_sites)