def test_slice(self): sliced_traj = self.traj[2:99:3] sliced_traj_from_structs = Trajectory.from_structures( self.structures[2:99:3]) if len(sliced_traj) == len(sliced_traj_from_structs): self.assertTrue( all([ sliced_traj[i] == sliced_traj_from_structs[i] for i in range(len(sliced_traj)) ])) else: self.assertTrue(False) sliced_traj = self.traj[:-4:2] sliced_traj_from_structs = Trajectory.from_structures( self.structures[:-4:2]) if len(sliced_traj) == len(sliced_traj_from_structs): self.assertTrue( all([ sliced_traj[i] == sliced_traj_from_structs[i] for i in range(len(sliced_traj)) ])) else: self.assertTrue(False)
def test_extend_equivalent_site_props(self): lattice = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] species = ["Si", "Si"] frac_coords = [ [[0, 0, 0], [0.5, 0.5, 0.5]], [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6]], [[0.2, 0.2, 0.2], [0.7, 0.7, 0.7]], ] # Trajectories with constant site properties site_properties_1 = [ { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], } ] traj_1 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_1) site_properties_2 = [ { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], } ] traj_2 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_2) # Test combining two trajectories with similar site_properties traj_combined = traj_1.copy() traj_combined.extend(traj_2) self.assertEqual(traj_combined.site_properties, site_properties_1)
def test_extend(self): traj = self.traj.copy() # Case of compatible trajectories compatible_traj = Trajectory.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "Traj_Combine_Test_XDATCAR_1")) traj.extend(compatible_traj) full_traj = Trajectory.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "Traj_Combine_Test_XDATCAR_Full")) compatible_success = self._check_traj_equality(self.traj, full_traj) # Case of incompatible trajectories traj = self.traj.copy() incompatible_traj = Trajectory.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "Traj_Combine_Test_XDATCAR_2")) incompatible_test_success = False try: traj.extend(incompatible_traj) except Exception: incompatible_test_success = True self.assertTrue(compatible_success and incompatible_test_success)
def test_variable_lattice(self): structure = self.structures[0] # Generate structures with different lattices structures = [] for i in range(10): new_lattice = np.dot(structure.lattice.matrix, np.diag(1 + np.random.random_sample(3) / 20)) temp_struct = structure.copy() temp_struct.lattice = Lattice(new_lattice) structures.append(temp_struct) traj = Trajectory.from_structures(structures, constant_lattice=False) # Check if lattices were properly stored self.assertTrue( all( np.allclose(struct.lattice.matrix, structures[i].lattice.matrix) for i, struct in enumerate(traj))) # Check if the file is written correctly when lattice is not constant. traj.write_Xdatcar(filename="traj_test_XDATCAR") # Load trajectory from written xdatcar and compare to original written_traj = Trajectory.from_file("traj_test_XDATCAR", constant_lattice=False) self._check_traj_equality(traj, written_traj) os.remove("traj_test_XDATCAR")
def load_trajectories_from_gfs(runs, db_file): fs_id = [] fs = [] for run in runs: if "INCAR" in run.keys(): # for backwards compatibility with older version of mpmorph fs_id.append(run["ionic_steps_fs_id"]) fs.append('previous_runs_gfs') elif "input" in run.keys(): fs_id.append( run["calcs_reversed"][0]["output"]["ionic_steps_fs_id"]) fs.append('structures_fs') for i, v in enumerate(fs_id): mmdb = VaspMDCalcDb.from_db_file(db_file, admin=True) ionic_steps_dict = load_ionic_steps(v, mmdb.db, fs[i]) if i == 0: trajectory = Trajectory.from_structures([ Structure.from_dict(i['structure']) for i in ionic_steps_dict ]) else: trajectory.extend( Trajectory.from_structures([ Structure.from_dict(i['structure']) for i in ionic_steps_dict ])) return trajectory
def process_traj(data): i, fs_id, fs, db_file = data[0], data[1], data[2], data[3] mmdb = VaspMDCalcDb.from_db_file(db_file, admin=True) ionic_steps_dict = load_ionic_steps(fs_id, mmdb.db, fs) structure = Structure.from_dict(ionic_steps_dict[0]['structure']) positions = [0] * len(ionic_steps_dict) for i, step in enumerate(ionic_steps_dict): _step = [atom['abc'] for atom in step["structure"]["sites"]] positions[i] = _step traj = Trajectory(structure.lattice.matrix, structure.species, positions, 0.002) return i, traj.as_dict()
def test_extend_no_frame_props(self): lattice = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] species = ['Si', 'Si'] frac_coords = [[[0, 0, 0], [0.5, 0.5, 0.5]], [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6]], [[0.2, 0.2, 0.2], [0.7, 0.7, 0.7]]] # Trajectory with no site_properties traj_1 = Trajectory(lattice, species, frac_coords) traj_2 = Trajectory(lattice, species, frac_coords) # Test combining two trajectories with no site properties traj_combined = traj_1.copy() traj_combined.extend(traj_2) self.assertEqual(traj_combined.frame_properties, None)
def test_xdatcar_write(self): self.traj.write_Xdatcar(filename="traj_test_XDATCAR") # Load trajectory from written xdatcar and compare to original written_traj = Trajectory.from_file(os.path.join("./", "traj_test_XDATCAR")) self._check_traj_equality(self.traj, written_traj)
def test_site_properties(self): lattice = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] species = ["Si", "Si"] frac_coords = [ [[0, 0, 0], [0.5, 0.5, 0.5]], [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6]], [[0.2, 0.2, 0.2], [0.7, 0.7, 0.7]], ] site_properties = [ { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[False, False, False], [False, False, False]], "magmom": [6, 6], }, { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], }, ] traj = Trajectory(lattice, species, frac_coords, site_properties=site_properties) # compare the overall site properties list self.assertEqual(traj.site_properties, site_properties) # # compare the site properties after slicing self.assertEqual(traj[0].site_properties, site_properties[0]) self.assertEqual(traj[1:].site_properties, site_properties[1:])
def test_frame_properties(self): lattice = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] species = ['Si', 'Si'] frac_coords = [[[0, 0, 0], [0.5, 0.5, 0.5]], [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6]], [[0.2, 0.2, 0.2], [0.7, 0.7, 0.7]]] site_properties = [{ 'selective_dynamics': [[True, True, True], [False, False, False]], 'magmom': [5, 5] }, { 'selective_dynamics': [[False, False, False], [False, False, False]], 'magmom': [6, 6] }, { 'selective_dynamics': [[True, True, True], [False, False, False]], 'magmom': [5, 5] }] frame_properties = {'energy_per_atom': [-3.0001, -3.0971, -3.0465]} traj = Trajectory(lattice, species, frac_coords, site_properties=site_properties, frame_properties=frame_properties) # compare the overall site properties list self.assertEqual(traj.frame_properties, frame_properties) # compare the site properties after slicing expected_output = {'energy_per_atom': [-3.0971, -3.0465]} self.assertEqual(traj[1:].frame_properties, expected_output)
def get_pymatgen_trajectory(self, include_shell=False): table = self.get_structure_table(input=True, include_shell=include_shell) lattices, constant_lattice = self.get_md_cell() frames = [x[table.index] for x in self.get_md_coords()] time = self.get_step_props()["time"] time_step = time[1] - time[0] species_labels = self.get_species_labels() symbols = table["label"].map(species_labels).values.tolist() structures = [ Structure( lattice=lattice, species=symbols, coords=coords, coords_are_cartesian=True, site_properties={"gulp_labels": table["label"]}, ) for lattice, coords in zip(lattices, frames) ] return Trajectory.from_structures(structures, time_step=time_step, constant_lattice=constant_lattice)
def calcs_reversed_to_trajectory(calcs_reversed: List[dict]): """ Converts data from calc_reversed to pymatgen Trajectory objects that contain structure, energy, force and stress data for each ionic step. Args: calcs_reversed: List of dictionaries in calcs_reversed entry of a task document. """ trajectories = [] for calculation in calcs_reversed: for step in calculation["output"]["ionic_steps"]: structures = [] frame_props = defaultdict(list) # type: dict structures.append(Structure.from_dict(step["structure"])) frame_props["e_fr_energy"].append(step["e_fr_energy"]) frame_props["e_wo_entrp"].append(step["e_wo_entrp"]) frame_props["e_0_energy"].append(step["e_wo_entrp"]) frame_props["forces"].append(step["forces"]) frame_props["stresses"].append(step["stress"]) traj = Trajectory.from_structures(structures, frame_properties=frame_props, time_step=None).as_dict() trajectories.append(traj) return trajectories
def test_list_slice(self): sliced_traj = self.traj[[10, 30, 70]] sliced_traj_from_structs = Trajectory.from_structures([self.structures[i] for i in [10, 30, 70]]) if len(sliced_traj) == len(sliced_traj_from_structs): self.assertTrue(all([sliced_traj[i] == sliced_traj_from_structs[i] for i in range(len(sliced_traj))])) else: self.assertTrue(False)
def test_slice(self): sliced_traj = self.traj[2:99:3] sliced_traj_from_structs = Trajectory.from_structures(self.structures[2:99:3]) if len(sliced_traj) == len(sliced_traj_from_structs): self.assertTrue(all([sliced_traj[i] == sliced_traj_from_structs[i] for i in range(len(sliced_traj))])) else: self.assertTrue(False)
def test_extend(self): traj = self.traj.copy() # Case of compatible trajectories compatible_traj = Trajectory.from_file(os.path.join(test_dir, "Traj_Combine_Test_XDATCAR_1")) traj.extend(compatible_traj) full_traj = Trajectory.from_file(os.path.join(test_dir, "Traj_Combine_Test_XDATCAR_Full")) compatible_success = self._check_traj_equality(self.traj, full_traj) # Case of incompatible trajectories traj = self.traj.copy() incompatible_traj = Trajectory.from_file(os.path.join(test_dir, "Traj_Combine_Test_XDATCAR_2")) incompatible_test_success=False try: traj.extend(incompatible_traj) except: incompatible_test_success=True self.assertTrue(compatible_success and incompatible_test_success)
def test_extend_frame_props(self): lattice = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] species = ["Si", "Si"] frac_coords = [ [[0, 0, 0], [0.5, 0.5, 0.5]], [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6]], [[0.2, 0.2, 0.2], [0.7, 0.7, 0.7]], ] # Trajectories with constant site properties frame_properties_1 = {"energy": [-3, -3.9, -4.1]} traj_1 = Trajectory(lattice, species, frac_coords, frame_properties=frame_properties_1) frame_properties_2 = {"energy": [-4.2, -4.25, -4.3]} traj_2 = Trajectory(lattice, species, frac_coords, frame_properties=frame_properties_2) # Test combining two trajectories with similar site_properties traj_combined = traj_1.copy() traj_combined.extend(traj_2) expected_frame_properties = {"energy": [-3, -3.9, -4.1, -4.2, -4.25, -4.3]} self.assertEqual(traj_combined.frame_properties, expected_frame_properties) # Mismatched frame propertied frame_properties_3 = {"energy": [-4.2, -4.25, -4.3], "pressure": [2, 2.5, 2.5]} traj_3 = Trajectory(lattice, species, frac_coords, frame_properties=frame_properties_3) traj_combined = traj_1.copy() traj_combined.extend(traj_3) expected_frame_properties = { "energy": [-3, -3.9, -4.1, -4.2, -4.25, -4.3], "pressure": [None, None, None, 2, 2.5, 2.5], } self.assertEqual(traj_combined.frame_properties, expected_frame_properties)
def test_displacements(self): poscar = Poscar.from_file(os.path.join(test_dir, "POSCAR")) structures = [poscar.structure] displacements = np.zeros((11, *np.shape(structures[-1].frac_coords))) for i in range(10): displacement = np.random.random_sample(np.shape(structures[-1].frac_coords)) / 20 new_coords = displacement + structures[-1].frac_coords structures.append(Structure(structures[-1].lattice, structures[-1].species, new_coords)) displacements[i+1, :, :] = displacement traj = Trajectory.from_structures(structures, constant_lattice=True) traj.to_displacements() self.assertTrue(np.allclose(traj.frac_coords, displacements))
def test_displacements(self): poscar = Poscar.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "POSCAR")) structures = [poscar.structure] displacements = np.zeros((11, *np.shape(structures[-1].frac_coords))) for i in range(10): displacement = np.random.random_sample(np.shape(structures[-1].frac_coords)) / 20 new_coords = displacement + structures[-1].frac_coords structures.append(Structure(structures[-1].lattice, structures[-1].species, new_coords)) displacements[i + 1, :, :] = displacement traj = Trajectory.from_structures(structures, constant_lattice=True) traj.to_displacements() self.assertTrue(np.allclose(traj.frac_coords, displacements))
def test_changing_lattice(self): structure = self.structures[0] # Generate structures with different lattices structures = [] for i in range(10): new_lattice = np.dot(structure.lattice.matrix, np.diag(1 + np.random.random_sample(3)/20)) temp_struct = structure.copy() temp_struct.modify_lattice(Lattice(new_lattice)) structures.append(temp_struct) traj = Trajectory.from_structures(structures, constant_lattice=False) # Check if lattices were properly stored self.assertTrue( all([np.allclose(struct.lattice.matrix, structures[i].lattice.matrix) for i, struct in enumerate(traj)]))
def setUp(self): xdatcar = Xdatcar(os.path.join(test_dir, "Traj_XDATCAR")) self.traj = Trajectory.from_file(os.path.join(test_dir, "Traj_XDATCAR")) self.structures = xdatcar.structures
def test_to_from_dict(self): d = self.traj.as_dict() traj = Trajectory.from_dict(d) self.assertEqual(type(traj), Trajectory)
def insert_task(self, task_doc, parse_dos=False, parse_bs=False, md_structures=False): """ Inserts a task document (e.g., as returned by Drone.assimilate()) into the database. Handles putting DOS and band structure into GridFS as needed. Args: task_doc: (dict) the task document parse_dos: (bool) attempt to parse dos in task_doc and insert into Gridfs parse_bs: (bool) attempt to parse bandstructure in task_doc and insert into Gridfs Returns: (int) - task_id of inserted document """ # insert dos into GridFS if parse_dos and "calcs_reversed" in task_doc: if "dos" in task_doc["calcs_reversed"][0]: # only store idx=0 DOS dos = json.dumps(task_doc["calcs_reversed"][0]["dos"], cls=MontyEncoder) gfs_id, compression_type = self.insert_gridfs(dos, "dos_fs") task_doc["calcs_reversed"][0][ "dos_compression"] = compression_type task_doc["calcs_reversed"][0]["dos_fs_id"] = gfs_id del task_doc["calcs_reversed"][0]["dos"] # insert band structure into GridFS if parse_bs and "calcs_reversed" in task_doc: if "bandstructure" in task_doc["calcs_reversed"][ 0]: # only store idx=0 BS bs = json.dumps(task_doc["calcs_reversed"][0]["bandstructure"], cls=MontyEncoder) gfs_id, compression_type = self.insert_gridfs( bs, "bandstructure_fs") task_doc["calcs_reversed"][0][ "bandstructure_compression"] = compression_type task_doc["calcs_reversed"][0]["bandstructure_fs_id"] = gfs_id del task_doc["calcs_reversed"][0]["bandstructure"] # insert structures at each ionic step into GridFS if md_structures and "calcs_reversed" in task_doc: # insert ionic steps into gridfs #TODO: Depricate this and move to only storing trajectory ionic_steps_json = json.dumps( task_doc["calcs_reversed"][0]['output']['ionic_steps'], cls=MontyEncoder) gfs_id, compression_type = self.insert_gridfs( ionic_steps_json, "structures_fs") task_doc["calcs_reversed"][0]['output'][ 'ionic_steps_compression'] = compression_type task_doc["calcs_reversed"][0]['output'][ 'ionic_steps_fs_id'] = gfs_id # Aggregate a trajectory ## Convert from a list of dictionaries to a dictionary of lists ionic_steps_dict = task_doc["calcs_reversed"][0]['output'][ 'ionic_steps'] del task_doc["calcs_reversed"][0]['output']['ionic_steps'] ionic_steps_defaultdict = defaultdict(list) for d in ionic_steps_dict: for key, val in d.items(): ionic_steps_defaultdict[key].append(val) ionic_steps = dict(ionic_steps_defaultdict.items()) ## extract structures from dictionary structures = [ Structure.from_dict(struct) for struct in ionic_steps['structure'] ] del ionic_steps['structure'] frame_properties = {} for key in [ 'e_fr_energy', 'e_wo_entrp', 'e_0_energy', 'kinetic', 'lattice kinetic', 'nosepot', 'nosekinetic', 'total' ]: frame_properties[key] = ionic_steps[key] # Create trajectory trajectory = Trajectory.from_structures( structures, constant_lattice=True, frame_properties=frame_properties, time_step=task_doc['input']['incar']['POTIM']) traj_dict = json.dumps(trajectory.as_dict(), cls=MontyEncoder) gfs_id, compression_type = self.insert_gridfs( traj_dict, "trajectories_fs") task_doc['trajectory'] = { 'formula': trajectory[0].composition.formula.replace(' ', ''), 'temperature': int(task_doc["input"]["incar"]["TEBEG"]), 'compression': compression_type, 'fs_id': gfs_id, 'dimension': list(np.shape(trajectory.frac_coords)), 'time_step': task_doc["input"]["incar"]["POTIM"], } # insert the task document and return task_id return self.insert(task_doc)
def setUp(self): xdatcar = Xdatcar(os.path.join(PymatgenTest.TEST_FILES_DIR, "Traj_XDATCAR")) self.traj = Trajectory.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "Traj_XDATCAR")) self.structures = xdatcar.structures
def test_extend_inequivalent_site_props(self): lattice = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] species = ["Si", "Si"] frac_coords = [ [[0, 0, 0], [0.5, 0.5, 0.5]], [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6]], [[0.2, 0.2, 0.2], [0.7, 0.7, 0.7]], ] # Trajectories with constant site properties site_properties_1 = [ { "selective_dynamics": [[False, False, False], [False, False, False]], "magmom": [5, 5], } ] traj_1 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_1) site_properties_2 = [ { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], } ] traj_2 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_2) # Test combining two trajectories with similar site_properties traj_combined = traj_1.copy() traj_combined.extend(traj_2) expected_site_props = [ { "selective_dynamics": [[False, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[False, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[False, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, True], [False, False, False]], "magmom": [5, 5], }, ] self.assertEqual(traj_combined.site_properties, expected_site_props) # Trajectory with const site_properties and trajectory with changing site properties site_properties_1 = [ { "selective_dynamics": [[True, False, False], [False, False, False]], "magmom": [5, 5], } ] traj_1 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_1) site_properties_2 = [ { "selective_dynamics": [[False, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, False], [False, False, False]], "magmom": [5, 5], }, ] traj_2 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_2) # Test combining two trajectories with similar site_properties traj_combined = traj_1.copy() traj_combined.extend(traj_2) expected_site_props = [ { "selective_dynamics": [[True, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[False, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, False], [False, False, False]], "magmom": [5, 5], }, ] self.assertEqual(traj_combined.site_properties, expected_site_props) # The other way around traj_combined = traj_2.copy() traj_combined.extend(traj_1) expected_site_props = [ { "selective_dynamics": [[False, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, False], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, False], [False, False, False]], "magmom": [5, 5], }, ] self.assertEqual(traj_combined.site_properties, expected_site_props) # Trajectory with no and trajectory with changing site properties site_properties_1 = None traj_1 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_1) site_properties_2 = [ { "selective_dynamics": [[False, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, False], [False, False, False]], "magmom": [5, 5], }, ] traj_2 = Trajectory(lattice, species, frac_coords, site_properties=site_properties_2) # Test combining two trajectories with similar site_properties traj_combined = traj_1.copy() traj_combined.extend(traj_2) expected_site_props = [ None, None, None, { "selective_dynamics": [[False, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, False], [False, False, False]], "magmom": [5, 5], }, ] self.assertEqual(traj_combined.site_properties, expected_site_props) # The other way around traj_combined = traj_2.copy() traj_combined.extend(traj_1) expected_site_props = [ { "selective_dynamics": [[False, True, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, False, True], [False, False, False]], "magmom": [5, 5], }, { "selective_dynamics": [[True, True, False], [False, False, False]], "magmom": [5, 5], }, None, None, None, ] self.assertEqual(traj_combined.site_properties, expected_site_props)
''' 分析AIMD结果,计算MSD 和 conductivity ''' import os from pymatgen.core.trajectory import Trajectory from pymatgen.io.vasp.outputs import Xdatcar from pymatgen import Structure from pymatgen.analysis.diffusion_analyzer import DiffusionAnalyzer import numpy as np import pickle # 这一步是读取 XDATCAR,得到一系列结构信息 traj = Trajectory.from_file('XDATCAR') # 这一步是实例化 DiffusionAnalyzer 的类 # 并用 from_structures 方法初始化这个类; 900 是温度,2 是POTIM 的值,1是间隔步数 # 间隔步数(step_skip)不太容易理解,但是根据官方教程: # dt = timesteps * self.time_step * self.step_skip diff = DiffusionAnalyzer.from_structures(traj,'Li',900,2,1) # 可以用内置的 plot_msd 方法画出 MSD 图像 # 有些终端不能显示图像,这时候可以调用 export_msdt() 方法,得到数据后再自己作图 diff.plot_msd() # 接下来直接得到 离子迁移率, 单位是 mS/cm C = diff.conductivity with open('result.dat','w') as f: f.write('# AIMD result for Li-ion\n') f.write('temp\tconductivity\n')
rc('text', usetex=True) import matplotlib.pylab as pylab params = { 'legend.fontsize': '15', 'figure.figsize': (7, 6), 'axes.labelsize': 20, 'axes.titlesize': 20, 'xtick.labelsize': 16, 'ytick.labelsize': 16 } pylab.rcParams.update(params) trajectory = Trajectory.from_file("./vasprun_md.xml") trajectory.write_Xdatcar(filename='XDATCAR_temp') images = read_vasp_xdatcar('XDATCAR_temp', index=None) print("total number of frames: " + str(len(images))) os.remove('./XDATCAR_temp') reference_frame = read_vasp('./SPOSCAR') desc = SOAP(species=[55, 51, 53], rcut=6.0, nmax=9, lmax=9, sigma=0.3, periodic=True, crossover=True, sparse=False) ref_features = desc.create(reference_frame)