예제 #1
0
 def collect_data(self, entry_id, workdir):
     if os.path.isfile(workdir + '/OUTCAR'):
         vo = VaspOutput(workdir + '/OUTCAR')
         if 'energy' in vo.final_data:
             if 'free_energy' in vo.final_data['energy']:
                 energy = vo.final_data['energy']['free_energy']
                 print('Uploading energy data for %s' % entry_id)
                 self.set_in_properties(entry_id, 'energy', energy)
                 return True
             else:
                 return False
         else:
             return False
     else:
         return False
예제 #2
0
    def update(self, workdir):
        """
        This routine determines how to proceed with the relaxation
        for one specific work directory

        :param workdir: (str) String representation of the id in the mongodb
        :return:
        """

        # workdir = self.basedir + os.sep + entry_id
        entry_id = os.path.basename(workdir)
        vj = self.vasp_jobs[entry_id]
        runj = self.runs[entry_id]
        if os.path.isfile(workdir + os.sep + 'OUTCAR'):
            vj.get_outputs()
        self.update_history(entry_id)

        if os.path.isfile(workdir + os.sep + 'RELAXED'):
            self.add_status(entry_id, 'RELAXED')
        elif not os.path.isfile(workdir + os.sep + 'PROCAR'):
            self.add_status(entry_id, 'NOPROCAR')
        else:
            self.del_status(entry_id, 'NOPROCAR')
            if not os.path.isfile(workdir + os.sep + 'OUTCAR'):
                self.add_status(entry_id, 'NOOUTCAR')
            else:
                self.del_status(entry_id, 'NOOUTCAR')
                print('-')
                vo = VaspOutput(workdir + os.sep + 'OUTCAR')
                relaxation_info = vo.relaxation_info()
                if len(relaxation_info) != 3:
                    print('[' + str(entry_id) + ']' +
                          ' Missing some data in OUTCAR (forces or stress)')
                    self.add_status(entry_id, 'NOOUTCAR')

                print('[' + str(entry_id) + ']' + 'Results:')
                for i in relaxation_info:
                    print('[' + str(entry_id) + '] %20s %12.5e' %
                          (i, relaxation_info[i]))

                # Conditions to consider the structure relaxed
                if relaxation_info['avg_force'] < self.target_force:
                    if relaxation_info['avg_stress_diag'] < self.target_stress:
                        if relaxation_info[
                                'avg_stress_non_diag'] < self.target_stress:
                            wf = open(workdir + os.sep + 'RELAXED', 'w')
                            for i in relaxation_info:
                                wf.write("%15s %12.3f" %
                                         (i, relaxation_info[i]))
                            wf.close()
                            wf = open(workdir + os.sep + 'COMPLETE', 'w')
                            for i in relaxation_info:
                                wf.write("%15s %12.3f" %
                                         (i, relaxation_info[i]))
                            wf.close()
                            self.add_status(entry_id, 'RELAXED')

        if self.modify_input(entry_id):

            # How to change ISIF
            if relaxation_info['avg_force'] < 0.1:
                if relaxation_info['avg_stress_diag'] < 0.1:
                    if relaxation_info['avg_stress_non_diag'] < 0.1:
                        vj.input_variables.variables['ISIF'] = 3
                    else:
                        vj.input_variables.variables['ISIF'] = 3
                else:
                    vj.input_variables.variables['ISIF'] = 3
            else:
                vj.input_variables.variables['ISIF'] = 2

            # How to change IBRION
            # if info['avg_force'] < 0.1 and info['avg_stress_diag'] < 0.1 and info['avg_stress_non_diag'] < 0.1:
            #    vj.input_variables.variables['IBRION'] = 1
            # elif info['avg_force'] < 1 and info['avg_stress_diag'] < 1 and info['avg_stress_non_diag'] < 1:
            #    vj.input_variables.variables['IBRION'] = 2
            # else:
            #    vj.input_variables.variables['IBRION'] = 3

            # How to change EDIFF
            if vj.input_variables.variables['EDIFF'] > 2 * 1E-4:
                vj.input_variables.variables['EDIFF'] = round_small(
                    vj.input_variables.variables['EDIFF'] / 2)
            else:
                vj.input_variables.variables['EDIFF'] = 1E-4

            # How to change EDIFFG
            if vj.input_variables.variables['EDIFFG'] < -2 * self.target_force:
                vj.input_variables.variables['EDIFFG'] = round_small(
                    vj.input_variables.variables['EDIFFG'] / 2)
            else:
                vj.input_variables.variables['EDIFFG'] = -self.target_force

            # Print new values
            print('[' + str(entry_id) + ']' + 'New Values:')
            for i in ['ISIF', 'IBRION', 'EDIFF', 'EDIFFG']:
                print('[' + str(entry_id) + ']' + i + ' : ',
                      vj.input_variables.variables[i])
            print('-')

            for i in ['OUTCAR']:
                if not os.path.exists(workdir + os.sep + i):
                    wf = open(workdir + os.sep + i, 'w')
                    wf.write('')
                    wf.close()
                log = logging.handlers.RotatingFileHandler(workdir + os.sep +
                                                           i,
                                                           maxBytes=1,
                                                           backupCount=1000)
                log.doRollover()

            try:
                vj.structure = read_poscar(workdir + os.sep + 'CONTCAR')
            except ValueError:
                print('Error reading CONTCAR')

            vj.set_inputs()
            properties = vj.outcar
            status = self.status[entry_id]
            newentry = self.population.db.update(entry_id,
                                                 structure=vj.structure,
                                                 properties=properties,
                                                 status=status)

            vj.save_json(workdir + os.sep + 'vaspjob.json')
            wf = open(workdir + os.sep + 'entry.json', 'w')
            json.dump(newentry,
                      wf,
                      sort_keys=True,
                      indent=4,
                      separators=(',', ': '))
            wf.close()
            return True
        else:
            vj.set_inputs()
            status = self.status[entry_id]
            newentry = self.population.db.update(entry_id,
                                                 structure=vj.structure,
                                                 status=status)

            vj.save_json(workdir + os.sep + 'vaspjob.json')
            wf = open(workdir + os.sep + 'entry.json', 'w')
            json.dump(newentry,
                      wf,
                      sort_keys=True,
                      indent=4,
                      separators=(',', ': '))
            wf.close()
            return True
예제 #3
0
    def update(self, workdir):
        """
        This routine determines how to proceed with the relaxation
        for one specific work directory

        :param workdir: (str) String representation of the id in the mongodb
        :return:
        """

        # workdir = self.basedir + os.sep + entry_id
        entry_id = os.path.basename(workdir)
        vj = self.vasp_jobs[entry_id]
        runj = self.runs[entry_id]
        if os.path.isfile(workdir + os.sep + 'OUTCAR'):
            vj.get_outputs()
        self.update_history(entry_id)

        if os.path.isfile(workdir + os.sep + 'RELAXED'):
            self.add_status(entry_id, 'RELAXED')
        elif not os.path.isfile(workdir + os.sep + 'PROCAR'):
            self.add_status(entry_id, 'NOPROCAR')
        else:
            self.del_status(entry_id, 'NOPROCAR')
            if not os.path.isfile(workdir + os.sep + 'OUTCAR'):
                self.add_status(entry_id, 'NOOUTCAR')
            else:
                self.del_status(entry_id, 'NOOUTCAR')
                print('-')
                vo = VaspOutput(workdir + os.sep + 'OUTCAR')
                relaxation_info = vo.relaxation_info()
                if len(relaxation_info) != 3:
                    print('[' + str(entry_id) + ']' + ' Missing some data in OUTCAR (forces or stress)')
                    self.add_status(entry_id, 'NOOUTCAR')

                print('[' + str(entry_id) + ']' + 'Results:')
                for i in relaxation_info:
                    print('[' + str(entry_id) + '] %20s %12.5e' % (i, relaxation_info[i]))

                # Conditions to consider the structure relaxed
                if relaxation_info['avg_force'] < self.target_force:
                    if relaxation_info['avg_stress_diag'] < self.target_stress:
                        if relaxation_info['avg_stress_non_diag'] < self.target_stress:
                            wf = open(workdir + os.sep + 'RELAXED', 'w')
                            for i in relaxation_info:
                                wf.write("%15s %12.3f" % (i, relaxation_info[i]))
                            wf.close()
                            wf = open(workdir + os.sep + 'COMPLETE', 'w')
                            for i in relaxation_info:
                                wf.write("%15s %12.3f" % (i, relaxation_info[i]))
                            wf.close()
                            self.add_status(entry_id, 'RELAXED')

        if self.modify_input(entry_id):

            # How to change ISIF
            if relaxation_info['avg_force'] < 0.1:
                if relaxation_info['avg_stress_diag'] < 0.1:
                    if relaxation_info['avg_stress_non_diag'] < 0.1:
                        vj.input_variables.variables['ISIF'] = 3
                    else:
                        vj.input_variables.variables['ISIF'] = 3
                else:
                    vj.input_variables.variables['ISIF'] = 3
            else:
                vj.input_variables.variables['ISIF'] = 2

            # How to change IBRION
            # if info['avg_force'] < 0.1 and info['avg_stress_diag'] < 0.1 and info['avg_stress_non_diag'] < 0.1:
            #    vj.input_variables.variables['IBRION'] = 1
            # elif info['avg_force'] < 1 and info['avg_stress_diag'] < 1 and info['avg_stress_non_diag'] < 1:
            #    vj.input_variables.variables['IBRION'] = 2
            # else:
            #    vj.input_variables.variables['IBRION'] = 3

            # How to change EDIFF
            if vj.input_variables.variables['EDIFF'] > 2 * 1E-4:
                vj.input_variables.variables['EDIFF'] = round_small(vj.input_variables.variables['EDIFF'] / 2)
            else:
                vj.input_variables.variables['EDIFF'] = 1E-4

            # How to change EDIFFG
            if vj.input_variables.variables['EDIFFG'] < - 2 * self.target_force:
                vj.input_variables.variables['EDIFFG'] = round_small(vj.input_variables.variables['EDIFFG'] / 2)
            else:
                vj.input_variables.variables['EDIFFG'] = - self.target_force

            # Print new values
            print('[' + str(entry_id) + ']' + 'New Values:')
            for i in ['ISIF', 'IBRION', 'EDIFF', 'EDIFFG']:
                print('[' + str(entry_id) + ']' + i + ' : ', vj.input_variables.variables[i])
            print('-')

            for i in ['OUTCAR']:
                if not os.path.exists(workdir + os.sep + i):
                    wf = open(workdir + os.sep + i, 'w')
                    wf.write('')
                    wf.close()
                log = logging.handlers.RotatingFileHandler(workdir + os.sep + i, maxBytes=1, backupCount=1000)
                log.doRollover()

            try:
                vj.structure = read_poscar(workdir + os.sep + 'CONTCAR')
            except ValueError:
                print('Error reading CONTCAR')

            vj.set_inputs()
            properties = vj.outcar
            status = self.status[entry_id]
            newentry = self.population.db.update(entry_id, structure=vj.structure, properties=properties, status=status)

            vj.save_json(workdir + os.sep + 'vaspjob.json')
            wf = open(workdir + os.sep + 'entry.json', 'w')
            json.dump(newentry, wf, sort_keys=True, indent=4, separators=(',', ': '))
            wf.close()
            return True
        else:
            vj.set_inputs()
            status = self.status[entry_id]
            newentry = self.population.db.update(entry_id, structure=vj.structure, status=status)

            vj.save_json(workdir + os.sep + 'vaspjob.json')
            wf = open(workdir + os.sep + 'entry.json', 'w')
            json.dump(newentry, wf, sort_keys=True, indent=4, separators=(',', ': '))
            wf.close()
            return True