Example #1
0
/* Precomputes the influence function 

     2.0/L^2 * exp(-(PI*n/(alpha*L))^2)/n^2 

   as a function of lattice vector n (NOT k=2*PI*n/L). 
   This is stored in the array

     Ghat[Maxkmax+1][Maxkmax+1][Maxkmax+1]

   For symmetry reasons only one octant is actually needed. 
*/
void Ewald_compute_influence_function(system_t *s, parameters_t *p, data_t *d)
{
  
  int    nx,ny,nz;
  FLOAT_TYPE n_sqr,fak1,fak2;
  const int kmax = p->mesh - 1;
  const int kmax2 = kmax*kmax;
  
  fak1 = 2.0/SQR(s->length);
  fak2 = SQR(PI/(p->alpha*s->length));

#ifdef _OPENMP
#pragma omp parallel for collapse(2) private(n_sqr)
#endif 
  for (nx=0; nx <= kmax; nx++)
    for (ny=0; ny <= kmax; ny++)
      for (nz=0; nz <= kmax; nz++) {
	n_sqr = SQR(nx) + SQR(ny) + SQR(nz);
	if ((nx==0 && ny==0 && nz==0) || (n_sqr > kmax2)) {
  //  printf("%d %d %d, kmax %d, kmax2 %d\n", nx, ny, nz, kmax, kmax2);
	  d->G_hat[r_ind(nx,ny,nz)] = 0.0;
        } else {
	  d->G_hat[r_ind(nx,ny,nz)] = fak1/n_sqr * EXP(-fak2*n_sqr);
	}
      }
}  
Example #2
0
//---------------------------------------------------------------------
std::vector<int>  getRInd(int const nBF, int const nD)
{
  std::vector<int> r_ind(nBF);
  for(int i=0; i<nBF;i++)
    r_ind[i]=nD*(2+nBF)+i*2;

  return r_ind;
}
Example #3
0
void Ewald_k_space(system_t *s, parameters_t *p, data_t *d, forces_t *f)
{
  int    i;
  int    nx, ny, nz;
  FLOAT_TYPE kr, energy=0.0;
  FLOAT_TYPE rhohat_re=0, rhohat_im=0, ghat=0;
  FLOAT_TYPE force_factor;
  FLOAT_TYPE Leni = 1.0/s->length;
  const int kmax = p->mesh;
  const int kmax2 = kmax*kmax;
  
  for (nx=-kmax; nx<=kmax; nx++)
    for (ny=-kmax; ny<=kmax; ny++)
      for (nz=-kmax; nz<=kmax; nz++)
	if (nx*nx + ny*ny + nz*nz <= kmax2) {
	  /* compute rhohat */
	  rhohat_re = 0.0;
	  rhohat_im = 0.0;
          ghat = d->G_hat[r_ind(abs(nx), abs(ny), abs(nz))];          
#ifdef _OPENMP          
#pragma omp parallel for private(kr) reduction( + : rhohat_re ) reduction( + : rhohat_im )
#endif
	  for (i=0; i<s->nparticles; i++) {
            kr = 2.0*PI*Leni*(nx*(s->p->x[i]) + ny*(s->p->y[i]) + nz*(s->p->z[i]));
	    rhohat_re += s->q[i] * COS(kr);
	    rhohat_im += s->q[i] * -SIN(kr);
          }
#ifdef _OPENMP
#pragma omp barrier

#pragma omp parallel for private(kr, force_factor)
#endif
	  for (i=0; i<s->nparticles; i++) {
	    kr = 2.0*PI*Leni*(nx*(s->p->x[i]) + ny*(s->p->y[i]) + nz*(s->p->z[i]));
	     
            force_factor = s->q[i] * ghat 
              * (rhohat_re*SIN(kr) + rhohat_im*COS(kr));

            f->f_k->x[i] += nx * force_factor;
            f->f_k->y[i] += ny * force_factor;
            f->f_k->z[i] += nz * force_factor;
	  }
	}
#ifdef _OPENMP
#pragma omp barrier
#endif
  /* compute energy */
  energy += ghat*(SQR(rhohat_re) + SQR(rhohat_im));

  s->energy +=(0.5*s->length /(2.0*PI)) * energy;
  s->energy += Ewald_self_energy(s, p);
}
Example #4
0
void P3M_ad( system_t *s, parameters_t *p, data_t *d, forces_t *f )
{
  
  /* Loop counters */
  int i, j, k, c_index; 
  /* Helper variables */
  FLOAT_TYPE T1;
  FLOAT_TYPE Leni = 1.0/s->length;
  int Mesh = p->mesh;
  
  memset(d->Qmesh, 0, 2*Mesh*Mesh*Mesh * sizeof(FLOAT_TYPE));

  TIMING_START_C
  
  /* chargeassignment */
  assign_charge_and_derivatives( s, p, d, 0);

  TIMING_STOP_C
  TIMING_START_G
  
  /* Forward Fast Fourier Transform */
  forward_fft(d);

  for (i=0; i<Mesh; i++)
    for (j=0; j<Mesh; j++)
      for (k=0; k<Mesh; k++)
	{
          c_index = c_ind(i,j,k);

	  T1 = d->G_hat[r_ind(i,j,k)];
	  d->Qmesh[c_index] *= T1;
	  d->Qmesh[c_index+1] *= T1;
	}

  /* Backward FFT */
  backward_fft(d);

  TIMING_STOP_G
  TIMING_START_F
    
  /* Force assignment */
  assign_forces_ad( Mesh * Leni * Leni * Leni , s, p, d, f, 0 );

#ifdef P3M_AD_SELF_FORCES
  Substract_self_forces(s,p,d,f);
#endif
  TIMING_STOP_F

  return;
}
Example #5
0
void Influence_function_berechnen_ad( system_t *s, parameters_t *p, data_t *d )
{

  int    NX,NY,NZ;
  FLOAT_TYPE Zaehler=0.0,Nenner1=0.0, Nenner2=0.0;

  int ind = 0;
  int Mesh = p->mesh;

  if(p->alpha == 0.0) {
    memset(d->G_hat, 0, Mesh*Mesh*Mesh*sizeof(FLOAT_TYPE));
    return;
  }
  /* bei Zahlen >= Mesh/2 wird noch Mesh abgezogen! */
#ifdef _OPENMP
#pragma omp parallel for private(ind, Zaehler, Nenner1, Nenner2) collapse(3)
#endif
  for (NX=0; NX<Mesh; NX++)
    {
      for (NY=0; NY<Mesh; NY++)
	{
	  for (NZ=0; NZ<Mesh; NZ++)
	    {
              ind = r_ind(NX,NY,NZ);

	      if ((NX==0) && (NY==0) && (NZ==0))
	 	d->G_hat[ind]=0.0;
              /* else if ((NX%(Mesh/2) == 0) && (NY%(Mesh/2) == 0) && (NZ%(Mesh/2) == 0)) */
              /*   d->G_hat[ind]=0.0; */
	      else
		{
		  Aliasing_sums_ad(NX,NY,NZ,s,p,d,&Zaehler,&Nenner1, &Nenner2);
		  d->G_hat[ind] = Zaehler / ( PI * Nenner1 * Nenner2 );
		}
	      assert(!isnan(d->G_hat[ind]));
	    }
	}
    }
  #ifdef _OPENMP
  #pragma omp barrier
  #endif
  
  #ifdef P3M_AD_SELF_FORCES
  Init_self_forces( s, p, d);
  #else
  #warning Self force compensation disabled
  #endif
}
Example #6
0
void Influence_ik_i( system_t *s, parameters_t *p, data_t *d )
{
    int    NX,NY,NZ;
    FLOAT_TYPE Dnx,Dny,Dnz;
    FLOAT_TYPE Zaehler[3]={0.0,0.0,0.0},Nenner1=0.0, Nenner2=0.0;
    FLOAT_TYPE zwi;

    int ind = 0;
    int Mesh = p->mesh;
    FLOAT_TYPE Leni = 1.0/s->length;

    for (NX=0; NX<Mesh; NX++)
    {
        for (NY=0; NY<Mesh; NY++)
        {
            for (NZ=0; NZ<Mesh; NZ++)
            {
                ind = r_ind( NX, NY, NZ );

                if ((NX==0) && (NY==0) && (NZ==0))
                    d->G_hat[ind]=0.0;
                else if ((NX%(Mesh/2) == 0) && (NY%(Mesh/2) == 0) && (NZ%(Mesh/2) == 0))
                    d->G_hat[ind]=0.0;
                else
                {
                    Aliasing_sums_ik_i( s, p, d, NX, NY, NZ, Zaehler, &Nenner1,  &Nenner2);

                    Dnx = d->Dn[NX];
                    Dny = d->Dn[NY];
                    Dnz = d->Dn[NZ];

                    zwi  = Dnx*Zaehler[0]*Leni + Dny*Zaehler[1]*Leni + Dnz*Zaehler[2]*Leni;
                    zwi /= ( SQR(Dnx*Leni) + SQR(Dny*Leni) + SQR(Dnz*Leni) );
                    zwi /= 0.5*(SQR(Nenner1) + SQR(Nenner2));

                    d->G_hat[ind] = 2.0 * zwi / PI;
                }
            }
        }
    }
}
 bool valid_entry() const { return r_ind() >= 0; }
Example #8
0
void P3M_ik_i( system_t *s, parameters_t *p, data_t *d, forces_t *f )
{
    /* Zaehlvariablen: */
    int i, j, k, l;
    /* Schnelles Modulo: */

    FLOAT_TYPE T1;

    FLOAT_TYPE Mesh = p->mesh;
    FLOAT_TYPE Leni = 1.0/s->length;

    FLOAT_TYPE dop;

    int c_index;

    /* Initialisieren von Qmesh */
    memset ( d->Qmesh, 0, 2*Mesh*Mesh*Mesh*sizeof ( FLOAT_TYPE ) );

    TIMING_START_C

    /* chargeassignment */
    assign_charge( s, p, d, 0 );
    assign_charge( s, p, d, 1 );

    TIMING_STOP_C

  /* assign_charge_interlacing( s, p, d ); */

    TIMING_START_G

    /* Durchfuehren der Fourier-Hin-Transformationen: */
    forward_fft(d);

    for (i=0; i<Mesh; i++)
        for (j=0; j<Mesh; j++)
            for (k=0; k<Mesh; k++)
            {
                c_index = c_ind(i,j,k);

                T1 = d->G_hat[r_ind(i,j,k)];
                d->Qmesh[c_index] *= T1;
                d->Qmesh[c_index+1] *= T1;

                for (l=0;l<3;l++) {
                    switch ( l ) {
                    case 0:
                        dop = d->Dn[i];
                        break;
                    case 1:
                        dop = d->Dn[j];
                        break;
                    case 2:
                        dop = d->Dn[k];
                        break;
                    }
                    d->Fmesh->fields[l][c_index]   = -2.0*PI*Leni*dop*d->Qmesh[c_index+1];
                    d->Fmesh->fields[l][c_index+1] =  2.0*PI*Leni*dop*d->Qmesh[c_index];
                }

            }

    /* Durchfuehren der Fourier-Rueck-Transformation: */
    backward_fft(d);

    TIMING_STOP_G

      TIMING_START_F

    /* force assignment */
    /* assign_forces ( 1.0 / ( 2.0*s->length*s->length*s->length ), s, p, d, f, 0 ); */
    /* assign_forces ( 1.0 / ( 2.0*s->length*s->length*s->length ), s, p, d, f, 1 ); */

   assign_forces_interlacing ( 1.0 / ( 2.0*s->length*s->length*s->length ), s, p, d, f );

    TIMING_STOP_F

    return;
}