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 md_gs_job = rxmd.job(path=path) md_gs_job.structure = gt_gs md_gs_job.forcefield = ezff.generate_forcefield(template, rr, FFtype='reaxff2', outfile=md_gs_job.path + '/ffield') # Run rxmd calculation md_gs_job.run(command='rxmd') # 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 = rxmd.job(path=path) md_freq_scan_job.structure = gt_freq_scan md_freq_scan_job.forcefield = ezff.generate_forcefield( template, rr, FFtype='reaxff2', outfile=md_freq_scan_job.path + '/ffield') # Run RXMD calculation md_freq_scan_job.run(command='rxmd') # Read output from completed RXMD 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 = rxmd.job(path=path) md_full_scan_job.structure = gt_full_scan md_full_scan_job.forcefield = ezff.generate_forcefield( template, rr, FFtype='reaxff2', outfile=md_full_scan_job.path + '/ffield') # Run RXMD calculation md_full_scan_job.run(command='rxmd') # Read output from completed RXMD 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' 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 ]