示例#1
0
int mindist3(int part_id, double r_catch, int *ids) {
  Particle *partCfgMD;
  double dx,dy,dz;
  int i, me, caught=0;

  partCfgMD = (Particle*)malloc(n_part*sizeof(Particle));
  mpi_get_particles(partCfgMD, NULL);
  me = -1; /* Since 'mpi_get_particles' returns the particles unsorted, it's most likely that 'partCfgMD[i].p.identity != i'
	      --> prevent that! */
  for(i=0; i<n_part; i++) if (partCfgMD[i].p.identity == part_id) me = i; 
  if (me == -1) {
      ostringstream msg;
      msg <<"failed to find desired particle " << part_id;
      runtimeError(msg);
    return 0;
  }
  for (i=0; i<n_part; i++) {
    if (i != me) {
      dx = partCfgMD[me].r.p[0] - partCfgMD[i].r.p[0];   dx -= dround(dx/box_l[0])*box_l[0];
      dy = partCfgMD[me].r.p[1] - partCfgMD[i].r.p[1];   dy -= dround(dy/box_l[1])*box_l[1];
      dz = partCfgMD[me].r.p[2] - partCfgMD[i].r.p[2];   dz -= dround(dz/box_l[2])*box_l[2];
      if (sqrt(SQR(dx)+SQR(dy)+SQR(dz)) < r_catch) ids[caught++]=partCfgMD[i].p.identity;
    }
  }
  free(partCfgMD); 
  return (caught);
}
示例#2
0
void ion_to_cylinder_r(double** xyz,double* Q, int pndx, double* fx, double* fy)
{

double rpi2=0;
double dpix=0;
double dpiy=0;  

for (int t1=0;t1<NP;t1++)
{
	
	dpix=pxy[pndx][0]-xyz[t1][0]; dpix-=dround(dpix/Ls[0])*Ls[0];
	dpiy=pxy[pndx][1]-xyz[t1][1]; dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2=(SQR(dpix)+SQR(dpiy));
	//e1(x)=-ei(-x)
	if (rpi2<=rmax2)
	{
   		*fx+=2*Q[t1]*prefactor*taus[pndx]*exp(-SQR(alpha)*(rpi2))*(dpix/rpi2);
		*fy+=2*Q[t1]*prefactor*taus[pndx]*exp(-SQR(alpha)*(rpi2))*(dpiy/rpi2);
		//*fx+=Q[t1]*prefactor*taus[pndx]*dpix/(rpi2)*(exp(-SQR(alpha)*(rpi2))*2*alpha/sqrt(PI)+erfc(alpha*sqrt(rpi2))/sqrt(rpi2));
		//*fy+=Q[t1]*prefactor*taus[pndx]*dpiy/(rpi2)*(exp(-SQR(alpha)*(rpi2))*2*alpha/sqrt(PI)+erfc(alpha*sqrt(rpi2))/sqrt(rpi2));
	}
	
    

}
}
示例#3
0
//--------------------------------------------------------------------
int update_ionpress(int Npol, int Nions,double* Qs, double** xyz, double* rpol, double** polcoord, double* rions,int*** press_extrap,double* box, int setzero)
{
double dr[]={0.01,0.015,0.02,0.025,0.03,0.035,0.04,0.045,0.05,0.055,0.06,0.065,0.07,0.075,0.08, 0.085, 0.09, 0.095, 0.1,0.105,0.11,0.115,0.12, 0.125,0.130};
double dx=0;
double dy=0;
double r2=0;
double r=0;
double angle=0;
if (setzero==1)
{

for (int i=0;i<Npol;i++)
	for (int j=0;j<ANGLEBINS;j++)
		for (int k=0;k<50;k++)	
			press_extrap[i][j][k]=0;

return 1;
}
else
{
	for (int i=0;i<Npol;i++)
	{
	//Note, distance not corrected with hard sphere radius, convenient for ploting
	// Angle wrt positive x-axis (1,0,0)
		for (int j=0;j<Nions; j++)
		{
		dx = xyz[j][0] - polcoord[i][0]; dx -= dround(dx/box[0])*box[0];
		dy = xyz[j][1] - polcoord[i][1]; dy -= dround(dy/box[1])*box[1]; 
		
		r2 = SQR(dx) + SQR(dy);
		r=sqrt(r2);
		//going through quadrats of coordinate system, scaling acos 0,pi->0,2pi
		angle=acos(dx/r);

		if (dx>0 && dy<0)
			angle=2*PI-angle;
		else if (dx<0 && dy<0)
			angle=(PI-angle)+PI;
	
			for (int k=0;k<25;k++)
			{
			if (Qs[j]>0 && r<rions[0]+rpol[i]+dr[k])
				press_extrap[i][(int)(angle/(2*PI)*ANGLEBINS)][k]++;
			if (Qs[j]<0 && r<rions[1]+rpol[i]+dr[k])
				press_extrap[i][(int)(angle/(2*PI)*ANGLEBINS)][k+25]++;
			}		
		}


	}

return 0;
}

}
示例#4
0
double buf_mindist4(double pos[3], int n_add, double *add) {
  double mindist=30000.0, dx,dy,dz;
  int i;

  if (n_add == 0) return (dmin(dmin(box_l[0],box_l[1]),box_l[2]));
  for (i=0; i<n_add; i++) {
    dx = pos[0] - add[3*i + 0];   dx -= dround(dx/box_l[0])*box_l[0];
    dy = pos[1] - add[3*i + 1];   dy -= dround(dy/box_l[1])*box_l[1];
    dz = pos[2] - add[3*i + 2];   dz -= dround(dz/box_l[2])*box_l[2];
    mindist = dmin(mindist, SQR(dx)+SQR(dy)+SQR(dz));
  }
  if (mindist<30000.0) return (sqrt(mindist));
  return (-1.0);
}
示例#5
0
int overlap_pol(double px, double py, double x, double y, double rpol, double r_ion, double* box)
{
double dx=x-px;
double dy=y-py;

dx -= dround(dx/box[0])*box[0];
dy -= dround(dy/box[1])*box[1];

int temp=0;

if (sqrt((dy)*(dy)+(dx)*(dx))<(r_ion+rpol))
	temp=1;

return temp;
}
示例#6
0
void Lattice::set_data_for_global_position_with_periodic_image(double* pos, void* data) {

    index_t replica[3];
    index_t global_index[3];
    index_t halo_index[3];


    for (int i = 0; i<3; i++) {
        global_index[i] = (int)dround((pos[i]-this->offset[i])/this->agrid[i]);
    }

    for (int i=-this->halo_size; i<=this->halo_size; i++) {
        for (int j=-this->halo_size; j<=this->halo_size; j++) {
            for (int k=-this->halo_size; k<=this->halo_size; k++) {
                replica[0]=global_index[0]+i*this->global_grid[0];
                replica[1]=global_index[1]+j*this->global_grid[1];
                replica[2]=global_index[2]+k*this->global_grid[2];
                if (map_global_index_to_halo_index(replica, halo_index)) {
                    set_data_for_local_halo_grid_index(halo_index, data);
                }

            }
        }
    }
}
示例#7
0
int Lattice::global_pos_to_lattice_halo_index(double* pos, index_t*  ind) {
    for (int i = 0; i<3; i++) {
        ind[i] = (int)dround((pos[i]-this->local_offset[i])/this->agrid[i])+this->halo_size;
        if (ind[i] < 0 || ind[i] >= this->halo_grid[i])
            return 0;
    }
    return 1;
}
示例#8
0
int overlap_ion(int Np, double** xyz, int move_ndx, double* rions, double* Qs, double x, double y, double z, double* box)
{

int moved_ion_type;
int ion_type;

double dx;
double dy;
double dz;

/*printf("box %lf %lf %lf\n", box[0],box[1],box[2]);
printf("rions %lf %lf\n", rions[0],rions[1]);
printf("Np %d", Np);*/

if (Qs[move_ndx]>0)
	moved_ion_type=0;
else
	moved_ion_type=1;

for (int i=0;i<Np;i++)
{
		
	if (Qs[i]>0)
		ion_type=0;
	else
		ion_type=1;
	//printf("distance %lf limit %lf\n", SQR(xyz[i][0]-xyz[move_ndx][0])+SQR(xyz[i][1]-xyz[move_ndx][1])+SQR(xyz[i][2]-xyz[move_ndx][2]),SQR(rions[ion_type]+rions[moved_ion_type]));
	//printf("x %lf y %lf z %lf\n", xyz[i][0], xyz[i][1],xyz[i][2]);
	dx=xyz[i][0]-x;
	dy=xyz[i][1]-y;
	dz=xyz[i][2]-z;

	dx -= dround(dx/box[0])*box[0];
	dy -= dround(dy/box[1])*box[1];
	dz -= dround(dz/box[2])*box[2];

	if (move_ndx!=i && (SQR(dx)+SQR(dy)+SQR(dz)<SQR(rions[ion_type]+rions[moved_ion_type])))
	{
		return 1;
	} 	
		
}
return 0;
}
示例#9
0
double Ewald_r_space_part_line(double** xyz, double *Q, 
		     double *MCcoord, double MCQ, int MCion)
{
  int    t2;
  double dx,dy,dz,r,r2,ar, dpix, dpiy, rpi2;
  double d1,d2,d3=0.0;
  double d3_ci=0;

   //cylinder-ion contribution
    for (int l=0;l<Npol;l++)
    {	
	dpix=pxy[l][0]-MCcoord[0]; 
	dpix-=dround(dpix/Ls[0])*Ls[0];
	
	dpiy=pxy[l][1]-MCcoord[1]; 
	dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2=(SQR(dpix)+SQR(dpiy));

	if (rpi2<=rmax2)
   		d3_ci-= MCQ*prefactor*taus[l]*Exponential_Integral_Ei(-SQR(alpha)*(rpi2));
	
    }	

    for (t2 = 0; t2<NP; t2++) {
      if ( t2 != MCion )
	{
	  dx = MCcoord[0] - xyz[t2][0]; dx -= dround(dx/Ls[0])*Ls[0];
	  dy = MCcoord[1] - xyz[t2][1]; dy -= dround(dy/Ls[1])*Ls[1]; 
	  dz = MCcoord[2] - xyz[t2][2]; dz -= dround(dz/Ls[2])*Ls[2];
	  r2 = SQR(dx) + SQR(dy) + SQR(dz);

	  
	  if (r2 <= rmax2) {

	    ar = alpha * (r = sqrt(r2));
	    d3 += ( d2 = (d1 = MCQ * Q[t2] * prefactor) * erfc(ar) / r );
	    
	  }
	}
    }

  return d3+d3_ci;
 //  return d3;	
}
示例#10
0
double mindist4(double pos[3]) {
  Particle *partCfgMD;
  double mindist=30000.0, dx,dy,dz;
  int i;

  if (n_part ==0) return (dmin(dmin(box_l[0],box_l[1]),box_l[2]));
  partCfgMD = (Particle*)malloc(n_part*sizeof(Particle));
  mpi_get_particles(partCfgMD, NULL); 
  for (i=0; i<n_part; i++) {
    dx = pos[0] - partCfgMD[i].r.p[0];   dx -= dround(dx/box_l[0])*box_l[0];
    dy = pos[1] - partCfgMD[i].r.p[1];   dy -= dround(dy/box_l[1])*box_l[1];
    dz = pos[2] - partCfgMD[i].r.p[2];   dz -= dround(dz/box_l[2])*box_l[2];
    mindist = dmin(mindist, SQR(dx)+SQR(dy)+SQR(dz));
  }
  free(partCfgMD); 
  if (mindist<30000.0)
    return (sqrt(mindist));
  return (-1.0);
}
示例#11
0
double vrelaxQuality(TVertex* v0, TVertex* v1,TVertex* v2,TVertex* v3)
{
	double qlty ,
		// Calculo el volumen
		x21,y21,z21,x31,y31,z31,x41,y41,z41 ,
		d1,d2,d3,vol ,
		// Calculo la calidad
		dx,dy,dz ,
		maxleng2, leng2 ;
	float4 p1,p2,p3, p4 ;

	p1 = v0->fPos;
	p2 = v1->fPos;
	p3 = v2->fPos;
	p4 = v3->fPos;

	x21 = p2.x-p1.x; y21 = p2.y-p1.y; z21 = p2.z-p1.z;
	x31 = p3.x-p1.x; y31 = p3.y-p1.y; z31 = p3.z-p1.z;
	x41 = p4.x-p1.x; y41 = p4.y-p1.y; z41 = p4.z-p1.z;
	d1 = y31*z41 - z31*y41;
	d2 = y41*z21 - z41*y21;
	d3 = y21*z31 - z21*y31;
	vol = (x21 * d1 + x31 * d2 + x41 * d3) / 6.0;
	qlty = vol;

	dx = p2.x-p1.x; 
	dy = p2.y-p1.y; 
	dz = p2.z-p1.z;
	maxleng2=dx*dx+dy*dy+dz*dz;
	dx = p3.x-p1.x; dy = p3.y-p1.y; dz = p3.z-p1.z;
	leng2=dx*dx+dy*dy+dz*dz;
	if(leng2 > maxleng2) maxleng2=leng2;
	dx = p4.x-p1.x; dy = p4.y-p1.y; dz = p4.z-p1.z;
	leng2=dx*dx+dy*dy+dz*dz;
	if(leng2 > maxleng2) maxleng2=leng2;
	dx = p3.x-p2.x; dy = p3.y-p2.y; dz = p3.z-p2.z;
	leng2=dx*dx+dy*dy+dz*dz;
	if(leng2 > maxleng2) maxleng2=leng2;
	dx = p4.x-p2.x; dy = p4.y-p2.y; dz = p4.z-p2.z;
	leng2=dx*dx+dy*dy+dz*dz;
	if(leng2 > maxleng2) maxleng2=leng2;
	dx = p4.x-p3.x; dy = p4.y-p3.y; dz = p4.z-p3.z;
	leng2=dx*dx+dy*dy+dz*dz;
	if(leng2 > maxleng2) maxleng2=leng2;

	if (vol>0) 
		qlty =(vol*(vol))/(maxleng2*maxleng2*maxleng2);
	else
		qlty =(vol*(-vol))/(maxleng2*maxleng2*maxleng2);


	int iqlty =dround( qlty * PRECISSION);    
	//return qlty;
	return 72.0 * ( (double)(iqlty)/(double)(PRECISSION));  //calcula fast quality
}
示例#12
0
void *subRound(void *hnd, c4snet_data_t *sd, c4snet_data_t*sk, int c, int size) {
  char *D = (char*) C4SNetGetData(sd);
  char *K = (char *) C4SNetGetData(sk);
  int i;
  for (i = 0; i < size; i++) {
    dround(&D[i * 8], &K[i * 7], c);
  }
  c++;
  C4SNetOut(hnd, 1, sd, sk, c, size);
  return hnd;
}
示例#13
0
//int Lattice::init(double *agrid, double* offset, int halo_size, size_t dim) {
int Lattice::init(double *agrid, double* offset, int halo_size, size_t dim) {
    this->dim=dim;

    /* determine the number of local lattice nodes */
    for (int d=0; d<3; d++) {
        this->agrid[d] = agrid[d];
        this->global_grid[d] = (int)dround(box_l[d]/agrid[d]);
        this->offset[d]=offset[d];
        this->local_index_offset[d]=(int) ceil((my_left[d]-this->offset[d])/this->agrid[d]);
        this->local_offset[d] = this->offset[d] +
            this->local_index_offset[d]*this->agrid[d];
        this->grid[d] = (int) ceil ( ( my_right[d] - this->local_offset[d]-ROUND_ERROR_PREC )
                                     / this->agrid[d]);
    }

    // sanity checks
    for (int dir=0;dir<3;dir++) {
      // check if local_box_l is compatible with lattice spacing
      if (fabs(local_box_l[dir]-this->grid[dir]*agrid[dir]) > ROUND_ERROR_PREC*box_l[dir]) {
        char *errtxt = runtime_error(256);
        ERROR_SPRINTF(errtxt, \
                      "{097 Lattice spacing agrid[%d]=%f " \
                      "is incompatible with local_box_l[%d]=%f " \
                      "(box_l[%d]=%f node_grid[%d]=%d)} ",       \
                      dir, agrid[dir], \
                      dir, local_box_l[dir], \
                      dir, box_l[dir], \
                      dir, node_grid[dir]);
      }
    }

    this->element_size = this->dim*sizeof(double);

    LATTICE_TRACE(fprintf(stderr,"%d: box_l (%.3f,%.3f,%.3f) grid (%d,%d,%d) node_neighbors (%d,%d,%d,%d,%d,%d)\n",this_node,local_box_l[0],local_box_l[1],local_box_l[2],this->grid[0],this->grid[1],this->grid[2],node_neighbors[0],node_neighbors[1],node_neighbors[2],node_neighbors[3],node_neighbors[4],node_neighbors[5]));

    this->halo_size = halo_size;
    /* determine the number of total nodes including halo */
    this->halo_grid[0] = this->grid[0] + 2*halo_size ;
    this->halo_grid[1] = this->grid[1] + 2*halo_size ;
    this->halo_grid[2] = this->grid[2] + 2*halo_size ;

    this->grid_volume = this->grid[0]*this->grid[1]*this->grid[2] ;
    this->halo_grid_volume = this->halo_grid[0]*this->halo_grid[1]*this->halo_grid[2] ;
    this->halo_grid_surface = this->halo_grid_volume - this->grid_volume ;
    this->halo_offset = get_linear_index(halo_size,halo_size,halo_size,this->halo_grid) ;

    this->interpolation_type = INTERPOLATION_LINEAR;

    allocate_memory();
    return ES_OK;

}
示例#14
0
//The original ewald function for testing
double Ewald_r_space(double** xyz, double *Q, double** F)
{
  int    t1,t2;
  double dx,dy,dz,r,r2,ar,ar2;
  double d1,d2,d3=0.0,d4;
  double Li=1/Ls[0];
  double Ltmp=Ls[0];  
//printf("L %lf Li %lf pre %lf rmax2 %lf\n", Ltmp,Li, prefactor, rmax2);
  static double wupi = 1.77245385090551602729816748334;

  for (t1 = 0; t1 < NP-1; t1++)   /* Quick and Dirty N^2 loop */
    for (t2 = t1 + 1; t2<NP; t2++) {
      dx = xyz[t1][0] - xyz[t2][0]; dx -= dround(dx*Li)*Ltmp;
      dy = xyz[t1][1] - xyz[t2][1]; dy -= dround(dy*Li)*Ltmp; 
      dz = xyz[t1][2] - xyz[t2][2]; dz -= dround(dz*Li)*Ltmp;
      r2 = SQR(dx) + SQR(dy) + SQR(dz);
      /*      printf("%d %d %le \n",t1+1,t2+1,sqrt(r2));*/
      /*      printf("%d  %d  %le  %le\n",t1+1,t2+1,r2,rmax2);*/

	if (r2 <= rmax2) {
	  //printf("Forces");
	  ar2 = SQR(ar = alpha * (r = sqrt(r2)));
	  d3 += ( d2 = (d1 = Q[t1] * Q[t2] * prefactor) * erfc(ar) / r );
	  printf("alpha %lf t1 %d t2 %d ar2 %lf d3 %lf\n", alpha, t1,t2,ar2,d3);	
	  if (F) {   /* if forces should be computed... */
	    d4  = ( d2 + d1*2.0*alpha*exp(-ar2)/wupi) / r2;
	    
	    F[t1][0] += d4*dx;
	    F[t1][1] += d4*dy;
	    F[t1][2] += d4*dz;
	    F[t2][0] -= d4*dx;
	    F[t2][1] -= d4*dy;
	    F[t2][2] -= d4*dz;
	  }
	}
    }
  return d3;
}
示例#15
0
static int
proc_line(struct prln_ctx_s ctx, char *line, size_t llen)
{
	struct dt_dt_s d;
	char *sp = NULL;
	char *ep = NULL;
	int rc = 0;

	do {
		/* check if line matches, */
		d = dt_io_find_strpdt2(
			line, llen, ctx.ndl, &sp, &ep, ctx.fromz);

		if (!dt_unk_p(d)) {
			if (UNLIKELY(d.fix) && !ctx.quietp) {
				rc = 2;
			}
			/* perform addition now */
			d = dround(d, ctx.st->durs, ctx.st->ndurs, ctx.nextp);

			if (ctx.hackz == NULL && ctx.fromz != NULL) {
				/* fixup zone */
				d = dtz_forgetz(d, ctx.fromz);
			}

			if (ctx.sed_mode_p) {
				__io_write(line, sp - line, stdout);
				dt_io_write(d, ctx.ofmt, ctx.outz, '\0');
				llen -= (ep - line);
				line = ep;
			} else {
				dt_io_write(d, ctx.ofmt, ctx.outz, '\n');
				break;
			}
		} else if (ctx.sed_mode_p) {
			line[llen] = '\n';
			__io_write(line, llen + 1, stdout);
			break;
		} else {
			/* obviously unmatched, warn about it in non -q mode */
			if (!ctx.quietp) {
				dt_io_warn_strpdt(line);
				rc = 2;
			}
			break;
		}
	} while (1);
	return rc;
}
示例#16
0
main(int argc, char *argv[])
{
      double f, lf;
      char *dummy;

      while (--argc)
      {
            f  = strtod((const char *)(*(++argv)), &dummy);
            if (0.0 == f)
            {
                  puts("0! = 0");
                  continue;
            }
            if (-1.0 == (lf = log10factorial(f)))
            {
                  printf(">>> ERROR: %g! is not a valid expression\n", f);
                  continue;
            }
            if (171.0 > f)
                  printf("%.14g! = %.14g\n", f, pow(10.0, lf));
            else
            {
                  printf("%.14g! = %.14ge+%ld\n", f,
                        pow(10.0, dfrac(lf)), (long)dround(lf));
            }
      }
      lf = log10C(1000000L,750000L);
      printf("\nJust to dazzle with you with big numbers:\n"
            "C(1000000,750000) = %.14ge+%ld\n",
            pow(10.0, dfrac(lf)), (long)dround(lf));
      lf = log10P(1000000L,750000L);
      printf("\n...once more:\n"
            "P(1000000,750000) = %.14ge+%ld\n",
            pow(10.0, dfrac(lf)), (long)dround(lf));
      return EXIT_SUCCESS;
}
示例#17
0
int main( int argc, char **argv )
{
    if( argc < 3 ) {
        std::cout << "usage: " << argv[0] << " test.stl test.res" << std::endl;
        return 100;
    }

    int rez = 0;
    try {
        Mesh m;
        m.load( argv[1] );
        std::ifstream res( argv[2] );
        for( double z = m.min().z(); z <= m.max().z(); z+=0.5 ) {
            std::ostringstream os;
            os <<  "z=" << dround( z );
            auto p = m.slice( z );
            for( const auto &pl : p ) {
                os << " polygon: [";
                for( const auto &pt : pl )
                    os << pt;
                os << "]";
            }
            std::string sres;
            if( !std::getline( res, sres ) )
                throw std::runtime_error( "unexpected end of result file" );
            
            if( os.str() != sres ) {
                std::cerr << "error: expected \"" << sres << "\"" << std::endl;
                std::cerr << "            got \"" << os.str() << "\"" << std::endl;
                rez = 102;
            }

        }
    }
    catch( const std::exception &ex )
    {
        std::cerr << "error: " << ex.what() << std::endl;
        return 101;
    }
    return rez;
}
示例#18
0
/** Calculates the dihedral angle between particle quadruple p1, p2,
p3 and p4. The dihedral angle is the angle between the planes
specified by the particle triples (p1,p2,p3) and (p2,p3,p4). 
Vectors a, b and c are the bond vectors between consequtive particles.
If the a,b or b,c are parallel the dihedral angle is not defined in which
case the routine returns phi=-1. Calling functions should check for that
(Written by: Arijit Maitra) */
inline void calc_dihedral_angle(Particle *p1, Particle *p2, Particle *p3, Particle *p4, 
				  double a[3], double b[3], double c[3], 
				  double aXb[3], double *l_aXb, double bXc[3], double *l_bXc, 
				  double *cosphi, double *phi)
{
  int i;

  get_mi_vector(a, p2->r.p, p1->r.p);
  get_mi_vector(b, p3->r.p, p2->r.p);
  get_mi_vector(c, p4->r.p, p3->r.p);

  /* calculate vector product a X b and b X c */
  vector_product(a, b, aXb);
  vector_product(b, c, bXc);

  /* calculate the unit vectors */
  *l_aXb = sqrt(sqrlen(aXb));
  *l_bXc = sqrt(sqrlen(bXc));

  /* catch case of undefined dihedral angle */
   if ( *l_aXb <= TINY_LENGTH_VALUE || *l_bXc <= TINY_LENGTH_VALUE ) { *phi = -1.0; *cosphi = 0; return;}

  for (i=0;i<3;i++) {
    aXb[i] /= *l_aXb;
    bXc[i] /= *l_bXc;
  }

  *cosphi = scalar(aXb, bXc);

  if ( fabs(fabs(*cosphi)-1)  < TINY_SIN_VALUE  ) *cosphi = dround(*cosphi);

  /* Calculate dihedral angle */
  *phi = acos(*cosphi);
  if( scalar(aXb, c) < 0.0 ) *phi = (2.0*PI) - *phi;

}
示例#19
0
/*----------------------------------------------------------------------*/
double Ewald_r_space_line_parts(double** xyz, double *Q, 
		     double* e_ii, double* e_pi, double* e_pp)
{
  int    t1,t2;
  double dx,dy,dz,r,r2,ar, dpix, dpiy;
  double d1,d2,d3=0.0, d3_ci=0, d3_cc=0;
  double rpi2=0;
  

  for (t1 = 0; t1 < NP-1; t1++)   /* Quick and Dirty N^2 loop */
  {
 //cylinder-ion contribution
    for (int l=0;l<Npol;l++)
    {	
	dpix=pxy[l][0]-xyz[t1][0]; dpix-=dround(dpix/Ls[0])*Ls[0];
	dpiy=pxy[l][1]-xyz[t1][1]; dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2=(SQR(dpix)+SQR(dpiy));
	//e1(x)=-ei(-x)
	if (rpi2<=rmax2)
   		d3_ci-= Q[t1]*prefactor*taus[l]*Exponential_Integral_Ei(-SQR(alpha)*(rpi2));
	
	
    }
    	

    for (t2 = t1 + 1; t2<NP; t2++) {
      dx = xyz[t1][0] - xyz[t2][0]; dx -= dround(dx/Ls[0])*Ls[0];
      dy = xyz[t1][1] - xyz[t2][1]; dy -= dround(dy/Ls[1])*Ls[1]; 
      dz = xyz[t1][2] - xyz[t2][2]; dz -= dround(dz/Ls[2])*Ls[2];
      r2 = SQR(dx) + SQR(dy) + SQR(dz);
      /*      printf("%d %d %le \n",t1+1,t2+1,sqrt(r2));*/
      /*      printf("%d  %d  %le  %le\n",t1+1,t2+1,r2,rmax2);*/

	if (r2 <= rmax2) {
	  //printf("Forces");
	  ar = alpha * (r = sqrt(r2));
	  d3 += ( d2 = (d1 = Q[t1] * Q[t2] * prefactor) * erfc(ar) / r );


	}
    }
  }
//final ion, look at the loop indices
t1=NP-1;
  for (int l=0;l<Npol;l++)
    {	
	dpix=pxy[l][0]-xyz[t1][0]; dpix-=dround(dpix/Ls[0])*Ls[0];
	dpiy=pxy[l][1]-xyz[t1][1]; dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2=(SQR(dpix)+SQR(dpiy));
	//e1(x)=-ei(-x)
	if (rpi2<=rmax2)
   		d3_ci-= Q[t1]*prefactor*taus[l]*Exponential_Integral_Ei(-SQR(alpha)*(rpi2));
	
	
    }
//cylinder-cylinder as a function of their separation
//should there be a cutoff here too, think about periodicity, will they always be l/2?

if (Npol==2)
	d3_cc=-prefactor*taus[1]*taus[0]*Ls[2]*Exponential_Integral_Ei(-SQR(alpha)*(SQR(pxy[1][0]-pxy[0][0])+SQR(pxy[1][1]-pxy[0][1])));

printf("real d3 %lf d3_ci %lf d3_cc %lf\n", d3,d3_ci,d3_cc);
*e_ii=d3;
*e_pi=d3_ci;
*e_pp=d3_cc;

  return d3+d3_ci+d3_cc;
  //return d3;	
}
/*-------------------------------------------------------------------------------------------------------*/
void update_verlet (void) {
	// define necessary variables: i, j and temporary position variables,
	double xi, yi, xj, yj;
	double dx, dy, sig_y;
	double r_squared;

	// count how many values there are in the list
	int k;

	// iterate over all particles, read positions
	for (int i=0; i<N; i++) {
		xi = position[2*i];
		yi = position[2*i+1];

		// save the amount of neighbors to particle i in k
		k = 0;

		for (int j=0; j<N; j+=2) {

			// ignore entry where particle i itself is inspected
			if (i == j)
				continue;

			// get the position of particle j
			xj = position[2*j];
			yj = position[2*j+1];

			// get the distance between both particles
			dx = xi - xj;
			dy = yi - yj;

			// alter dx, this accounts for Lees-Edwards conditions
			sig_y 	= dround(dy*Li);
			dx 		+= sig_y * box_A;

 			// find images through altering dx and dy
			dx -= dround(dx*Li)*L;
			dy -= sig_y * L;

			// find out squared distance and check against the verlet cutoff
			r_squared = dx*dx + dy*dy;

			// squaring is a strict monotonous function, thus we can check with the squares of the values (saves N*N sqrt()-calls)
			if(cutoff_squared >= r_squared) {
				// check whether there is enough space in the verlet list
				if (k == N_Verlet -1) {
					fprintf(stderr, "Verlet list is too short!!\n");
					fprintf(stderr, "N: %d, N_Verlet: %d, k: %d\n", N, N_Verlet, k);
					exit(EXIT_FAILURE);
				}

				// add neighbor and signums into verlet and sign list
				verlet[N_Verlet*i+k] 	= j;
				k++;
			}
		}

		for (int j=1; j<N; j+=2) {

			// ignore entry where particle i itself is inspected
			if (i == j)
				continue;

			// get the position of particle j
			xj = position[2*j];
			yj = position[2*j+1];

			// get the distance between both particles
			dx = xi - xj;
			dy = yi - yj;

			// alter dx, this accounts for Lees-Edwards conditions
			sig_y 	= dround(dy*Li);
			dx 		+= sig_y * box_B;

 			// find images through altering dx and dy
			dx -= dround(dx*Li)*L;
			dy -= sig_y * L;

			// find out squared distance and check against the verlet cutoff
			r_squared = dx*dx + dy*dy;

			// squaring is a strict monotonous function, thus we can check with the squares of the values (saves N*N sqrt()-calls)
			if(cutoff_squared >= r_squared) {
				// check whether there is enough space in the verlet list
				if (k == N_Verlet -1) {
					fprintf(stderr, "Verlet list is too short!!\n");
					fprintf(stderr, "N: %d, N_Verlet: %d, k: %d\n", N, N_Verlet, k);
					exit(EXIT_FAILURE);
				}

				// add neighbor and signums into verlet and sign list
				verlet[N_Verlet*i+k] 	= j;
				k++;
			}
		}

		// edit last entry of row, here we store how many neighbors particle i has, and reset distance counting vector
		verlet[N_Verlet*(i+1)-1] 		= k;
		verlet_distance[2*i]	= 0;
		verlet_distance[2*i+1] 	= 0;
	}

	// reset thread specific verlet counter
	for (int i=0; i<thread_number; i++) {
		verlet_max[2*i] 	= 0;
		verlet_max[2*i+1]	= 0;
	}
}
/*-------------------------------------------------------------------------------------------------------*/
static void *iteration (int *no) {
	// Define necessary variables
	double xi, xj, yi, yj;
	double dx, dy, sig_y;
	double r_squared;

	double temp_force;
	double temp;

	double u1, u2, g1, g2;

	int min = borders[*no];
	int max = borders[*no+1];

	int iterate;
	int j;

	double m_i_one;
	double m_i_two;

	double weigh_brown_one;
	double weigh_brown_two;

	double D_kT_one;
	double D_kT_two;

	double shear_one;
	double shear_two;

	double* box_one;
	double* box_two;

	double m_j;

	if (min%2 == 0){
		// get the relation of all even values, this is basically the interaction relation this particle will have with other particles
		m_i_one = 1.0;
		m_i_two = m;

		// set the appropriate diffusion parameters according to index of particle
		weigh_brown_one = weigh_brown_A;
		weigh_brown_two = weigh_brown_B;

		D_kT_one = D_Brown_A/kT;
		D_kT_two = D_Brown_B/kT;

		// assign the right box displacement parameter
		box_one = &box_A;
		box_two = &box_B;

		// shear_one = v_s / (D_kT_one * L) * delta_t;
		// shear_two = v_s / (D_kT_two * L) * delta_t;
		shear_one = v_A / (L) * delta_t;
		shear_two = v_B / (L) * delta_t;
	}
	else {
		// get the relation of all even values, this is basically the interaction relation this particle will have with other particles
		m_i_one = m;
		m_i_two = 1.0;

		// set the appropriate diffusion parameters according to index of particle
		weigh_brown_one = weigh_brown_B;
		weigh_brown_two = weigh_brown_A;

		D_kT_one = D_Brown_B/kT;
		D_kT_two = D_Brown_A/kT;

		// assign the right box displacement parameter
		box_one = &box_B;
		box_two = &box_A;

		// shear_one = v_s / (D_kT_one * L) * delta_t;
		// shear_two = v_s / (D_kT_two * L) * delta_t;
		shear_one = v_B / (L) * delta_t;
		shear_two = v_A / (L) * delta_t;
	}

	// let the simulation run until the thread is terminated
	while(cont == 1) {
		// iterate 2D-forces over all particles A in Verlet-List
		for (int i=min; i<max; i+=2) {
			// get the position of the current particle
			xi = position[2*i];
			yi = position[2*i+1];

			// initiate forces for this round
			force[2*i]	 = 0;
			force[2*i+1] = 0;

			// get the amount of particles we have to iterate
			iterate = verlet[N_Verlet*(i+1)-1];

			// iterate to number given in last entry of i in Verlet-List
			for (int k=0; k<iterate; k+=1) {
				// get the next particle and it's position within the root box
				j  = verlet[N_Verlet*i+k];
				xj = position[2*j];
				yj = position[2*j+1];

				// assign the appropriate interaction relation to the particle, depending whether it has even or uneven index
				m_j = (j%2)*m + (j+1)%2;

				// Get the distance between both particles
				dx = xi - xj;
				dy = yi - yj;

				// alter dx, this accounts for Lees-Edwards conditions
				sig_y 	=  dround(dy*Li);
				dx 		+= sig_y * (*box_one);

 				// find images through altering dx and dy
				dx 		-= dround(dx*Li)*L;
				dy		-= sig_y * L;

				// get square of distance and compute force in x and y direction
				r_squared = dx*dx + dy*dy;
				temp_force = (m_i_one*m_j/sqrt(r_squared))*(3*Gamma_A/(r_squared*r_squared)-force_cutoff); // WARNING: this is F/r

				force[2*i] 		+= temp_force*dx; // equals F*x/r = F*cos(phi) (x-component)
				force[2*i+1]	+= temp_force*dy; // equals F*y/r = F*sin(phi) (y-component)
			}
		}

		// iterate 2D-forces over all particles B in Verlet-List
		for (int i=min+1; i<max; i+=2) {
			// get the position of the current particle
			xi = position[2*i];
			yi = position[2*i+1];

			// initiate forces for this round
			force[2*i]	 = 0;
			force[2*i+1] = 0;

			// get the amount of particles we have to iterate
			iterate = verlet[N_Verlet*(i+1)-1];

			// iterate to number given in last entry of i in Verlet-List
			for (int k=0; k<iterate; k+=1) {
				// get the next particle and it's position within the root box
				j  = verlet[N_Verlet*i+k];
				xj = position[2*j];
				yj = position[2*j+1];

				// assign the appropriate interaction relation to the particle, depending whether it has even or uneven number
				m_j = (j%2)*m + (j+1)%2;

				// Get the distance between both particles
				dx = xi - xj;
				dy = yi - yj;

				// alter dx, this accounts for Lees-Edwards conditions
				sig_y 	=  dround(dy*Li);
				dx 		+= sig_y * (*box_two);

 				// find images through altering dx and dy
				dx		-= dround(dx*Li)*L;
				dy		-= sig_y * L;

				// get square of distance and compute force in x and y direction
				r_squared = dx*dx + dy*dy;
				temp_force = (m_i_two*m_j/sqrt(r_squared))*(3*Gamma_A/(r_squared*r_squared)-force_cutoff); // WARNING: this is F/r

				force[2*i] 		+= temp_force*dx; // equals F*x/r = F*cos(phi) (x-component)
				force[2*i+1]	+= temp_force*dy; // equals F*y/r = F*sin(phi) (y-component)
			}
		}

		// wait for all threads to finish iteration of forces, then continue with writing position data
		pthread_barrier_wait(&barrier_internal);

		// compute new positions for particles A from forces, remember periodic boundary conditions
		for (int i=min; i<max; i+=2) {

			xi = position[2*i];
			yi = position[2*i+1];

			// use Box-Muller-method in order to obtain two independent standard normal values
			do {
				u1 = rand()/(double)RAND_MAX;
			} while (u1 == 0.0);
			do {
				u2 = rand()/(double)RAND_MAX;
			} while (u2 == 0.0);

			temp = sqrt(-2*log(u1));
			g1 = temp*cos(TWO_PI*u2);
			g2 = temp*sin(TWO_PI*u2);

			// Calculate next positions and total displacement for all particles
			dx = D_kT_one*delta_t*force[2*i]   + weigh_brown_one * g1 + position[2*i+1]*shear_one;
			dy = D_kT_one*delta_t*force[2*i+1] + weigh_brown_one * g2;

			position[2*i]		+= dx;
			position[2*i+1] 	+= dy;

			displacement[2*i]	+= dx;
			displacement[2*i+1] += dy;

			// update list of total displacement for each particle after last verlet-list update
			verlet_distance[2*i] 	+= (xi - position[2*i]);
			verlet_distance[2*i+1] 	+= (yi - position[2*i+1]);

			if ((temp = sqrt(verlet_distance[2*i]*verlet_distance[2*i] + verlet_distance[2*i+1]*verlet_distance[2*i+1])) > verlet_max[2*(*no)]) {
				verlet_max[2*(*no)+1] = verlet_max[2*(*no)];
				verlet_max[2*(*no)] = temp;
			} else if (temp > verlet_max[2*(*no)+1]) {
				verlet_max[2*(*no)+1] = temp;
			}

			// Calculate x positions with periodic boundary conditions, check whether the particle moved from one row to another
			position[2*i] 	-= floor(position[2*i]*Li)*L;
			position[2*i]	-= (floor((position[2*i+1]+L)*Li)-1)*(*box_one); // WTF?!?

			// Calculate y positions with periodic boundary conditions
			position[2*i+1] -= floor(position[2*i+1]*Li)*L;
		}

		// compute new positions for particles B from forces, remember periodic boundary conditions
		for (int i=min+1; i<max; i+=2) {

			xi = position[2*i];
			yi = position[2*i+1];

			// use Box-Muller-method in order to obtain two independent standard normal values
			do {
				u1 = rand()/(double)RAND_MAX;
			} while (u1 == 0.0);
			do {
				u2 = rand()/(double)RAND_MAX;
			} while (u2 == 0.0);

			temp = sqrt(-2*log(u1));
			g1 = temp*cos(TWO_PI*u2);
			g2 = temp*sin(TWO_PI*u2);

			// Calculate next positions and total displacement for all particles
			dx = D_kT_two*delta_t*force[2*i]   + weigh_brown_two * g1 + position[2*i+1]*shear_two;
			dy = D_kT_two*delta_t*force[2*i+1] + weigh_brown_two * g2;

			position[2*i]		+= dx;
			position[2*i+1] 	+= dy;

			displacement[2*i]	+= dx;
			displacement[2*i+1] += dy;

			// update list of total displacement for each particle after last verlet-list update
			verlet_distance[2*i] 	+= (xi - position[2*i]);
			verlet_distance[2*i+1] 	+= (yi - position[2*i+1]);

			if ((temp = sqrt(verlet_distance[2*i]*verlet_distance[2*i] + verlet_distance[2*i+1]*verlet_distance[2*i+1])) > verlet_max[2*(*no)]) {
				verlet_max[2*(*no)+1] = verlet_max[2*(*no)];
				verlet_max[2*(*no)] = temp;
			} else if (temp > verlet_max[2*(*no)+1]) {
				verlet_max[2*(*no)+1] = temp;
			}

			// Calculate x positions with periodic boundary conditions, check whether the particle moved from one row to another
			position[2*i] 	-= floor(position[2*i]*Li)*L;
			position[2*i]	-= (floor((position[2*i+1]+L)*Li)-1)*(*box_two);

			// Calculate y positions with periodic boundary conditions
			position[2*i+1] -= floor(position[2*i+1]*Li)*L;
		}

		// Signal to main thread, that all threads have finished their iteration
		pthread_barrier_wait(&barrier_main_one);

		// thread is done with one iteration, it will now wait for a signal from the main thread to continue
		pthread_barrier_wait(&barrier_main_two);
	}

	return NULL;
}
示例#22
0
/** Calculate lj-angle force between particle p1 and p2
    Involves 6 particles total */
inline void add_ljangle_force(Particle *p1, Particle *p2, IA_parameters *ia_params,
                              double d[3], double dist)
{
    if(!CUTOFF_CHECK(dist < ia_params->LJANGLE_cut))
        return;
    int j;
    double frac2=0.0, frac10=0.0, rad=0.0, radprime=0.0;
    double r31[3], r41[3], r52[3], r62[3], rij[3], rik[3], rkn[3];
    double l_rij, l_rik, l_rkn, l_rij2, l_rik2, l_rkn2;
    double cos_jik, cos_ikn;
    double angular_jik, angular_ikn, angular_jik_prime, angular_ikn_prime;
    /* Recreate angular dependence of potential by including 6 particles instead of 2. */
    Particle *p3=NULL, *p4=NULL, *p5=NULL, *p6=NULL;
    int part1p, part1n, part2p, part2n;
    /* Optional 2nd environment */
    double effective_eps=ia_params->LJANGLE_eps, z1, z2, z_middle, z_ref, z_ref5,
           localz0=ia_params->LJANGLE_z0, localdz2=ia_params->LJANGLE_dz/2.,
           localkappa6=pow(1/ia_params->LJANGLE_kappa,6);



    /* Retrieve the bonded partners from parsing */
    if (ia_params->LJANGLE_bonded1type == p1->p.type) {
        part1p = p1->p.identity + ia_params->LJANGLE_bonded1pos;
        part1n = p1->p.identity + ia_params->LJANGLE_bonded1neg;
        part2p = p2->p.identity + ia_params->LJANGLE_bonded2pos;
        part2n = p2->p.identity + ia_params->LJANGLE_bonded2neg;
    } else {
        part1p = p1->p.identity + ia_params->LJANGLE_bonded2pos;
        part1n = p1->p.identity + ia_params->LJANGLE_bonded2neg;
        part2p = p2->p.identity + ia_params->LJANGLE_bonded1pos;
        part2n = p2->p.identity + ia_params->LJANGLE_bonded1neg;
    }

    if (part1p >= 0 && part1p < n_part &&
            part1n >= 0 && part1n < n_part &&
            part2p >= 0 && part2p < n_part &&
            part2n >= 0 && part2n < n_part     ) {

        p3 = local_particles[part1p];
        p4 = local_particles[part1n];
        p5 = local_particles[part2p];
        p6 = local_particles[part2n];

        /* Check whether pointers have been allocated.
         * Otherwise, there's a communication error (verlet skin too small).
         */
        if (p3==NULL ||p4==NULL ||p5==NULL ||p6==NULL)
            fprintf(stderr, "LJANGLE - Communication error, all particles cannot be reached locally.\n");



        get_mi_vector(r31, p1->r.p, p3->r.p);
        get_mi_vector(r41, p1->r.p, p4->r.p);
        get_mi_vector(r52, p2->r.p, p5->r.p);
        get_mi_vector(r62, p2->r.p, p6->r.p);


        /* Bead i represents the central particle of monomer 1.
         * Bead j is the virtual particle that gives the orientation of monomer 1.
         * Bead k represents the central particle of monomer 2.
         * Bead n is the virtual particle that gives the orientation of monomer 2.
         */
        for(j=0; j<3; ++j) {
            rij[j] = r31[j] + r41[j];
            rik[j] = -d[j]; /* At this point, rik[3] has length dist */
            rkn[j] = r52[j] + r62[j];
        }

        l_rij2 = sqrlen(rij);
        l_rik2 = dist*dist;
        l_rkn2 = sqrlen(rkn);
        l_rij  = sqrt(l_rij2);
        l_rik  = dist;
        l_rkn  = sqrt(l_rkn2);

        cos_jik = scalar(rij,rik)/(l_rij*l_rik);
        cos_ikn = -scalar(rik,rkn)/(l_rik*l_rkn);

        if(cos_jik>0. && cos_ikn>0.) {
            angular_jik       = pow(cos_jik,2);
            angular_ikn       = pow(cos_ikn,2);
            angular_jik_prime = -2*cos_jik;
            angular_ikn_prime = -2*cos_ikn;

            /* Optional 2nd environment */
            if (localdz2 > 0.) {
                /* calculate center position of the interaction (calculate minimal distance) */
                z1  = p1->r.p[2];
                z2  = p2->r.p[2];
                z_middle  = z1 + z2;
                z_middle /= 2.;
                if (PERIODIC(2))
                    if (z_middle > box_l[2] || z_middle < 0.)
                        z_middle -= dround(z_middle *box_l_i[2])*box_l[2];

                /* If we're in the environment #2 region, calculate the new interaction strength */
                if (z_middle > localz0 - localdz2 && z_middle <= localz0) {
                    z_ref = z_middle - localz0 + localdz2;
                    z_ref5 = pow(z_ref,5);
                    effective_eps += (ia_params->LJANGLE_epsprime - ia_params->LJANGLE_eps) *
                                     localkappa6*z_ref5*fabs(z_ref) /
                                     (1 + localkappa6*z_ref5*z_ref);
                } else if (z_middle > localz0 && z_middle < localz0 + localdz2) {
                    z_ref = z_middle - localz0 - localdz2;
                    z_ref5 = pow(z_ref,5);
                    effective_eps -= (ia_params->LJANGLE_epsprime - ia_params->LJANGLE_eps) *
                                     localkappa6*z_ref5*fabs(z_ref) /
                                     (1 + localkappa6*z_ref5*z_ref);
                }
            }

            /* normal case: resulting force/energy smaller than capping. */
            if(dist > ia_params->LJANGLE_capradius) {
                frac2 = SQR(ia_params->LJANGLE_sig/dist);
                frac10 = frac2*frac2*frac2*frac2*frac2;
                rad        = effective_eps * frac10*(5.0 * frac2 - 6.0);
                radprime   = 60.0 * effective_eps * frac10*(1.0 - frac2) / dist;

#ifdef LJ_WARN_WHEN_CLOSE
                if(radprime > 1000) fprintf(stderr,"%d: LJANGLE-Warning: Pair (%d-%d) force=%f dist=%f\n",
                                                this_node,p1->p.identity,p2->p.identity,radprime,dist);
#endif
            }
            /* capped part of lj-angle potential. */
            else if(dist > 0.0) {
                /* set the length of rik to capradius */
                for (j=0; j<3; ++j)
                    rik[j] *= ia_params->LJANGLE_capradius/dist;

                l_rik = ia_params->LJANGLE_capradius;

                frac2 = SQR(ia_params->LJANGLE_sig/ia_params->LJANGLE_capradius);
                frac10 = frac2*frac2*frac2*frac2*frac2;

                rad        = effective_eps * frac10*(5.0 * frac2 - 6.0);
                radprime   = 60.0 * effective_eps * frac10*(1.0 - frac2) / (ia_params->LJANGLE_capradius);
            }

            /* Regroup the last two cases in one */
            /* Propagate all forces in this function rather than in the forces.hpp file */
            if (dist > 0.0) {
                for(j=0; j<3; ++j) {
                    p1->f.f[j] += angular_jik * angular_ikn * rik[j]/l_rik *radprime
                                  + angular_ikn * rad * angular_jik_prime
                                  * ( ( 2*rik[j]-rij[j] )/( l_rij*l_rik )
                                      - cos_jik*( 2*rij[j]/l_rij2 - rik[j]/l_rik2 ) )
                                  + angular_jik * rad * angular_ikn_prime
                                  * ( rkn[j]/( l_rik*l_rkn )
                                      + cos_ikn*rik[j]/l_rik2 );
                    p2->f.f[j] += -angular_jik * angular_ikn * rik[j]/l_rik *radprime
                                  + angular_ikn * rad * angular_jik_prime
                                  * ( rij[j]/( l_rij*l_rik )
                                      - cos_jik*rik[j]/l_rik2 )
                                  + angular_jik * rad * angular_ikn_prime
                                  * ( -(2*rik[j]+rkn[j])/(l_rik*l_rkn)
                                      - cos_ikn*( 2*rkn[j]/l_rkn2 + rik[j]/l_rik2 ) );
                    p3->f.f[j] += angular_ikn * rad * angular_jik_prime
                                  * ( -rik[j]/(l_rij*l_rik)
                                      + cos_jik*rij[j]/l_rij2 );
                    p4->f.f[j] += angular_ikn * rad * angular_jik_prime
                                  * ( -rik[j]/(l_rij*l_rik)
                                      + cos_jik*rij[j]/l_rij2 );
                    p5->f.f[j] += angular_jik * rad * angular_ikn_prime
                                  * ( rik[j]/(l_rik*l_rkn)
                                      + cos_ikn*rkn[j]/l_rkn2 );
                    p6->f.f[j] += angular_jik * rad * angular_ikn_prime
                                  * ( rik[j]/(l_rik*l_rkn)
                                      + cos_ikn*rkn[j]/l_rkn2 );
                }
            }


            /* this should not happen! In this case consider only radial potential*/
            else {
                LJ_TRACE(fprintf(stderr, "%d: LJ-angle warning: Particles id1=%d id2=%d exactly on top of each other\n",this_node,p1->p.identity,p2->p.identity));

                frac2 = SQR(ia_params->LJANGLE_sig/ia_params->LJANGLE_capradius);
                frac10 = frac2*frac2*frac2*frac2*frac2;
                rad   = effective_eps * frac10*(5.0 * frac2 - 6.0) / ia_params->LJANGLE_capradius;

                p1->f.f[0] += rad * ia_params->LJANGLE_capradius;
            }


            ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: LJANGLE   f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist,radprime));
            ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: LJANGLE   f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist,radprime));

            LJ_TRACE(fprintf(stderr,"%d: LJANGLE: Pair (%d-%d) dist=%.3f: force+-: (%.3e,%.3e,%.3e)\n",
                             this_node,p1->p.identity,p2->p.identity,dist,rad*d[0],rad*d[1],rad*d[2]));
        }
示例#23
0
//--------------------------------------------------------------------------------------//
//			Optimized ewald functions for two particle move:
//				Quick and ditry implementation
double Ewald_r_space_doublemove(double** xyz, double *Q, 
		     double *MCcoord, double MCQ, int MCion,double *MCcoord2, double MCQ2, int MCion2)
{ 
  int    t2;
  double dx,dy,dz,r,r2,ar, dpix, dpiy, rpi2,rpi2_2, dx2,dy2,dz2,r2_2;
  double d1,d2,d3=0.0;
  double d3_ci=0;

   //cylinder-ion contributions
	
    for (int l=0;l<Npol;l++)
    {	

	dpix=pxy[l][0]-MCcoord[0]; 
	dpix-=dround(dpix/Ls[0])*Ls[0];
	
	dpiy=pxy[l][1]-MCcoord[1]; 
	dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2=(SQR(dpix)+SQR(dpiy));

	if (rpi2<=rmax2)
   		d3_ci-= MCQ*prefactor*taus[l]*Exponential_Integral_Ei(-SQR(alpha)*(rpi2));


	dpix=pxy[l][0]-MCcoord2[0]; 
	dpix-=dround(dpix/Ls[0])*Ls[0];
	
	dpiy=pxy[l][1]-MCcoord2[1]; 
	dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2_2=(SQR(dpix)+SQR(dpiy));

	if (rpi2_2<=rmax2)
   		d3_ci-= MCQ2*prefactor*taus[l]*Exponential_Integral_Ei(-SQR(alpha)*(rpi2_2));
	
    }
    for (t2 = 0; t2<NP; t2++) {
	//mutual contribution of ions dont have to be counted if we only use the difference
      if ( t2 != MCion && t2!=MCion2 )
	{
	  dx = MCcoord[0] - xyz[t2][0]; dx -= dround(dx/Ls[0])*Ls[0];
	  dy = MCcoord[1] - xyz[t2][1]; dy -= dround(dy/Ls[1])*Ls[1]; 
	  dz = MCcoord[2] - xyz[t2][2]; dz -= dround(dz/Ls[2])*Ls[2];
	  r2 = SQR(dx) + SQR(dy) + SQR(dz);

	  dx2 = MCcoord2[0] - xyz[t2][0]; dx2 -= dround(dx2/Ls[0])*Ls[0];
	  dy2 = MCcoord2[1] - xyz[t2][1]; dy2 -= dround(dy2/Ls[1])*Ls[1]; 
	  dz2 = MCcoord2[2] - xyz[t2][2]; dz2 -= dround(dz2/Ls[2])*Ls[2];
	  r2_2 = SQR(dx2) + SQR(dy2) + SQR(dz2);

	  
	  if (r2 <= rmax2) {

	    ar = alpha * (r = sqrt(r2));
	    d3 += ( d2 = (d1 = MCQ * Q[t2] * prefactor) * erfc(ar) / r );
	    
	  }
	  if (r2_2 <= rmax2) {

	    ar = alpha * (r = sqrt(r2_2));
	    d3 += ( d2 = (d1 = MCQ2 * Q[t2] * prefactor) * erfc(ar) / r );
	    
	  }
	}
	
    }

  return d3+d3_ci;
 //  return d3;	
}
示例#24
0
/** Metadynamics main function:
* - Calculate reaction coordinate
* - Update profile and biased force
* - apply external force
*/
void meta_perform()
{
    if(meta_switch == META_OFF)  return;

    double ppos1[3] = {0,0,0}, ppos2[3] = {0,0,0}, factor;
    int img1[3], img2[3], c, i, np, flag1 = 0, flag2 = 0;
    Particle *p, *p1 = NULL, *p2 = NULL;
    Cell *cell;

    for (c = 0; c < local_cells.n; c++) {
        cell = local_cells.cell[c];
        p  = cell->part;
        np = cell->n;
        for(i = 0; i < np; i++) {
            if (p[i].p.identity == meta_pid1) {
                flag1 = 1;
                p1 = &p[i];
                memcpy(ppos1, p[i].r.p, 3*sizeof(double));
                memcpy(img1, p[i].l.i, 3*sizeof(int));
#ifdef LEES_EDWARDS
                {
                    double pv[3];
                    memcpy(pv, part[i].m.v, 3*sizeof(double));
                    unfold_position(ppos1, pv, img1);
                }
#else
                unfold_position(ppos1, img1);
#endif
                if (flag1 && flag2) {
                    /* vector r2-r1 - Not a minimal image! Unfolded position */
                    vector_subt(meta_cur_xi,ppos2,ppos1);
                    break;
                }
            }
            if (p[i].p.identity == meta_pid2) {
                flag2 = 1;
                p2 = &p[i];
                memcpy(ppos2, p[i].r.p, 3*sizeof(double));
                memcpy(img2, p[i].l.i, 3*sizeof(int));
#ifdef LEES_EDWARDS
                {
                    double pv[3];
                    memcpy(pv, part[i].m.v, 3*sizeof(double));
                    unfold_position(ppos2, pv, img2);
                }
#else
                unfold_position(ppos2, img2);
#endif
                if (flag1 && flag2) {
                    /* vector r2-r1 - Not a minimal image! Unfolded position */
                    vector_subt(meta_cur_xi,ppos2,ppos1);
                    break;
                }
            }
        }
    }

    if (flag1 == 0 || flag2 == 0) {
        ostringstream msg;
        msg <<"Metadynamics: can't find pid1 or pid2.\n";
        runtimeError(msg);
        return;
    }

    /* Now update free energy profile
    * Here, we're following the functional form of
    * Marsili etal., J Comp. Chem, 31 (2009).
    * Instead of gaussians, we use so-called Lucy's functions */

    for (i = 0; i < meta_xi_num_bins; ++i) {
        if (meta_switch == META_DIST) {
            // reaction coordinate value
            meta_val_xi = sqrt(sqrlen(meta_cur_xi));
            // Update free energy profile and biased force
            meta_acc_fprofile[i] -= calculate_lucy(meta_xi_min+i*meta_xi_step,meta_val_xi);
            meta_acc_force[i] -= calculate_deriv_lucy(meta_xi_min+i*meta_xi_step,meta_val_xi);

            // direction of the bias force
            unit_vector(meta_cur_xi,meta_apply_direction);
        } else if (meta_switch == META_REL_Z) {
            // reaction coordinate value: relative height of z_pid1 with respect to z_pid2
            meta_val_xi = -1.*meta_cur_xi[2];
            // Update free energy profile and biased force
            meta_acc_fprofile[i] -= calculate_lucy(meta_xi_min+i*meta_xi_step,meta_val_xi);
            meta_acc_force[i] -= calculate_deriv_lucy(meta_xi_min+i*meta_xi_step,meta_val_xi);

            // direction of the bias force (-1 to be consistent with META_DIST: from 1 to 2)
            meta_apply_direction[0] = meta_apply_direction[1] = 0.;
            meta_apply_direction[2] = -1.;
        } else {
            ostringstream msg;
            msg <<"Undefined metadynamics scheme.\n";
            runtimeError(msg);
            return;
        }
    }

    /** Apply force */

    // Calculate the strength of the applied force
    if (meta_val_xi < meta_xi_min) {
        // below the lower bound
        factor = -1. * meta_f_bound * (meta_xi_min-meta_val_xi)/meta_xi_step;
    } else if (meta_val_xi > meta_xi_max) {
        // above the upper bound
        factor = meta_f_bound * (meta_val_xi-meta_xi_max)/meta_xi_step;
    } else {
        // within the RC interval
        i = (int) dround((meta_val_xi-meta_xi_min)/meta_xi_step);
        if (i < 0) i = 0;
        if (i >= meta_xi_num_bins) i=meta_xi_num_bins-1;
        factor = meta_acc_force[i];
    }

    /* cancel previous force to external force of particle */
    for (i = 0; i<3; ++i) {
        p1->f.f[i] +=       factor * meta_apply_direction[i];
        p2->f.f[i] += -1. * factor * meta_apply_direction[i];
    }
}
示例#25
0
double Ewald_r_space_line(double** xyz, double *Q, 
		     double *Fx, double *Fy, double *Fz)
{
  int    t1,t2;
  double dx,dy,dz,r,r2,ar,ar2, dpix, dpiy;
  double d1,d2,d3=0.0,d4, d3_ci=0, d3_cc=0;
  double rpi2=0;
  static double wupi = 1.77245385090551602729816748334;

  for (t1 = 0; t1 < NP-1; t1++)   /* Quick and Dirty N^2 loop */
  {
 //cylinder-ion contribution
    for (int l=0;l<Npol;l++)
    {	
	dpix=pxy[l][0]-xyz[t1][0]; dpix-=dround(dpix/Ls[0])*Ls[0];
	dpiy=pxy[l][1]-xyz[t1][1]; dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2=(SQR(dpix)+SQR(dpiy));
	//e1(x)=-ei(-x)
	if (rpi2<=rmax2)
   		d3_ci-= Q[t1]*prefactor*taus[l]*Exponential_Integral_Ei(-SQR(alpha)*(rpi2));
	
	
    }
    	

    for (t2 = t1 + 1; t2<NP; t2++) {
      dx = xyz[t1][0] - xyz[t2][0]; dx -= dround(dx/Ls[0])*Ls[0];
      dy = xyz[t1][1] - xyz[t2][1]; dy -= dround(dy/Ls[1])*Ls[1]; 
      dz = xyz[t1][2] - xyz[t2][2]; dz -= dround(dz/Ls[2])*Ls[2];
      r2 = SQR(dx) + SQR(dy) + SQR(dz);
      /*      printf("%d %d %le \n",t1+1,t2+1,sqrt(r2));*/
      /*      printf("%d  %d  %le  %le\n",t1+1,t2+1,r2,rmax2);*/

	if (r2 <= rmax2) {
	  //printf("Forces");
	  ar2 = SQR(ar = alpha * (r = sqrt(r2)));
	  d3 += ( d2 = (d1 = Q[t1] * Q[t2] * prefactor) * erfc(ar) / r );

	  if (Fx||Fy||Fz) {   /* if forces should be computed... */
	    d4  = ( d2 + d1*2.0*alpha*exp(-ar2)/wupi) / r2;
	    
	    Fx[t1] += d4*dx;
	    Fy[t1] += d4*dy;
	    Fz[t1] += d4*dz;
	    Fx[t2] -= d4*dx;
	    Fy[t2] -= d4*dy;
	    Fz[t2] -= d4*dz;
	  }
	}
    }
  }
//final ion, look at the loop indices
t1=NP-1;
  for (int l=0;l<Npol;l++)
    {	
	dpix=pxy[l][0]-xyz[t1][0]; dpix-=dround(dpix/Ls[0])*Ls[0];
	dpiy=pxy[l][1]-xyz[t1][1]; dpiy-=dround(dpiy/Ls[1])*Ls[1];
	rpi2=(SQR(dpix)+SQR(dpiy));
	//e1(x)=-ei(-x)
	if (rpi2<=rmax2)
   		d3_ci-= Q[t1]*prefactor*taus[l]*Exponential_Integral_Ei(-SQR(alpha)*(rpi2));
	
	
    }
//cylinder-cylinder as a function of their separation
//should there be a cutoff here too, think about periodicity, will they always be l/2?

if (Npol==2)
	d3_cc=-prefactor*taus[1]*taus[0]*Ls[2]*Exponential_Integral_Ei(-SQR(alpha)*(SQR(pxy[1][0]-pxy[0][0])+SQR(pxy[1][1]-pxy[0][1])));

printf("real line d3 %lf d3_ci %lf d3_cc %lf\n", d3,d3_ci,d3_cc);
  return d3+d3_ci+d3_cc;
  //return d3;	
}