def get_geometry(self): try: geometry = read_from_record(self.root_path, 'optimized_geometry', 'geo_opt') if isinstance(self.fixed_atoms, list) and len( self.fixed_atoms) == 2: geometry = Geometry(geometry=geometry, fixed_atoms=self.fixed_atoms) else: geometry = Geometry(geometry=geometry) except KeyError as e: print(e) print('Optimized lattice parameter not found!' 'Please check out?') sys.exit() # here need a better way to deal with return geometry
def geo_opt(path): rec = 'Geometry Optimization begins.\n' rec += '---' * 25 print(rec) record(path, rec) # read infos from input.ini file Ini = IniReader() project_name, system_type, group_type, lattice_parameter, number_atoms, geometry, fixed_atoms = Ini.get_basic_info( ) record_data_json(path, 'project_name', project_name) record_data_json(path, 'system_type', system_type) record_data_json(path, 'lattice_parameter', lattice_parameter) record_data_json(path, 'geometry', geometry) record_data_json(path, 'fixed_atoms', fixed_atoms) if isinstance(fixed_atoms, list) and len(fixed_atoms) == 2: geometry = Geometry(geometry=geometry, fixed_atoms=fixed_atoms) else: geometry = Geometry(geometry=geometry) bs, functional, nodes, crystal_path = Ini.get_geo_opt() record_data_json(path, 'basis_set', bs, section='geo_opt') record_data_json(path, 'functional', functional, section='geo_opt') record_data_json(path, 'nodes', nodes, section='geo_opt') job = os.path.join(path, 'geo_opt') job = Job(job) if not GeoOpt.if_job_finish(job): # generation of INPUT Geo_Inp = GeoOpt.Geo_Opt_Input(job, project_name, system_type, group_type, lattice_parameter, geometry, bs, functional) Geo_Inp.gen_input() # copy file and submit the job job = GeoOpt.submit(job, nodes, crystal_path, path) else: job.status = 'finished' # read and record the results GeoOpt.read_record_result(job, path) rec = 'Geometry optimization finished!\n' rec += '***' * 25 print(rec) record(path, rec)
def get_geometry(self): path = self.hf1_job.root_path json_file = os.path.join(path, 'opt_geo_and_latt.json') with open(json_file, 'r') as f: data = json.load(f) geo_data = data['geometry'] coor = '({}, {})'.format(self.hf1_job.x, self.hf1_job.z) try: geometry = geo_data[coor] if type(self.fixed_atoms) == list and len(self.fixed_atoms) == 2: geometry = Geometry(json_form=geometry, fixed_atoms=self.fixed_atoms) else: geometry = Geometry(json_form=geometry) except KeyError as e: print(e) print('Geometry not found!' 'Please check out?') sys.exit() # here need a better way to deal with return geometry
def get_diff_geometry(self): new_geometrys = [] new_geometrys_dict = {} z_coord = [] for atom in self.upper_layer: z = float(atom[4]) z_coord.append(z) for dist in self.delta_distances: # print(dist) new_upper_layer = deepcopy(self.upper_layer) for i in range(len(self.upper_layer)): new_atom_z = z_coord[i] + dist new_atom_z = round(new_atom_z, 12) new_upper_layer[i][4] = new_atom_z new_geometry = new_upper_layer + self.under_layer new_geometry = Geometry(geometry=new_geometry) new_geometrys.append(new_geometry) new_geometrys_dict[dist] = new_geometry return new_geometrys_dict
def get_new_geometrys(self): new_geometrys = [] new_geometrys_dict = {} x_coord = [] for atom in self.upper_layer: x = float(atom[2]) x_coord.append(x) if self.shift_series != 'default': self.delta_displacement = [s for s in self.shift_series if s != 0 ] # setting the relative shift manually for displace in self.delta_displacement: new_upper_layer = deepcopy(self.upper_layer) for i in range(len(self.upper_layer)): new_x = x_coord[i] + displace new_upper_layer[i][2] = new_x new_geometry = new_upper_layer + self.under_layer new_geometry = Geometry(geometry=new_geometry) new_geometrys.append(new_geometry) new_geometrys_dict[displace] = new_geometry return new_geometrys_dict
def hf1(path, moni): rec = 'First Hartree Fock Calculation begins.\n' rec += '---' * 25 print(rec) record(path, rec) # read info from input.ini file init_dist = HF1.read_init_dis(path) Ini = ReadIni() name, slab_or_molecule, group, lattice_parameter, number_of_atoms, geometry, fixed_atoms = Ini.get_basic_info( ) geometry = Geometry(geometry=geometry) bs_type, nodes, crystal_path = Ini.get_hf1() cal_parameters = Ini.get_cal_parameters('HF1') if nodes == '' or nodes == 'default': nodes = 12 record_data_json(path, 'basis_set', bs_type, section='hf1') record_data_json(path, 'nodes', nodes, section='hf1') jobs_GeoOpt = HF1.select_jobs(path) jobs_HF1 = [] new_jobs = [] hf1_jobs_finished = [] # input for the whole system # print('number Geo Opt', len(jobs_GeoOpt)) for job in jobs_GeoOpt: path_GeoOpt = job.path # Bilayer path_HF1 = path_GeoOpt.replace('geo_opt', 'hf1') new_job = Job(path_HF1) if not HF1.if_cal_finish(new_job): Inp = HF1.Input(job, name, slab_or_molecule, group, bs_type, layertype='bilayer', fiexed_atoms=fixed_atoms, cal_parameters=cal_parameters, geometry=geometry, lattice_parameters=lattice_parameter) Inp.gen_input() HF1.copy_submit_scr(new_job, nodes, crystal_path) new_jobs.append(new_job) else: hf1_jobs_finished.append(new_job) jobs_HF1.append(new_job) # upperlayer path_upper = os.path.join(path_HF1, 'upperlayer') new_job = Job(path_upper) if not HF1.if_cal_finish(new_job): Inp = HF1.Layer_Inp(job, name, slab_or_molecule, group, bs_type, layertype='upperlayer', fiexed_atoms=fixed_atoms, cal_parameters=cal_parameters) Inp.gen_input() HF1.copy_submit_scr(new_job, nodes, crystal_path) new_jobs.append(new_job) else: hf1_jobs_finished.append(new_job) jobs_HF1.append(new_job) # underlayer path_under = os.path.join(path_HF1, 'underlayer') new_job = Job(path_under) if not HF1.if_cal_finish(new_job): Inp = HF1.Layer_Inp(job, name, slab_or_molecule, group, bs_type, layertype='underlayer', fiexed_atoms=fixed_atoms, cal_parameters=cal_parameters) Inp.gen_input() HF1.copy_submit_scr(new_job, nodes, crystal_path) new_jobs.append(new_job) else: hf1_jobs_finished.append(new_job) jobs_HF1.append(new_job) # Submit the calculation job hf1_jobs_finished_new = HF1.submit(new_jobs, nodes, crystal_path, moni) hf1_jobs_finished += hf1_jobs_finished_new # read calculation results HF1.read_all_results_hf1(hf1_jobs_finished, init_dist) # deal with not-converged jobs # jobs_not_converged = [job for job in hf1_jobs_finished if job.status == 'not converged'] # hf1_jobs_finished = [job for job in hf1_jobs_finished if job.status != 'not converged'] # # try to not use GUESSP # for job in jobs_not_converged: # HF1.delete_guessp(job) # new_jobs_finished = HF1.submit(jobs_not_converged) # hf1_jobs_finished += new_jobs_finished # jobs_not_converged = [job for job in hf1_jobs_finished if job.status == 'not converged'] # hf1_jobs_finished = [job for job in hf1_jobs_finished if job.status != 'not converged'] # # if still not converged, try to change some parameters # while len(jobs_not_converged) > 0: # HF1.change_parameters(jobs_not_converged) # new_jobs_finished = HF1.submit(jobs_not_converged) # hf1_jobs_finished += hf1_jobs_finished_new # jobs_not_converged = [job for job in hf1_jobs_finished if job.status == 'not converged'] # hf1_jobs_finished = [job for job in hf1_jobs_finished if job.status != 'not converged'] rec = 'HF1 finished!\n' rec += '***' * 25 print(rec) record(path, rec)
def hf1_start(path, moni): rec = 'First Hartree Fock Calculation begins.\n' rec += '---' * 25 print(rec) record(path, rec) # read infos from input.ini file Ini = ReadIni() name, slab_or_molecule, group, lattice_parameter, number_atoms, geometry, fixed_atoms = Ini.get_basic_info( ) distance_series, shift_series = Ini.get_series() cal_parameters = Ini.get_cal_parameters('Geo_Opt') record_data_json(path, 'project_name', name) record_data_json(path, 'system_type', slab_or_molecule) record_data_json(path, 'lattice_parameter', lattice_parameter) record_data_json(path, 'geometry', geometry) record_data_json(path, 'fixed_atoms', fixed_atoms) if isinstance(fixed_atoms, list) and len(fixed_atoms) == 2: geometry = Geometry(geometry=geometry, fixed_atoms=fixed_atoms) else: geometry = Geometry(geometry=geometry) original_geometry = deepcopy(geometry) bs_type, nodes, crystal_path = Ini.get_hf1() cal_parameters = Ini.get_cal_parameters('HF1') if nodes == '' or nodes == 'default': nodes = 12 record_data_json(path, 'basis_set', bs_type, section='hf1') record_data_json(path, 'nodes', nodes, section='hf1') jobs_HF1 = [] new_jobs = [] hf1_jobs_finished = [] # generation of the first INPUT dirname = 'x_0/z_0' job = os.path.join(path, 'hf1') job = os.path.join(job, dirname) job = Job(job) jobs_finished = [] GeoOPt.write_init_dist(geometry, path) job_geo_dict = {job: geometry} # Generation of the job with different layer distance diff_distances = GeoOPt.Range_of_Distances(geometry, distance_series) geo_with_diff_distance = diff_distances.get_geo_series() init_distance = diff_distances.init_distance for distance, geometry in geo_with_diff_distance.items(): new_job = deepcopy(job) new_z_dirname = 'z_{0:.3f}'.format(distance) new_job.reset('z_dirname', new_z_dirname) job_geo_dict[new_job] = geometry # Generation of the job with different displacement, produce ((0.1, 0), # (0.25, 0), (0.35, 0), (0.5, 0)) range_of_displacement = GeoOPt.Range_of_Displacement( original_geometry, shift_series) geo_with_diff_displacement = range_of_displacement.get_geo_series() job_geo_dict_dis = {} for displacement, geometry in geo_with_diff_displacement.items(): new_job = deepcopy(job) new_x_dirname = 'x_{0:.2f}'.format(displacement) new_job.reset('x_dirname', new_x_dirname) job_geo_dict_dis[new_job] = geometry job_geo_dict[new_job] = geometry # generate jobs with various distance under different relatvie shifts for shift, geometry in geo_with_diff_displacement.items(): Geo_with_diff_Dis_diff_Distance = GeoOPt.Range_of_Distances( geometry, distance_series) geo_with_diff_dis_diff_distance = Geo_with_diff_Dis_diff_Distance.get_geo_series( ) distances = sorted(geo_with_diff_dis_diff_distance.keys()) loc = 3 for i in range(len(distances)): if distances[i - 1] <= 0 and distances[i] >= 0: loc = i # Select the some of the distance values for key in list(geo_with_diff_dis_diff_distance.keys()): if key not in distances[loc - 2:loc + 2]: del geo_with_diff_dis_diff_distance[key] # print(list(geo_with_diff_dis_diff_distance.keys())) for distance, geo in geo_with_diff_dis_diff_distance.items(): dirname = 'x_{0:.2f}/z_{1:.3f}'.format(shift, distance) new_path = os.path.join(path, os.path.join('geo_opt', dirname)) new_job = Job(new_path) # print(new_job) job_geo_dict[new_job] = geo # generation all INPUT files for job, geometry in job_geo_dict.items(): if not HF1.if_cal_finish(job): # print('JOB not finished yet: ', job) HF1_Inp = HF1.Input(job, name, slab_or_molecule, group, bs_type, layertype='bilayer', fiexed_atoms=fixed_atoms, cal_parameters=cal_parameters, geometry=geometry, lattice_parameters=lattice_parameter) HF1_Inp.gen_input() HF1.copy_submit_scr(job, nodes, crystal_path) new_jobs.append(job) else: jobs_finished.append(job) jobs_HF1.append(job) # deal with layers # upperlayer path_upper = os.path.join(job.path, 'upperlayer') upper_job = Job(path_upper) if not HF1.if_cal_finish(upper_job): Inp = HF1.Layer_Inp(job, name, slab_or_molecule, group, bs_type, layertype='upperlayer', fiexed_atoms=fixed_atoms, cal_parameters=cal_parameters, geometry=geometry, lattice_parameters=lattice_parameter) Inp.gen_input() HF1.copy_submit_scr(upper_job, nodes, crystal_path) new_jobs.append(upper_job) else: hf1_jobs_finished.append(upper_job) jobs_HF1.append(upper_job) # underlayer path_under = os.path.join(job.path, 'underlayer') under_job = Job(path_under) if not HF1.if_cal_finish(under_job): Inp = HF1.Layer_Inp(job, name, slab_or_molecule, group, bs_type, layertype='underlayer', fiexed_atoms=fixed_atoms, cal_parameters=cal_parameters, geometry=geometry, lattice_parameters=lattice_parameter) Inp.gen_input() HF1.copy_submit_scr(under_job, nodes, crystal_path) new_jobs.append(under_job) else: hf1_jobs_finished.append(under_job) jobs_HF1.append(upper_job) # Submit the calculation job hf1_jobs_finished_new = HF1.submit(new_jobs, nodes, crystal_path, moni) hf1_jobs_finished += hf1_jobs_finished_new # read calculation results init_dist = HF1.read_init_dis(path) HF1.read_all_results_hf1(hf1_jobs_finished, init_dist) rec = 'HF1 finished!\n' rec += '***' * 25 print(rec) record(path, rec)
def geo_opt(path, moni): rec = 'Geometry Optimization begins.' print(rec) record(path, rec) GeoOPt.creat_geo_lat_json(path) # might be deleted # read infos from input.ini file Ini = ReadIni() name, slab_or_molecule, group, lattice_parameter, number_atoms, geometry, fixed_atoms = Ini.get_basic_info() distance_series, shift_series = Ini.get_series() cal_parameters = Ini.get_cal_parameters('Geo_Opt') record_data_json(path, 'project_name', name) record_data_json(path, 'system_type', slab_or_molecule) record_data_json(path, 'lattice_parameter', lattice_parameter) record_data_json(path, 'geometry', geometry) record_data_json(path, 'fixed_atoms', fixed_atoms) if isinstance(fixed_atoms, list) and len(fixed_atoms) == 2: geometry = Geometry(geometry=geometry, fixed_atoms=fixed_atoms) else: geometry = Geometry(geometry=geometry) original_geometry = deepcopy(geometry) bs_type, functional, nodes, crystal_path = Ini.get_geo_opt() record_data_json(path, 'basis_set', bs_type, section='geo_opt') record_data_json(path, 'functional', functional, section='geo_opt') record_data_json(path, 'nodes', nodes, section='geo_opt') # test_ini_read(group, lattice_parameter, number_atoms, slab_or_molecule) jobs = [] new_jobs = [] # generation of the first INPUT dirname = 'x_0/z_0' job = os.path.join(path, 'geo_opt') job = os.path.join(job, dirname) job = Job(job) jobs_finished = [] if not if_cal_finish(job): Geo_Inp = GeoOPt.Geo_Opt_Input( job, name, slab_or_molecule, group, lattice_parameter, geometry, bs_type, functional, cal_parameters) Geo_Inp.gen_input() new_jobs.append(job) else: jobs_finished.append(job) jobs.append(job) GeoOPt.write_init_dist(geometry, path) job_geo_dict = {} # Generation of the job with different layer distance diff_distances = GeoOPt.Range_of_Distances(geometry, distance_series) geo_with_diff_distance = diff_distances.get_geo_series() init_distance = diff_distances.init_distance for distance, geometry in geo_with_diff_distance.items(): new_job = deepcopy(job) new_z_dirname = 'z_{0:.3f}'.format(distance) new_job.reset('z_dirname', new_z_dirname) job_geo_dict[new_job] = geometry # Generation of the job with different displacement, produce ((0.1, 0), # (0.25, 0), (0.35, 0), (0.5, 0)) range_of_displacement = GeoOPt.Range_of_Displacement( original_geometry, shift_series) geo_with_diff_displacement = range_of_displacement.get_geo_series() job_geo_dict_dis = {} for displacement, geometry in geo_with_diff_displacement.items(): new_job = deepcopy(job) new_x_dirname = 'x_{0:.2f}'.format(displacement) new_job.reset('x_dirname', new_x_dirname) job_geo_dict_dis[new_job] = geometry job_geo_dict[new_job] = geometry # generate jobs with various distance under different relatvie shifts for shift, geometry in geo_with_diff_displacement.items(): Geo_with_diff_Dis_diff_Distance = GeoOPt.Range_of_Distances(geometry, distance_series) geo_with_diff_dis_diff_distance = Geo_with_diff_Dis_diff_Distance.get_geo_series() distances = list(geo_with_diff_dis_diff_distance.keys()) distances.sort() loc = 3 for i in range(len(distances)): if distances[i-1] <= 0 and distances[i] >= 0: loc = i # Select the some of the distance values for key in list(geo_with_diff_dis_diff_distance.keys()): if key not in distances[loc-2:loc+2]: del geo_with_diff_dis_diff_distance[key] # print(list(geo_with_diff_dis_diff_distance.keys())) for distance, geo in geo_with_diff_dis_diff_distance.items(): dirname = 'x_{0:.2f}/z_{1:.3f}'.format(shift, distance) new_path = os.path.join(path, os.path.join('geo_opt', dirname)) new_job = Job(new_path) # print(new_job) job_geo_dict[new_job] = geo # generation all INPUT files besides the first one above for job, geometry in job_geo_dict.items(): if not if_cal_finish(job): # print('JOB not finished yet: ', job) Geo_Inp = GeoOPt.Geo_Opt_Input( job, name, slab_or_molecule, group, lattice_parameter, geometry, bs_type, functional, cal_parameters) Geo_Inp.gen_input() new_jobs.append(job) else: jobs_finished.append(job) jobs.append(job) # Copy files and Submit the calculation job above new_jobs_finished = GeoOPt.submit( new_jobs, nodes, crystal_path, moni) jobs_finished += new_jobs_finished # # Select the optimal distance of each x point # para = [ # name, # slab_or_molecule, # group, # lattice_parameter, # bs_type, # functional, # nodes, # crystal_path] # # x_10 # x_10 = {job: geometry for job, geometry in job_geo_dict_dis.items() # if job.x == '0.10'} # jobs_10 = [job for job in job_geo_dict_dis.keys() if job.x == '0.10'] # init_job_10 = jobs_10[0] # jobs_10, x_10, min_job_10, jobs_10_finished = GeoOPt.select_optimal_dist( # x_10, 0, para) # jobs += jobs_10 # # x_25 # x_25 = {job: geometry for job, geometry in job_geo_dict_dis.items() # if job.x == '0.25'} # jobs_25 = [job for job in job_geo_dict_dis.keys() if job.x == '0.25'] # init_job_25 = jobs_25[0] # pos_min_10 = look_for_in_list(jobs_10, min_job_10) # pos_init_10 = look_for_in_list(jobs_10, init_job_10) # diff = pos_min_10 - pos_init_10 # jobs_25, x_25, min_job_25, jobs_25_finished = GeoOPt.select_optimal_dist( # x_25, diff, para) # jobs += jobs_25 # # x_35 # x_35 = {job: geometry for job, geometry in job_geo_dict_dis.items() # if job.x == '0.35'} # init_job_35 = list(x_35.keys())[0] # pos_min_25 = look_for_in_list(jobs_25, min_job_25) # pos_init_25 = look_for_in_list(jobs_25, init_job_25) # diff = pos_min_25 - pos_init_25 # jobs_35, x_35, min_job_35, jobs_35_finished = GeoOPt.select_optimal_dist( # x_35, diff, para) # jobs += jobs_35 # # x_50 # x_50 = {job: geometry for job, geometry in job_geo_dict_dis.items() # if job.x == '0.50'} # init_job_50 = list(x_50.keys())[0] # pos_min_35 = look_for_in_list(jobs_35, min_job_35) # pos_init_35 = look_for_in_list(jobs_35, init_job_35) # diff = pos_min_35 - pos_init_35 # jobs_50, x_50, min_job_50, jobs_50_finished = GeoOPt.select_optimal_dist( # x_50, diff, para) # jobs += jobs_50 # # # read calculation results # jobs_finished += jobs_10_finished # jobs_finished += jobs_25_finished # jobs_finished += jobs_35_finished # jobs_finished += jobs_50_finished GeoOPt.read_all_results(jobs_finished, init_distance) rec = 'Geometry optimization finished!\n' rec += '***'*25 print(rec) record(path, rec)