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;

}