diff --git a/README.md b/README.md index caab1da..b47db1c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ -# ase-neb-abacus -NEB or CI-NEB workflow by ASE and ABACUS using ASE-ABACUS interface, -Which use enhanced NEB method in ASE, like Dynamic NEB `DyNEB`, improved-tangent method `IT-NEB`, and also `AutoNEB` in ASE. +# ATST-Tools +Advanced ASE Transition State Tools for ABACUS, including: +- NEB and improvement, like Dynamic NEB +- CI-NEB, IT-NEB and others +- AutoNEB +- Dimer -Version v1.0.2 +Version v1.1 ## Dependencies: - [ASE](https://wiki.fysik.dtu.dk/ase/about.html) @@ -14,12 +17,13 @@ Notice: GPAW and ABACUS should be dependent on same MPI and libraries environmen For instance, if your ABACUS is installed by Intel-OneAPI toolchain, your GPAW should NOT be dependent on gcc-toolchain like OpenMPI and OpenBLAS. -## Usage -The workflow is based on 3 main python scripts and 1 workflow submit script. Namely: +## NEB workflow +### Usage +The NEB workflow is based on 3 main python scripts and 1 workflow submit script. Namely: - `neb_make.py` will make initial guess for NEB calculation, which is based on ABACUS (and other calculator) output files of initial and final state. This script will generate `init_neb_chain.traj` for neb calculation. Also, You can do continuation calculation by using this script. You can get more usage by `python neb_make.py`. -- `neb_run.py` is the key running script, which will run NEB calculation based on `init_neb_chain.traj` generated by `neb_make.py`. This script will generate `neb.traj` for neb calculation. Users should edit this file to set parameters for NEB calculation. sereal running can be performed by `python neb_run.py`, while parallel running can be performed by `mpirun gpaw python neb_run.py`. -When running, the NEB trajectory will be output to `neb.traj`, and NEB images calculation will be doing in `NEB-rank{i}` for each rank which do calculation of each image. +- `neb_run.py` is the key running script of NEB, which will run NEB calculation based on `init_neb_chain.traj` generated by `neb_make.py`. This script will generate `neb.traj` for neb calculation. Users should edit this file to set parameters for NEB calculation. sereal running can be performed by `python neb_run.py`, while parallel running can be performed by `mpirun gpaw python neb_run.py`. +When running, the NEB trajectory will be output to `neb.traj`, and NEB images calculation will be doing in `NEB-rank{i}` directory for each rank which do calculation of each image. - `neb_post.py` will post-process the NEB calculation result, which will based on `neb.traj` from neb calculation. This script will generate nebplots.pdf to view neb calculation result, and also print out the energy barrier and reaction energy. You can get more usage by `python neb_post.py`. Meanwhile, users can also view result by `ase -T gui neb.traj` or `ase -T gui neb.traj@-{n_images}:` by using ASE-GUI - `neb_submit.sh` will do all NEB process in one workflow scripts and running NEB calculation in parallel. Users should edit this file to set parameters for NEB calculation. Also this submit script can be used as a template for job submission in HPC. the Default setting is for `slurm` job submission system. @@ -43,13 +47,25 @@ Also, user can run each step in one script `neb_submit.sh` by `bash neb_submit.s > Notice: Before you start neb calculation process, make sure that you have check the nodes and cpus setting in `neb_submit.sh` and `neb_run.py` to make sure that you can reach the highest performance !!! -## Method +### Method - For serial NEB calculation, DyNEB, namely dynamic NEB method `ase.mep.neb.DyNEB` is for default used. - For parallel NEB calculation, `ase.mep.neb.NEB` traditional method is for default used, and `ase.mep.autoneb.AutoNEB` method should be independently used. - The Improved Tangent NEB method `IT-NEB` and Climbing Image NEB method `CI-NEB` in ASE are also default used in this workflow, which is highly recommended by Sobervea. But in `AutoNEB`, `eb` method is used for default. - Users can change lots of parameter for different NEB setting. one can refer to [ASE NEB calculator](https://wiki.fysik.dtu.dk/ase/ase/neb.html#module-ase.neb) for more details: - Notice: in surface calculation and hexangonal system, the vaccum and c-axis should be set along y-direction but not z-direction, which is much more efficient for ABACUS calculation. +## Dimer workflow +### Usage +The Dimer workflow is based on 2 main python scripts and 2 workflow submit script. Namely: +- `neb2dimer.py` can be used by `python neb2dimer [neb.traj] ([n_max])`, which will transform NEB trajetory `neb.traj` or NEB result trajectory `neb_result.traj` to Dimer input files, including: +- - `dimer_init.traj` for initial state of Dimer calculation +- - `displacement_vector.npy` for displacement vector of Dimer calculation +- `dimer_run.py` is the key running script of Dimer calculation, which will run Dimer calculation based on `dimer_init.traj` and `displacement_vector.npy` generated by `neb2dimer.py` or based on other setting. This script will generate `dimer.traj` for Dimer calculation trajectory. Users should edit this file to set parameters for Dimer calculation, and run Dimer calculation by `python dimer_run.py`. When running, any Dimer images calculation will be doing in `Dimer` directory. +- `dimer_submit.sh` will do Dimer workflow in one scripts. The Default setting is for `slurm` job submission system. +- `neb-dimer_srun.sh` is a try to run NEB + Dimer calculation in one server scripts. The Default setting is for `slurm` job submission system. + +### Method +(Waiting for update) ## Examples - Li-diffu-Si: Li diffusion in Si, an example for running ASE-NEB-ABACUS based on existing ABACUS input files of initial and final state, using ABACUS as SCF calculator and ASE as optimizer and NEB calculator. Also, an dflow example is proposed. @@ -58,9 +74,9 @@ Also, user can run each step in one script `neb_submit.sh` by `bash neb_submit.s - CO-Pt111 : CO dissociation on Pt(111) surface, an example for running ASE-NEB-ABACUS based on existing ABACUS input files of initial and final state, use ABACUS as SCF calculator, use ABACUS as optimizer for optimization of initial state and final state, use ASE as NEB calculator - Cy-Pt_graphene: Cyclohexane dehydrogenation on Pt-doped graphene surface, an example for running ASE-NEB-ABACUS based on existing ABACUS input files of initial and final state, use ABACUS as optimizer for optimization of initial state and final state, use ASE as NEB calculator +AutoNEB example ix on update, Dimer example is preparing ## Next Examples -- `AutoNEB` test - CO-Fe100: CO dissociation on Fe(100) surface, in this example we will focus on setting `magmom` during NEB calculation, which is important for spin-polarized magnetic system. - TS of MTM process by H2O2 in Cu/Ag-ZSM5 system, including: - - proton transfer process @@ -83,7 +99,8 @@ Also, user can run each step in one script `neb_submit.sh` by `bash neb_submit.s - [x] More test in surface reaction system - [x] Parallel computing during images relaxation by `gpaw python` - [x] `AutoNEB` implementation +- [x] Connected to Dimer method - [ ] More test in magnetic surface reaction system -- [ ] Connected to Dimer method +- [ ] put calculation setting in an independent file (decoupling run*.py) diff --git a/dimer/dimer_run.py b/dimer/dimer_run.py new file mode 100644 index 0000000..435317c --- /dev/null +++ b/dimer/dimer_run.py @@ -0,0 +1,155 @@ +from ase import Atom, Atoms +from ase.io import Trajectory, read, write +from ase.mep import DimerControl, MinModeAtoms, MinModeTranslate +from ase.optimize import BFGS, FIRE +from ase.calculators.abacus import Abacus, AbacusProfile +import os, sys + +import numpy as np + +fmax = 0.05 +dimer_input_file = 'dimer_init.traj' +init_eigenmode_method = 'displacement' +displacement_input = 'displacement_vector.npy' + +# setting for calculator +mpi = 16 +omp = 4 +abacus = "abacus" +#lib_dir = "/lustre/home/2201110432/example/abacus" +lib_dir = "/home/james/example" +pseudo_dir = f"{lib_dir}/PP" +basis_dir = f"{lib_dir}/ORB" +pp = { + 'H':'H_ONCV_PBE-1.0.upf', + 'Au':'Au_ONCV_PBE-1.0.upf', + } +basis = { + 'H':'H_gga_6au_100Ry_2s1p.orb', + 'Au':'Au_gga_7au_100Ry_4s2p2d1f.orb', + } +kpts = [3, 1, 3] +parameters = { + 'calculation': 'scf', + 'nspin': 2, + 'xc': 'pbe', + 'ecutwfc': 100, + 'ks_solver': 'genelpa', + 'symmetry': 0, + 'vdw_method': 'd3_bj', + 'smearing_method': 'gaussian', + 'smearing_sigma': 0.001, + 'basis_type': 'lcao', + 'mixing_type': 'broyden', + 'scf_thr': 1e-6, + 'scf_nmax': 100, + 'kpts': kpts, + 'pp': pp, + 'basis': basis, + 'pseudo_dir': pseudo_dir, + 'basis_dir': basis_dir, + 'cal_force': 1, + 'cal_stress': 1, + 'out_stru': 1, + 'out_chg': 0, + 'out_mul': 0, + 'out_bandgap': 0, + 'efield_flag': 1, + 'dip_cor_flag': 1, + 'efield_dir': 1, + 'efield_pos_max': 0.7 +} + + +class AbacusDimer: + """Customize Dimer calculation by using ABACUS""" + + def __init__(self, init_Atoms, parameters, abacus='abacus', + mpi=1, omp=1, directory='DIMER', + traj_file='dimer.traj', + init_eigenmode_method='displacement', + displacement_vector: np.ndarray = None,): + """Initialize Dimer method by using ASE-ABACUS + + init_Atoms (Atoms object): starting image, can be from every way including NEB result + parameters (dict): settings of abacus input parameters + abacus (str): Abacus executable file. Default: 'abacus' + directory (str): calculator directory name, for parallel calculation {directory}-rank{i} will be the directory name + mpi (int): number of MPI for abacus calculator + omp (int): number of OpenMP for abacus calculator + traj_file (str): trajectory file name for dimer calculation, when running dimer calculation, trajetory will be written to this file, default is 'dimer.traj' + init_eigenmode_method (str): dimer initial eigenmode method. Choose from 'displacement' and 'gauss'. + displacement_vector (np.ndarray): displacement vector for dimer initial eigenmode. Only used when init_eigenmode_method is 'displacement' + """ + self.init_Atoms = init_Atoms + self.parameters = parameters + self.abacus = abacus + self.mpi = mpi + self.omp = omp + self.directory = directory + self.traj_file = traj_file + self.init_eigenmode_method = init_eigenmode_method + self.displacement_vector = displacement_vector + + def set_calculator(self): + """Set Abacus calculators""" + os.environ['OMP_NUM_THREADS'] = f'{self.omp}' + profile = AbacusProfile( + argv=['mpirun', '-np', f'{self.mpi}', self.abacus]) + out_directory = self.directory + calc = Abacus(profile=profile, directory=out_directory, + **self.parameters) + return calc + + def set_d_mask_by_displacement(self): + """set mask by displacement""" + print("=== Set mask by displacement vector where displacement is [0,0,0] ===") + d_mask = self.displacement_vector != np.zeros(3) + d_mask = d_mask[:,0].tolist() + return d_mask + + def set_d_mask_by_constraint(self): + """set mask by constraint of Atoms""" + print("=== Set mask by constraint read from init Atoms ===") + dimer_init = self.init_Atoms + const_list = dimer_init._get_constraints()[0] + const_list = const_list.todict()['kwargs']['indices'] + d_mask = [True] * len(dimer_init) + for ind in const_list: + d_mask[ind] = False + return d_mask + + def run(self, fmax=0.05): + """run dimer calculation workflow""" + dimer_init = self.init_Atoms + dimer_init.calc = self.set_calculator() + dimer_traj = Trajectory(self.traj_file, 'w', dimer_init) + if self.init_eigenmode_method == "displacement": + # d_mask = self.set_d_mask_by_displacement() # not the best + d_mask = self.set_d_mask_by_constraint() + d_control = DimerControl(initial_eigenmode_method=self.init_eigenmode_method, + displacement_method="vector", + mask=d_mask) + d_atoms = MinModeAtoms(dimer_init, d_control) + d_atoms.displace(displacement_vector=self.displacement_vector) + elif self.init_eigenmode_method == "gauss": + # leave a way for random displacement + d_mask = self.set_d_mask_by_constraint() + d_control = DimerControl(initial_eigenmode_method=self.init_eigenmode_method, + mask=d_mask) + d_atoms = MinModeAtoms(dimer_init, d_control) + else: + raise ValueError("init_eigenmode_method must be displacement or gauss") + dimer_relax = MinModeTranslate(d_atoms, trajectory=dimer_traj) + dimer_relax.run(fmax=fmax) + +if __name__ == "__main__": +# running process +# read initial guessed neb chain + dimer_init = read(dimer_input_file) + displacement_vector = np.load(displacement_input) + dimer = AbacusDimer(dimer_init, parameters, abacus=abacus, + mpi=mpi, omp=omp, + init_eigenmode_method=init_eigenmode_method, + displacement_vector=displacement_vector) + dimer.run(fmax=fmax) diff --git a/dimer/dimer_submit.sh b/dimer/dimer_submit.sh new file mode 100644 index 0000000..1899b96 --- /dev/null +++ b/dimer/dimer_submit.sh @@ -0,0 +1,33 @@ +#!/bin/bash +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=16 +#SBATCH --cpus-per-task=4 +#SBATCH -J DIMER-ABACUS +#SBATCH -o run_dimer.out +#SBATCH -e run_dimer.err +#SBATCH -p C064M0256G + +# JamesMisaka in 2023-11-14 +# workflow of ase-abacus-dimer method +# for one calculator, ntasks-per-node for mpi, cpus-per-task for openmp + +# in developer's PKU-WM2 server +source /lustre/home/2201110432/apps/miniconda3/etc/profile.d/conda.sh +conda activate gpaw-intel +module load abacus/3.4.2-icx + +# if one just done neb calculation +python neb2dimer.py neb.traj # or neb_latest.traj + +# Job state +echo $SLURM_JOB_ID > JobRun.state +echo "Start at $(date)" >> JobRun.state + +# just do dimer by run ! +# do check your ntasks(mpi) and cpu(omp) setting is right +python dimer_run.py + +echo "===== Dimer Calculation Done at $(date)! =====" + +# Job State +echo "End at $(date)" >> JobRun.state \ No newline at end of file diff --git a/dimer/neb-dimer_srun.sh b/dimer/neb-dimer_srun.sh new file mode 100644 index 0000000..0d0281b --- /dev/null +++ b/dimer/neb-dimer_srun.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# full workflow controling NEB and Dimer calculation + +NEB_JOBID=$(sbatch neb_submit.sh) | awk '{print $4}' # get the jobid of neb and submit neb job +echo "NEB_JOBID is ${NEB_JOBID}" +DIMER_JOBID=$(sbatch --dependency=afterok:${NEB_JOBID} dimer_submit.sh) | awk '{print $4}' # submit dimer job after neb job done +echo "Dimer Job Submitted and will be run after NEB job !" +echo "DIMER_JOBID is ${DIMER_JOBID}" \ No newline at end of file diff --git a/dimer/neb2dimer.py b/dimer/neb2dimer.py new file mode 100644 index 0000000..86b7ca7 --- /dev/null +++ b/dimer/neb2dimer.py @@ -0,0 +1,73 @@ +import numpy as np +import sys +from ase.io import Trajectory, read, write +from ase.mep.neb import NEBTools + +def neb2dimer(neb_traj:list, n_max:int=0, out_traj='dimer_init.traj', out_vec='displacement_vector.npy', + step_before_TS:int=1, step_after_TS:int=1): + ''' + Transform neb chain to dimer init + ''' + # you should use the latest neb chain or other single neb chain + # but a full neb chain is permitted, in which the latest neb chain will be used + if n_max == 0: + print("=== n_max set to 0, get n_images by using NEBTools ===") + n_images = NEBTools(neb_traj)._guess_nimages() + elif (n_max >= 0) and (type(n_max) == int): + n_images = n_max + 2 + else: + raise ValueError("n_max must be a non-negative integer") + if len(neb_traj) < n_images: + raise ValueError(f"n_images ={n_images} is larger than the length of neb_traj ={len(neb_traj)}") + elif len(neb_traj) > n_images: + print(f"=== n_images ={n_images} is smaller than the length of neb_traj ={len(neb_traj)} ! Only the last {n_images} images are used ===") + # used neb_chain is the final traj + neb_chain = neb_traj[-n_images:] + # get TS information from NEB chain + barrier = NEBTools(neb_chain).get_barrier()[0] + fmax = NEBTools(neb_chain).get_fmax() + raw_barrier = max([image.get_potential_energy() for image in neb_chain]) + TS_info = [(ind, image) + for ind, image in enumerate(neb_chain) + if image.get_potential_energy() == raw_barrier][0] + print(f"=== Locate TS in {TS_info[0]} of 0-{n_images-1} images ===") + print(f"=== TS Barrier: {barrier:.4f} (eV) ===") + print(f"=== TS Fmax: {fmax:.4f} (eV/A) ===") + print(f"=== TS images is output as {out_traj} for dimer init ===") + # output TS of neb for dimer init + write(out_traj, TS_info[1], format='traj') + # output displancement vector by using the nearest two images of TS + ind_before_TS = TS_info[0] - step_before_TS + ind_after_TS = TS_info[0] + step_after_TS + img_before = neb_chain[ind_before_TS] + img_after = neb_chain[ind_after_TS] + print(f"=== Displacement vector is generated by position minus from {ind_after_TS} image to {ind_before_TS} image ===") + displacement_vector = (img_after.positions - img_before.positions) + print(f"=== Displacement vector is output as {out_vec} for dimer init ===") + np.save(out_vec,displacement_vector) + return + +if __name__ == "__main__": + msg = ''' +neb2dimer.py is to make dimer inputfile by using neb result +Usage: + python neb2dimer.py [traj_file] ([n_max]) + Notice that n_max = n_images - 2 +These sctipt will output two files: + dimer_init.traj: TS of neb chain for dimer init-structure + displacement_vector.npy: displacement vector of dimer init + ''' + if len(sys.argv) < 2: + print(msg) + elif len(sys.argv) == 2: + if sys.argv == "--help" or sys.argv == "-h": + print(msg) + else: + traj_file = sys.argv[1] + neb_traj = Trajectory(traj_file) + neb2dimer(neb_traj) + else: + traj_file = sys.argv[1] + n_max = int(sys.argv[2]) + neb_traj = Trajectory(traj_file) + neb2dimer(neb_traj, n_max) \ No newline at end of file diff --git a/examples/H2-Au111/neb_para_8img_8node/neb_latest.traj b/examples/H2-Au111/neb_para_8img_8node/neb_latest.traj new file mode 100644 index 0000000..ca5226f Binary files /dev/null and b/examples/H2-Au111/neb_para_8img_8node/neb_latest.traj differ diff --git a/examples/H2-Au111/neb_para_8img_8node/nebplots_all.pdf b/examples/H2-Au111/neb_para_8img_8node/nebplots_all.pdf index 898ff97..b8bddcb 100644 Binary files a/examples/H2-Au111/neb_para_8img_8node/nebplots_all.pdf and b/examples/H2-Au111/neb_para_8img_8node/nebplots_all.pdf differ diff --git a/examples/H2-Au111/neb_para_8img_8node/nebplots_chain.pdf b/examples/H2-Au111/neb_para_8img_8node/nebplots_chain.pdf index fc6024b..35fe325 100644 Binary files a/examples/H2-Au111/neb_para_8img_8node/nebplots_chain.pdf and b/examples/H2-Au111/neb_para_8img_8node/nebplots_chain.pdf differ diff --git a/examples/H2-Au111/neb_para_8img_8node/out b/examples/H2-Au111/neb_para_8img_8node/out deleted file mode 100644 index 84a0d2a..0000000 --- a/examples/H2-Au111/neb_para_8img_8node/out +++ /dev/null @@ -1,13 +0,0 @@ -num: 0; Energy: -239256.26878 (eV) -num: 1; Energy: -239256.24673 (eV) -num: 2; Energy: -239256.15888 (eV) -num: 3; Energy: -239255.88496 (eV) -num: 4; Energy: -239255.148 (eV) -num: 5; Energy: -239255.2698 (eV) -num: 6; Energy: -239255.50369 (eV) -num: 7; Energy: -239255.67735 (eV) -num: 8; Energy: -239255.83488 (eV) -num: 9; Energy: -239255.88577 (eV) -Number of images per band guessed to be 10. - Processing band 0 / 69 Processing band 1 / 69 Processing band 2 / 69 Processing band 3 / 69 Processing band 4 / 69 Processing band 5 / 69 Processing band 6 / 69 Processing band 7 / 69 Processing band 8 / 69 Processing band 9 / 69 Processing band 10 / 69 Processing band 11 / 69 Processing band 12 / 69 Processing band 13 / 69 Processing band 14 / 69 Processing band 15 / 69 Processing band 16 / 69 Processing band 17 / 69 Processing band 18 / 69 Processing band 19 / 69 Processing band 20 / 69 Processing band 21 / 69 Processing band 22 / 69 Processing band 23 / 69 Processing band 24 / 69 Processing band 25 / 69 Processing band 26 / 69 Processing band 27 / 69 Processing band 28 / 69 Processing band 29 / 69 Processing band 30 / 69 Processing band 31 / 69 Processing band 32 / 69 Processing band 33 / 69 Processing band 34 / 69 Processing band 35 / 69 Processing band 36 / 69 Processing band 37 / 69 Processing band 38 / 69 Processing band 39 / 69 Processing band 40 / 69 Processing band 41 / 69 Processing band 42 / 69 Processing band 43 / 69 Processing band 44 / 69 Processing band 45 / 69 Processing band 46 / 69 Processing band 47 / 69 Processing band 48 / 69 Processing band 49 / 69 Processing band 50 / 69 Processing band 51 / 69 Processing band 52 / 69 Processing band 53 / 69 Processing band 54 / 69 Processing band 55 / 69 Processing band 56 / 69 Processing band 57 / 69 Processing band 58 / 69 Processing band 59 / 69 Processing band 60 / 69 Processing band 61 / 69 Processing band 62 / 69 Processing band 63 / 69 Processing band 64 / 69 Processing band 65 / 69 Processing band 66 / 69 Processing band 67 / 69 Processing band 68 / 69 - Processing band 0 / 1 diff --git a/autoneb_run.py b/neb/autoneb_run.py similarity index 100% rename from autoneb_run.py rename to neb/autoneb_run.py diff --git a/autoneb_submit.sh b/neb/autoneb_submit.sh similarity index 100% rename from autoneb_submit.sh rename to neb/autoneb_submit.sh diff --git a/neb_make.py b/neb/neb_make.py similarity index 100% rename from neb_make.py rename to neb/neb_make.py diff --git a/neb_post.py b/neb/neb_post.py similarity index 66% rename from neb_post.py rename to neb/neb_post.py index d8f7472..345f368 100644 --- a/neb_post.py +++ b/neb/neb_post.py @@ -12,8 +12,9 @@ class NEBPost(): def __init__(self, images, n_max: int = 0): self.all_image = images if n_max == 0: - print("=== n_max set to 0, using all images ===") - self.neb_chain = self.all_image.copy() + print("=== n_max set to 0, automatically detect the images of chain by NEBTools ===") + self.n_images = NEBTools(self.all_image)._guess_nimages() + self.neb_chain = images[ - self.n_images:] elif (n_max > 0) and (type(n_max) == int): self.n_images = n_max + 2 self.neb_chain = images[ - self.n_images:] @@ -50,26 +51,35 @@ def view_neb_bands(self): msg = ''' Usage: For Traditional NEB process result: - python neb_post.py [traj_file] [n_images] + python neb_post.py [traj_file] ([n_images]) For AutoNEB result: - python neb_post.py --autoneb ([autoneb_traj_files]) + python neb_post.py --autoneb \{[autoneb_traj_files]\} ''' - if len(sys.argv) < 3: + if len(sys.argv) < 2: print(msg) - elif sys.argv[1] == "--autoneb": - traj_files = sys.argv[2:] - result_atoms = [read(traj, format="traj") for traj in traj_files] - result = NEBPost(result_atoms, 0) - result.get_barrier() - result.plot_all_bands() - result.write_latest_bands() - else: + elif len(sys.argv) == 2: traj_file = sys.argv[1] - n_max = int(sys.argv[2]) all_images = read(traj_file, index=":", format="traj") - result = NEBPost(all_images, n_max) + result = NEBPost(all_images, 0) result.get_barrier() result.plot_all_bands() result.plot_neb_bands() result.write_latest_bands() + else: + if sys.argv[1] == "--autoneb": + traj_files = sys.argv[2:] + result_atoms = [read(traj, format="traj") for traj in traj_files] + result = NEBPost(result_atoms, 0) + result.get_barrier() + result.plot_all_bands() # in autoneb we only have one chain + result.write_latest_bands() + else: + traj_file = sys.argv[1] + n_max = int(sys.argv[2]) + all_images = read(traj_file, index=":", format="traj") + result = NEBPost(all_images, n_max) + result.get_barrier() + result.plot_all_bands() + result.plot_neb_bands() + result.write_latest_bands() \ No newline at end of file diff --git a/neb_run.py b/neb/neb_run.py similarity index 100% rename from neb_run.py rename to neb/neb_run.py index f8e8c5c..9b464a7 100644 --- a/neb_run.py +++ b/neb/neb_run.py @@ -11,18 +11,18 @@ #from pathlib import Path # setting for NEB -mpi = 16 -omp = 2 neb_optimizer = FIRE # suited for CI-NEB neb_directory = "NEBrun" +fmax = 0.05 # eV / Ang algorism = "improvedtangent" # IT-NEB is recommended neb_type = "neb" # neb, dyneb, but not autoneb init_chain = "init_neb_chain.traj" climb = True -fmax = 0.05 # eV / Ang parallel = True # setting for calculator +mpi = 16 +omp = 2 abacus = "abacus" lib_dir = "/lustre/home/2201110432/example/abacus" #lib_dir = "" diff --git a/neb_submit.sh b/neb/neb_submit.sh similarity index 97% rename from neb_submit.sh rename to neb/neb_submit.sh index 8570453..457ab6d 100644 --- a/neb_submit.sh +++ b/neb/neb_submit.sh @@ -67,3 +67,6 @@ echo "===== Done at $(date)! =====" # Job State echo "End at $(date)" >> JobRun.state + +# if plus dimer method +# sbatch dimer_submit.sh