wmaee.codes.vasp

1from wmaee.codes.vasp.vasp_inputs import automatic_kpoints, regular_kpoints, generate_potcar, write_incar, write_inputs
2from wmaee.codes.vasp.vasp_runner import run_vasp
3from wmaee.codes.vasp.vasp_outputs import parse_output, parse_AIMD
4
5__all__ = ['automatic_kpoints', 'regular_kpoints', 'generate_potcar', 'write_incar', 'write_inputs', 'run_vasp', 'parse_output']
def automatic_kpoints(length: float, write: Optional[bool] = False) -> None:
17def automatic_kpoints(length: float, write: Optional[bool] = False) -> None:
18    """
19    Writes a KPOINTS file for generating a regular Gamma-centered k-point mesh.
20
21    Parameters
22    ----------
23    length : float
24        The length (R_k) that determines the subdivisions N1, N2, and N3.
25    write : bool, optional
26        If True, writes the KPOINTS file; if False, returns the KPOINTS content as a string.
27        Default is False.
28
29    Returns
30    -------
31    None or str
32        If write is True, writes the KPOINTS file and returns None.
33        If write is False, returns the KPOINTS content as a string.
34    """
35    kpts = 'Fully automatic mesh\n'
36    kpts += '0 # indicates automatic generation scheme\n'
37    kpts += 'Auto # fully automatic\n'
38    kpts += f'{length} # length (R_k)'
39
40    if write:
41        with open('KPOINTS', 'w') as output:
42            output.write(kpts)
43    else:
44        return kpts

Writes a KPOINTS file for generating a regular Gamma-centered k-point mesh.

Parameters
  • length (float): The length (R_k) that determines the subdivisions N1, N2, and N3.
  • write (bool, optional): If True, writes the KPOINTS file; if False, returns the KPOINTS content as a string. Default is False.
Returns
  • None or str: If write is True, writes the KPOINTS file and returns None. If write is False, returns the KPOINTS content as a string.
def regular_kpoints( kpoints: Tuple[int, int, int] = (1, 1, 1), shift: Tuple[float, float, float] = (0.0, 0.0, 0.0), Gamma: bool = True, write: bool = False) -> None:
47def regular_kpoints(kpoints: Tuple[int, int, int] = (1, 1, 1),
48                    shift: Tuple[float, float, float] = (0.0, 0.0, 0.0),
49                    Gamma: bool = True,
50                    write: bool = False) -> None:
51    """
52    Writes a KPOINTS file for generating a regular k-point mesh.
53
54    Parameters
55    ----------
56    kpoints : tuple of int, optional
57        Subdivisions N_1, N_2, and N_3 along the reciprocal lattice vectors.
58        Default is (1, 1, 1).
59    shift : tuple of float, optional
60        Shift of the mesh (s_1, s_2, s_3).
61        Default is (0.0, 0.0, 0.0).
62    Gamma : bool, optional
63        If True, generates a Gamma-centered mesh; if False, uses Monkhorst-Pack scheme.
64        Default is True.
65    write : bool, optional
66        If True, writes the KPOINTS file; if False, returns the KPOINTS content as a string.
67        Default is False.
68
69    Returns
70    -------
71    None or str
72        If write is True, writes the KPOINTS file and returns None.
73        If write is False, returns the KPOINTS content as a string.
74    """
75    kpts = 'Regular k-point mesh\n'
76    kpts += '0 # indicates automatic number of k-points\n'
77    if Gamma:
78        kpts += 'Gamma # generate a Gamma centered mesh\n'
79    else:
80        kpts += 'Monkhorst # Monkhorst-Pack scheme\n'
81    kpts += f'{kpoints[0]} {kpoints[1]} {kpoints[2]} # subdivisions N_1, N_2, and N_3 along the reciprocal lattice vectors\n'
82    kpts += f'{shift[0]} {shift[1]} {shift[2]} # shift of the mesh (s_1, s_2, s_3)'
83
84    if write:
85        with open('KPOINTS', 'w') as output:
86            output.write(kpts)
87    else:
88        return kpts

Writes a KPOINTS file for generating a regular k-point mesh.

Parameters
  • kpoints (tuple of int, optional): Subdivisions N_1, N_2, and N_3 along the reciprocal lattice vectors. Default is (1, 1, 1).
  • shift (tuple of float, optional): Shift of the mesh (s_1, s_2, s_3). Default is (0.0, 0.0, 0.0).
  • Gamma (bool, optional): If True, generates a Gamma-centered mesh; if False, uses Monkhorst-Pack scheme. Default is True.
  • write (bool, optional): If True, writes the KPOINTS file; if False, returns the KPOINTS content as a string. Default is False.
Returns
  • None or str: If write is True, writes the KPOINTS file and returns None. If write is False, returns the KPOINTS content as a string.
def generate_potcar( struct: Union[ase.atoms.Atoms, Any], potcar_dir: Optional[str] = None, xc: Optional[str] = None, potcar_mapping: Optional[Dict[str, str]] = {}, write: Optional[bool] = True) -> Optional[Any]:
 92def generate_potcar(struct: Union[Atoms, Any], 
 93                    potcar_dir: Optional[str] = None,
 94                    xc: Optional[str] = None, 
 95                    potcar_mapping: Optional[Dict[str, str]] = {},
 96                    write: Optional[bool] = True) -> Optional[Any]:
 97    """
 98    Generate a POTCAR file for VASP calculations based on the elements in the structure.
 99
100    Parameters
101    ----------
102    struct : Union[ase.Atoms, pymatgen.Structure]
103        The structure for which POTCAR is to be generated. Can be either a pymatgen Structure or 
104        an ASE Atoms object.
105    potcar_dir : str, optional
106        The directory where the VASP POTCAR files are located.
107    xc : str, optional
108        The exchange-correlation functional. Defaults to value in defined in
109        `wmaee.config.yaml`.
110    potcar_mapping : dict, optional
111        An optional mapping of species to POTCARs, e.g. {'Fe': 'Fe_pv'}. 
112        For elements not explicitly specified, a default mapping {'X': 'X'}
113        will be applied.
114    write : bool, optional
115        Whether to write the POTCAR (into the current directory).
116
117    Returns
118    -------
119    pymatgen.Potcar or None
120        A Potcar object representing the POTCAR files for the elements in the structure 
121        if pymatgen is available. Otherwise, returns None.
122    """
123    
124    if potcar_dir == None:
125        # No POTCAR dir specified, let's get it from config
126        cfg = Config()
127        root = cfg.get('applications').get('vasp').get('potential_path')
128        if xc == None:
129            xc = cfg.get('applications').get('vasp').get('potentials').get('default')
130        xc_path = cfg.get('applications').get('vasp').get('potentials').get(xc)
131        potcar_dir = os.path.join(root, xc_path)
132    
133    pmg = test_pmg()
134    
135    if pmg and isinstance(struct, Structure):
136        # structure is pymatgen.core.Structure, convert to ase.Atoms
137        struct = AseAtomsAdaptor.get_atoms(struct)
138    if not isinstance(struct, Atoms):
139        raise TypeError('Unknown structure type')
140    
141    # get list of species ordered as in structure
142    sp = [struct[0].symbol]
143    for s in struct[1:]:
144        if s.symbol != sp[-1]:
145            sp += [s.symbol]
146    for s in set(sp):
147        if s not in potcar_mapping.keys():
148            potcar_mapping[s] = s
149    if pmg:
150        # let's use pymatgen's engine to get dictionary of all 
151        # single POTCARs we need
152        potcars = {
153            X: PotcarSingle.from_file(os.path.join(potcar_dir, potcar_mapping[X], 'POTCAR')) 
154            for X in sp
155            }
156
157        # construct POTCAR
158        potcar = Potcar()
159        functionals = []
160        for X in sp:
161            potcar.append(potcars[X])
162            functionals.append(potcars[X].functional)
163        potcar.functional = functionals[0]
164
165        if write:
166            # Write the POTCAR to a file
167            with open('POTCAR', 'w') as outfile:
168                outfile.write(str(potcar))
169                
170        return potcar
171    
172    # pymatgen is not available; should we write POTCAR? If so, let's just 
173    # concatenate corresponding files
174    if write:
175        with open('POTCAR', 'w') as outfile:
176            for X in sp:
177                with open(os.path.join(potcar_dir, potcar_mapping[X], 'POTCAR'), 'r') as infile:
178                    copyfileobj(infile, outfile)
179
180    return None

Generate a POTCAR file for VASP calculations based on the elements in the structure.

Parameters
  • struct (Union[ase.Atoms, pymatgen.Structure]): The structure for which POTCAR is to be generated. Can be either a pymatgen Structure or an ASE Atoms object.
  • potcar_dir (str, optional): The directory where the VASP POTCAR files are located.
  • xc (str, optional): The exchange-correlation functional. Defaults to value in defined in wmaee.config.yaml.
  • potcar_mapping (dict, optional): An optional mapping of species to POTCARs, e.g. {'Fe': 'Fe_pv'}. For elements not explicitly specified, a default mapping {'X': 'X'} will be applied.
  • write (bool, optional): Whether to write the POTCAR (into the current directory).
Returns
  • pymatgen.Potcar or None: A Potcar object representing the POTCAR files for the elements in the structure if pymatgen is available. Otherwise, returns None.
def write_incar(incar: Dict[str, Any], filename: str = 'INCAR') -> None:
288def write_incar(incar: Dict[str, Any], filename: str = 'INCAR') -> None:
289    """
290    Function writes an INCAR file.
291
292    Parameters
293    ----------
294    incar : Dict[str, Any]
295        A dictionary of key-value pairs specifying the INCAR file.
296    filename : str, optional
297        The name of the final INCAR file. Default is 'INCAR'.
298
299    Returns
300    -------
301    None
302        Writes the INCAR file.
303    """
304    with open(filename, 'w') as f:
305        for key, value in incar.items():
306            f.write(f"{key} = {value}\n")

Function writes an INCAR file.

Parameters
  • incar (Dict[str, Any]): A dictionary of key-value pairs specifying the INCAR file.
  • filename (str, optional): The name of the final INCAR file. Default is 'INCAR'.
Returns
  • None: Writes the INCAR file.
def write_inputs( struct: Union[ase.atoms.Atoms, Any], incar: Union[dict, Any], kpoints: Union[NoneType, str, Any] = None, potcar: Optional[Any] = None, xc: Optional[str] = None, potcar_mapping: Optional[Dict[str, str]] = {}, directory: Optional[str] = None) -> None:
311def write_inputs(struct: Union[Atoms, Any],
312                 incar: Union[dict, Any],
313                 kpoints: Optional[Union[None, str, Any]] = None,
314                 potcar: Optional[Union[None, Any]] = None,
315                 xc: Optional[Union[str, None]] = None,
316                 potcar_mapping: Optional[Dict[str, str]] = {},
317                 directory: Optional[Union[None, str]] = None) -> None:
318    """
319    Write VASP input files.
320    Warning: If destination already contains any of the VASP inputs, they 
321    get overwritten!
322
323    Parameters
324    ----------
325    struct : Union[ase.Atoms, pymatgen.core.Structure, pymatgen.io.vasp.Poscar]
326        Atomic structure information.
327    incar : Union[dict, pymatgen.io.vasp.Incar]
328        INCAR file information.
329    kpoints : Optional[Union[None, str, pymatgen.io.vasp.Kpoints]], optional
330        KPOINTS file information (default is None). If equal to None, INCAR must 
331        contain k-points specification via KSPACING tag/
332    potcar : Optional[Union[None, pymatgen.io.vasp.Potcar]], optional
333        POTCAR file information (default is None and autogeneration based on 
334        struct is used).
335    xc : Optional[Union[str, None]], optional
336        Exchange-correlation functional information (default is None and the 
337        value is taken from wmaee.conf.yaml file).
338    potcar_mapping : Optional[Dict[str, str]], optional
339        Mapping of elements to POTCAR files (default is {}).
340    directory : Optional[Union[None, str]], optional
341        Directory to write files (default is None, e.g. current directory).
342
343    Returns
344    -------
345    None
346    """
347    
348    pmg = test_pmg()
349    if directory == None:
350        directory = '.'
351    directory = os.path.expanduser(directory)
352    with working_directory(directory):
353        # POSCAR
354        if isinstance(struct, Atoms):
355            write(filename='POSCAR', images=struct, format='vasp', direct=True)
356        elif pmg and isinstance(struct, Poscar):
357            struct.write_file(filename='POSCAR')
358            struct = struct.structure # for POTCAR generation
359        elif pmg and isinstance(struct, Structure):
360            struct.to(filename='POSCAR', fmt='poscar')
361        else:
362            raise TypeError('Unknown structure type')
363            
364        # INCAR
365        if isinstance(incar, dict):
366            write_incar(incar)
367        elif pmg and isinstance(incar, Incar):
368            incar.write_file(filename='INCAR')
369        else:
370            raise TypeError('Unknown incar type')
371        
372        # KPOINTS
373        if kpoints == None and 'KSPACING' not in incar:
374            raise ValueError('kpoints must be specified when KSPACING is not in incar')
375        elif isinstance(kpoints, str):
376            with open('KPOINTS', 'w') as output:
377                output.write(kpoints)
378        elif pmg and isinstance(kpoints, Kpoints):
379            kpoints.write_file(filename='KPOINTS')
380            
381        # POTCAR
382        if pmg and isinstance(potcar, Potcar):
383            with open('POTCAR', 'w') as outfile:
384                outfile.write(str(potcar))
385        else:
386            generate_potcar(struct=struct, xc=xc, 
387                            potcar_mapping=potcar_mapping, write=True)

Write VASP input files. Warning: If destination already contains any of the VASP inputs, they get overwritten!

Parameters
  • struct (Union[ase.Atoms, pymatgen.core.Structure, pymatgen.io.vasp.Poscar]): Atomic structure information.
  • incar (Union[dict, pymatgen.io.vasp.Incar]): INCAR file information.
  • kpoints (Optional[Union[None, str, pymatgen.io.vasp.Kpoints]], optional): KPOINTS file information (default is None). If equal to None, INCAR must contain k-points specification via KSPACING tag/
  • potcar (Optional[Union[None, pymatgen.io.vasp.Potcar]], optional): POTCAR file information (default is None and autogeneration based on struct is used).
  • xc (Optional[Union[str, None]], optional): Exchange-correlation functional information (default is None and the value is taken from wmaee.conf.yaml file).
  • potcar_mapping (Optional[Dict[str, str]], optional): Mapping of elements to POTCAR files (default is {}).
  • directory (Optional[Union[None, str]], optional): Directory to write files (default is None, e.g. current directory).
Returns
  • None
def run_vasp( command: Optional[str] = None, args: Optional[Dict[str, Union[str, int]]] = None, directory: Optional[str] = None, log: Union[bool, str] = True) -> None:
 7def run_vasp(command: Optional[str] = None,
 8             args: Optional[Dict[str, Union[str, int]]] = None,
 9             directory: Optional[str] = None,
10             log: Union[bool, str] = True) -> None:
11    """
12    Run VASP (Vienna Ab initio Simulation Package) using the specified command,
13    arguments, and working directory.
14
15    Parameters
16    ----------
17    command : str, optional
18        The VASP command. If not provided, it will be obtained from the
19        configuration file.
20    args : dict, optional
21        Additional arguments to be passed to the VASP command.
22    directory : str, optional
23        The working directory for running VASP.
24    log : bool or str, optional
25        If True, capture the output to the screen. If a string is provided,
26        capture the output to the specified log file. If False, run silently
27        without capturing output.
28
29    Returns
30    -------
31    None
32    """
33    
34    if command == None:
35        # get the VASP command from wmaee.conf.yaml
36        cfg = Config()
37        command = cfg.get('applications').get('vasp').get('runner').get('script')
38        args_template = cfg.get('applications').get('vasp').get('runner').get('args')
39        # replace defaults with whatever was provided
40        if args == None:
41            args = dict()
42        for a in args:
43            if a in args_template:
44                args_template[a] = args[a]
45        for a in args_template:
46            command = command.replace('{{ ' + str(a) + ' }}', str(args_template[a]))
47    
48    logfile = False
49    if not log:
50        # silent
51        stdout = subprocess.DEVNULL
52        stderr = subprocess.DEVNULL
53    elif isinstance(log, str):
54        # capture to file
55        stdout = subprocess.PIPE
56        stderr = subprocess.STDOUT
57    else:
58        # don't capture -> screen
59        stdout = None
60        stderr = None
61    
62    if directory == None:
63        directory = '.'
64    with working_directory(directory):
65        run = subprocess.run(command, shell=True, stdout = stdout,
66                             stderr = stderr, text = True)
67        if isinstance(log, str):
68            with open(log, 'w') as output:
69                output.write(run.stdout)

Run VASP (Vienna Ab initio Simulation Package) using the specified command, arguments, and working directory.

Parameters
  • command (str, optional): The VASP command. If not provided, it will be obtained from the configuration file.
  • args (dict, optional): Additional arguments to be passed to the VASP command.
  • directory (str, optional): The working directory for running VASP.
  • log (bool or str, optional): If True, capture the output to the screen. If a string is provided, capture the output to the specified log file. If False, run silently without capturing output.
Returns
  • None
def parse_output( directory: Optional[str] = None, POSCAR: str = 'POSCAR', CONTCAR: str = 'CONTCAR', OSZICAR: str = 'OSZICAR', OUTCAR: str = 'OUTCAR', vasprun: str = 'vasprun.xml', XDATCAR: str = 'XDATCAR', DOSCAR: str = 'DOSCAR', ase_atoms: bool = False, parse_oszicar: bool = False, parse_outcar: bool = False, parse_vasprun: bool = True, parse_vasprun_dos: bool = False, parse_xdatcar: bool = False, parse_doscar: bool = False, return_DocDict: bool = True) -> Union[wmaee.core.data_structs.DotDict, Dict[str, Any]]:
 24def parse_output(directory: Optional[str] = None,
 25                 POSCAR: str = 'POSCAR',
 26                 CONTCAR: str = 'CONTCAR',
 27                 OSZICAR: str = 'OSZICAR',
 28                 OUTCAR: str = 'OUTCAR',
 29                 vasprun: str = 'vasprun.xml',
 30                 XDATCAR: str = 'XDATCAR',
 31                 DOSCAR: str = 'DOSCAR',
 32                 ase_atoms: bool = False,
 33                 parse_oszicar: bool = False,
 34                 parse_outcar: bool = False,
 35                 parse_vasprun: bool = True,
 36                 parse_vasprun_dos: bool = False,
 37                 parse_xdatcar: bool = False,
 38                 parse_doscar: bool = False,
 39                 return_DocDict: bool = True,
 40                ) -> Union[DotDict, Dict[str, Any]]:
 41    """
 42    Parse VASP output files and return relevant information.
 43
 44    Parameters
 45    ----------
 46    directory : str or None, optional
 47        The path to the directory containing VASP output files. If None, the current working directory is used.
 48    POSCAR : str, optional
 49        Name of the POSCAR file. Default is 'POSCAR'.
 50    CONTCAR : str, optional
 51        Name of the CONTCAR file. Default is 'CONTCAR'.
 52    OSZICAR : str, optional
 53        Name of the OSZICAR file. Default is 'OSZICAR'.
 54    OUTCAR : str, optional
 55        Name of the OUTCAR file. Default is 'OUTCAR'.
 56    vasprun : str, optional
 57        Name of the vasprun.xml file. Default is 'vasprun.xml'.
 58    XDATCAR : str, optional
 59        Name of the XDATCAR file. Default is 'XDATCAR'.
 60    ase_atoms : bool, optional
 61        Use ASE atoms instead of pymatgen structure if True. Default is False.
 62    parse_oszicar : bool, optional
 63        Parse ionic step energies from OSZICAR if True (only for pymatgen). Default is False.
 64    parse_outcar : bool, optional
 65        Parse final energies (and also magnetization if pymatgen is available) from OUTCAR if True. Default is False.
 66    parse_vasprun : bool, optional
 67        Parse vasprun.xml for ionic relaxation energies if True. Default is True.
 68    parse_vasprun_dos : bool, optional
 69        Parse DOS information from vasprun.xml if True (only if pymatgen is available). Default is False.
 70    parse_xdatcar : bool, optional
 71        Parse ionic relaxation steps from XDATCAR if True. Default is False.
 72    return_DocDict : bool, optional
 73        Return DotDict instead of a regular dictionary if True. Default is True.
 74
 75    Returns
 76    -------
 77    DotDict or dict
 78        A DotDict or dictionary containing parsed information.
 79    """
 80    
 81    pmg = test_pmg()
 82    output_data = {}
 83
 84    # Use the current working directory if vasp_dir is not provided
 85    if directory is None:
 86        directory = os.getcwd()
 87    directory = os.path.expanduser(directory)
 88
 89    # Check if the directory exists
 90    if not os.path.isdir(directory):
 91        raise ValueError('Directory '+directory+' does not exist.')
 92
 93    # Parse initial and final structures from POSCAR and CONTCAR
 94    filename = os.path.join(directory, POSCAR)
 95    if os.path.isfile(filename):
 96        if pmg and not ase_atoms:
 97            output_data['initial_structure'] = Poscar.from_file(filename=filename, check_for_POTCAR=False).structure
 98        else:
 99            output_data['initial_structure'] = read_vasp(filename)
100
101    filename = os.path.join(directory, CONTCAR)
102    if os.path.isfile(filename):
103        if pmg and not ase_atoms:
104            output_data['final_structure'] = Poscar.from_file(filename=filename, check_for_POTCAR=False).structure
105        else:
106            output_data['final_structure'] = read_vasp(filename)
107            
108    # Parse energies from OSZICAR if available - only pymatgen! - fast for energies
109    oszicar_file = os.path.join(directory, OSZICAR)
110    if parse_oszicar and pmg and os.path.isfile(oszicar_file):
111        oszicar = Oszicar(oszicar_file)
112        output_data['final_energy'] = oszicar.final_energy
113        output_data['ionic_step_energies'] = [s['E0'] for s in oszicar.ionic_steps]
114        
115    # Parse data from OUTCAR
116    if parse_outcar:
117        filename = os.path.join(directory, OUTCAR)
118        if os.path.isfile(filename):
119            if pmg:
120                # pymatgen parser
121                outcar = Outcar(filename)
122                output_data['total_magnetization'] = outcar.total_mag
123                output_data['magnetization'] = outcar.magnetization
124                output_data['final_energy'] = outcar.final_energy
125            else:
126                # ase (limited) parser
127                outcar = read_vasp_out(filename, index=slice(None))
128                energies = []
129                forces = []
130                stress = []
131                for s in outcar:
132                    energies.append(s.calc.get_potential_energy())
133                    forces.append(np.array(s.calc.get_forces()))                    
134                    stress.append(from_voigt(_BUG_ASE_GPA*np.array(s.calc.get_stress()), div_two=False))
135                output_data['final_energy'] = energies[-1]
136                output_data['ionic_step_energies'] = energies
137                output_data['ionic_step_forces'] = forces
138                output_data['ionic_step_stress'] = stress
139                output_data['final_stress'] = output_data['ionic_step_stress'][-1]
140                output_data['final_forces'] = output_data['ionic_step_forces'][-1]
141                # output_data['final_energy'] = outcar.calc.get_potential_energy()
142
143    # Parse vasprun.xml for electronic structure information and DOS if enabled
144    filename = os.path.join(directory, vasprun)
145    if parse_vasprun and os.path.isfile(filename):
146        if pmg: # pymatgen parser
147            if parse_vasprun_dos:
148                vrun = Vasprun(filename=filename, parse_eigen=False, parse_potcar_file=False, parse_projected_eigen=False, parse_dos=True)
149                dos = vrun.complete_dos
150                energy = dict(
151                    Emin=min(dos.energies), Emax=max(dos.energies), EF=dos.efermi, 
152                    EN=len(dos.energies), Eg=dos.get_gap(), E=dos.energies
153                )
154                # @TODO add parsing PDOS from vasprun.xml                
155                output_data['dos'] = dict(energy=energy, TDOS=dos.get_densities(), PDOS=None)
156                if return_DocDict:
157                    output_data['dos'] = DotDict(output_data['dos'])
158            else:
159                vrun = Vasprun(filename=filename, parse_eigen=False, parse_potcar_file=False, parse_projected_eigen=False, parse_dos=False)
160            output_data['final_energy'] = vrun.final_energy # first try to read final energy
161            output_data['ionic_step_energies'] = [s['e_0_energy'] for s in vrun.ionic_steps]
162            if 'forces' in vrun.ionic_steps[0].keys():
163                output_data['ionic_step_forces'] = [np.array(s['forces']) for s in vrun.ionic_steps]
164            if 'stress' in vrun.ionic_steps[0].keys():
165                output_data['ionic_step_stress'] = [-1*np.array(s['stress'])/10 for s in vrun.ionic_steps]
166        else: # ase parser
167            vrun = read_vasp_xml(filename, index=slice(None))
168            energies = []
169            forces = []
170            stress = []
171            for s in vrun:
172                energies.append(s.calc.get_potential_energy())
173                forces.append(np.array(s.calc.get_forces()))                
174                stress.append(from_voigt(_BUG_ASE_GPA*np.array(s.calc.get_stress()), div_two=False))
175            output_data['final_energy'] = energies[-1]
176            output_data['ionic_step_energies'] = energies
177            output_data['ionic_step_forces'] = forces
178            output_data['ionic_step_stress'] = stress
179        output_data['final_stress'] = output_data['ionic_step_stress'][-1]
180        output_data['final_forces'] = output_data['ionic_step_forces'][-1]
181            
182    # Parse ionic relaxation steps from XDATCAR
183    filename = os.path.join(directory, XDATCAR)
184    if parse_xdatcar and os.path.isfile(filename):
185        if pmg:
186            # pymatgen
187            xdatcar = Xdatcar(filename)
188            structures = xdatcar.structures
189        else:
190            # ase
191            structures = read_vasp_xdatcar(filename, index=slice(None))
192        output_data['ionic_relaxation'] = structures
193            
194    # Parse DOS from DOSCAR
195    filename = os.path.join(directory, DOSCAR)
196    if parse_doscar and os.path.isfile(filename):
197        from wmaee.scopes.dos import dos
198        from wmaee.core.io import working_directory
199        with working_directory(directory):
200            DOS = dos()
201            DOS.read_DOS_VASP(fDOSCAR=DOSCAR, fPOSCAR=POSCAR)
202            if return_DocDict:
203                output_data['dos'] = DotDict(dict(energy=DOS.energy, TDOS=DOS.TDOS, PDOS=DOS.PDOS))
204            else:
205                output_data['dos'] = dict(energy=DOS.energy, TDOS=DOS.TDOS, PDOS=DOS.PDOS)
206            
207        
208    if return_DocDict:
209        return DotDict(output_data)
210    else:
211        return output_data

Parse VASP output files and return relevant information.

Parameters
  • directory (str or None, optional): The path to the directory containing VASP output files. If None, the current working directory is used.
  • POSCAR (str, optional): Name of the POSCAR file. Default is 'POSCAR'.
  • CONTCAR (str, optional): Name of the CONTCAR file. Default is 'CONTCAR'.
  • OSZICAR (str, optional): Name of the OSZICAR file. Default is 'OSZICAR'.
  • OUTCAR (str, optional): Name of the OUTCAR file. Default is 'OUTCAR'.
  • vasprun (str, optional): Name of the vasprun.xml file. Default is 'vasprun.xml'.
  • XDATCAR (str, optional): Name of the XDATCAR file. Default is 'XDATCAR'.
  • ase_atoms (bool, optional): Use ASE atoms instead of pymatgen structure if True. Default is False.
  • parse_oszicar (bool, optional): Parse ionic step energies from OSZICAR if True (only for pymatgen). Default is False.
  • parse_outcar (bool, optional): Parse final energies (and also magnetization if pymatgen is available) from OUTCAR if True. Default is False.
  • parse_vasprun (bool, optional): Parse vasprun.xml for ionic relaxation energies if True. Default is True.
  • parse_vasprun_dos (bool, optional): Parse DOS information from vasprun.xml if True (only if pymatgen is available). Default is False.
  • parse_xdatcar (bool, optional): Parse ionic relaxation steps from XDATCAR if True. Default is False.
  • return_DocDict (bool, optional): Return DotDict instead of a regular dictionary if True. Default is True.
Returns
  • DotDict or dict: A DotDict or dictionary containing parsed information.