# include "wpmd_split.h" //# include "erf.h" void AWPMD_split::resize(int flag){ for(int s=0;s<2;s++){ wf_norm[s].resize(ne[s]); if(flag&(0x8|0x4)){ //electron forces needed wf_norm_der[s].resize(nvar[s]); ovl_der[s].resize(nvar[s]); E_der[s].resize(nvar[s]); if(flag&(0x8|0x4) || norm_needed){ //electron forces or norm matrix needed if(approx==HARTREE){ // L and Norm are needed in block form Lh[s].resize(nvar[s]); if(norm_needed){ Normh[s].resize(ne[s]); for(int i=0;i 1) return LOGERR(-1,fmt("AWPMD_split.set_electrons: invaid spin setting (%d)!",s),LINFO); // calculating the total n nvar[s]=0; int n=0; for(int i=0;i0){ // width PBC, keeping the width are within [0,Lextra] w[i]=fmod(w[i],Lextra); if(w[i]<0) w[i]+=Lextra; rw=w[i]; // WP width for energy evaluation is within [0, L/2] if(rw > Lextra/2) rw = Lextra - rw; } else rw=w[i]; wp[s][i].init(rw,x[i],v[i]*m_electron/h_plank,pw[i]/h_plank);*/ wp[s][i]=create_wp(x[i],v[i],w[i],pw[i],mass); //printf("%15d %15g\n",i,rw); // assign default partition partition1[s].push_back(i+1); } // assign electronic charge if(q) qe[s].assign(q,q+nwp[s]); else qe[s].assign(nwp[s],-1); return 1; } void AWPMD_split::eterm_deriv(int ic1,int s1,int c1, int j1,int ic2,int s2, int c2, int k2,cdouble pref, const OverlapDeriv &o,cdouble v,cdouble dv_aj_conj, cdouble dv_ak,cVector_3 dv_bj_conj, cVector_3 dv_bk){ cdouble cj(split_c[s1][ic1+j1][0],split_c[s1][ic1+j1][1]); cdouble ck(split_c[s2][ic2+k2][0],split_c[s2][ic2+k2][1]); int indw1=8*ic1, indw2=8*ic2; int indn1=(nvar[s1]/10)*8+2*ic1, indn2=(nvar[s2]/10)*8+2*ic2; cdouble part_jk=conj(cj)*ck; int M= 1; //(j1==k2 ? 1 : 2); // over a_k_re E_der[s2][indw2+8*k2]+= M*real(pref*part_jk*(o.da2_re()*v+o.I0*dv_ak)); // over a_k_im E_der[s2][indw2+8*k2+1]+= M*real(pref*part_jk*(o.da2_im()*v+i_unit*o.I0*dv_ak)); // over a_j_re E_der[s1][indw1+8*j1]+= M*real(pref*part_jk*(o.da1_re()*v+o.I0*dv_aj_conj)); // over a_j_im E_der[s1][indw1+8*j1+1]+= M*real(pref*part_jk*(o.da1_im()*v-i_unit*o.I0*dv_aj_conj)); for(int i=0;i<3;i++){ // over b_k_re E_der[s2][indw2+8*k2+2+2*i]+= M*real(pref*part_jk*(o.db2_re(i)*v+o.I0*dv_bk[i])); // over b_k_im E_der[s2][indw2+8*k2+2+2*i+1]+= M*real(pref*part_jk*(o.db2_im(i)*v+i_unit*o.I0*dv_bk[i])); // over b_j_re E_der[s1][indw1+8*j1+2+2*i]+= M*real(pref*part_jk*(o.db1_re(i)*v+o.I0*dv_bj_conj[i])); // over b_j_im E_der[s1][indw1+8*j1+2+2*i+1]+= M*real(pref*part_jk*(o.db1_im(i)*v-i_unit*o.I0*dv_bj_conj[i])); } // over ck_re E_der[s2][indn2+2*k2]+=M*real(pref*conj(cj)*o.I0*v); // over ck_im E_der[s2][indn2+2*k2+1]+=M*real(pref*i_unit*conj(cj)*o.I0*v); // over cj_re E_der[s1][indn1+2*j1]+=M*real(pref*ck*o.I0*v); // over cj_im E_der[s1][indn1+2*j1+1]+=M*real(-pref*i_unit*ck*o.I0*v); double t= -M*real(pref*part_jk*o.I0*v); // nonlocal terms: TODO: make a separate global loop for summation of nonlocal terms for(int j=0;j -mu, v -> -v !!! } for(int k1=j1+1;k1(E_der[s1].begin()+indw1,(double *)&fe_x[iv1+k1],(double *)&fe_p[iv1+k1],&fe_w[iv1+k1],&fe_pw[iv1+k1], 1./one_h); fe_c[iv1+k1]+=-Vector_2(E_der[s1][indn1+2*k1],E_der[s1][indn1+2*k1+1]); }// k1 ic1+=nspl[s1][c1]; // incrementing block1 wp address iv1+=nspl[s1][c1]; // incrementing global variable address } } } } //e same as interaction, but using Hartee factorization (no antisymmetrization) int AWPMD_split::interaction_hartree(int flag, Vector_3P fi, Vector_3P fe_x, Vector_3P fe_p, double *fe_w, double *fe_pw, Vector_2P fe_c){ // resize arrays if needed enum APPROX tmp=HARTREE; swap(tmp,approx); // do not neeed large matrices resize(flag); swap(tmp,approx); // clearing forces clear_forces(flag,fi,fe_x,fe_p,fe_w,fe_pw,fe_c); // calculate block norms and (optionally) derivatives calc_norms(flag); Eee = Ew = 0.; for(int s1=0;s1<2;s1++){ Ee[s1]=0.; Eei[s1]=0.; int ic1=0; // starting index of the wp for current electron for(int c1=0;c1 ovl_tolerance; } ik+=nspl[s][k]; // incrementing block1 wp address } O[s] = Y[s]; // save overlap matrix //3. inverting the overlap matrix int info=0; if(nes && approx!=HARTREE){ /*FILE *f1=fopen(fmt("matrO_%d.d",s),"wt"); fileout(f1,Y[s],"%15g"); fclose(f1);8*/ ZPPTRF("L",&nes,Y[s].arr,&info); // analyze return code here if(info<0) return LOGERR(info,fmt("AWPMD.interacton: call to ZPTRF failed (exitcode %d)!",info),LINFO); ZPPTRI("L",&nes,Y[s].arr,&info); if(info<0) return LOGERR(info,fmt("AWPMD.interacton: call to ZPTRI failed (exitcode %d)!",info),LINFO); /*f1=fopen(fmt("matrY_%d.d",s),"wt"); fileout(f1,Y[s],"%15g"); fclose(f1);*/ } // Clearing matrices for electronic forces /* if(flag&0x4){ Te[s].Set(0.); Tei[s].Set(0.); }*/ } # if 1 // calculating the M matrix if(norm_needed || ( flag&(0x8|0x4) && approx!=HARTREE ) ){ for(int s1=0;s1<2;s1++){ if(approx!=HARTREE){ M[s1].Set(0.); L[s1].Set(0.); if(norm_needed) Norm[s1].Set(0.); } else Lh[s1].assign(nvar[s1],0.); int indn=(nvar[s1]/10)*8; int ic1=0; for(int c1=0;c1