|
| 1 | +# |
| 2 | +# This script can be used for any purpose without limitation subject to the |
| 3 | +# conditions at http://www.ccdc.cam.ac.uk/Community/Pages/Licences/v2.aspx |
| 4 | +# |
| 5 | +# This permission notice and the following statement of attribution must be |
| 6 | +# included in all copies or substantial portions of this script. |
| 7 | +# |
| 8 | +# 2016-12-06 - created by Anthony Reilly, The Cambridge Crystallographic Data Centre based on code from Andrew Maloney, CCDC |
| 9 | +# 2021-02-24 - updated by Alex Moldovan, The Cambridge Crystallographic Data Centre |
| 10 | +# |
| 11 | + |
| 12 | +import os |
| 13 | +from ccdc.utilities import ApplicationInterface |
| 14 | + |
| 15 | + |
| 16 | +def make_castep_input(crystal, kp_spacing=0.06, cut_off=750.000, task='SinglePoint', di_opt=False): |
| 17 | + # cell file |
| 18 | + with open('%s.cell' % crystal.identifier, 'w') as cell_file: |
| 19 | + cell_file.write('%BLOCK LATTICE_ABC\n') |
| 20 | + cell_file.write(' %11.7f %11.7f %11.7f\n' % crystal.cell_lengths) |
| 21 | + cell_file.write(' %11.7f %11.7f %11.7f\n' % crystal.cell_angles) |
| 22 | + cell_file.write('%ENDBLOCK LATTICE_ABC\n\n') |
| 23 | + cell_file.write('%BLOCK POSITIONS_FRAC\n') |
| 24 | + for op in crystal.symmetry_operators: |
| 25 | + mol = crystal.symmetric_molecule(op, [0, 0, 0], force=False) |
| 26 | + for atom in mol.atoms: |
| 27 | + cell_file.write(' %s %19.16f %19.16f %19.16f\n' % (atom.atomic_symbol, |
| 28 | + atom.fractional_coordinates.x, |
| 29 | + atom.fractional_coordinates.y, |
| 30 | + atom.fractional_coordinates.z)) |
| 31 | + cell_file.write('%ENDBLOCK POSITIONS_FRAC\n\n') |
| 32 | + |
| 33 | + cell_file.write('KPOINT_MP_SPACING ' + str(kp_spacing) + '\n\n') |
| 34 | + |
| 35 | + cell_file.write('%BLOCK SYMMETRY_OPS\n') |
| 36 | + for op in crystal.symmetry_operators: |
| 37 | + rotation = crystal.symmetry_rotation(op) |
| 38 | + trans = crystal.symmetry_translation(op) |
| 39 | + cell_file.write(' %18.15f %18.15f %18.15f\n' % (rotation[0], rotation[1], rotation[2])) |
| 40 | + cell_file.write(' %18.15f %18.15f %18.15f\n' % (rotation[3], rotation[4], rotation[5])) |
| 41 | + cell_file.write(' %18.15f %18.15f %18.15f\n' % (rotation[6], rotation[7], rotation[8])) |
| 42 | + cell_file.write(' %18.15f %18.15f %18.15f\n' % (trans[0], trans[1], trans[2])) |
| 43 | + cell_file.write('###\n') |
| 44 | + cell_file.write('%ENDBLOCK SYMMETRY_OPS\n\n') |
| 45 | + |
| 46 | + # param file |
| 47 | + with open('%s.param' % crystal.identifier, 'w') as param_file: |
| 48 | + param_file.write('task : ' + task + '\n') |
| 49 | + param_file.write('comment : CASTEP calculation for %s\n' % crystal.identifier) |
| 50 | + |
| 51 | + param_file.write('xc_functional : PBE\n') |
| 52 | + param_file.write('sedc_scheme : TS\n') |
| 53 | + |
| 54 | + param_file.write('metals_method : dm\n') |
| 55 | + param_file.write('mixing_scheme : Pulay\n') |
| 56 | + param_file.write('spin_polarized : false\n') |
| 57 | + param_file.write('opt_strategy : speed\n') |
| 58 | + param_file.write('cut_off_energy : ' + str(cut_off) + '\n') |
| 59 | + param_file.write('grid_scale : 2.0\n') |
| 60 | + param_file.write('fine_grid_scale : 3.0\n') |
| 61 | + param_file.write('elec_energy_tol : 1.000e-008\n') |
| 62 | + param_file.write('fix_occupancy : true\n') |
| 63 | + if task != 'SinglePoint': |
| 64 | + param_file.write('finite_basis_corr : 2\n') |
| 65 | + |
| 66 | + param_file.write('geom_modulus_est : 50 GPa\n') |
| 67 | + param_file.write('geom_max_iter : 200\n') |
| 68 | + param_file.write('num_backup_iter : 1\n') |
| 69 | + |
| 70 | + param_file.write('geom_energy_tol : 5E-06\n') |
| 71 | + param_file.write('geom_stress_tol : 0.02\n') |
| 72 | + param_file.write('geom_disp_tol : 1E-03\n') |
| 73 | + param_file.write('geom_force_tol : 5E-03\n') |
| 74 | + if di_opt: |
| 75 | + param_file.write('geom_method : delocalised \n') |
| 76 | + |
| 77 | + param_file.write('write_cif_structure : true\n') |
| 78 | + param_file.write('write_cell_structure : true\n') |
| 79 | + param_file.write('#continuation : default\n') |
| 80 | + |
| 81 | + return True |
| 82 | + |
| 83 | + |
| 84 | +if __name__ == '__main__': |
| 85 | + helper = ApplicationInterface() |
| 86 | + entry = helper.current_entry |
| 87 | + crystal = entry.crystal |
| 88 | + os.chdir(helper.output_directory_path) |
| 89 | + make_castep_input(crystal) |
0 commit comments