From da16a7e50ba74aee5d6d08fe49f41d673fe3c551 Mon Sep 17 00:00:00 2001 From: julient31 Date: Fri, 5 Apr 2019 13:22:46 -0600 Subject: [PATCH] Commit JT 040519 - initial rotation with Rodrigues' formula + exception - worked on neb_spin documentation - removed pair/spin warning for neb/spin --- doc/src/Eqs/neb_spin_k.jpg | Bin 0 -> 8348 bytes doc/src/Eqs/neb_spin_k.tex | 16 + doc/src/Eqs/neb_spin_rodrigues_formula.jpg | Bin 0 -> 20271 bytes doc/src/Eqs/neb_spin_rodrigues_formula.tex | 16 + doc/src/neb_spin.txt | 430 +++++++++++++++++++ examples/SPIN/gneb/iron/in.gneb.iron | 3 +- examples/SPIN/gneb/skyrmion/in.gneb.skyrmion | 3 +- src/SPIN/fix_neb_spin.h | 30 +- src/SPIN/neb_spin.cpp | 140 +++--- src/SPIN/neb_spin.h | 2 +- src/SPIN/pair_spin_dmi.cpp | 3 +- src/SPIN/pair_spin_exchange.cpp | 2 +- src/SPIN/pair_spin_magelec.cpp | 3 +- src/SPIN/pair_spin_neel.cpp | 3 +- 14 files changed, 560 insertions(+), 91 deletions(-) create mode 100644 doc/src/Eqs/neb_spin_k.jpg create mode 100644 doc/src/Eqs/neb_spin_k.tex create mode 100644 doc/src/Eqs/neb_spin_rodrigues_formula.jpg create mode 100644 doc/src/Eqs/neb_spin_rodrigues_formula.tex create mode 100644 doc/src/neb_spin.txt diff --git a/doc/src/Eqs/neb_spin_k.jpg b/doc/src/Eqs/neb_spin_k.jpg new file mode 100644 index 0000000000000000000000000000000000000000..add309694f9f0a0901b33bce69d7ef1bdce600a1 GIT binary patch literal 8348 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 I`Ni!20@5|3n*aa+ literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/neb_spin_k.tex b/doc/src/Eqs/neb_spin_k.tex new file mode 100644 index 0000000000..f0ce8e180e --- /dev/null +++ b/doc/src/Eqs/neb_spin_k.tex @@ -0,0 +1,16 @@ +\documentclass[preview]{standalone} +\usepackage{varwidth} +\usepackage[utf8x]{inputenc} +\usepackage{amsmath, amssymb, graphics, setspace} + +\begin{document} +\begin{varwidth}{50in} + \begin{equation} + \vec{k}_i = + \frac{\vec{m}_i^I \times \vec{m}_i^F}{\left|\vec{m}_i^I + \times \vec{m}_i^F\right|} + %&{\rm ~if~}& \vec{m}_i^I \times \vec{m}_i^F + , \nonumber + \end{equation} +\end{varwidth} +\end{document} diff --git a/doc/src/Eqs/neb_spin_rodrigues_formula.jpg b/doc/src/Eqs/neb_spin_rodrigues_formula.jpg new file mode 100644 index 0000000000000000000000000000000000000000..66070f7bc5b8050ec71d8947d3f2da3ec4e8ed38 GIT binary patch literal 20271 zcmb@t1$11!vL@PQ<~Fn4W@ct)W@d^RVu+cU9dpdgY{$&Z?3f{TVrI^B{(H~4GwZII zd8F3bU6QIkm3C{ZtF%jhR{!h(P-P`$BmrO_i5`p|0Qj>35CcGfga6GR3GyRD!9qbn zLPEjAz(B(y!XqLgz#||aA)})rA)_H9AfRHQqG13rF)YGu#H{_<%J21 zk$kWMAmJ$81C+CcCQ?CKbh&Wp!*RDBIxU0@Nl)AQg#FTl}O_ad|24)O^y9JWAGu#)@&yXEf!Na8Ze$fe3r>UK)(V00sEPr8avHlaU*s7x|y%q)wf_r`HAo=qRfq+`?2>3u=k7NhJ9Tz_3Dk z4W?N_JC+(gCo6ToT!ud-N&)-CSfMmDo-RDtqC<#`2{fx+7`*k7u0cF2P7)_;m~K3H zrZtr|OR^>T_^v2ZaoZhBp#`&=Gq0?SK8@7zLUu*)aa+n>gE!{l2Rdn5Q$T)&(iu#Z~JU=FjnK}6rOJVj(9QZ5> z8$X~m85-R_jNLW!i9lE6X>l`#`wi01nH{{_18*z~(`8RTuCeopW#5cD>SS0iZh?^F zhL~hZy)rX_6rS|hR=8iGZaB`>kQ+hd+HAPQYUs-i6CfW0y4&KAyBoWJq#+oOQ*CsY ztx+5le-evN6O^Ra#gmMD1v~sp#zL8~Xux`O*b=wyT*(K2x`CyC1^NLJ@ z&U8shwqSOhT#6tU6AD4&H?u4-lbWkZJS@VQ%fl!Vq4Z1)7sk@@H?*8} z!nvSw9R?_;Olr$K%aAd4^RON76c?v#NRw%WAe@@ykVFEDl1X<07_Z*XL4ag_>4Cgy zq=drckbEu5sCM8eK1HlsoUH4~q4-jh{4$`@n387CT~tzjkj?B)Iq^^2dKff zSEsN(0s!DRhxEpO+y9d!&Q_Wm^1SC)GW`Vch;kyzlt)Z8`vLnj_(q^Su{-Mi?PD!s zLIr?9f`k2CMIoU6k%a<>fP@Bs!Jq;$(Xp7(Fi0raIkCBfNy%80oj#T+*pI~v3<~@Y zU|fmVp$o`Tjc@i^u0+f4=$bUav6!u1*UURJX4*VbMe^lP$?pBy>tv4NyM6Y6zPE!- zU6=HP2T;j1ssF2}wa^tN#a=-`W3!pvmGc2xEh#paS!7{+wSA*T{rMESKw!J3P~b?y zbZ3bEW*lXl6`f$In3M^N_9JM_mcVJj96fe<)Iu04CaVF0E)7zL^t53Q=aIkR5J&Tk zCeR~9cs`%G{To69o*93Lez-|A^R&?)fM)&C1S4sDpOsXL*5&m?idoGcz=FmL>r_Ir zv3)ddkORzMrL5ACaR;Pi^uu?r19F7e>Nod!n+UP&AXysDcQdG2GIpb`jk{z^7mk7n zV~2KdrLD7pG#N|K+xZV3^E5NWEs~(GjO1*E#k`{4qVx?R(u&f@%^T``f{AcphwpOE z3{;~MW6Ro3R8|y8S551)+o*s(E{HviVyc3)lwFYoS=LMqUtL^LT=YH@@;#Boqf-Uh z76{>jcUxVxP-qeAaT|?0YYSL&IcT6W<&#uFY7s@G{Ma(3xqDaqR6M@7uEuw@ZsiAq zN||XzpK}<{%RQx3udzOz^%4ezK2u?D2bQn1gw`PsJBl2bc`%$JQU2X)xnHgCUFpiQ zvvr|ifAL;u^qicmQ<+LJ3wypF*c?+U{4CB5G#&yD%{>K;wt zS)}Z|d#g&3owsHcR1zWuw|Dr;bK5hXX^a62*oyFXu%EhOXDSv9E#5I?uhBv(4o|-; zntv(LY3;^V55ILQr3YSm&MfgOENit?ZD(C)#71hS7Sl<~p=YF4Ik;J+rP|nFUF3G$ z-P!%>;~qcYHZ96w3H@=YMbG#%sNJISE>1*sKCaaj8LAcrXVt`_6r|lv8{F0ms-}BQ zX)09P879XCj^9LT5k@$@8)eJb5%JCw+eXvaH_o4r>(y!o)fjufFphV)sB8B@jK(Yu z<65+x-MTKdyvS*Kq*a|UXft4B#eVfr-Slq4bcI-1^UzpGDj0?(98P%AtqfaHNfLN+ zYS#K$qmWP;T769?1`;jSwv>;TYYx2H0k7k(dwU=#PrdgL^@x;QV^oG~SbBokm)|y| z)x0wtTV@d>=5U0)^j>PBw>_YvE?{L#{o3>Cw~+$Yw|vvbImMb5(WL!SMBuFR$#yxn zxSPvtlkYE07!***`F~f5NM6#4dC5)vv$wNqYsGDKTl(U6ZDJw-9Yi!95~3F9T3A}G z(#@HErb^>s?+N8Udy=)XtZI~zBy1Ezw^kw+Tc<%QV1cU%T592uqe6{giT4WZ<4i=- z^F4yWb4O{-*6Ha);raHM?YMEc;j<(aEfnl(`5t&Jo|a#K!OU~P%$*fMQOPjU)oN56 zU@^Ot2qmcvm{9mN;)J{*GP%*2s?}Mw0RtJ;2Ikr5?@1VEHV2JBFsf1*F~WdoErD{- zA~h8Aps1<2R`ZjN?$e4BuKL6QK9ZnFAVfh0?3IO^7E{(sDO;NKy*nDqmxvt=slm14 z)J0M5VjH;Hbt#>>G-%W==i^eDWkUPqC)QVLrw&hS!!N|mLHqW_MaIqcajGX{FW1Q3 z*QCRHVZa@;^3C8RDb$N=ehc+gKIk@oZIq4xp97d zHaE+us9m-@G7HHU; zVyIQ=?8vq78f1~qS6VpdNt~KkJ{0|qn(MLOuPf{>3^oN(XuC-)>jo2s{-kZ~u_N_% zCaC66`PCYLW_SB|u(<%TuO0ZDAB+~*AFHhqZzdyMt?<7d!qkP#3TC0-205t;OdSyO zSVLI066?3o1J=tcZ|Ezx(nEBr-ga|B7k5Bu{xGNM4^H={xBU2~0s7bwPI8~DS;_CY zN+Y^r$5&35+>aIQo^4*$HoVhJD-Kj2zj=}424TH$^$^K`m58%gmV!}|*{8K^Rrb9v z`utZ;H)5t#UZZ`R9BKvV);UU}g=1HP_A4`6RxP}xI@`_QMEfLaWGaVaIcj@v9((p7 z>*%6u_949$Ln$EHRD%&XP!?iZ;zG*Z4~S{C6(_{bHw0|)3eg;ye4?+XWRM0H>ls6< zz1z+A2p09cT%#~#C0(8g_AI%9#wp(g9gPg&pa6JmsXu82l=VTe_#=M+mD=qnvh1ex z=X=haxD4cZv7h;KJ%+$rvG~r$O@+B#qU9rgJO)cKQzEY4@+=fb**^j`p3sFL1Dp=A zGSJ$upyQ0?ahs1_ONAhQF@x)6d_GnOlFP(^vwtoXj#FfRxTLPU2D$7DIQ4~K z1r&goGw9hg0+H(X3K8UPNs`Q!%3~;dpY!@Y{f_UWxB=f_B+KA&5y>fpsh{wxq7`-m zUU5`sT2wcVFtqPp>zCvW74|x}2}r?vGelQucJ+9S0RgVe7Pf%Th!8=3Yzm}dMOtR< z{7yInMelYMz2`fzaU78SVob4`q?9rwPVx-y5pnsj3pP;4_;yjQ@>UiEiZ;igkGIU{azK5B3l1|mg-0gzhC_9h6&wVLM*J}6@fvf<491EF8{SzBLj-Yl zp(%^JW9TeKe6fBXt-oFn`eC-~+|;pY_ZxGo^&}e36dw)M#CZ5t{12d4qYIg5#b){8 zYRXEL^s4ZMY#7l|T_GUY6*qn|88h-q*o~skysbZoXai?LugFpLef*WpJGPJb-kZIGK!D zZZq@O-$VN^H}D@53y}AZA@$)Q3V~q}|8F?J|IML>3IGTDu*@J~;NfAR{+eokOK1Qn zbPQ4!6;v`26CkUqb6{dVGzmE~8@s4!eIJNJ%q1zge{TL#T+J*frD699lT+B$jY3)7 zDLABY;6H6SXrT{V?nI_MH`j}1(cmD22JUBj{|q68JSuOv43#oO@Pz-HeiDd5`4=OZ zoWb|j{de8kH|{@xXrLUHijIu>61*y>xqTZEt2VkbegjTM3VQ62PdB@qj)JN&2&u`o z*l{BEQh#1aW>g&jcZcx@&^-p!!L(3if;00x-TJ|w8Zrybn&<*f_oWiGYb2wxO|eDSalu^Xd9u3W(vJ~+mIP9DawIQ;|ASCPg9 z6J>BY{Kc1Gqx1UoA!!BP5l*_bZ5e9-xMWW>V2?hQmvz$CO;Hg=83)EDfzR?JESQEB zRjr{~c+|)QeH8xNw+G$YdP!fzOoPoyQChHdEy&BI|IiM~T*E?6*Argb+bLC&f`hsk zOV1JF>kv{=G~sLEr!PlL3pf=M>Vf>UHC-l`Q9e>x;Zp5Y>5f|8`YDVmdQNKdtt*x^ zXa((9FCDD?S~o7#7;M{yT%#i#d$uz1IJ8i;m*jt7B%xH_`wW=4PT;1J&*5q2TS(dG z`6T;pO{yIH#*ky5YntvokCX!c@)K>b17>3QWYu%d*YECUfJhrZ>|>~DiOr!20W%XW z!M&*v++1s`k=5SzcO(@pR<-_4gQ+k^Znr9TO!%bkyZGpD!rNiqI`d8?Q$>%ZiHBFe zhU6E<`?-w`S$R$e{V)n09lB?RdOmj+jZMJ`qT{CdmR$+&f1*FbP?rHkBPy5IdkCca z!%$PUs#){4UJT?w<3(gy@gog$9lp2yFY3Dxl+={;%Ckfpdfiygsp5#>BbK%GbrRbM zpp-EscVOhlemb35g%v8<*$;^=JfUcd}a+iJaep4S|iTfJ-oFhG7ZKjTkY| zmlx?)MV|9ruLtw)Yke4&#m&a&Rv-}9&5$sY-$zo}I}vN!3%_AycLd!ox!=x~*iKE^ zpZX8r`ySLN_U;#`+S0HB5O3J3KBB$_ySXb`j6yoj4l6kdbP&aSU7W|6!+T6kIH9L&J>%86F%u=j1l#T+VN+wS6c|;VGk2u8Qt*mM|1zAY65EfZ6cN94q8Z;xN+v2rtv~H;msZowDc2BcP zskhSIyLn3JXK|kc9oo%Ckr(C}g?kWojhKsq3a$D|lZ5}_wvT^lQ{9@RQ{1sxamuacNs{TmNx9wH8bP)SPk=7OdL8no-C)MK0%y7_f zH#|-P1wWR)w8^xGDkFL#b*5g`Gd=F{?VDBS^a^pwiyWD;2cL$d3|qP_t^6yH zg5q{#k~yPy2G4COs-MI+?Veg+g*W6Ajlx=5z@T^TW3bGO`4r*8)Kic@CI}RHS>z9A z4JSninl`>ZoJm_H-EXu;Pyznd+tgcrGoBI;ag&yJORNDY%oGH2LmBbfCj>J418A0O zDU!K({uy&zm_o}!%jc)Z6Li>>N*V7k+|T<5Gv6ZqTls-6%~{rNY3#xO>qcOC(6+~W z#zDY(jVVd+&BhZIa8boGAy4l{pcK>Hz8^MINqNwC@+JWts3q8@@abmO%px( zg5Nl;OmrC|9RwY5VhYLRkQ+P(Cr1!fNyUGP3- z5X#pN+FQ2V8BrcRw9+e2eN`KgGo+mrz9iA?er0zl7>#3ZU~VH%zj~#o(}X93e_I!D)I@?_xva-p z9dRu5F@giRG`TLw$Kt@aqKm#g##YemK)a8GW$0^Gk$03hLl@$m% zZbl;wV7kZtGrM}jV*dc(%QH&K%lGR~Z=1uBCoV3=E6QoHGILY!8}$usvbx%`F1I6T zV=xv^TKm*WO8K6Q@zMMS<`@{%MYTa#v`*HIX=xQ{+kwj!zifmW9c#BYLZ@9*o0V>D z1?gmad>(Fpu7$dhOgKX^b{%5vfOpocIBL-=FaG4LsbsEBQ*n>c`p_ zM)KTYYkXQ#okn^pZi6`X_zyszIZ3i_-?>~zp^p%=S!$%L zCQa1W0QC>xu=Gg}&CmLH>g;36`#0kH=PLaHn3*w>$A|dMh)wZFBT6$)AN87DbrJs# z6T+W+Z!@NzIvx|+K#r=|fshWGD?c-9Gew+WmZ+JuQ&s@o#7d5Ms*LL4epe(7r%9|; zK;(po$Mt&4AZOD`%8jWWL!um7!9w7BZwtJFF*+{3&vNPVb~&0bd$Q1I66*aLL)LsFqr z|Me(6e?r(Y+lBxx=S@e+w0+4Z5?VkL*I__q8A&AV2yLWyW&#d9=^j5i%eYMLp9+*b0gndWVQ>15 zG2OB`cPL8uGX8YZ-9kWR|1hP^P;upmfOem`XGP+ZUC%nudP%U!`_kKDSz(zBsGy+9SH+%w6nnM7}YI z%>`$OWXSN_5smcir{IY6;3IFP%?kUt%QDDWMf*-_S#I2AcwbFOHk@_y?AK66He9SAu&?A27l3me|MFIj@MI* z0deTq*5au|nk*)KF@zXW737Lsol zv38FgO$Jk0!Ph;>9;Y{>_{N3}GNzUas} zyAzxrgJor)){#SEOivy4+Ad(aiIp{QxhPhh(xB?it>Es&?pMrlMz|pI<1WoBa4#z^ zGWqZ&9OdHCm}WHp0M2($%&RYHXo16V1a#ZK9`@jUtCCL>80XbI9ByW1en3-}omNz) zncVws;uQz+;AfF=Pr??5pea$lrC%$uhS_TC#1e=n<6J{?NGSpBr<9Qcx!+^e2u4;M zd%#jQrQ5jK=U$sXje!ULe(7q{9p`?}vf;KfQ>P^>NsC7G{ zA$whogFjpW%lHpK>4ocg^R0^qOSWghw$I0l{PUR)3#fJ}3PkS{Fl1>({rIWB{E+JV z+npKh#LQH~@hhX^{ps5`2U>lG{5Uf_fma`Aq2e-cW>;!98md^c)kl7pU|6nwla2rB zR;-ri2r~fXcZhbQK8+WI;hLAlV7dLObC`1;-De%QvGj78fzb_!b8K+2cWhmYciDcM zwA{W&X8ra8fxG>V{s-_{M@2kWVV3@U_OQd6RgMjV`$lLW?zTi$X$@Ijs`_abS@4tj zOs%Gl6kVm}yWA(O3Z~7O9)z!lsVs{}so!8=Lz}I8usKg5{KzBi2~bH?{J?~V3{9|1 z7|bW~dB)E6EW+K4cMpFO-jHV4}nxnId`99_gT9pTkryuAAj@*CS>R zzB9wZ50^BP{NkUt{?ZRyHT#$LZA_ld`t(eKU{;}_?1|94<6G+jlKRT>KgNU@x$%lzFGz7R^asA@Ilw+m|H zjqK{z0h2Ih$Ob$Izq@Qs%mQ+6%pOc=>5kSU&+Qd^j;Bhxg}m@R3^ z7n|8#_IOa1q}zs>v$R2P#E}*jD`cZFrs~5Fqf4nZuHlj<g6(3b`Raz%P4c1**YU!D))AQL50?Fh08#sox=S_|=BDELNSw5~SnIYoZ{D{jlsIYQSBZCV*y zf(zb9N*qHDevBS6JtI8Q&j3Y91AYdd; zULVe1#}!@lWnO}I%Pb(pM;EFNQcYHwnEU7U2r|w5uvmqZCH=Wq8s9YM_52uUAS70e zVI-?MBEKR`rXbc0k^^0L^UeM}TMmg{RSX!RoL82#eE!?vCI)v16y!RrqQO{eSf!yX zv!{S7cYWZDDIlfU5`C$&kj(h|St1Urq$NvzM^Bf>K&*QeS5HN1hde~gJ)ZC8VxSp{ zT1L+~G19U%d)Jn>XhBNO>o9I3cfkGihc5(%meS%^wz8x;iG$$R7jKHPj3x>6ua*J< zrlqW93Ya?C!^J6A8iHic-P>N-T7o&Ty1nQl{^}g>+g_@rl``4Xi73Vyp0!1e$3$py zp!?nCiq!7qUT^Uo=YHP=en+gMXwFeQ9m<$t zRlJEjdOVV(A@fRi#EC1guQs1^jIAiPVfPB$JQ+mNQ*6e^Ki1mq`Hc9fIH|(c z|Km^ICA{ro`=nO`Ox*$CVOp%Dnar(1M%2f8WhA{FUQ`{T0O4Vh8}?Pax^4WYn%+XN zw#yxpuPz56_Ujgog;;*I1!q^ih!nyXWI4qJbw$t4B$Ohb$LD7oazb1Ee2@8DSFWh; zz@CC6mgVAcY zwCG4v$`gu4^_a1dLRO_jaFP%fw~0k8(+ybckYfe&j67^&_(gpaGL zuPFE!%UeE5{K_i*+Ym_$O-mTLOrYQsqIbdWNLxyKH1XoKcw?OM$qEb!O)Hji3w{ly zi0;}}ls^E>P|M=*UGKqYy{RZ1LJx;ThJ~^7hsHq}u(_1f{Q*=lva)D~_#KTeCG-eH z??Od>yrop+m$KgN6@E=|HSE7$d?EHS2*nB!F!^DJ&A!rMl@z3^66%eYE4yuXymTFD zWC&yag2W&}cU0N_xgC)&m%x?gK(BbMl${&XU*p%AqUy;GQ4gj8dYXECRW#CpQPpji zVBbF;?T~?dh<1JmSk-qD!sQoFAjFk1)zT2NuTsI%yXhaooURS= zBKDCUiN=`0TvFb!14^X5Ue-&vR_+o>ZOyan4cd_K}g3?(Uxh>8iSb0A4#{v~sLpYYtSveVVS;*Nw!{{WVFC>{eKp*oH^;!uVA zA)I}_9X6d*5Ss^Yp5Vt{#sETGuuM~OfYe`AY*-w}L9o+0F{~|%Hu={r#AHG@6{vX< zRmno$pHATED+9#^z#=sQ7D-g6<9rc013Ig=uugDg^sj|SJEZFzUQLbbVp%i-?J2|L zH>*OJv@r0zYd!Y>Pql^qHUaxU(b2qg^cQun#X-2Vk-aoQ)$?)UpuHVPo>l)^{M`z>ay=8^_0u3{1@lvlN?M62{t87zD_hA_>`|N@a=S z^LlzP`hSBD8(4Z!U9Ka+|yXvO(!Tm^!>oY`ZWd!R=?~j3ZLfb zdl0wI;-- zc7|4c^aBYO;dqvky+Hg|qY$gDR6{p@=@oD zz~llCs9)TsGw}r37RZ$-9!kjoft}obcp}h6N;%%!t8tDXE3v zF;>0|$Om(6fOVL&Wt(g-4eo0xi?V!FXz-Z;-gQhG<`mnNfq+z0mph6`i5Nk1B3l)n z7^E{Q(f5vpszHHj&)}~}`*Sov0~4}7UPZU#u)%u1U;|D%0W`)oc#6HMCv=kb?|%n5 ze~ZP|GRH;NS`1kQT}=!x#y59Fh&z(177y~!jY0z$(?3F#Nao62D2jtYcsjju7?)|l zigbilAhxEcBa*Tb)3SovVl)3IEhrEOvEV+bSZ7PlQd(amn5p1&f5L9s%eIXpSb528 z>H|lN5M_@R`JV6+k0KHM#niTken2o%4J>bLRb)eTJRnl}WuYXT8x4vanzOcIqa-=e z;p?yJw~Vp=(R7}|^&?3!R}epOfG<_J;DYe#JSY|sLN)=@6qzi(RbB}Q<77>OCn~;G zEDs$_Wdh?Uk{gu5m7!mqEB8tWo z$U_S~Iflhsm&qy)wH5p(?~z0oB;rqMr^?cw)Q8y@GAz5goP;2v&qXt4Y>9RLsg^>| z^1)gbb`KjiT9cVG&vGd`wb~;)PILATpmAMdN#db;5_dX**Awn2O-_-I4uqh7ajZnH0Jx~th77I7!I{xOO-Dc?vCb5#tIcj zAqV+!PX|Je7bCV(-ZGE-mdHj?iH^}tuf*UhZBNCTqN|r=B4}u$>BWf*+=OG&o}ENx zDCVN4?UfC!xe=31+NH3=7((QTGD`d)R)yB`y^EcZa_{W3HuI^;BlO7_w0qYBvosks zo7Z~|)WD6mZZ{{($x?nZ=g>*BDAM-C!u0%w`-yib}E6 zwVk$sd;N?C{zpyt0R}z@M`A;GyuCBQW$1%?^~7HbR1@LIgLGf~?}Olj^cxlSWG;*x z-)Au=6C%+TkBhC;$M3+Nt2=CwnQ+~X((4lXmP$M74N`xNLlw{_>E=)_xz!y#m}dc~NR)6S6cw9z(y9FeoZ!a?NJ;6;l#CmPojq zjqZ5hY&Mf$Z7}w-oea0=7H^KAxE%{tj2*{4PNq*9wRxqw7LFY6U5=;dPW+(gYerc_ zbF=UnY_BmAa)2C~!=RsG%~*mix!SOL{4q?y*PWWz9k8fS3LU=i)OWWag_~K@A!2fQ z0M9M<&K;s<89KX6Yo1H7R-5NK4cwPo5BZ=uyj<2Ie_;V&57g(M07P{f+OZ$}wKs)B zL6PF&t5%Y~#Jx$P?mJPm<_ge8TyLYea1k#@n8CI>GuBx*DFx0K4^UqL4E-;v8ESptxyOuR77pb`m0z1lQ;`vWL}6TFsdJdO+_9~*#$$6~+2gY( z&gazh)$Iic7p{|86u8ykKs=$_b`jR0*M#yEGIvDz`=#Z~aX-=A%z{bP%l0a3jIK9P zvc)?cU#CRbE5fB9Nfr~1s(JkZu)|qd`kawscLaGAx&hYxD0o0|GLXGc5$2LIzs>>? z)6SunJX8#(ZL4{mOuJ#Rz>nSDx(t#@nj}kO%86%DB$)aPo_ZlL;bj{>qtLycKxX~S z6N?g*Ob56gGxZ&x1*E#sOyPzus=X{@idPgUH7hbA2ZT5~V6Uf)=fVOXL|pJ`GH&1S zRPI@1{f2Eagq}1GX@Kk57}R*N`0dFFqlYlR6($P0syG#+*^6}0q+jr~s7t(lIm1(& zs+)%*hB449cKI-Cf4s|Nj3#g~IbB)&*r#J2Z!4xpvwi+{9Rq*_3ohZSyM4}$;W_zH z?)s!g%cLxc3>`?*%5)5!ViC#>@8!ep!zYgBCnx})E_@*SA=O>_S{V2hU2VU>iSH^+ zESq2mpCqGQ-ed4yHYL287A6g^me(caM(5$X^18*Hb?l8Go{9YLya{~6oeY~1v>>=N z4-e$KhN?T#cF|lr!c}iy1@zPPvn|FRZ_YmeXpN3z3@TgxBXvDS`$_EiDx8tvp){8_LPyMkug;PtQ!tbFi5U=?J# zn%yemFWR(yNy_e@A_i|TE@ZNcDCjNd^mY~Oj2_i8axI;KsuKL`!F)7u7g|tQ>2;@c)dzPM$7T}b22fBm_;ntp0uFevlM0?qt_KTcVZVs#jbRE zEdNwqvQMztNMUuYVpC+Er7k0FJfE_;8D5LR16#3c_y*o%T| zXf!=-bCtcIgANLFva+3*V+SS{^me1^HS$h5+=AEq&SR&YW>DrNG&!OAO`VT0QH0t3 zSa1kQ_GMt34So9$;67%p) zM+K`K*12nT!b9rXsny3k8J-`w^xr2lC0%TZj5kmDm$_uIx88I_bvyTWOs*s#*L3PV z^m&TX)I@PWJ?8uvqQlDi~0%apqj z@4lLYD?utjti)TG#~#*q=OKrLpe01`(q}wTbUB%aIwCEmKOlb^GPFGzW@ij2c>I-G z0d_pBs5cKOleD<(L?wjmi|muXE!QcMIeke4dTRFPq7d!gzB93{bGJ5vc07#EN`_YT|HanHBy>cnbW984nTIG%zY`Ii$Is_goSnBOhRD`x6e>qRjb7_632pNpTd9T ztx82gL+fZ6HP0_#aN~Af8_-&K&-;z!;XpR<&Z2@Dvmbjxg8HmU zJCHth;i^PFUx|~thBV|-d5VuJ$;r#_SYCe#pl%UG$;V>qmm>^1`_;3MC30+fD9!12mMd|U*cc%NBv(~ z8k8Un2!Q(#0R@PF5&)nN9snE&9Tor%_=}JL2MQ2|43YtW!$E%3d=P(OMIce7NrGfZ z(Es)YLKg-FNPkFu6hR5FBnhw}aA`;YEMyWGAV>uCah3}GLkGBzz90i+K2DxNesmfH z2Lk`A9%Rx7tjGrf037x&au6&i=|hJPG-&`j;2#9Ak1Gkd3?ShHT!tjzLm%nCP~bA4 z5Bv{>!KEQTaDqetA8e>_puauBeTQc7WBUfNd6nLjQW2JS^f_WTGWrDV&LH5ALq+Hj_Ljl zf&P!}9aI$)=8s5alKj3);W=fe`rUu;?tDaDEHR_xhE(8)ol_DKyrudu03oG&uE)_- zz$BpjAo?WT1?bA_GFSE6>=&JfY^2L&6lm`BpwKxa7P)Gt(JH`9b(IO^40~>hVh0Ej zgu|HazE`6JrJ%Tw&>7A>lK`Jp2kLM9 z>I}Z&MElyOiQ$8#s(%};bi*Rnz`vxe+hb^`4DiSph-Bsr<`}MZ#MxmPq9L)Tk>s0t zUx6=SIMsp7e5TOLt9vfn4%7%ovrpBBXqqNQZ9f@r`HX$>4RfTAsh3z12TgcUFkoV& zGQbsAJlR-1S1Vwt(fyw!F-I zoXdNXZ|;n1V@wadva=Csi?A|1Xig++GLm8AkU*{TZdAMqx1>MLBnZW$&LC7(Mt#jz zI&#YBy4)?|$1etXkEK3JZx%@Y%9m!A&Km@)00s9d8*6Wd9JybUiGBGs5SCO;!m~}N z4bDcCdczSyn_1Hn7%GaGnEfN8B*j=>1(8I(3$3Y%WrH;1h}fsnv=71&=>98S`m=01jCg33LD~Opf7s zelhAMR$NOE>|(`&gvj_P!EW{_11Oa%AV>}Qht;-6{l^R9!lz!l{@?a)p1@C-A@85~ zh}b6i6Y6@SQY1WSJXk{*n<9&a5kWP;Z`YNxuggrJZe5q?g)urveYr2X#wT@(Z4U zcNE$>gA0iU367&mI=+8n=tW<~a+@5HEx9$?OBM zwvHqoiw1jX1Y+J^}z|x)Fsb% z7Q4$&E*Ts`VMqP4GBA0quXW3;^P;jy@nfO;q&lEG^Jr|L+2=>7lza(TLDSw`Vs}x+ zx!-~V@NJIn=9ldFOD2LryRs?WWrm8(e7(X%Xgn+lmzRnfZa7ExSbnK2LtvWFxX>zt zhayzdINw5~^AyM&j{enGC!l}|?~=h7Ris|A%3l!(z1kVx6eGYDc(Gihstm|Ptf~!F zo~@fuT#zz+#}pGCVBk|A^m+V3g>NB4+@SPMAb>^d=ETG_k~SH=^C~Sh)@QvF5$LDp zpZb-cH8AUe8fIJ2K@myoO{r7AD9_oY6lLJGwP*C!4fAZU175}r4>s*Cgag*&HFHEV zpF=iA+AV3WHuy`GB@&D@;bSGU^z3Ft!I!aP(**ZdgUCn#VN;#oafm&D$ZkqZng}Lw;7}D-3tJ) z!x*B%rg#xl9VSE-H2H^30ffC1CipsD5fgJ z{Y0>&mrLLL=RN1F?G$`yap2{E*8b&`DdOUe* zc7uC$xZYcOgLV#9=>Rk-JyUU`$!x?dH1jdAkIf0^fJ`QoFAg7&g1PurC*SB4M9N+% z8SAV}9a+aET&Wr7{jB1l&yEU9l>V)ukV)v7Bm97b1O_Z5pnn3zP2Fc>0Iv^e4v9tr za^0MC3WWCrWCD{?gy>EYt0TkXRo~aX5iI!zO}vr=d0_1g^NDVEVebADnD)T_P~N&h z0A$EGcl6#YhJ@%qQxKUAF}AROTTYMjTer<0K>pq34?3+MGso?`UTaz05i|c+qgEab zb)!Ik#@NZs7-Jd6*k_0kvP29sF=Wd`Mz-*wv1H5MFk>lYh-CX}EQ1&-A@x<(DBBEu zWU0)TC8?~Ht>yL3d4Ih3-~0ETbMLwL&wJ19+z&SF$?C0>x29`er&|6D_Y$(Pa82J$ zuy}o-Fqfpl%2m^<`v%I`5{pBVbJO)5Xe->wPeMlw;wVWkZ7U%HzKc0mu7P=Da=El( zQO^gh<1Z#)KZy201AFqAe!cRZWYOcg)L+1P^R)T>=q>vKOOAUQA{zejwomkzZxxpQ z>bX>F#K>T%et{)xYx~fOa#O*#0}XWS3@c?>XV$?Q^*9#snZ;!IpiMZuN>|J%I*@$! zK)~97iITqfzNA^?$$L6~CC1Q|`E<0-_+^Y5sObF2%KK;kmUyWt=Dr8vMcnR!WmzLd zW5dzIK0;{9J~K5Yuy*D2hWiro^DC_F6;VL z(Y!0}am{wieV$tCL`Wt288$b}7^QKmk`yu1L>TUH_QtRoVbyPisopsc`48!#MVJ7; zRRY(Ekj;$md3q9BG$XaEbnAD4rDjA~N@>o|&LLM1%^99{qK7B&nSV|0(-h0D{U2N) zPC`9_-;N8Y7irUZ0k42mwyP#oGNvR_&%rT-Sq;#g3HYL z)*ak0T;&ciTJZFTwK;x#YfoJBIA~G=pRln4HGV{5Q-?pW+UHy0QQIe_in;~2w&ncH zh_Qfith_Y4ZhSu@*7Cy7)8SW|!tCFaq}Sw5gg4y9+CGrCI{G-Q`)yf$Yq!sabuYH}Z|@BBm?;SQmk+-g&A3Fo)i{ z{7(=}&tE_EOd&jv1a78qxKK`rtXoghhgctc&62JyxE?+?jn4t3Q~d?p-w4Lw8XA74 z{4ElgcjDml zCiX)e2E}^v-D2Gq%tu3uRgw=)N=#b3IGX~gdwN{CNei9erdU31qWvJQp2Lwg9N@E_+Kfs1FMmM*hw-fLeIpue)Ul6KNrhe(5RHZ@K< zU!T<~lBN};`@%CRlY=Sfi`j_}+N*80n>tMxe|_B@+Pt)pt?Y0@S~B%e!p(Ne>Qc0) zkE?h%NARXVge~>s{D{>JUyUcffT+a+bq5#y44I5%YwO53^aGaUdl2^Y&D^kbI4enY zsw87L!yWUw99Fg5&{XBN*)0CF;zd}#@N#TP(35p@Yc++hLj~fEiG^O|^Y_QT;QlXa zX&ugw>SA~LMD4gi0P3*?-ae6hg9A3>Nvt!MWnD{h+M2qZSM|nga|_X3-S-%LQ!3`r zeq82WMN86E=A>i2N=6(5Q6 zi>gFxCj8hAu6-mO@i4Lg7+ghsa@STr@3T5hb@AlGQ=UEQRJ^*(7~WbT_-7jwVry#+6<=bX)$P{6iVC0!Q%k+Uy7PR#{)5s0$cLU| zF~lq5#SmYk#W*z8s1rD+0`Q4TYyc!kU565fzmVO9S=wW$zCJ`Ctdg)WbzKHe3Wwde z9u@Ru$-$j^+@_{iXDxk31pU6*J12-dTsA&?^(I560jyk)$|Ny86ytX75NU6IMwM`? zZ0Xaix4^Wrnw%4e5s(!^PR5Y{WxJ59mVNWpN-vdqtGMjJR>J_ug_R?0kE4M|*He#t zvdAb(o~H-x2HR01J``zOEAyEA$P{O3)fZ|sn)5I~Fw}3|$WKlREKbZ5Ec!(8dXp*h zw|G^H7@u{RtP0{lGLF`C_H;90Y!-<5Xm`e=m$p&m%vJP1OT0LAFgqZd!K(^G$zI>U2)b<{lL5hjyEgem1U@bbg#6OcAGra^zil*;N)=#hzn3<=};1ioO?Hm z60^X1CHURKWEkOYQn8s~BtgkhMpK{pNOOw?3-k^)y>yWP06{!G*MW0MIT6~g*68Hb z3|_x97*%^X`QhbL<+y8l?Q+Cyou^M!whg>VLei9c{i&9diV5>VP16Bqxa)pY0z-sH zFcsEHnK+ztbO)M;6TM~R_)gOFQQPxgg4FM4`0iEkCMbgBha@G&w5agxC?q3-Si&sQ zSaZ6V1v2nY>^2@%z`XUJ?<%9K$>2qOgsy#i?>-wLpDLM%8jHo-98Z$j4DHHO-AEyZ zx~t0u)Gp{xQmR9_U;xSRxi46)2zU?dT!(=-ZGp?gLo7&858<$^LCqQ0hAtUq9Nl?C zeOKD9At`U;$t0hFIiiIW+VOEf)*@mEwwg@?gA5ZKqtXoR_xRZdL!Ebn@;|w3l$W&U zM!SYsFRB(Ew(lvjM1KGMhi?-v5psO5z$~~24d~$ym7J72e8k<_(+wKNWQ-XZ9jwCE z;GqlAVap>H(Ozu==wn?gf&-{^I+ zI2J+fu{BQ5%=@&LYu}Wq*V_n3kUyUfZ~Eg@rU4wX$Cva}W}>u5-xLZ@^bMVXjt@zA zSe^Tc@wt=vH8|>ulPwGzmN^|%RR(uG6%uNXVy4Lw)=VBW26 z-RCI3r!am3QnRY;-~~MqT`#O(Tl>GE7yEFt1AV=lXcr+Mp)<+VC0Py_8kb&zA^1?* iulMl(Ejg6htkcF`;nw0ZWQ~!kwqP|rYY?6DYx-ZX9e?Qn literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/neb_spin_rodrigues_formula.tex b/doc/src/Eqs/neb_spin_rodrigues_formula.tex new file mode 100644 index 0000000000..4a8347cd79 --- /dev/null +++ b/doc/src/Eqs/neb_spin_rodrigues_formula.tex @@ -0,0 +1,16 @@ +\documentclass[preview]{standalone} +\usepackage{varwidth} +\usepackage[utf8x]{inputenc} +\usepackage{amsmath, amssymb, graphics, setspace} + +\begin{document} +\begin{varwidth}{50in} + \begin{equation} + \vec{m}_i^{\nu} = \vec{m}_i^{I} \cos(\omega_i^{\nu}) + + (\vec{k}_i \times \vec{m}_i^{I}) \sin(\omega_i^{\nu}) + + (1.0-\cos(\omega_i^{\nu})) \vec{k}_i (\vec{k}_i\cdot + \vec{m}_i^{I}) + , \nonumber + \end{equation} +\end{varwidth} +\end{document} diff --git a/doc/src/neb_spin.txt b/doc/src/neb_spin.txt new file mode 100644 index 0000000000..33cb4cc2ed --- /dev/null +++ b/doc/src/neb_spin.txt @@ -0,0 +1,430 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Commands_all.html) + +:line + +neb command :h3 + +[Syntax:] + +neb/spin etol ttol N1 N2 Nevery file-style arg keyword :pre + +etol = stopping tolerance for energy (energy units) :ulb,l +ttol = stopping tolerance for torque ( units) :l +N1 = max # of iterations (timesteps) to run initial NEB :l +N2 = max # of iterations (timesteps) to run barrier-climbing NEB :l +Nevery = print replica energies and reaction coordinates every this many timesteps :l +file-style = {final} or {each} or {none} :l + {final} arg = filename + filename = file with initial coords for final replica + coords for intermediate replicas are linearly interpolated + between first and last replica + {each} arg = filename + filename = unique filename for each replica (except first) + with its initial coords + {none} arg = no argument all replicas assumed to already have + their initial coords :pre +keyword = {verbose} +:ule + +[Examples:] + +neb/spin 0.1 0.0 1000 500 50 final coords.final +neb/spin 0.0 0.001 1000 500 50 each coords.initial.$i +neb/spin 0.0 0.001 1000 500 50 none verbose :pre + +[Description:] + +Perform a geodesic nudged elastic band (GNEB) calculation using multiple +replicas of a system. Two or more replicas must be used; the first +and last are the end points of the transition path. + +GNEB is a method for finding both the spin configurations and height +of the energy barrier associated with a transition state, e.g. +spins to perform a collective rotation from one energy basin to +another. +The implementation in LAMMPS follows the discussion in the +following paper: "(Bessarab)"_#Bessarab. + +Each replica runs on a partition of one or more processors. Processor +partitions are defined at run-time using the "-partition command-line +switch"_Run_options.html. Note that if you have MPI installed, you +can run a multi-replica simulation with more replicas (partitions) +than you have physical processors, e.g you can run a 10-replica +simulation on just one or two processors. You will simply not get the +performance speed-up you would see with one or more physical +processors per replica. See the "Howto replica"_Howto_replica.html +doc page for further discussion. + +NOTE: As explained below, a GNEB calculation performs a damped dynamics +minimization across all the replicas. The "spin"_min_spin.html +style minimizer has to be defined in your input script. + +When a GNEB calculation is performed, it is assumed that each replica +is running the same system, though LAMMPS does not check for this. +I.e. the simulation domain, the number of magnetic atoms, the +interaction potentials, and the starting configuration when the neb +command is issued should be the same for every replica. + +In a GNEB calculation each replica is connected to other replicas by +inter-replica nudging forces. These forces are imposed by the "fix +neb/spin"_fix_neb_spin.html command, which must be used in conjunction +with the neb command. +The group used to define the fix neb/spin command defines the +GNEB magnetic atoms which are the only ones that inter-replica springs +are applied to. +If the group does not include all magnetic atoms, then non-GNEB +magnetic atoms have no inter-replica springs and the torques they feel +and their precessional motion is computed in the usual way due only +to other magnetic atoms within their replica. +Conceptually, the non-GNEB atoms provide a background force field for +the GNEB atoms. +Their magnetic spins can be allowed to precess during the GNEB +minimization procedure. + +The initial spin configuration for each of the replicas can be +specified in different manners via the {file-style} setting, as +discussed below. Only atomic spins whose initial coordinates should +differ from the current configuration need to be specified. + +Conceptually, the initial and final configurations for the first +replica should be states on either side of an energy barrier. + +As explained below, the initial configurations of intermediate +replicas can be spin coordinates interpolated in a linear fashion +between the first and last replicas. This is often adequate for +simple transitions. For more complex transitions, it may lead to slow +convergence or even bad results if the minimum energy path (MEP, see +below) of states over the barrier cannot be correctly converged to +from such an initial path. In this case, you will want to generate +initial states for the intermediate replicas that are geometrically +closer to the MEP and read them in. + +################################################################### + +:line + +For a {file-style} setting of {final}, a filename is specified which +contains atomic and spin coordinates for zero or more atoms, in the +format described below. +For each atom that appears in the file, the new coordinates are +assigned to that atom in the final replica. Each intermediate replica +also assigns a new spin to that atom in an interpolated manner. +This is done by using the current direction of the spin at the starting +point and the read-in direction as the final point. +The angular distance between them is calculated, and the new direction +is assigned to be a fraction of the angular distance. + +NOTE: The "angular distance" between the starting and final point is +evaluated in the geodesic sense, as described in "(Bessarab)"_#Bessarab. + +NOTE: The angular interpolation between the starting and final point +is achieved using Rodrigues formula: + +:c,image(Eqs/neb_spin_rodrigues_formula.jpg) + +with m_i^I is the initial spin configuration for the spin i, +where the rotation and k_i is defined as: + +:c,image(Eqs/neb_spin_k.jpg) + +The distance between them is calculated, and the new position +is assigned to be a fraction of the distance. E.g. if there are 10 +replicas, the 2nd replica will assign a position that is 10% of the +distance along a line between the starting and final point, and the +9th replica will assign a position that is 90% of the distance along +the line. Note that for this procedure to produce consistent +coordinates across all the replicas, the current coordinates need to +be the same in all replicas. LAMMPS does not check for this, but +invalid initial configurations will likely result if it is not the +case. + +NOTE: The "distance" between the starting and final point is +calculated in a minimum-image sense for a periodic simulation box. +This means that if the two positions are on opposite sides of a box +(periodic in that dimension), the distance between them will be small, +because the periodic image of one of the atoms is close to the other. +Similarly, even if the assigned position resulting from the +interpolation is outside the periodic box, the atom will be wrapped +back into the box when the NEB calculation begins. + +For a {file-style} setting of {each}, a filename is specified which is +assumed to be unique to each replica. This can be done by using a +variable in the filename, e.g. + +variable i equal part +neb 0.0 0.001 1000 500 50 each coords.initial.$i :pre + +which in this case will substitute the partition ID (0 to N-1) for the +variable I, which is also effectively the replica ID. See the +"variable"_variable.html command for other options, such as using +world-, universe-, or uloop-style variables. + +Each replica (except the first replica) will read its file, formatted +as described below, and for any atom that appears in the file, assign +the specified coordinates to its atom. The various files do not need +to contain the same set of atoms. + +For a {file-style} setting of {none}, no filename is specified. Each +replica is assumed to already be in its initial configuration at the +time the neb command is issued. This allows each replica to define +its own configuration by reading a replica-specific data or restart or +dump file, via the "read_data"_read_data.html, +"read_restart"_read_restart.html, or "read_dump"_read_dump.html +commands. The replica-specific names of these files can be specified +as in the discussion above for the {each} file-style. Also see the +section below for how a NEB calculation can produce restart files, so +that a long calculation can be restarted if needed. + +NOTE: None of the {file-style} settings change the initial +configuration of any atom in the first replica. The first replica +must thus be in the correct initial configuration at the time the neb +command is issued. + +:line + +A NEB calculation proceeds in two stages, each of which is a +minimization procedure, performed via damped dynamics. To enable +this, you must first define a damped dynamics +"min_style"_min_style.html, such as {quickmin} or {fire}. The {cg}, +{sd}, and {hftn} styles cannot be used, since they perform iterative +line searches in their inner loop, which cannot be easily synchronized +across multiple replicas. + +The minimizer tolerances for energy and force are set by {etol} and +{ftol}, the same as for the "minimize"_minimize.html command. + +A non-zero {etol} means that the NEB calculation will terminate if the +energy criterion is met by every replica. The energies being compared +to {etol} do not include any contribution from the inter-replica +nudging forces, since these are non-conservative. A non-zero {ftol} +means that the NEB calculation will terminate if the force criterion +is met by every replica. The forces being compared to {ftol} include +the inter-replica nudging forces. + +The maximum number of iterations in each stage is set by {N1} and +{N2}. These are effectively timestep counts since each iteration of +damped dynamics is like a single timestep in a dynamics +"run"_run.html. During both stages, the potential energy of each +replica and its normalized distance along the reaction path (reaction +coordinate RD) will be printed to the screen and log file every +{Nevery} timesteps. The RD is 0 and 1 for the first and last replica. +For intermediate replicas, it is the cumulative distance (normalized +by the total cumulative distance) between adjacent replicas, where +"distance" is defined as the length of the 3N-vector of differences in +atomic coordinates, where N is the number of NEB atoms involved in the +transition. These outputs allow you to monitor NEB's progress in +finding a good energy barrier. {N1} and {N2} must both be multiples +of {Nevery}. + +In the first stage of NEB, the set of replicas should converge toward +a minimum energy path (MEP) of conformational states that transition +over a barrier. The MEP for a transition is defined as a sequence of +3N-dimensional states, each of which has a potential energy gradient +parallel to the MEP itself. The configuration of highest energy along +a MEP corresponds to a saddle point. The replica states will also be +roughly equally spaced along the MEP due to the inter-replica nudging +force added by the "fix neb"_fix_neb.html command. + +In the second stage of NEB, the replica with the highest energy is +selected and the inter-replica forces on it are converted to a force +that drives its atom coordinates to the top or saddle point of the +barrier, via the barrier-climbing calculation described in +"(HenkelmanB)"_#HenkelmanB. As before, the other replicas rearrange +themselves along the MEP so as to be roughly equally spaced. + +When both stages are complete, if the NEB calculation was successful, +the configurations of the replicas should be along (close to) the MEP +and the replica with the highest energy should be an atomic +configuration at (close to) the saddle point of the transition. The +potential energies for the set of replicas represents the energy +profile of the transition along the MEP. + +:line + +A few other settings in your input script are required or advised to +perform a NEB calculation. See the NOTE about the choice of timestep +at the beginning of this doc page. + +An atom map must be defined which it is not by default for "atom_style +atomic"_atom_style.html problems. The "atom_modify +map"_atom_modify.html command can be used to do this. + +The minimizers in LAMMPS operate on all atoms in your system, even +non-NEB atoms, as defined above. To prevent non-NEB atoms from moving +during the minimization, you should use the "fix +setforce"_fix_setforce.html command to set the force on each of those +atoms to 0.0. This is not required, and may not even be desired in +some cases, but if those atoms move too far (e.g. because the initial +state of your system was not well-minimized), it can cause problems +for the NEB procedure. + +The damped dynamics "minimizers"_min_style.html, such as {quickmin} +and {fire}), adjust the position and velocity of the atoms via an +Euler integration step. Thus you must define an appropriate +"timestep"_timestep.html to use with NEB. As mentioned above, NEB +will often converge more quickly if you use a timestep about 10x +larger than you would normally use for dynamics simulations. + +:line + +Each file read by the neb command containing atomic coordinates used +to initialize one or more replicas must be formatted as follows. + +The file can be ASCII text or a gzipped text file (detected by a .gz +suffix). The file can contain initial blank lines or comment lines +starting with "#" which are ignored. The first non-blank, non-comment +line should list N = the number of lines to follow. The N successive +lines contain the following information: + +ID1 x1 y1 z1 +ID2 x2 y2 z2 +... +IDN xN yN zN :pre + +The fields are the atom ID, followed by the x,y,z coordinates. The +lines can be listed in any order. Additional trailing information on +the line is OK, such as a comment. + +Note that for a typical NEB calculation you do not need to specify +initial coordinates for very many atoms to produce differing starting +and final replicas whose intermediate replicas will converge to the +energy barrier. Typically only new coordinates for atoms +geometrically near the barrier need be specified. + +Also note there is no requirement that the atoms in the file +correspond to the NEB atoms in the group defined by the "fix +neb"_fix_neb.html command. Not every NEB atom need be in the file, +and non-NEB atoms can be listed in the file. + +:line + +Four kinds of output can be generated during a NEB calculation: energy +barrier statistics, thermodynamic output by each replica, dump files, +and restart files. + +When running with multiple partitions (each of which is a replica in +this case), the print-out to the screen and master log.lammps file +contains a line of output, printed once every {Nevery} timesteps. It +contains the timestep, the maximum force per replica, the maximum +force per atom (in any replica), potential gradients in the initial, +final, and climbing replicas, the forward and backward energy +barriers, the total reaction coordinate (RDT), and the normalized +reaction coordinate and potential energy of each replica. + +The "maximum force per replica" is the two-norm of the 3N-length force +vector for the atoms in each replica, maximized across replicas, which +is what the {ftol} setting is checking against. In this case, N is +all the atoms in each replica. The "maximum force per atom" is the +maximum force component of any atom in any replica. The potential +gradients are the two-norm of the 3N-length force vector solely due to +the interaction potential i.e. without adding in inter-replica +forces. + +The "reaction coordinate" (RD) for each replica is the two-norm of the +3N-length vector of distances between its atoms and the preceding +replica's atoms, added to the RD of the preceding replica. The RD of +the first replica RD1 = 0.0; the RD of the final replica RDN = RDT, +the total reaction coordinate. The normalized RDs are divided by RDT, +so that they form a monotonically increasing sequence from zero to +one. When computing RD, N only includes the atoms being operated on by +the fix neb command. + +The forward (reverse) energy barrier is the potential energy of the +highest replica minus the energy of the first (last) replica. + +Supplementary information for all replicas can be printed out to the +screen and master log.lammps file by adding the verbose keyword. This +information include the following. The "path angle" (pathangle) for +the replica i which is the angle between the 3N-length vectors (Ri-1 - +Ri) and (Ri+1 - Ri) (where Ri is the atomic coordinates of replica +i). A "path angle" of 180 indicates that replicas i-1, i and i+1 are +aligned. "angletangrad" is the angle between the 3N-length tangent +vector and the 3N-length force vector at image i. The tangent vector +is calculated as in "(HenkelmanA)"_#HenkelmanA for all intermediate +replicas and at R2 - R1 and RM - RM-1 for the first and last replica, +respectively. "anglegrad" is the angle between the 3N-length energy +gradient vector of replica i and that of replica i+1. It is not +defined for the final replica and reads nan. gradV is the norm of the +energy gradient of image i. ReplicaForce is the two-norm of the +3N-length force vector (including nudging forces) for replica i. +MaxAtomForce is the maximum force component of any atom in replica i. + +When a NEB calculation does not converge properly, the supplementary +information can help understanding what is going wrong. For instance +when the path angle becomes acute, the definition of tangent used in +the NEB calculation is questionable and the NEB cannot may diverge +"(Maras)"_#Maras2. + + +When running on multiple partitions, LAMMPS produces additional log +files for each partition, e.g. log.lammps.0, log.lammps.1, etc. For a +NEB calculation, these contain the thermodynamic output for each +replica. + +If "dump"_dump.html commands in the input script define a filename +that includes a {universe} or {uloop} style "variable"_variable.html, +then one dump file (per dump command) will be created for each +replica. At the end of the NEB calculation, the final snapshot in +each file will contain the sequence of snapshots that transition the +system over the energy barrier. Earlier snapshots will show the +convergence of the replicas to the MEP. + +Likewise, "restart"_restart.html filenames can be specified with a +{universe} or {uloop} style "variable"_variable.html, to generate +restart files for each replica. These may be useful if the NEB +calculation fails to converge properly to the MEP, and you wish to +restart the calculation from an intermediate point with altered +parameters. + +There are 2 Python scripts provided in the tools/python directory, +neb_combine.py and neb_final.py, which are useful in analyzing output +from a NEB calculation. Assume a NEB simulation with M replicas, and +the NEB atoms labeled with a specific atom type. + +The neb_combine.py script extracts atom coords for the NEB atoms from +all M dump files and creates a single dump file where each snapshot +contains the NEB atoms from all the replicas and one copy of non-NEB +atoms from the first replica (presumed to be identical in other +replicas). This can be visualized/animated to see how the NEB atoms +relax as the NEB calculation proceeds. + +The neb_final.py script extracts the final snapshot from each of the M +dump files to create a single dump file with M snapshots. This can be +visualized to watch the system make its transition over the energy +barrier. + +To illustrate, here are images from the final snapshot produced by the +neb_combine.py script run on the dump files produced by the two +example input scripts in examples/neb. Click on them to see a larger +image. + +:image(JPG/hop1_small.jpg,JPG/hop1.jpg) +:image(JPG/hop2_small.jpg,JPG/hop2.jpg) + +:line + +[Restrictions:] + +This command can only be used if LAMMPS was built with the SPIN +package. See the "Build package"_Build_package.html doc +page for more info. + +:line + +[Related commands:] + +"min/spin"_min_spin.html, "fix neb/spin"_fix_neb_spin.html + +[Default:] + +none + +:line + +:link(Bessarab) +[(Bessarab)] Bessarab, Uzdin, Jonsson, Comp Phys Comm, 196, +335-347 (2015). diff --git a/examples/SPIN/gneb/iron/in.gneb.iron b/examples/SPIN/gneb/iron/in.gneb.iron index c794292cfb..95e7071cb0 100644 --- a/examples/SPIN/gneb/iron/in.gneb.iron +++ b/examples/SPIN/gneb/iron/in.gneb.iron @@ -7,11 +7,10 @@ atom_style spin # necessary for the serial algorithm (sametag) atom_modify map array -read_data initial.iron_spin - # setting mass, mag. moments, and interactions for bcc iron # (mass not necessary for fixed lattice calculation) +read_data initial.iron_spin mass 1 55.845 pair_style spin/exchange 3.5 diff --git a/examples/SPIN/gneb/skyrmion/in.gneb.skyrmion b/examples/SPIN/gneb/skyrmion/in.gneb.skyrmion index cbab56631b..cf55c9d1d4 100644 --- a/examples/SPIN/gneb/skyrmion/in.gneb.skyrmion +++ b/examples/SPIN/gneb/skyrmion/in.gneb.skyrmion @@ -7,11 +7,10 @@ atom_style spin # necessary for the serial algorithm (sametag) atom_modify map array -read_data initial.skyrmion - # setting mass, mag. moments, and interactions for bcc iron # (mass not necessary for fixed lattice calculation) +read_data initial.skyrmion mass 1 55.845 pair_style hybrid/overlay spin/exchange 3.1 spin/dmi 3.1 diff --git a/src/SPIN/fix_neb_spin.h b/src/SPIN/fix_neb_spin.h index 9bbacc8bf0..8e016b2e23 100644 --- a/src/SPIN/fix_neb_spin.h +++ b/src/SPIN/fix_neb_spin.h @@ -60,20 +60,20 @@ class FixNEB_spin : public Fix { double **spprev,**spnext,**fmnext; double **springF; double **tangent; - double **xsend,**xrecv; // coords to send/recv to/from other replica - double **fsend,**frecv; // coords to send/recv to/from other replica - double **spsend,**sprecv; // sp to send/recv to/from other replica - double **fmsend,**fmrecv; // fm to send/recv to/from other replica - tagint *tagsend,*tagrecv; // ditto for atom IDs + double **xsend,**xrecv; // coords to send/recv to/from other replica + double **fsend,**frecv; // coords to send/recv to/from other replica + double **spsend,**sprecv; // sp to send/recv to/from other replica + double **fmsend,**fmrecv; // fm to send/recv to/from other replica + tagint *tagsend,*tagrecv; // ditto for atom IDs - // info gathered from all procs in my replica - double **xsendall,**xrecvall; // coords to send/recv to/from other replica - double **fsendall,**frecvall; // force to send/recv to/from other replica - double **spsendall,**sprecvall; // sp to send/recv to/from other replica - double **fmsendall,**fmrecvall; // fm to send/recv to/from other replica - tagint *tagsendall,*tagrecvall; // ditto for atom IDs + // info gathered from all procs in my replica + double **xsendall,**xrecvall; // coords to send/recv to/from other replica + double **fsendall,**frecvall; // force to send/recv to/from other replica + double **spsendall,**sprecvall; // sp to send/recv to/from other replica + double **fmsendall,**fmrecvall; // fm to send/recv to/from other replica + tagint *tagsendall,*tagrecvall; // ditto for atom IDs - int *counts,*displacements; // used for MPI_Gather + int *counts,*displacements; // used for MPI_Gather double geodesic_distance(double *, double *); void inter_replica_comm(); @@ -97,16 +97,16 @@ E: Potential energy ID for fix neb does not exist Self-explanatory. -E: Too many active NEB atoms +E: Too many active GNEB atoms UNDOCUMENTED -E: Too many atoms for NEB +E: Too many atoms for GNEB UNDOCUMENTED U: Atom count changed in fix neb -This is not allowed in a NEB calculation. +This is not allowed in a GNEB calculation. */ diff --git a/src/SPIN/neb_spin.cpp b/src/SPIN/neb_spin.cpp index 69c59e0484..77a94c5e84 100644 --- a/src/SPIN/neb_spin.cpp +++ b/src/SPIN/neb_spin.cpp @@ -111,6 +111,8 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, double **sp = atom->sp; int nlocal = atom->nlocal; + int temp_flag,rot_flag; + temp_flag = rot_flag = 0; int ii = 0; double spinit[3],spfinal[3]; for (int i = 0; i < nlocal; i++) { @@ -123,7 +125,7 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, spfinal[2] = buf_final[ii+2]; // interpolate intermediate spin states - + if (fraction == 0.0) { sp[i][0] = spinit[0]; sp[i][1] = spinit[1]; @@ -133,7 +135,8 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, sp[i][1] = spfinal[1]; sp[i][2] = spfinal[2]; } else { - initial_rotation(spinit,spfinal,fraction); + temp_flag = initial_rotation(spinit,spfinal,fraction); + rot_flag = MAX(temp_flag,rot_flag); sp[i][0] = spfinal[0]; sp[i][1] = spfinal[1]; sp[i][2] = spfinal[2]; @@ -141,6 +144,14 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, ii += 3; } + + // warning message if one or more couples (spi,spf) were aligned + // this breaks Rodrigues' formula, and an arbitrary rotation + // vector has to be chosen + + if ((rot_flag > 0) && (comm->me == 0)) + error->warning(FLERR,"arbitrary initial rotation of one or more spin(s)"); + } /* ---------------------------------------------------------------------- */ @@ -494,6 +505,8 @@ void NEB_spin::readfile(char *file, int flag) int ncount = 0; + int temp_flag,rot_flag; + temp_flag = rot_flag = 0; int nread = 0; while (nread < nlines) { nchunk = MIN(nlines-nread,CHUNK); @@ -566,7 +579,8 @@ void NEB_spin::readfile(char *file, int flag) sp[m][1] = spfinal[1]; sp[m][2] = spfinal[2]; } else { - initial_rotation(spinit,spfinal,fraction); + temp_flag = initial_rotation(spinit,spfinal,fraction); + rot_flag = MAX(temp_flag,rot_flag); sp[m][0] = spfinal[0]; sp[m][1] = spfinal[1]; sp[m][2] = spfinal[2]; @@ -588,6 +602,13 @@ void NEB_spin::readfile(char *file, int flag) nread += nchunk; } + // warning message if one or more couples (spi,spf) were aligned + // this breaks Rodrigues' formula, and an arbitrary rotation + // vector has to be chosen + + if ((rot_flag > 0) && (comm->me == 0)) + error->warning(FLERR,"arbitrary initial rotation of one or more spin(s)"); + // check that all atom IDs in file were found by a proc if (flag == 0) { @@ -621,69 +642,24 @@ void NEB_spin::readfile(char *file, int flag) } /* ---------------------------------------------------------------------- - initial configuration of spin sploc using Rodrigues' formula + initial configuration of intermediate spins using Rodrigues' formula interpolates between initial (spi) and final (stored in sploc) ------------------------------------------------------------------------- */ -void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) +int NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) { - // implementing initial rotation using atan2 - // this may not be a sufficient routine, need more accurate verifications + // no interpolation for initial and final replica - // interpolation only for intermediate replica + if (fraction == 0.0 || fraction == 1.0) return 0; - if (fraction == 0.0 || fraction == 1.0) return; - - // initial, final and inter ang. values - - //double itheta,iphi,ftheta,fphi,ktheta,kphi; - //double spix,spiy,spiz,spfx,spfy,spfz; - //double spkx,spky,spkz,iknorm; - - //spix = spi[0]; - //spiy = spi[1]; - //spiz = spi[2]; - - //spfx = sploc[0]; - //spfy = sploc[1]; - //spfz = sploc[2]; - - //iphi = itheta = fphi = ftheta = 0.0; - - //iphi = acos(spiz); - //if (sin(iphi) != 0.0) - // itheta = acos(spix/sin(iphi)); - - //fphi = acos(spfz); - //if (sin(fphi) != 0.0) - // ftheta = acos(spfx/sin(fphi)); - - //kphi = iphi + fraction*(fphi-iphi); - //ktheta = itheta + fraction*(ftheta-itheta); - - //spkx = cos(ktheta)*sin(kphi); - //spky = sin(ktheta)*sin(kphi); - //spkz = cos(kphi); - - //double knormsq = spkx*spkx + spky*spky + spkz*spkz; - //if (knormsq != 0.0) - // iknorm = 1.0/sqrt(knormsq); - - //spkx *= iknorm; - //spky *= iknorm; - //spkz *= iknorm; - - //sploc[0] = spkx; - //sploc[1] = spky; - //sploc[2] = spkz; - + int rot_flag = 0; double kx,ky,kz; double spix,spiy,spiz,spfx,spfy,spfz; double kcrossx,kcrossy,kcrossz,knormsq; double kdots; double spkx,spky,spkz; - double sdot,omega,iknorm,isnorm; + double sidotsf,omega,iknorm,isnorm; spix = spi[0]; spiy = spi[1]; @@ -698,43 +674,73 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) kz = spix*spfy - spiy*spfx; knormsq = kx*kx+ky*ky+kz*kz; - - if (knormsq != 0.0) { - iknorm = 1.0/sqrt(knormsq); - kx *= iknorm; - ky *= iknorm; - kz *= iknorm; + sidotsf = spix*spfx + spiy*spfy + spiz*spfz; + + // if knormsq == 0.0, init and final spins are aligned + // Rodrigues' formula breaks, needs to define another axis k + + if (knormsq == 0.0) { + if (sidotsf > 0.0) { // spins aligned and in same direction + return 0; + } else if (sidotsf < 0.0) { // spins aligned and in opposite directions + + // defining a rotation axis + // first guess, k = spi x [100] + // second guess, k = spi x [010] + + if (spiy*spiy + spiz*spiz != 0.0) { // spin not along [100] + kx = 0.0; + ky = spiz; + kz = -spiy; + } else if (spix*spix + spiz*spiz != 0.0) { // spin not along [010] + kx = -spiz; + ky = 0.0; + kz = spix; + } else error->all(FLERR,"Incorrect initial rotation operation"); + rot_flag = 1; + } } - + kcrossx = ky*spiz - kz*spiy; kcrossy = kz*spix - kx*spiz; kcrossz = kx*spiy - ky*spix; kdots = kx*spix + ky*spiz + kz*spiz; - sdot = spix*spfx + spiy*spfy + spiz*spfz; - omega = acos(sdot); + omega = acos(sidotsf); omega *= fraction; - spkx = spix*cos(omega) + kcrossx*sin(omega); - spky = spiy*cos(omega) + kcrossy*sin(omega); - spkz = spiz*cos(omega) + kcrossz*sin(omega); + // applying Rodrigues' formula + + spkx = spix*cos(omega); + spky = spiy*cos(omega); + spkz = spiz*cos(omega); + + spkx += kcrossx*sin(omega); + spky += kcrossy*sin(omega); + spkz += kcrossz*sin(omega); spkx += kx*kdots*(1.0-cos(omega)); spky += ky*kdots*(1.0-cos(omega)); spkz += kz*kdots*(1.0-cos(omega)); + // normalizing resulting spin vector + isnorm = 1.0/sqrt(spkx*spkx+spky*spky+spkz*spkz); if (isnorm == 0.0) - error->all(FLERR,"Incorrect rotation operation"); + error->all(FLERR,"Incorrect initial rotation operation"); spkx *= isnorm; spky *= isnorm; spkz *= isnorm; + // returns rotated spin + sploc[0] = spkx; sploc[1] = spky; sploc[2] = spkz; + + return rot_flag; } /* ---------------------------------------------------------------------- diff --git a/src/SPIN/neb_spin.h b/src/SPIN/neb_spin.h index 5988c04a3a..b7c20bc3a9 100644 --- a/src/SPIN/neb_spin.h +++ b/src/SPIN/neb_spin.h @@ -57,7 +57,7 @@ class NEB_spin : protected Pointers { double *fmaxatomInRepl; // force on an image void readfile(char *, int); - void initial_rotation(double *, double *, double); + int initial_rotation(double *, double *, double); void open(char *); void print_status(); }; diff --git a/src/SPIN/pair_spin_dmi.cpp b/src/SPIN/pair_spin_dmi.cpp index 5e9ff7a39e..41430d230f 100644 --- a/src/SPIN/pair_spin_dmi.cpp +++ b/src/SPIN/pair_spin_dmi.cpp @@ -171,10 +171,11 @@ void PairSpinDmi::init_style() int ifix = 0; while (ifix < modify->nfix) { if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + if (strcmp(modify->fix[ifix]->style,"neb/spin") == 0) break; ifix++; } if ((ifix == modify->nfix) && (comm->me == 0)) - error->warning(FLERR,"Using pair/spin style without nve/spin"); + error->warning(FLERR,"Using pair/spin style without nve/spin or neb/spin"); // get the lattice_flag from nve/spin diff --git a/src/SPIN/pair_spin_exchange.cpp b/src/SPIN/pair_spin_exchange.cpp index 71b4c2ebf6..0260a611cf 100644 --- a/src/SPIN/pair_spin_exchange.cpp +++ b/src/SPIN/pair_spin_exchange.cpp @@ -162,7 +162,7 @@ void PairSpinExchange::init_style() ifix++; } if ((ifix == modify->nfix) && (comm->me == 0)) - error->warning(FLERR,"Using pair/spin style without nve/spin"); + error->warning(FLERR,"Using pair/spin style without nve/spin or neb/spin"); // get the lattice_flag from nve/spin diff --git a/src/SPIN/pair_spin_magelec.cpp b/src/SPIN/pair_spin_magelec.cpp index 6ff003521d..1f1488b93c 100644 --- a/src/SPIN/pair_spin_magelec.cpp +++ b/src/SPIN/pair_spin_magelec.cpp @@ -164,10 +164,11 @@ void PairSpinMagelec::init_style() int ifix = 0; while (ifix < modify->nfix) { if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + if (strcmp(modify->fix[ifix]->style,"neb/spin") == 0) break; ifix++; } if ((ifix == modify->nfix) && (comm->me == 0)) - error->warning(FLERR,"Using pair/spin style without nve/spin"); + error->warning(FLERR,"Using pair/spin style without nve/spin or neb/spin"); // get the lattice_flag from nve/spin diff --git a/src/SPIN/pair_spin_neel.cpp b/src/SPIN/pair_spin_neel.cpp index a39d6f3461..03041da17f 100644 --- a/src/SPIN/pair_spin_neel.cpp +++ b/src/SPIN/pair_spin_neel.cpp @@ -171,10 +171,11 @@ void PairSpinNeel::init_style() int ifix = 0; while (ifix < modify->nfix) { if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + if (strcmp(modify->fix[ifix]->style,"neb/spin") == 0) break; ifix++; } if ((ifix == modify->nfix) && (comm->me == 0)) - error->warning(FLERR,"Using pair/spin style without nve/spin"); + error->warning(FLERR,"Using pair/spin style without nve/spin or neb/spin"); // get the lattice_flag from nve/spin