doublevar HEG_system::ewaldElectron(Sample_point * sample) { sample->updateEEDist(); const int nlatvec=1; Array1 <doublevar> r1(3), r2(3); Array1 <doublevar> eidist(5); //-------------Electron-electron real-space part (pairs only, // no self-interaction) doublevar elecElec_real=0; for(int e1=0; e1< totnelectrons; e1++) { for(int e2 =e1+1; e2 < totnelectrons; e2++) { sample->getEEDist(e1,e2, eidist); for(int d=0; d< 3; d++) r1(d)=eidist(d+2); //----over lattice vectors for(int kk=-nlatvec; kk <=nlatvec; kk++) { for(int jj=-nlatvec; jj <=nlatvec; jj++) { for(int ii=-nlatvec; ii <=nlatvec; ii++) { for(int d=0; d< 3; d++) { r2(d)=r1(d)+kk*latVec(0,d)+jj*latVec(1,d)+ii*latVec(2,d); } doublevar r=sqrt(r2(0)*r2(0)+r2(1)*r2(1)+r2(2)*r2(2)); elecElec_real+=erfcm(alpha*r)/r; } } } //----done lattice vectors } } //---------electron reciprocal part (this DOES include the self-interaction) doublevar rdotg; Array2 <doublevar> elecpos(totnelectrons, 3); sample->getAllElectronPos(elecpos); doublevar elecElec_recip=0; for(int gpt=0; gpt < ngpoints; gpt++) { doublevar sum_sin=0, sum_cos=0; for(int e=0; e< totnelectrons; e++) { rdotg=gpoint(gpt, 0)*elecpos(e,0) +gpoint(gpt, 1)*elecpos(e,1) +gpoint(gpt, 2)*elecpos(e,2); sum_sin+=sin(rdotg); sum_cos+=cos(rdotg); } // NOTE: 1/2 from \sum_{e != e'} is cancelled with the fact that // we use only one g-point from g,-g pair elecElec_recip+=(sum_cos*sum_cos + sum_sin*sum_sin)*gweight(gpt); } //cout << "elecElec_real " << elecElec_real << endl; //cout << "elecElec_recip " << elecElec_recip << endl; return elecElec_real + elecElec_recip; }
bool CollisionShape2DEditor::forward_input_event(const InputEvent& p_event) { if (!node) { return false; } if (!node->get_shape().is_valid()) { return false; } if (shape_type == -1) { return false; } switch( p_event.type ) { case InputEvent::MOUSE_BUTTON: { const InputEventMouseButton& mb = p_event.mouse_button; Matrix32 gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); Point2 gpoint(mb.x,mb.y); if (mb.button_index == BUTTON_LEFT) { if (mb.pressed) { for (int i = 0; i < handles.size(); i++) { if (gt.xform(handles[i]).distance_to(gpoint) < 8) { edit_handle = i; break; } } if (edit_handle==-1) { pressed = false; return false; } original = get_handle_value(edit_handle); pressed = true; return true; } else { if (pressed) { commit_handle(edit_handle, original); edit_handle = -1; pressed = false; return true; } } } return false; } break; case InputEvent::MOUSE_MOTION: { const InputEventMouseMotion& mm = p_event.mouse_motion; if (edit_handle == -1 || !pressed) { return false; } Point2 gpoint = Point2(mm.x,mm.y); Point2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); cpoint = canvas_item_editor->snap_point(cpoint); cpoint = node->get_global_transform().affine_inverse().xform(cpoint); set_handle(edit_handle, cpoint); return true; } break; } return false; }
int HEG_system::setupEwald(Array2 <doublevar> & crossProduct) { //----Set up reciprocal Ewald sum const int ndim=3; smallestheight=1e99; //!< smallest distance that spans the cell for(int i=0; i< ndim; i++) { doublevar tempheight=0; doublevar length=0; for(int j=0; j< ndim; j++) { tempheight+=crossProduct(i,j)*latVec(i,j); length+=crossProduct(i,j)*crossProduct(i,j); } tempheight=fabs(tempheight)/sqrt(length); if(tempheight < smallestheight ) smallestheight=tempheight; } debug_write(cout, "elsu ", smallestheight,"\n"); // We want only the simulation cell and its nearest neighbours // to contribute into the real-space part of Ewald sum; alpha // has to be chosen so that there are no contributions from distances // larger than smallestheight, i.e., we want // erfc(alpha*smallestheight) \sim 0 // note: erfc(5)=1.5e-12, erfc(6)=2.2e-17, erfc(6.5)=3.8e-20 // --- // 5.0 chosen in PERIODIC system seems to be large enough; change // from 5.0 to 6.5 doubles the number of g-points alpha=5.0/smallestheight; debug_write(cout, "alpha ", alpha, "\n"); const int gmax=24; //Could make this an option. const double qweight_cut=1e-18; ngpoints=(gmax+1)*(2*gmax+1)*(2*gmax+1)-gmax*(2*gmax+1)-gmax; Array2 <doublevar> gpointtemp(ngpoints,3); Array1 <doublevar> gweighttemp(ngpoints); int currgpt=0; int totgpt=0; int smallgpt=0; for(int ig=0; ig <= gmax; ig++) { int jgmin=-gmax; if(ig==0) jgmin=0; for(int jg=jgmin; jg <= gmax; jg++) { int kgmin=-gmax; if(ig==0 && jg==0) kgmin=0; for(int kg=kgmin; kg <= gmax; kg++) { totgpt++; for(int i=0; i< ndim; i++) { gpointtemp(currgpt, i)=2*pi*(ig*recipLatVec(0,i) +jg*recipLatVec(1,i) +kg*recipLatVec(2,i)); } doublevar gsqrd=0; // |g|^2 for(int i=0; i< ndim; i++) { gsqrd+=gpointtemp(currgpt,i)*gpointtemp(currgpt,i); } if(gsqrd > 1e-8) { // throw away (0,0,0) gweighttemp(currgpt)=4.0 * pi*exp(-gsqrd/(4*alpha*alpha)) /(cellVolume*gsqrd); if(gweighttemp(currgpt) > qweight_cut) { currgpt++; } } else { smallgpt++; } } } } if ( ngpoints != totgpt ) { error("Wrong number of g-points while setting up Ewald summation."); } if ( smallgpt != 1 ) { error("More than 1 g-point detected as 0."); } if ( currgpt+smallgpt >= totgpt ) { error("Increase gmax in HEG_system.cpp, current value is too small."); } cout << "Reciprocal Ewald will use " << currgpt << " g-points out of " << totgpt << " examined." << endl; //Adjust to the correct number of kpoints.. ngpoints=currgpt; gpoint.Resize(ngpoints, 3); gweight.Resize(ngpoints); for(int i=0; i< ngpoints; i++) { for(int d=0; d< ndim; d++) { gpoint(i,d)=gpointtemp(i,d); } gweight(i)=gweighttemp(i); } constEwald(); return 1; }