def my_error_function(rr): # Get a unique path for GULP jobs from the MPI rank. Set to '0' for serial jobs try: path = str(pool.rank) except: path = '0' # Calculate Ground State md_gs_job = gulp.job(path=path) md_gs_job.structure = gt_gs md_gs_job.forcefield = ezff.generate_forcefield(template, rr, FFtype='reaxff') md_gs_job.options['pbc'] = False md_gs_job.options['relax_atoms'] = False md_gs_job.options['relax_cell'] = False # Run GULP calculation md_gs_job.run(command='gulp') # Read output from completed GULP job and clean-up md_gs_energy = md_gs_job.read_energy() md_gs_job.cleanup() # Calculate PES Scan for frequency error md_freq_scan_job = gulp.job(path=path) md_freq_scan_job.structure = gt_freq_scan md_freq_scan_job.forcefield = ezff.generate_forcefield(template, rr, FFtype='reaxff') md_freq_scan_job.options['pbc'] = False md_freq_scan_job.options['relax_atoms'] = False md_freq_scan_job.options['relax_cell'] = False # Run GULP calculation md_freq_scan_job.run(command='gulp') # Read output from completed GULP job and clean-up md_freq_scan_energy = md_freq_scan_job.read_energy() md_freq_scan_job.cleanup() # Calculate PES Scan for dissociation error md_full_scan_job = gulp.job(path=path) md_full_scan_job.structure = gt_full_scan md_full_scan_job.forcefield = ezff.generate_forcefield(template, rr, FFtype='reaxff') md_full_scan_job.options['pbc'] = False md_full_scan_job.options['relax_atoms'] = False md_full_scan_job.options['relax_cell'] = False # Run GULP calculation md_full_scan_job.run(command='gulp') # Read output from completed GULP job and clean-up md_full_scan_energy = md_full_scan_job.read_energy() md_full_scan_job.cleanup() # Calculate error freq_error = ezff.error_energy(md_freq_scan_energy - md_gs_energy, gt_freq_scan_energy - gt_gs_energy, weights='minima') dissociation_error = ezff.error_energy(md_full_scan_energy - md_gs_energy, gt_full_scan_energy - gt_gs_energy, weights='dissociation') return [freq_error, dissociation_error]
def my_error_function(rr): # Get a unique path for GULP jobs from the MPI rank. Set to '0' for serial jobs try: path = str(pool.rank) except: path = '0' # Calculate Ground State Charges md_gs_job = gulp.job(path = path) md_gs_job.structure = gt_gs md_gs_job.forcefield = ezff.generate_forcefield(template, rr, FFtype = 'reaxff') md_gs_job.options['pbc'] = False md_gs_job.options['relax_atoms'] = False md_gs_job.options['relax_cell'] = False md_gs_job.options['atomic_charges'] = True # Run GULP calculation md_gs_job.run(command='gulp') # Read output from completed GULP job and clean-up md_gs_atomic_charges = md_gs_job.read_atomic_charges() md_gs_job.cleanup() # Calculate Relaxation md_relax_job = gulp.job(path = path) md_relax_job.structure = gt_gs md_relax_job.forcefield = ezff.generate_forcefield(template, rr, FFtype = 'reaxff') md_relax_job.options['pbc'] = False md_relax_job.options['relax_atoms'] = True md_relax_job.options['relax_cell'] = False md_relax_job.options['atomic_charges'] = True # Run GULP calculation md_relax_job.run(command='gulp') # Read output from completed GULP job and clean-up md_relax = md_relax_job.read_structure() md_relax_job.cleanup() # Calculate error charg_error = ezff.error_atomic_charges(MD=md_gs_atomic_charges, GT=gt_gs_atomic_charges) disp_error = ezff.error_structure_distortion(MD=md_relax, GT=gt_gs) return [charg_error, disp_error]
def my_error_function(variable_values): # Get rank from pool try: myrank = pool.rank except: myrank = 0 # Configure GULP job. path = str(myrank) md_job = gulp.job(path=path) md_job.structure = gt_structure md_job.forcefield = ezff.generate_forcefield(template, variable_values, FFtype='SW') md_job.options['pbc'] = True md_job.options['relax_atoms'] = True md_job.options['relax_cell'] = True # Submit job and read output md_job.run() # Calculate errors in lattice constant and elastic modulus moduli = md_job.read_elastic_moduli( ) # 6X6 elastic modulus tensor inside a list of length 1 (for a single input structure) md_bulk_modulus = np.mean([ moduli[0][i, i] for i in range(3) ]) # Bulk modulus is sum of diagonal elements in moduli[0] bulk_modulus_error = np.linalg.norm( md_bulk_modulus - gt_bulk_modulus ) # Error is the L2 norm of deviation from the ground truth value md_structure = md_job.read_structure( ) # Read relaxed structure after optimization error_abc, error_ang = ezff.error_lattice_constant( MD=md_structure, GT=gt_structure ) # error_abc = error in lattice constants, error_ang = error in lattice angles latt_error = np.linalg.norm(error_abc[0]) # error in 'a' lattice constant return [latt_error, bulk_modulus_error]
def my_error_function(variable_values): # Get rank from pool try: myrank = pool.rank except: myrank = 0 # FOR THE RELAXED STRUCTURE path = str(myrank) relaxed_job = gulp.job(path=path) ffio.write_forcefield_file(str(myrank) + '/FF', template, variable_values, verbose=False) relaxed_job.forcefield = str(myrank) + '/FF' relaxed_job.temporary_forcefield = False relaxed_job.structure = gt_structure relaxed_job.pbc = True relaxed_job.options['relax_atoms'] = True relaxed_job.options['relax_cell'] = True # Submit job and read output relaxed_job.write_script_file() relaxed_job.run(command='gulp') # Calculate errors in lattice constant and elastic modulus moduli = gulp.read_elastic_moduli(relaxed_job.path + '/' + relaxed_job.outfile) md_bulk_modulus = np.mean([moduli[i, i] for i in range(3)]) lattice = gulp.read_lattice_constant(relaxed_job.path + '/' + relaxed_job.outfile) bulk_modulus_error = np.linalg.norm(md_bulk_modulus - gt_bulk_modulus) latt_error = np.linalg.norm(lattice['err_abc'][0]) #relaxed_job.cleanup() # FINISH RELAXED JOB return [latt_error, bulk_modulus_error]
def my_error_function(variable_values): # Get rank from pool try: myrank = pool.rank except: myrank = 0 # FOR THE RELAXED STRUCTURE path = str(myrank) + '/relaxed' relaxed_job = gulp.job(path=path) ffio.write_forcefield_file(str(myrank) + '/FF', template, variable_values, verbose=False) relaxed_job.forcefield = str(myrank) + '/FF' relaxed_job.temporary_forcefield = False relaxed_job.structure = gt_relaxed_structure relaxed_job.pbc = True relaxed_job.options['relax_atoms'] = True relaxed_job.options['relax_cell'] = True relaxed_job.options['phonon_dispersion'] = True # Submit job and read output relaxed_job.options['phonon_dispersion_from'] = '0 0 0' relaxed_job.options['phonon_dispersion_to'] = '0.5 0.5 0' relaxed_job.write_script_file() relaxed_job.run(command='gulp') md_relaxed_disp_GS = gulp.read_phonon_dispersion(relaxed_job.path + '/out.gulp.disp') phon_error_relax = ezff.error_phonon_dispersion(md_relaxed_disp_GS, gt_relaxed_disp_GS, weights='acoustic') # Calculate errors in lattice constant and elastic modulus moduli = gulp.read_elastic_moduli(relaxed_job.path + '/' + relaxed_job.outfile) lattice = gulp.read_lattice_constant(relaxed_job.path + '/' + relaxed_job.outfile) a_latt_error = np.linalg.norm(lattice['err_abc'][0]) b_latt_error = np.linalg.norm(lattice['err_abc'][1]) modulus_error = np.linalg.norm((moduli[0, 0] * lattice['abc'][2] * 2.0 / 13.97) - gt_elastic_modulus) relaxed_job.cleanup() # FINISH RELAXED JOB # FOR THE COMPRESSED STRUCTURE path = str(myrank) + '/compressed' compressed_job = gulp.job(path=path) compressed_job.forcefield = str(myrank) + '/FF' compressed_job.temporary_forcefield = False compressed_job.structure = gt_compressed_structure compressed_job.pbc = True compressed_job.options['relax_atoms'] = True compressed_job.options['relax_cell'] = False compressed_job.options['phonon_dispersion'] = True # Submit job and read output compressed_job.options['phonon_dispersion_from'] = '0 0 0' compressed_job.options['phonon_dispersion_to'] = '0.5 0.5 0' compressed_job.write_script_file() compressed_job.run(command='gulp') md_compressed_disp_GS = gulp.read_phonon_dispersion(compressed_job.path + '/out.gulp.disp') phon_error_compressed = ezff.error_phonon_dispersion(md_compressed_disp_GS, gt_compressed_disp_GS, weights='acoustic') compressed_job.cleanup() # FINISH COMPRESSED JOB # FOR THE EXPANDED STRUCTURE path = str(myrank) + '/expanded' expanded_job = gulp.job(path=path) expanded_job.forcefield = str(myrank) + '/FF' expanded_job.temporary_forcefield = False expanded_job.structure = gt_expanded_structure expanded_job.pbc = True expanded_job.options['relax_atoms'] = True expanded_job.options['relax_cell'] = False expanded_job.options['phonon_dispersion'] = True # Submit job and read output expanded_job.options['phonon_dispersion_from'] = '0 0 0' expanded_job.options['phonon_dispersion_to'] = '0.5 0.5 0' expanded_job.write_script_file() expanded_job.run(command='gulp') md_expanded_disp_GS = gulp.read_phonon_dispersion(expanded_job.path + '/out.gulp.disp') phon_error_expanded = ezff.error_phonon_dispersion(md_expanded_disp_GS, gt_expanded_disp_GS, weights='acoustic') expanded_job.cleanup() # FINISH EXPANDED JOB return [ a_latt_error, b_latt_error, modulus_error, phon_error_relax, phon_error_compressed, phon_error_expanded ]
def my_error_function(variable_values): # Get rank from pool try: myrank = pool.rank except: myrank = 0 # FOR THE RELAXED STRUCTURE path = str(myrank) + '/relaxed' relaxed_job = gulp.job(path=path) relaxed_job.structure = gt_relax_structure relaxed_job.forcefield = ezff.generate_forcefield(template, variable_values, FFtype='SW') relaxed_job.options['pbc'] = True relaxed_job.options['relax_atoms'] = True relaxed_job.options['relax_cell'] = True relaxed_job.options['phonon_dispersion'] = True relaxed_job.options['phonon_dispersion_from'] = '0 0 0' relaxed_job.options['phonon_dispersion_to'] = '0.5 0.5 0' # Submit job and read output relaxed_job.run() # Read output from completed GULP job and cleanup job files md_relax_disp_GS = relaxed_job.read_phonon_dispersion() md_relaxed_moduli = relaxed_job.read_elastic_moduli() md_relaxed_structure = relaxed_job.read_structure() relaxed_job.cleanup() # FINISH RELAXED JOB # FOR THE COMPRESSED STRUCTURE path = str(myrank) + '/compressed' compressed_job = gulp.job(path=path) compressed_job.structure = gt_compressed_structure compressed_job.forcefield = ezff.generate_forcefield(template, variable_values, FFtype='SW') compressed_job.options['pbc'] = True compressed_job.options['relax_atoms'] = True compressed_job.options['relax_cell'] = False compressed_job.options['phonon_dispersion'] = True compressed_job.options['phonon_dispersion_from'] = '0 0 0' compressed_job.options['phonon_dispersion_to'] = '0.5 0.5 0' # Submit job and read output compressed_job.run() # Read output from completed GULP job and cleanup job files md_compressed_disp_GS = compressed_job.read_phonon_dispersion() compressed_job.cleanup() # FINISH COMPRESSED JOB # FOR THE EXPANDED STRUCTURE path = str(myrank) + '/expanded' expanded_job = gulp.job(path=path) expanded_job.structure = gt_expanded_structure expanded_job.forcefield = ezff.generate_forcefield(template, variable_values, FFtype='SW') expanded_job.options['pbc'] = True expanded_job.options['relax_atoms'] = True expanded_job.options['relax_cell'] = False expanded_job.options['phonon_dispersion'] = True expanded_job.options['phonon_dispersion_from'] = '0 0 0' expanded_job.options['phonon_dispersion_to'] = '0.5 0.5 0' # Submit job and read output expanded_job.run() # Read output from completed GULP job and cleanup job files md_expanded_disp_GS = expanded_job.read_phonon_dispersion() expanded_job.cleanup() # FINISH EXPANDED JOB # Compute 5 errors from the 3 GULP jobs error_abc, error_ang = ezff.error_lattice_constant(MD=md_relaxed_structure, GT=gt_relax_structure) a_lattice_error = np.linalg.norm( error_abc[0]) # Error in 'a' lattice constant b_lattice_error = np.linalg.norm( error_abc[1]) # Error in 'b' lattice constant md_c11 = md_relaxed_moduli[0][0, 0] * md_relaxed_structure.box[2, 2] * ( 2.0 / 13.97 ) # Extracting c11 for a bulk-like layered structure from the monolayer GULP calculation modulus_error = np.linalg.norm(md_c11 - gt_c11) phon_error_relaxed = ezff.error_phonon_dispersion(MD=md_relax_disp_GS, GT=gt_relax_disp_GS, weights='acoustic') phon_error_expanded = ezff.error_phonon_dispersion(MD=md_expanded_disp_GS, GT=gt_expanded_disp_GS, weights='acoustic') phon_error_compressed = ezff.error_phonon_dispersion( MD=md_compressed_disp_GS, GT=gt_compressed_disp_GS, weights='acoustic') return [ a_lattice_error, b_lattice_error, modulus_error, phon_error_relaxed, phon_error_compressed, phon_error_expanded ]
def my_error_function(rr): # Get a unique path for GULP jobs from the MPI rank. Set to '0' for serial jobs try: path = str(pool.rank) except: path = '0' # Calculate_Ground_State gt_gs = qchem.read_ground_state('ground_truths/optCHOSx.out') gt_gs_energy = gt_gs.snaplist[0].energy md_gs_job = gulp.job(path = path) ffio.write_forcefield_file(md_gs_job.path+'/FF',template,rr,verbose=False) md_gs_job.forcefield = md_gs_job.path + '/FF' md_gs_job.temporary_forcefield = False md_gs_job.structure = gt_gs md_gs_job.pbc = False md_gs_job.options['relax_atoms'] = False md_gs_job.options['relax_cell'] = False md_gs_job.write_script_file(convert_reax_forcefield) md_gs_job.run(command='gulp') md_gs_energy = gulp.read_energy(md_gs_job.path + '/' + md_gs_job.outfile) md_gs_job.cleanup() # Calculate Small Length Scan for Bond Frequencies gt_freq_scan = qchem.read_scan('ground_truths/frequency_length_scan/CHOSx.out') md_freq_scan_energies = [] gt_freq_scan_energies = [] for snapID, snapshot in enumerate(gt_freq_scan.snaplist): gt_freq_scan_energies.append(snapshot.energy) md_freq_scan_job = gulp.job(path = path) ffio.write_forcefield_file(md_freq_scan_job.path+'/FF',template,rr,verbose=False) thisstructure = xtal.AtTraj() thisstructure.snaplist.append(snapshot) md_freq_scan_job.forcefield = md_freq_scan_job.path + '/FF' md_freq_scan_job.temporary_forcefield = False md_freq_scan_job.structure = thisstructure md_freq_scan_job.pbc = False md_freq_scan_job.options['relax_atoms'] = False md_freq_scan_job.options['relax_cell'] = False md_freq_scan_job.write_script_file(convert_reax_forcefield) md_freq_scan_job.run(command='gulp') md_freq_scan_energy = gulp.read_energy(md_freq_scan_job.path + '/' + md_freq_scan_job.outfile) md_freq_scan_energies.append(md_freq_scan_energy) md_freq_scan_job.cleanup() del md_freq_scan_job # Calculate error md_freq_scan_energies = np.array(md_freq_scan_energies) gt_freq_scan_energies = np.array(gt_freq_scan_energies) md_gs_energy = np.array(md_gs_energy) gt_gs_energy = np.array(gt_gs_energy) freq_error = ezff.error_PES_scan( md_freq_scan_energies-md_gs_energy, gt_freq_scan_energies-gt_gs_energy, weights = 'minima') # Calculate Full Length Scan for Bond Dissociation Energy gt_dis_scan = qchem.read_scan(['ground_truths/dissociation_length_scan/CHOSx.run1.out', 'ground_truths/dissociation_length_scan/CHOSx.run2.out', 'ground_truths/dissociation_length_scan/CHOSx.run3.out']) md_dis_scan_energies = [] gt_dis_scan_energies = [] for snapID, snapshot in enumerate(gt_dis_scan.snaplist): gt_dis_scan_energies.append(snapshot.energy) md_dis_scan_job = gulp.job(path = path) ffio.write_forcefield_file(md_dis_scan_job.path+'/FF',template,rr,verbose=False) thisstructure = xtal.AtTraj() thisstructure.snaplist.append(snapshot) md_dis_scan_job.forcefield = md_dis_scan_job.path + '/FF' md_dis_scan_job.temporary_forcefield = False md_dis_scan_job.structure = thisstructure md_dis_scan_job.pbc = False md_dis_scan_job.options['relax_atoms'] = False md_dis_scan_job.options['relax_cell'] = False md_dis_scan_job.write_script_file(convert_reax_forcefield) md_dis_scan_job.run(command='gulp') md_dis_scan_energy = gulp.read_energy(md_dis_scan_job.path + '/' + md_dis_scan_job.outfile) md_dis_scan_energies.append(md_dis_scan_energy) md_dis_scan_job.cleanup() del md_dis_scan_job # Calculate error md_dis_scan_energies = np.array(md_dis_scan_energies) gt_dis_scan_energies = np.array(gt_dis_scan_energies) md_gs_energy = np.array(md_gs_energy) gt_gs_energy = np.array(gt_gs_energy) dis_error = ezff.error_PES_scan( md_dis_scan_energies-md_gs_energy, gt_dis_scan_energies-gt_gs_energy, weights = 'dissociation') return [freq_error, dis_error]