Files
VASP_calc/electrochemistry/echem/neb/__pycache__/autoneb.cpython-310.pyc

185 lines
17 KiB
Plaintext
Raw Normal View History

2026-01-08 19:47:32 +03:00
o
F Ui<55>g<00>@s<>dZddlZddlZddlZddlZddlmZddlmZddl m
Z
ddl m Z ddl mZddlmZdd lmZdd
lmZdd lmZdd lmZdd lmZddlmZddlmZddlZejedd<10>ZGdd<12>d<12>Z Gdd<14>d<14>Z!dd<16>Z"dS)z<>
AutoNEB realization from ASE package
E. L. Kolsbjerg, M. N. Groves, and B. Hammer, J. Chem. Phys, 145, 094107, 2016. (doi: 10.1063/1.4961868)
modified by: Sergey Pavlov
<EFBFBD>N)<01>log)<01>exp)<01> ExitStack)<01>Path)<01>warn)<01>
Trajectory)<01>read)<01>NEB)<01>BFGS)<01>FIRE)<01> NEBOptimizer)<01>SinglePointCalculatorT)<01>flushc@steZdZdZ   
d!d d<0E>Zd"dd<10>Zdd<12>Z d"dd<14>Zdd<16>Zdd<18>Z dd<1A>Z
dd<1C>Z dd<1E>Z dd <20>Z d S)#<23>AutoNEBa<42> AutoNEB object.
The AutoNEB algorithm streamlines the execution of NEB and CI-NEB
calculations following the algorithm described in:
E. L. Kolsbjerg, M. N. Groves, and B. Hammer, J. Chem. Phys,
145, 094107, 2016. (doi: 10.1063/1.4961868)
The user supplies at minimum the two end-points and possibly also some
intermediate images.
The stages are:
1) Define a set of images and name them sequentially.
Must at least have a relaxed starting and ending image
User can supply intermediate guesses which do not need to
have previously determined energies (probably from another
NEB calculation with a lower level of theory)
2) AutoNEB will first evaluate the user provided intermediate images
3) AutoNEB will then add additional images dynamically until n_max
is reached
4) A climbing image will attempt to locate the saddle point
5) All the images between the highest point and the starting point
are further relaxed to smooth the path
6) All the images between the highest point and the ending point are
further relaxed to smooth the path
Step 4 and 5-6 are optional steps!
Parameters:
attach_calculators:
Function which adds valid calculators to the list of images supplied.
prefix: string or path
All files that the AutoNEB method reads and writes are prefixed with
prefix
n_simul: int
The number of relaxations run in parallel.
n_max: int
The number of images along the NEB path when done.
This number includes the two end-points.
Important: due to the dynamic adding of images around the peak n_max
must be updated if the NEB is restarted.
climb: boolean
Should a CI-NEB calculation be done at the top-point
fmax: float or list of floats
The maximum force along the NEB path
maxsteps: int
The maximum number of steps in each NEB relaxation.
If a list is given the first number of steps is used in the build-up
and final scan phase;
the second number of steps is used in the CI step after all images
have been inserted.
k: float
The spring constant along the NEB path
method: str (see neb.py)
Choice betweeen three method:
'aseneb', standard ase NEB implementation
'improvedtangent', published NEB implementation
'eb', full spring force implementation (default)
optimizer: object
Optimizer object, defaults to FIRE
Use of the valid strings 'BFGS' and 'FIRE' is deprecated.
space_energy_ratio: float
The preference for new images to be added in a big energy gab
with a preference around the peak or in the biggest geometric gab.
A space_energy_ratio set to 1 will only considder geometric gabs
while one set to 0 will result in only images for energy
resolution.
The AutoNEB method uses a fixed file-naming convention.
The initial images should have the naming prefix000.traj, prefix001.traj,
... up until the final image in prefix00N.traj
Images are dynamically added in between the first and last image until
n_max images have been reached.
<20>
iterations皙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>'<><E79A99><EFBFBD><EFBFBD><EFBFBD>?T<>ebr F<><00>?N<>idppcCs<>||_t|<02>|_||_||_| |_g|_||_||_||_ ||_
|
|_ | |_ | |_ |dvr6d|_tdd<04>n||_|dur@tj}||_||_t| t<14>rbz tttd<05>| |_Wntyatd<06><01>w| |_t|j<02>||_|jjdd<08>dS) N)r<00>linearrz%Interpolation method not implementet.zUsing the IDPP method.)r
r r z'Optimizer needs to be BFGS, FIRE or NEBT<42><01>exist_ok)<1D>attach_calculatorsr<00>prefix<69>n_simul<75>n_max<61>climb<6D>
all_images<EFBFBD>parallel<65>maxsteps<70>fmax<61>k<>method<6F>remove_rotation_and_translation<6F>space_energy_ratio<69>interpolate_method<6F>print<6E>mpi<70>world<6C> smooth_curve<76>
isinstance<EFBFBD>strr
r r <00> optimizer<65>KeyError<6F> Exception<6F> iter_folder<65>mkdir)<12>selfrrrrr1r"r!r#rr$r.r%r&r*r r+r'<00>r4<00>@/home/testuser/ALEXks/VASP/electrochemistry/echem/neb/autoneb.py<70>__init__jsF
<06>
<04>
<EFBFBD> <02>zAutoNEB.__init__cCs@t<00><00>}|j|||||d<01>Wd<00>dS1swYdS)N<>r<00>
many_steps)r<00>_execute_one_neb)r3<00>n_cur<75>to_runrr8<00> exitstackr4r4r5<00>execute_one_neb<65>s

<08>"<22>zAutoNEB.execute_one_nebcCs>|jd|<02><00>jdd<03>|jd|<02><00>d|d<05>d|d<05>d<07>S)z<>When doing the i'th NEB optimization a set of files
prefixXXXiter00i.traj exists with XXX ranging from 000 to the N images
currently in the NEB.<2E>iter_Tr<00>i<>03d<33>iter<65>.traj)r1r2)r3r?<00>iiterr4r4r5<00> iter_trajpath<74>s&zAutoNEB.iter_trajpathc s<>|j}<06>jd7_<01>jjdkrYt|<02>D]D}||dd<03>vrX<72>j|d<04>d<05>}t|d<06>j|d<07><03> } | <09><08>Wd<00>n1s@wY<00><00> |<07>j<01>}
t
j <0B> |<08>rXt <0A>||
<EFBFBD>q<14>jjdkrgtd <09>j|<03><00><00><10>fd
d <0B>|D<00>|<03>j<01>t<11>fd d <0B>|D<00><01>fd d <0B>|dd<03>D<00><01>j<12>j<13>j|d<0E>} <0B>jd<0F>j<01><00>d<10>jd<04>d<11>} |<06>j| | d<12><02>} <0A>j<13>r|d}t|<03>d}<0F>jj|}d<01>jj|}||<00>jjks<>J<00>|t<06>j||d<04>d<05>d<06>j||<00>jj|dkd<14><04>} <09><00> ||<00>j<01>}
|t|
d<06>j||<00>jj|dkd<14><04>}| <0A>| <09>| <0A>|<12>nLd}t|dd<03><00>D]A\}}<11><00> |<11>j<01>}
|t|
d<06>j|<00><03>}| <0A>t|||<13>j<08>|t<06>j|d<04>d<05>d<06>j|<00><03>} | <0A>t| ||<13>j<08>|d7}<13>q&t<1C>jttf<02><02>rz|<05>rz<72>jd}nt<1C>jttf<02><02>r<>|<05>s<><73>jd}n<03>j}t<1C>j ttf<02><02>r<>|<05>r<><72>j d}nt<1C>j ttf<02><02>r<>|<05>s<><73>j d}n<03>j }| j!||d<15>t"<22>#t$| <0B>| _%| <0B>%<25><00><00>&<26>}td<16>j<01>d|<16><00><04>dS)z4Internal method which executes one NEB optimization.<2E>r<00><><EFBFBD><EFBFBD><EFBFBD>r@rB<00>w)<02>mode<64>atomsNzNow starting iteration %d on c<00>g|]}<01>j|<00>qSr4<00>r<00><02>.0r?<00>r3r4r5<00>
<listcomp><3E><00>z,AutoNEB._execute_one_neb.<locals>.<listcomp>crJr4rKrLrNr4r5rO<00>rPcrJr4)r#rLrNr4r5rO<00>rP)r#r$r r%rr>Zlog_iterz.log)<01>logfile<6C>)<01>master)r"<00>steps<70>Energies after iteration <20>: )'<27> enter_context<78> iterationr*<00>rank<6E>rangerrr<00>writerD<00>os<6F>path<74>isfile<6C>shutil<69>copy2r(rr r$r r%r1r.<00>len<65>size<7A>attach<63> enumerate<74> seriel_writerr,r!<00>list<73>tupler"<00>run<75>types<65>
MethodType<EFBFBD>store_E_and_F_in_spc<70>
distribute<EFBFBD> get_energies)r3r<r:r;rr8<00>
closelaterr?<00>filename<6D>traj<61> filename_ref<65>neb<65>logpath<74>qn<71>nneb<65>nim<69>n<>j<>trajhist<73>numrTr"<00>energiesr4rNr5r9<00>s<>  <06>
<1C>  <02> <06> <04>   <08> <08>
  <06><06>     zAutoNEB._execute_one_nebc(CsJ
|<00><00>}t|j<02>|jdkr<>t|jttf<02>r"|jgt|j<02>d|_|jj dkr,t
d<04>g}t |d<00>D]}|j|d<00> <0C>|j|<00> <0C>}|<02> tj<0F>|<04><01>q4t<0E>|<02>}|jj dkr`t
d|<05>t|j<02>dkrk|j}nd}|j|g}t |<06>D] }||d<00><12>g7}qw||j|dg7}t|<07>} | j|jd<06>|jd|d<00>}
|
|dd<08>7}
|
<EFBFBD>|j|dd<07><00>|
|_|jd|<05>} | |j||dg|d7} | <0B>|j|dd<07><00>| |_||7}t|j<02>|jdks|<00><17>} td d
<EFBFBD>| D<00><01>} |jj dk<02>rt
d <0B>| dk<03>r>t|jttf<02><02>r|jgt|j<02>d|_|<00><18>\}}|j||d d <0A>|<00><17>} tdd
<EFBFBD>| D<00><01>} | dk<03>s |jj dk<02>rIt
d<0F>||jk<00>r<>t|jttf<02><02>rd|jgt|j<02>d|_|jj dk<02>rut
dd<11>||j<1A><02>g}t |d<00>D]}|j|d<00> <0C>|j|<00> <0C>}|<02> tj<0F>|<04><01><00>q}|jd<00> <0C>|jd<00> <0C>}tj<0F>|<10>}t|<02>|}|<00><17>}g}t|<13>}t|<13>|}t |d<00>D]&}||d||||d||d|d|}|<14> t|<17><01><00>q<>t|<14>|}|||jk<04>rt<0E>|<02>}d}nt<0E>|<14>}d}|jj dk<02>r<>t
d<14>|<05>d<15>|d<00>d|<00>t |<01>D]V}||k<01>rK|j d|j!<21><00>|<08>}|j d|j!d<00><00>|<08>}n|j d|j!<21><00>|<08>}|j d|j!d<00><00>|d<00>}|j d|j!d<00><00>j"dd<19>t#j$||dd<1A><00>q)|j|g}||d<00><12>g7}||j|dg7}t|<07>} | j|jd<06>|jd|d<00>}
|
|dd<08>7}
|
<EFBFBD>|j|dd<07><00>|
|_|jd|<05>} | |j|dgd7} | <0B>|j|dd<07><00>| |_|d7}|<00><18>\}}|j||d d <0A>||jk<00>sO|jj dk<02>r t
d<1B>|j%<25>r<>t|jttf<02><02>r"|jgt|j<02>d|_|jj dk<02>rft
d<1C>t |<01>D]4}|j d|j!<21><00>|<08>}|j d|j!d<00><00>|<08>}|j d|j!d<00><00>j"dd<19>t#j$||dd<1A><00>q1|<00>&<26>}|d|jd}t|d<03>}t|||jd<00>}t't |||jd<00><02>}|j||ddd<1D>|j(<28>s<>|jS|<00><17>}|<00>&<26>}d}tj<0F>|j|<00> <0C>|jd<00> <0C><00>} tj<0F>|j|<00> <0C>|jd<00> <0C><00>}!| d t)d<1F>}"|!d t)d<1F>}#g}$g}%t |<1E>D]%}|j|<00> <0C>|j|d<00> <0C>d|jd<00> <0C>}&|$<24> tj<0F>|&<26><01><00>q<>t |t|j<02>d<00>D]%}|j|<00> <0C>|j|d<00> <0C>d|jd<00> <0C>}&|%<25> tj<0F>|&<26><01><00>qg} |$D]}'| <0B> |t*|'| d |"<00><00><00>q@|%D]}'| <0B> |t*|'| d |#<00><00><00>qV| |_|jj dk<02>r<>t
d <20>t |<01>D]4}|j d|j!<21><00>|<08>}|j d|j!d<00><00>|<08>}|j d|j!d<00><00>j"dd<19>t#j$||dd<1A><00>q||<00>&<26>}||jd}|dk<05>r<>|j|t |||jd<00>d d <0A>|d8}|dk<05>s<>|<00>&<26>}|jj dk<02>r<>t
d!<21>||j|jdk<01>r|j|t |||jd<00>d d <0A>|d7}||j|jdk<01>s<>|<00><17>} t
d"|j!<21>d#| <0C><00><04>|jS)$z'Run the AutoNEB optimization algorithm.rRrErz!Now adding images for initial runz Max length between images is at )r$NrFcS<00>g|]}||kr|<01>qSr4r4<00>rM<00>er4r4r5rO7<00>zAutoNEB.run.<locals>.<listcomp>z)Start of evaluation of the initial imagesF)rcSr|r4r4r}r4r4r5rOErzFinished initialisation phase.z3****Now adding another image until n_max is reachedz ({0}/{1})****zspring length!z%energy difference between neighbours!zAdding image between {0} andz {0}. New image point is selectedzon the basis of the biggest r>Tr)<01> dirs_exist_okzn_max images has been reachedz(****Now doing the CI-NEB calculation****r7<00>
g<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?zNow moving from top to startzNow moving from top to endrUrV)+<2B>__initialize__rarrr,r#<00>float<61>intr*rYr(rZ<00> get_positions<6E>append<6E>np<6E>linalg<6C>norm<72>argmax<61>copyr <00> interpolater'<00>extendrm<00>which_images_to_run_onr=r<00>format<61>max<61>min<69>absr&r1rXr2r_<00>copytreer<00>get_highest_energy_indexrfr+rr)(r3r:<00>spring_lengthsrx<00>
spring_vec<EFBFBD>jmax<61> n_between<65> toInterpolater?rr<00>tmp<6D>k_tmpr{<00>n_non_valid_energiesr;<00>
climb_safe<EFBFBD> total_vec<65>tl<74>fRr~<00>ed<65>emin<69>enorm<72>delta_E<5F>gR<67>tZ folder_fromZ folder_to<74>highest_energy_indexru<00>peak<61>k_max<61>d1<64>d2<64>l1<6C>l2<6C>x1<78>x2<78>v<>xr4r4r5rhs<>  <04>
 
   <14>0
 
<EFBFBD>
  <04> <04>  <04>   &<06><02><04> 


 <04> 
    <0C>M 
 <06> <06>  <02><02> <04> <02><02> <04>$$ 
<06>
<EFBFBD><06><16>z AutoNEB.runc s<>tj<01><02>jd<00>std<02>jd<03><02><01>fdd<05>t<05>j<06>D<00>}td|<01><00><02>|dd}<02>jj d kr9td
t
|<01>d <0B>t
|<01>dkrCt d <0C><01>tt
|<01><01>D] }|||krVt d d<0E><02>qI<71>jj d kr<>|D]>}<03><00> |d <09>}tj<01>|<04>r<>z t<00> |t|<04>d<00>Wn ty<>Ynw<00>j|d<10>d<11>}zt<0F>||<04>Wq_ty<>Yq_w<00>j<08><11>t|<02>D]%}||vr<><72>j|d<10>d<11>}t|<05>}<06>j<13>|<06>q<><71>j<13><14>jd <00><15><00>q<>d <09>_|S)zLoad files from the filesystem.z000.trajzNo file with name %s000.trajz'was found. Should contain initial imagecs*g|]}tj<01><02>j|d<00>d<01><00>r|<01>qS)r@rB)r\r]r^rrLrNr4r5rO<00>s
<EFBFBD>z*AutoNEB.__initialize__.<locals>.<listcomp>z<Traj files with the following indexes were initially found: rFrErz The NEB initially has %d images z(including the end-points)zOnly a start point existsz"Files must be ordered sequentiallyz without gaps.z.bakr@rB)r\r]r^r<00>IOErrorrZrr(r*rYrar0rD<00>renamer-r_r`<00>barrierrrr<>r<>rX)r3<00> index_existsr:r?rqro<00>newimr4rNr5r<><00>sV
<04>   <04>  <04><02>    <02> <02>
 zAutoNEB.__initialize__c CsDg}|jD]}z |<01>|<02><02><00>Wqty|<01>tj<05>Yqw|S)zSUtility method to extract all energies and insert np.NaN at
invalid images.)rr<><00>get_potential_energy<67> RuntimeErrorr<72><00>NaN)r3r{<00>ar4r4r5rm%s
 <02>zAutoNEB.get_energiescCs*z|<01><00>}W|Stytj}Y|Sw)zRUtility method to extract energy of an image and return np.NaN
if invalid.)r<>r<>r<>r<>)r3<00>image<67>energyr4r4r5<00>get_energies_one_image0s
 <0C><02>zAutoNEB.get_energies_one_imagecCs2|<00><00>}dd<02>t|<01>D<00>}t|dd<04>d<05>d}|S)z4Find the index of the image with the highest energy.cSs g|] \}}||kr||f<02>qSr4r4)rMr?r~r4r4r5rO<s z4AutoNEB.get_highest_energy_index.<locals>.<listcomp>cSs|dS)NrEr4)r<>r4r4r5<00><lambda>=sz2AutoNEB.get_highest_energy_index.<locals>.<lambda>)<01>keyr)rmrdr<>)r3r{<00> valid_entriesr<73>r4r4r5r<>9sz AutoNEB.get_highest_energy_indexc
Cs<>t|j<01>}|<00><02>}|}d}d}td|d<00>D]}||||kr.|d7}t||<06>}t||<06>}q||d|dkrBttd|<01><02>dfS|<00><07>}|d|jd}t|d<01>}t|||jd<00>}t||d<00>}t||j|<04>|j}tt|||jd<00><02>} |<00> |j| d<00>|<00> |j| d<00>kr<>| dd8<|<00> |j| d<00>|<00> |j| d<00>ks<>|<00> |j| d<00>|<00> |j| d<00>kr<>| dd7<|<00> |j| d<00>|<00> |j| d<00>ks<>| || dd<05>vfS)z<>Determine which set of images to do a NEB at.
The priority is to first include all images without valid energies,
secondly include the highest energy image.rrErRFrF)
rarrmrZr<>r<>rfr<>rr<>)
r3r:r{<00> first_missing<6E> last_missing<6E> n_missingr?r<>ru<00>to_user4r4r5r<>@sF


<02>
<04><12><04><04><12><04>zAutoNEB.which_images_to_run_on) rrrrTrr FrNTFr)FF)<0E>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__doc__r6r=rDr9rhr<>rmr<>r<>r<>r4r4r4r5rs(M
<EFBFBD>
,
<EFBFBD>`s1  rc@seZdZdd<02>Zdd<04>ZdS)recCs||_||_||_dS)N)rpr?rz)r3rpr?rzr4r4r5r6hs
zseriel_writer.__init__cCs&|j|jddkr|j<02><03>dSdS)NrEr)rzr?rpr[rNr4r4r5r[ms<04>zseriel_writer.writeN)r<>r<>r<>r6r[r4r4r4r5regs recCs<>|<00><00>|j}|jrat<03>d<01>}t<03>|jdf<02>}td|jd<00>D]C}|d|jj |jd}|jj
|krB||<00><00>}||<00> <0B>|d<|j<08> ||<05>|j<08> ||<05>t |j||d|d<05>|j|_qdSdS)zVCollect the energies and forces on all nodes and store as
single point calculatorsrE<00>rRr)r<><00>forcesN)<0F>
get_forces<EFBFBD>imagesr r<><00>empty<74>natomsrZ<00>nimagesr*rbrYr<><00> broadcastr <00>calc)r3r<>r<>r<>r?<00>rootr4r4r5rkrs&
  <10><04>rk)#r<><00>numpyr<79>r_r\ri<00>mathrr<00>
contextlibr<00>pathlibr<00>warningsr<00>ase.iorr<00> ase.mep.nebr <00> ase.optimizer
r r <00>ase.calculators.singlepointr <00> ase.parallelr r)<00> functools<6C>partialr(rrerkr4r4r4r5<00><module>s6             N