1##################################################################
2##  (c) Copyright 2015-  by Jaron T. Krogel                     ##
3##################################################################
4
5
6#====================================================================#
7#  vasp.py                                                           #
8#    Nexus interface for the VASP simulation code.                   #
9#                                                                    #
10#  Content summary:                                                  #
11#    Vasp                                                            #
12#      Simulation class for VASP.                                    #
13#      Handles passing of structure dependencies for relax and NEB.  #
14#                                                                    #
15#    generate_vasp                                                   #
16#      User-facing function to generate VASP simulation objects.     #
17#                                                                    #
18#    VaspHT                                                          #
19#      Original VASP interface supporting only template inputs.      #
20#                                                                    #
21#    generate_vasp_ht                                                #
22#      User interface to VaspHT.                                     #
23#                                                                    #
24#====================================================================#
25
26
27import os
28from generic import obj
29from simulation import Simulation,SimulationInput,SimulationAnalyzer
30from vasp_input import VaspInput,generate_vasp_input,generate_poscar,Poscar
31from vasp_analyzer import VaspAnalyzer,read_vxml
32from structure import Structure
33from debug import *
34
35
36
37class Vasp(Simulation):
38    input_type         = VaspInput
39    analyzer_type      = VaspAnalyzer
40    generic_identifier = 'vasp'
41    application        = 'vasp'
42    application_properties = set(['serial','mpi'])
43    application_results    = set(['structure'])
44
45    allow_overlapping_files = True
46
47    vasp_save_files = 'INCAR KPOINTS POSCAR CONTCAR DOSCAR EIGENVAL IBZKPT OSZICAR OUTCAR PCDAT XDATCAR vasprun.xml'.split()
48
49    def set_files(self):
50        self.infile  = 'INCAR'
51        self.outfile = self.identifier + self.outfile_extension
52        self.errfile = self.identifier + self.errfile_extension
53    #end def set_files
54
55
56    def check_result(self,result_name,sim):
57        input = self.input
58        if result_name=='structure':
59            calculating_result = input.producing_structure()
60        else:
61            calculating_result = False
62        #end if
63        return calculating_result
64    #end def check_result
65
66
67    def get_result(self,result_name,sim):
68        result = obj()
69        input = self.input
70        if result_name=='structure':
71            # get structure from CONTCAR
72            ccfile = os.path.join(self.locdir,self.identifier+'.CONTCAR')
73            if not os.path.exists(ccfile):
74                self.error('CONTCAR file does not exist for relax simulation at '+self.locdir)
75            #end if
76            contcar = Poscar(ccfile)
77            structure = Structure()
78            if contcar.elem is not None:
79                structure.read_poscar(ccfile)
80            else:
81                elem,elem_count = self.system.structure.order_by_species()
82                structure.read_poscar(ccfile,elem=elem)
83            #end if
84            if input.poscar.dynamic is not None:
85                structure.freeze(
86                    input.poscar.dynamic,
87                    negate = True
88                    )
89            #end if
90            result.structure = structure
91        else:
92            self.error('ability to get result '+result_name+' has not been implemented')
93        #end if
94        return result
95    #end def get_result
96
97
98    def incorporate_result(self,result_name,result,sim):
99        input = self.input
100        if result_name=='structure':
101            if input.performing_neb():
102                if 'neb_structures' not in self:
103                    self.neb_structures = []
104                #end if
105                neb_structures = self.neb_structures
106                if len(neb_structures)>1:
107                    self.error('NEB simulation at {0} depends on more than two structures\n  please check your inputs'.format(self.locdir))
108                #end if
109                neb_structures.append(result.structure.copy())
110                if len(neb_structures)==2:
111                    input.setup_neb(*neb_structures,images=input.incar.images)
112                #end if
113            else:
114                input.poscar = generate_poscar(result.structure)
115            #end if
116        else:
117            self.error('ability to incorporate result '+result_name+' has not been implemented')
118        #end if
119    #end def incorporate_result
120
121
122    def app_command(self):
123        return self.app_name
124    #end def app_command
125
126
127    def check_sim_status(self):
128        outpaths = []
129        if not self.input.performing_neb():
130            outpath = os.path.join(self.locdir,self.identifier+'.OUTCAR')
131            exists  = os.path.exists(outpath)
132            if not exists:
133                outpath = os.path.join(self.locdir,'OUTCAR')
134            #end if
135            outpaths.append(outpath)
136        else:
137            for i in range(self.input.incar.images):
138                outpaths.append(os.path.join(self.locdir,str(i+1).zfill(2),'OUTCAR'))
139            #end for
140        #end if
141        success = False
142        all_exist = True
143        for outpath in outpaths:
144            all_exist &= os.path.exists(outpath)
145        #end for
146        if all_exist:
147            success = True
148            for outpath in outpaths:
149                outcar = open(outpath,'r').read()
150                success &= 'General timing and accounting' in outcar
151            #end for
152        #end if
153        self.finished = success
154    #end def check_sim_status
155
156
157    def get_output_files(self):
158        output_files = []
159        for file in self.vasp_save_files:
160            native_file = os.path.join(self.locdir,file)
161            save_file   = os.path.join(self.locdir,self.identifier+'.'+file)
162            if os.path.exists(native_file):
163                os.system('cp {0} {1}'.format(native_file,save_file))
164                output_files.append(file)
165            #end if
166        #end for
167        return output_files
168    #end def get_output_files
169#end class Vasp
170
171
172
173def generate_vasp(**kwargs):
174    sim_args,inp_args = Vasp.separate_inputs(kwargs,copy_pseudos=False)
175
176    sim_args.input = generate_vasp_input(**inp_args)
177    vasp = Vasp(**sim_args)
178
179    return vasp
180#end def generate_vasp
181
182
183