int parse_id_list(Tcl_Interp* interp, int argc, char** argv, int* change, IntList** ids ) {
  int i,ret;
//  char** temp_argv; int temp_argc;
//  int temp;
  IntList* input=(IntList*)malloc(sizeof(IntList));
  IntList* output=(IntList*)malloc(sizeof(IntList));
  init_intlist(input);
  alloc_intlist(input,1);
  init_intlist(output);
  alloc_intlist(output,1);
  if (argc<1) {
    Tcl_AppendResult(interp, "Error parsing id list\n", (char *)NULL);
    return TCL_ERROR;
  }


  if (ARG0_IS_S("ids")) {
    if (!parse_int_list(interp, argv[1],input)) {
      Tcl_AppendResult(interp, "Error parsing id list\n", (char *)NULL);
      return TCL_ERROR;
    } 
    *ids=input;
    for (i=0; i<input->n; i++) {
      if (input->e[i] >= n_part) {
        Tcl_AppendResult(interp, "Error parsing ID list. Given particle ID exceeds the number of existing particles\n", (char *)NULL);
        return TCL_ERROR;
      }
    }
    *change=2;
    return TCL_OK;

  } else if ( ARG0_IS_S("types") ) {
    if (!parse_int_list(interp, argv[1],input)) {
      Tcl_AppendResult(interp, "Error parsing types list\n", (char *)NULL);
      return TCL_ERROR;
    } 
    if( (ret=convert_types_to_ids(input,output))<=0){
        Tcl_AppendResult(interp, "Error parsing types list. No particle with given types found.\n", (char *)NULL);
        return TCL_ERROR;
    } else { 
      *ids=output;
    }
    *change=2;
    return TCL_OK;
  } else if ( ARG0_IS_S("all") ) {
    if( (ret=convert_types_to_ids(NULL,output))<=0){
        Tcl_AppendResult(interp, "Error parsing keyword all. No particle found.\n", (char *)NULL);
        return TCL_ERROR;
    } else { 
      *ids=output;
    }
    *change=1;
    return TCL_OK;
  }

  Tcl_AppendResult(interp, "unknown keyword given to observable: ", argv[0] , (char *)NULL);
  return TCL_ERROR;
}
Пример #2
0
/** 
    Calculate the center of mass, total mass, velocity, total force, and trap force on all trapped molecules 
*/
void calc_mol_info () {

  /* list of trapped molecules on this node */
  IntList local_trapped_mols;

  /* check to see if all the topology information has been synced to the various slave nodes */
  if ( !topo_part_info_synced ) {
    char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE);
    ERROR_SPRINTF(errtxt, "{ 093 can't calculate molforces: must execute analyse set topo_part_sync first }");
    return;
  }

  init_intlist(&local_trapped_mols);

  /* Find out which trapped molecules are on this node */
  get_local_trapped_mols(&local_trapped_mols);

  /* Calculate the center of mass, mass, velocity, force of whatever fraction of each trapped molecule is on this node*/
  calc_local_mol_info(&local_trapped_mols);

  /* Communicate all this molecular information between nodes.
     It is all sent to the master node which combines it, calculates the trap forces,
     and sends the information back */
  if (this_node == 0) { 
    mpi_comm_mol_info(&local_trapped_mols);
  } else {
    mpi_comm_mol_info_slave(&local_trapped_mols);
  }

  realloc_intlist(&local_trapped_mols,0);
}
Пример #3
0
void realloc_topology(int size)
{
  int m;

  for(m = size ; m < n_molecules; m++) {
    realloc_intlist(&topology[m].part, 0);
  }
  
  topology = (Molecule*)Utils::realloc(topology, size*sizeof(Molecule));

  if (n_molecules < 0)
    n_molecules = 0;
  for(m = n_molecules; m < size; m++) {
    init_intlist(&topology[m].part);
#ifdef MOLFORCES
    topology[m].trap_flag = 32; 
    topology[m].noforce_flag = 32;
    topology[m].favcounter = -1;
    topology[m].fav[0] = 0;
    topology[m].fav[1] = 0;
    topology[m].fav[2] = 0;
    topology[m].trap_force[0] = 0;
    topology[m].trap_force[1] = 0;
    topology[m].trap_force[2] = 0;
#endif /*MOLFORCES*/
  }
  n_molecules = size;
  
  topo_part_info_synced = 0;

}
Пример #4
0
void nbhood(double pt[3], double r, IntList *il, int planedims[3] )
{
  double d[3];
  int i,j;
  double r2;

  r2 = r*r;

  init_intlist(il);
 
  updatePartCfg(WITHOUT_BONDS);

  for (i = 0; i<n_part; i++) {
    if ( (planedims[0] + planedims[1] + planedims[2]) == 3 ) {
      get_mi_vector(d, pt, partCfg[i].r.p);
    } else {
      /* Calculate the in plane distance */
      for ( j= 0 ; j < 3 ; j++ ) {
	d[j] = planedims[j]*(partCfg[i].r.p[j]-pt[j]);
      }
    }

    if (sqrlen(d) < r2) {
      realloc_intlist(il, il->n + 1);
      il->e[il->n] = partCfg[i].p.identity;
      il->n++;
    }
  }
}
Пример #5
0
void wall_sort_particles()
{
  // 1. reallocate the boxes for the particle identities
  // save current number of bins
  int n_part_in_bin = wallstuff_boundaries.n-1;
  // free old boxes
  for (int i = 0; i < n_part_in_bin; ++i) {
    realloc_intlist(&wallstuff_part_in_bin[i], wallstuff_part_in_bin[i].n = 0);
  }
  wallstuff_part_in_bin = (IntList*)realloc(wallstuff_part_in_bin, 
                                            (wallstuff_boundaries.n-1)*sizeof(IntList));
  // initialize new ones
  for (int i = n_part_in_bin; i < wallstuff_boundaries.n-1; ++i) {
    init_intlist(&wallstuff_part_in_bin[i]);
  }

  // 2. for each particle, find the box and put its
  // identity there
  for(int i=0; i<n_part; i++) {
    double x = partCfg[i].r.p[0];
    // ignore particles outside the wallstuff_boundaries
    if (x < wallstuff_boundaries.e[0] || x > wallstuff_boundaries.e[wallstuff_boundaries.n-1])
      continue;
    // simple bisection on the particle's x-coordinate
    int s = 0;
    int e = wallstuff_boundaries.n - 1;
    while (e - s > 1) {
      int c = (e + s)/2;
      if (x >= wallstuff_boundaries.e[c]) s = c; else e = c;
    }
    // and add the particle to the resulting list
    realloc_grained_intlist(&wallstuff_part_in_bin[s], wallstuff_part_in_bin[s].n + 1, 8);
    wallstuff_part_in_bin[s].e[wallstuff_part_in_bin[s].n++] = i;
  }
}
Пример #6
0
double calc_vanhove(int ptype, double rmin, double rmax, int rbins, int tmax, double *msd, double **vanhove) 
{
  int i, c1, c3, c3_max, ind, np=0;
  double p1[3],p2[3],dist;
  double bin_width, inv_bin_width;
  IntList p;

  /* create particle list */
  init_intlist(&p);
  for(i=0; i<n_part; i++) { if( partCfg[i].p.type == ptype ) { np ++; } }
  if(np==0) { return 0; }
  alloc_intlist(&p,np);
  for(i=0; i<n_part; i++) { if( partCfg[i].p.type == ptype ) { p.e[p.n]=i; p.n++; } }

  /* preparation */
  bin_width     = (rmax-rmin) / (double)rbins;
  inv_bin_width = 1.0 / bin_width;
 
  /* calculate msd and store distribution in vanhove */
  for(c1=0; c1<n_configs; c1++) { 
    c3_max=(c1+tmax+1)>n_configs ? n_configs : c1+tmax+1;
    for(c3=(c1+1); c3<c3_max; c3++) { 
      for(i=0; i<p.n; i++) {
	p1[0]=configs[c1][3*p.e[i] ]; p1[1]=configs[c1][3*p.e[i]+1]; p1[2]=configs[c1][3*p.e[i]+2];
	p2[0]=configs[c3][3*p.e[i]  ]; p2[1]=configs[c3][3*p.e[i]+1]; p2[2]=configs[c3][3*p.e[i]+2];
	dist = distance(p1, p2);
	if(dist > rmin && dist < rmax) {
	  ind = (int) ( (dist - rmin)*inv_bin_width );
	  vanhove[(c3-c1-1)][ind]++;
	}
	msd[(c3-c1-1)] += dist*dist;
      }
    }
  }

  /* normalize */
  for(c1=0; c1<(tmax); c1++) { 
    for(i=0; i<rbins; i++) { vanhove[c1][i] /= (double) (n_configs-c1-1)*p.n; }
    msd[c1] /= (double) (n_configs-c1-1)*p.n;
  }

  realloc_intlist(&p,0);
  return np;
}
Пример #7
0
void send_particles(ParticleList *particles, int node)
{
  int pc;
  /* Dynamic data, bonds and exclusions */
  IntList local_dyn;

  PART_TRACE(fprintf(stderr, "%d: send_particles %d to %d\n", this_node, particles->n, node));

  MPI_Send(&particles->n, 1, MPI_INT, node, REQ_SNDRCV_PART, comm_cart);
  MPI_Send(particles->part, particles->n*sizeof(Particle),
	   MPI_BYTE, node, REQ_SNDRCV_PART, comm_cart);

  init_intlist(&local_dyn);
  for (pc = 0; pc < particles->n; pc++) {
    Particle *p = &particles->part[pc];
    int size =  local_dyn.n + p->bl.n;
#ifdef EXCLUSIONS
    size += p->el.n;
#endif
    realloc_intlist(&local_dyn, size);
    memcpy(local_dyn.e + local_dyn.n, p->bl.e, p->bl.n*sizeof(int));
    local_dyn.n += p->bl.n;
#ifdef EXCLUSIONS
    memcpy(local_dyn.e + local_dyn.n, p->el.e, p->el.n*sizeof(int));
    local_dyn.n += p->el.n;
#endif
  }

  PART_TRACE(fprintf(stderr, "%d: send_particles sending %d bond ints\n", this_node, local_dyn.n));
  if (local_dyn.n > 0) {
    MPI_Send(local_dyn.e, local_dyn.n*sizeof(int),
	     MPI_BYTE, node, REQ_SNDRCV_PART, comm_cart);
    realloc_intlist(&local_dyn, 0);
  }

  /* remove particles from this nodes local list and free data */
  for (pc = 0; pc < particles->n; pc++) {
    local_particles[particles->part[pc].p.identity] = NULL;
    free_particle(&particles->part[pc]);
  }

  realloc_particlelist(particles, particles->n = 0);
}
int parse_generic_structure_info(Tcl_Interp *interp, int argc, char **argv)
{
  int arg;
  IntList il;
  init_intlist(&il);

  realloc_topology(argc);
  
  for (arg = 0; arg < argc; arg++) {
    if (!ARG_IS_INTLIST(arg, il)) {
      realloc_topology(0);
      realloc_intlist(&il, 0);
      return TCL_ERROR;
    }
    topology[arg].type = il.e[0];
    realloc_intlist(&topology[arg].part, topology[arg].part.n = il.n - 1);
    memcpy(topology[arg].part.e, &il.e[1], (il.n - 1)*sizeof(int));
  }
  realloc_intlist(&il, 0);

  return TCL_OK;
}
Пример #9
0
int tclcommand_analyze_parse_generic_structure(Tcl_Interp *interp, int argc, char **argv)
{
  int arg;
  IntList il;
  init_intlist(&il);

  realloc_topology(argc);
  
  for (arg = 0; arg < argc; arg++) {
    if (!ARG_IS_INTLIST(arg, il)) {
      realloc_topology(0);
      realloc_intlist(&il, 0);
      return TCL_ERROR;
    }
    topology[arg].type = il.e[0];
    realloc_intlist(&topology[arg].part, topology[arg].part.n = il.n - 1);
    memmove(topology[arg].part.e, &il.e[1], (il.n - 1)*sizeof(int));
  }
  realloc_intlist(&il, 0);
  
  
  return tclcommand_analyze_set_parse_topo_part_sync(interp);
}
Пример #10
0
int tclcommand_analyze_set_parse_trapmol(Tcl_Interp *interp, int argc, char **argv)
{

#ifdef MOLFORCES
#ifdef EXTERNAL_FORCES
  int trap_flag = 0;
  int noforce_flag =0;
  int i;
#endif
#endif
  int mol_num;
  double spring_constant;
  double drag_constant;
  int isrelative;
  DoubleList trap_center;
  IntList trap_coords;
  IntList noforce_coords;
  char usage[] = "trapmol usage: <mol_id> { <xpos> <ypos> <zpos> } <isrelative> <spring_constant> <drag_constant> coords   { <trapped_coord> <trapped_coord> <trapped_coord> } noforce_coords {<noforce_coord> <noforce_coord> <noforce_coord>}";

  init_doublelist(&trap_center);
  init_intlist(&trap_coords);
  alloc_intlist(&trap_coords,3);
  init_intlist(&noforce_coords);
  alloc_intlist(&noforce_coords,3);
  /* Unless coords are specified the default is just to trap it completely */
  trap_coords.e[0] = 1;
  trap_coords.e[1] = 1;
  trap_coords.e[2] = 1;

  Tcl_ResetResult(interp);
  /* The first argument should be a molecule number */
  if (!ARG0_IS_I(mol_num)) {
    Tcl_AppendResult(interp, "first argument should be a molecule id", (char *)NULL);
    Tcl_AppendResult(interp, usage, (char *)NULL); 
    return TCL_ERROR;
  } else {
    /* Sanity checks */
    if (mol_num > n_molecules) {
      Tcl_AppendResult(interp, "trapmol: cannot trap mol %d because it does not exist",mol_num , (char *)NULL);
    return TCL_ERROR;
    }
    argc--;
    argv++;
  }

  /* The next argument should be a double list specifying the trap center */
  if (!ARG0_IS_DOUBLELIST(trap_center)) {
    Tcl_AppendResult(interp, "second argument should be a double list", (char *)NULL);
    Tcl_AppendResult(interp, usage , (char *)NULL);
    return TCL_ERROR;
  } else {
    argc -= 1;
    argv += 1;
  }

  /* The next argument should be an integer specifying whether the trap is relative (fraction of box_l) or absolute */
  if (!ARG0_IS_I(isrelative)) {
    Tcl_AppendResult(interp, "third argument should be an integer", (char *)NULL);
    Tcl_AppendResult(interp, usage, (char *)NULL);
    return TCL_ERROR;
  } else {
    argc -= 1;
    argv += 1;
  }

  /* The next argument should be the spring constant for the trap */
  if (!ARG0_IS_D(spring_constant)) {
    Tcl_AppendResult(interp, "fourth argument should be a double", (char *)NULL);
    Tcl_AppendResult(interp, usage, (char *)NULL);
    return TCL_ERROR;
  } else {
    argc -= 1;
    argv += 1;
  }

  /* The next argument should be the drag constant for the trap */
  if (!ARG0_IS_D(drag_constant)) {
    Tcl_AppendResult(interp, "fifth argument should be a double", (char *)NULL);
    Tcl_AppendResult(interp, usage, (char *)NULL);
    return TCL_ERROR;
  } else {
    argc -= 1;
    argv += 1;
  }

  /* Process optional arguments */
  while ( argc > 0 ) {    
    if ( ARG0_IS_S("coords") ) {
      if ( !ARG_IS_INTLIST(1,trap_coords) ) {
	Tcl_AppendResult(interp, "an intlist is required to specify coords", (char *)NULL);
	Tcl_AppendResult(interp, usage, (char *)NULL);
	return TCL_ERROR;
      }
      argc -= 2;
      argv += 2;
    } else if ( ARG0_IS_S("noforce_coords")) {
      if ( !ARG_IS_INTLIST(1,noforce_coords) ) {
	Tcl_AppendResult(interp, "an intlist is required to specify coords", (char *)NULL);
	Tcl_AppendResult(interp, usage, (char *)NULL);
	return TCL_ERROR;
      }
      argc -= 2;
      argv += 2;
    } else {
      Tcl_AppendResult(interp, "an option is not recognised", (char *)NULL);
      Tcl_AppendResult(interp, usage, (char *)NULL);
      return TCL_ERROR;
    }      
  }

#ifdef MOLFORCES 
#ifdef EXTERNAL_FORCES 
  for (i = 0; i < 3; i++) {
    if (trap_coords.e[i])
      trap_flag |= COORD_FIXED(i);
  
    if (noforce_coords.e[i])
      noforce_flag |= COORD_FIXED(i);
  }
  if (set_molecule_trap(mol_num, trap_flag,&trap_center,spring_constant, drag_constant, noforce_flag, isrelative) == TCL_ERROR) {
    Tcl_AppendResult(interp, "set topology first", (char *)NULL);
    return TCL_ERROR;
  }
#else
    Tcl_AppendResult(interp, "Error: EXTERNAL_FORCES not defined ", (char *)NULL);
    return TCL_ERROR;
#endif
#endif

  realloc_doublelist(&trap_center,0);
  realloc_intlist(&trap_coords,0);
  realloc_intlist(&noforce_coords,0);
  return tclcommand_analyze_set_parse_topo_part_sync(interp);
  
}
Пример #11
0
int tclcommand_inter_coulomb_parse_ewaldgpu(Tcl_Interp * interp, int argc, char ** argv)
{
	double r_cut;
	int num_kx;
	int num_ky;
	int num_kz;
	double accuracy;
	double alpha=-1;
	IntList il;
	init_intlist(&il);

  if (argc < 1)
  {
  	Tcl_AppendResult(interp, "expected: inter coulomb <bjerrum> ewaldgpu <r_cut> (<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) <alpha> \nexpected: inter coulomb <bjerrum> ewaldgpu tune <accuracy> [<precision>] \nexpected: inter coulomb <bjerrum> ewaldgpu tunealpha <r_cut> <K_cut> [<precision>]",(char *) NULL);
    return TCL_ERROR;
  }

  if (ARG0_IS_S("tune"))
  {
    int status = tclcommand_inter_coulomb_parse_ewaldgpu_tune(interp, argc-1, argv+1, 0);
    if(status==TCL_OK) return TCL_OK;
    if(status==TCL_ERROR)
    {
    	Tcl_AppendResult(interp, "Accuracy could not been reached. Choose higher K_max or lower accuracy",(char *) NULL);
    	    return TCL_ERROR;
    }

  }

  if (ARG0_IS_S("tunealpha"))
    return tclcommand_inter_coulomb_parse_ewaldgpu_tunealpha(interp, argc-1, argv+1);

  if(! ARG0_IS_D(r_cut))
    return TCL_ERROR;

  if(argc < 3 || argc > 5) {
  	Tcl_AppendResult(interp, "expected: inter coulomb <bjerrum> ewaldgpu <r_cut> (<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) <alpha> \nexpected: inter coulomb <bjerrum> ewaldgpu tune <accuracy> [<precision>] \nexpected: inter coulomb <bjerrum> ewaldgpu tunealpha <r_cut> <K_cut> [<precision>]",(char *) NULL);
    return TCL_ERROR;
  }

  if(! ARG_IS_I(1, num_kx))
  {
    if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) )
    {
      Tcl_AppendResult(interp, "integer or interger list of length 3 expected", (char *) NULL);
      return TCL_ERROR;
    }
    else
    {
      num_kx = il.e[0];
      num_ky = il.e[1];
      num_kz = il.e[2];
    }
  }
  else
  {
  	num_kz = num_ky = num_kx;
  }

  if(argc > 2)
  {
    if(! ARG_IS_D(2, alpha))
      return TCL_ERROR;
  }
  else
  {
    Tcl_AppendResult(interp, "Automatic ewaldgpu tuning not implemented.",
		     (char *) NULL);
    return TCL_ERROR;
  }

  if(argc > 3)
  {
    if(! ARG_IS_D(3, accuracy))
    {
      Tcl_AppendResult(interp, "accuracy double expected", (char *) NULL);
      return TCL_ERROR;
    }
  }

  // Create object
  EwaldgpuForce *A=new EwaldgpuForce(r_cut, num_kx, num_ky, num_kz, alpha);
  FI.addMethod(A);
  rebuild_verletlist = 1;
  ewaldgpu_params.ewaldgpu_is_running = true;
  ewaldgpu_params.isTuned = true;
	mpi_bcast_coulomb_params();
	mpi_bcast_event(INVALIDATE_SYSTEM);
  return TCL_OK;
}
Пример #12
0
int tclcommand_inter_coulomb_parse_ewaldgpu_tunealpha(Tcl_Interp * interp, int argc, char ** argv)
{
	double r_cut;
	double alpha;
	int num_kx;
	int num_ky;
	int num_kz;
	double precision=0.000001;

	IntList il;
	init_intlist(&il);

  if (argc < 3)
  {
    Tcl_AppendResult(interp, "wrong # arguments: <r_cut> <K_cut,x> <K_cut,y><K_cut,z> [<precision>]  ", (char *) NULL);
    return TCL_ERROR;
  }

  /* PARSE EWALD COMMAND LINE */
  /* epsilon */
  if (! ARG_IS_D(0, r_cut))
  {
    Tcl_AppendResult(interp, "<r_cut> should be a double",(char *) NULL);
  }
  /* k_cut */
  if(! ARG_IS_I(1, num_kx))
  {
    if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) )
    {
      Tcl_AppendResult(interp, "integer or integer list of length 3 expected", (char *) NULL);
      return TCL_ERROR;
    }
    else
    {
      num_kx = il.e[0];
      num_ky = il.e[1];
      num_kz = il.e[2];
    }
  }
  else
  {
  	num_kz = num_ky = num_kx;
  }
  /* precision */
  if (! ARG_IS_D(2, precision))
  {
    Tcl_AppendResult(interp, "<precision> should be a double",
		     (char *) NULL);
    return 0;
  }
  //Compute alpha
  double q_sqr = ewaldgpu_compute_q_sqare();
  alpha = ewaldgpu_compute_optimal_alpha(r_cut, num_kx, num_ky, num_kz, q_sqr, box_l, precision);
  ewaldgpu_params.isTuned = true;
  mpi_bcast_coulomb_params();
  mpi_bcast_event(INVALIDATE_SYSTEM);
  // Create object
  EwaldgpuForce *A=new EwaldgpuForce(r_cut, num_kx, num_ky, num_kz, alpha);
  FI.addMethod(A);
  rebuild_verletlist = 1;

  return TCL_OK;
}
Пример #13
0
int tclcommand_inter_coulomb_parse_ewaldgpu_notune(Tcl_Interp * interp, int argc, char ** argv)
{
	double r_cut=-1;
	int num_kx=-1;
	int num_ky=-1;
	int num_kz=-1;
	double alpha=-1;
	IntList il;
	init_intlist(&il);

	if(argc < 3 || argc > 5) {
		Tcl_AppendResult(interp, "\nExpected: inter coulomb <bjerrum> ewaldgpu <r_cut> (<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) <alpha>",(char *) NULL);
		return TCL_ERROR;
	}
	if(! ARG_IS_D(0,r_cut))
	{
		Tcl_AppendResult(interp, "\n<r_cut> double expected", (char *) NULL);
		return TCL_ERROR;
	}
	if(! ARG_IS_I(1, num_kx))
	{
		if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) )
		{
			Tcl_AppendResult(interp, "\n(<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) integer or integer list of length 3 expected", (char *) NULL);
			return TCL_ERROR;
		}
		else
		{
			num_kx = il.e[0];
			num_ky = il.e[1];
			num_kz = il.e[2];
		}
	}
	else
	{
		num_kz = num_ky = num_kx;
	}
	if(argc > 2)
	{
		if(! ARG_IS_D(2, alpha))
		{
			Tcl_AppendResult(interp, "\n<alpha> double expected", (char *) NULL);
			return TCL_ERROR;
		}
	}
	else
	{
		Tcl_AppendResult(interp, "\nAutomatic ewaldgpu tuning not implemented.",
				 (char *) NULL);
		return TCL_ERROR;
	}

	//Turn on ewaldgpu
	if (!ewaldgpuForce) // inter coulomb ewaldgpu was never called before
	{
		ewaldgpuForce = new EwaldgpuForce(espressoSystemInterface, r_cut, num_kx, num_ky, num_kz, alpha);
		forceActors.add(ewaldgpuForce);
		energyActors.add(ewaldgpuForce);
	}
	//Broadcast parameters
	ewaldgpuForce->set_params(r_cut, num_kx, num_ky, num_kz, alpha);
	coulomb.method = COULOMB_EWALD_GPU;
	ewaldgpu_params.isTunedFlag = false;
	ewaldgpu_params.isTuned = true;
	rebuild_verletlist = 1;
	mpi_bcast_coulomb_params();
	return TCL_OK;
}
Пример #14
0
int tclcommand_inter_coulomb_parse_p3m(Tcl_Interp * interp, int argc, char ** argv)
{
  double r_cut, alpha, accuracy = -1.0;
  int mesh[3], cao, i;
  IntList il;
  init_intlist(&il);

  if (argc < 1) {
    Tcl_AppendResult(interp, "expected: inter coulomb <bjerrum> p3m tune | [gpu] <r_cut> { <mesh> | \\{ <mesh_x> <mesh_y> <mesh_z> \\} } <cao> [<alpha> [<accuracy>]]",
		     (char *) NULL);
    return TCL_ERROR;  
  }

  if (ARG0_IS_S("gpu")) {
    coulomb.method = COULOMB_P3M_GPU;
    
    argc--;
    argv++;
  }

  if (ARG0_IS_S("tune"))
    return tclcommand_inter_coulomb_parse_p3m_tune(interp, argc-1, argv+1, 0);

  if (ARG0_IS_S("tunev2"))
    return tclcommand_inter_coulomb_parse_p3m_tune(interp, argc-1, argv+1, 1);
      
  if(! ARG0_IS_D(r_cut))
    return TCL_ERROR;  

  if(argc < 3 || argc > 5) {
    Tcl_AppendResult(interp, "wrong # arguments: inter coulomb <bjerrum> p3m [gpu] <r_cut> { <mesh> | \\{ <mesh_x> <mesh_y> <mesh_z> \\} } <cao> [<alpha> [<accuracy>]]",
		     (char *) NULL);
    return TCL_ERROR;
  }

  if(! ARG_IS_I(1, mesh[0])) {
    Tcl_ResetResult(interp);
    if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) ) {
      Tcl_AppendResult(interp, "integer or integer list of length 3 expected", (char *) NULL);
      return TCL_ERROR;
    } else {
      mesh[0] = il.e[0];
      mesh[1] = il.e[1];
      mesh[2] = il.e[2];
    }
  } else {
    mesh[1] = mesh[2] = mesh[0];
  }
  if ( mesh[0]%2 != 0 || mesh[1]%2 != 0 || mesh[2]%2 != 0 ) {
    Tcl_AppendResult(interp, "P3M requires an even number of mesh points in all directions", (char *) NULL);
    return TCL_ERROR;
  }
  
  if(! ARG_IS_I(2, cao)) {
    Tcl_AppendResult(interp, "integer expected", (char *) NULL);
    return TCL_ERROR;
  }
	
  if(argc > 3) {
    if(! ARG_IS_D(3, alpha))
      return TCL_ERROR;
  }
  else {
    Tcl_AppendResult(interp, "Automatic p3m tuning not implemented.",
		     (char *) NULL);
    return TCL_ERROR;  
  }

  if(argc > 4) {
    if(! ARG_IS_D(4, accuracy)) {
      Tcl_AppendResult(interp, "double expected", (char *) NULL);
      return TCL_ERROR;
    }
  }

  if ((i = p3m_set_params(r_cut, mesh, cao, alpha, accuracy)) < 0) {
    switch (i) {
    case -1:
      Tcl_AppendResult(interp, "r_cut must be positive", (char *) NULL);
      break;
    case -2:
      Tcl_AppendResult(interp, "mesh must be positive", (char *) NULL);
      break;
    case -3:
      Tcl_AppendResult(interp, "cao must be between 1 and 7 and less than mesh",
		       (char *) NULL);
      break;
    case -4:
      Tcl_AppendResult(interp, "alpha must be positive", (char *) NULL);
      break;
    case -5:
      Tcl_AppendResult(interp, "accuracy must be positive", (char *) NULL);
      break;
    default:;
      Tcl_AppendResult(interp, "unspecified error", (char *) NULL);
    }

    return TCL_ERROR;
  }

  return TCL_OK;
}
Пример #15
0
/**
   This routine calculates the orientational order parameter for a
   lipid bilayer.  
*/
int orient_order(double* result, double* stored_dirs)
{
  double dir[3];
  double refdir[3] = {0,0,1};
  double sumdir[3] = {0,0,0};
  double zref;
  int bilayer_cnt;
  int i,atom,tmpzdir;
  double dp;
  double len;

  IntList l_orient;
  init_intlist(&l_orient);
  realloc_intlist(&l_orient, n_molecules);

  bilayer_cnt = 0;
  *result = 0;


  // Check to see if the grid has been set and if not then interpret
  if ( xdir + ydir + zdir == -3 ) {
    tmpzdir = 2;
  } else { 
    tmpzdir = zdir;
  };

  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);
  /* Make sure particles are sorted */
  if (!sortPartCfg()) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt, "{035 could not sort partCfg, particles have to start at 0 and have consecutive identities} ");
    return ES_ERROR;
  }

  /* Calculate the reference z position as its mean.*/
  zref = calc_zref( tmpzdir );
 

  /* Calculate the orientation of all the lipids in turn and include
   only UP or DOWN lipids in a calculation of the overall orientation
   direction of the bilayer .. ie the reference vector from which we
   can calculate the orientational order. */

  for ( i = 0 ; i < n_molecules ; i++) {
    atom = topology[i].part.e[0];
    l_orient.e[i] = lipid_orientation(atom,partCfg,zref,dir,refdir);
    stored_dirs[i*3] = dir[0];
    stored_dirs[i*3+1] = dir[1];
    stored_dirs[i*3+2] = dir[2];

    if ( l_orient.e[i] == LIPID_UP ) {
      sumdir[0] += dir[0];
      sumdir[1] += dir[1];
      sumdir[2] += dir[2];
      bilayer_cnt++;
    }
    if ( l_orient.e[i] == LIPID_DOWN ) {
      sumdir[0] -= dir[0];
      sumdir[1] -= dir[1];
      sumdir[2] -= dir[2];
      bilayer_cnt++;
    }
  }

  /* Normalise the bilayer normal vector */
  len = 0.0;
  for ( i = 0 ; i < 3 ; i++) {
    sumdir[i] = sumdir[i]/(double)(bilayer_cnt);
    len += sumdir[i]*sumdir[i];
  }
  for ( i = 0 ; i < 3 ; i++) {
    sumdir[i] = sumdir[i]/sqrt(len);
  }

  /* Calculate the orientational order */
  for ( i = 0 ; i < n_molecules ; i++ ) {
    dir[0] = stored_dirs[i*3];
    dir[1] = stored_dirs[i*3+1];
    dir[2] = stored_dirs[i*3+2];

    if ( l_orient.e[i] != LIPID_STRAY && l_orient.e[i] != REAL_LIPID_STRAY ) {
      dp = scalar(dir,sumdir);
      *result += dp*dp*1.5-0.5;      
    }

  }

  
  realloc_intlist(&l_orient, 0);

  *result = *result/(double)(bilayer_cnt);
  return ES_OK;
}
Пример #16
0
void auto_exclusion(int distance)
{
  int count, p, i, j, p1, p2, p3, dist1, dist2;
  Bonded_ia_parameters *ia_params;
  Particle *part1;
  /* partners is a list containing the currently found excluded particles for each particle,
     and their distance, as a interleaved list */
  IntList *partners;

  updatePartCfg(WITH_BONDS);

  /* setup bond partners and distance list. Since we need to identify particles via their identity,
     we use a full sized array */
  partners    = (IntList*)malloc((max_seen_particle + 1)*sizeof(IntList));
  for (p = 0; p <= max_seen_particle; p++)
    init_intlist(&partners[p]);

  /* determine initial connectivity */
  for (p = 0; p < n_part; p++) {
    part1 = &partCfg[p];
    p1    = part1->p.identity;
    for (i = 0; i < part1->bl.n;) {
      ia_params = &bonded_ia_params[part1->bl.e[i++]];
      if (ia_params->num == 1) {
	p2 = part1->bl.e[i++];
	/* you never know what the user does, may bond a particle to itself...? */
	if (p2 != p1) {
	  add_partner(&partners[p1], p1, p2, 1);
	  add_partner(&partners[p2], p2, p1, 1);
	}
      }
      else
	i += ia_params->num;
    }
  }

  /* calculate transient connectivity. For each of the current neighbors,
     also exclude their close enough neighbors.
  */
  for (count = 1; count < distance; count++) {
    for (p1 = 0; p1 <= max_seen_particle; p1++) {
      for (i = 0; i < partners[p1].n; i += 2) {
	p2 = partners[p1].e[i];
	dist1 = partners[p1].e[i + 1];
	if (dist1 > distance) continue;
	/* loop over all partners of the partner */
	for (j = 0; j < partners[p2].n; j += 2) {
	  p3 = partners[p2].e[j];
	  dist2 = dist1 + partners[p2].e[j + 1];
	  if (dist2 > distance) continue;
	  add_partner(&partners[p1], p1, p3, dist2);
	  add_partner(&partners[p3], p3, p1, dist2);
	}
      }
    }
  }

  /* setup the exclusions and clear the arrays. We do not setup the exclusions up there,
     since on_part_change clears the partCfg, so that we would have to restore it
     continously. Of course this could be optimized by bundling the exclusions, but this
     is only done once and the overhead is as much as for setting the bonds, which
     the user apparently accepted.
  */
  for (p = 0; p <= max_seen_particle; p++) {
    for (j = 0; j < partners[p].n; j++)
      if (p < partners[p].e[j]) change_exclusion(p, partners[p].e[j], 0);
    realloc_intlist(&partners[p], 0);
  }
  free(partners);
}
Пример #17
0
void recv_particles(ParticleList *particles, int node)
{
  int transfer=0, read, pc;
  IntList local_dyn;

  PART_TRACE(fprintf(stderr, "%d: recv_particles from %d\n", this_node, node));

  MPI_Recv(&transfer, 1, MPI_INT, node,
	   REQ_SNDRCV_PART, comm_cart, MPI_STATUS_IGNORE);

  PART_TRACE(fprintf(stderr, "%d: recv_particles get %d\n", this_node, transfer));

  realloc_particlelist(particles, particles->n + transfer);
  MPI_Recv(&particles->part[particles->n], transfer*sizeof(Particle), MPI_BYTE, node,
	   REQ_SNDRCV_PART, comm_cart, MPI_STATUS_IGNORE);
  particles->n += transfer;

  init_intlist(&local_dyn);
  for (pc = particles->n - transfer; pc < particles->n; pc++) {
    Particle *p = &particles->part[pc];
    local_dyn.n += p->bl.n;
#ifdef EXCLUSIONS
    local_dyn.n += p->el.n;
#endif

    PART_TRACE(fprintf(stderr, "%d: recv_particles got particle %d\n", this_node, p->p.identity));
    if (local_particles[p->p.identity] != NULL) {
      fprintf(stderr, "%d: transmitted particle %d is already here...\n", this_node, p->p.identity);
      errexit();
    }
  }

  update_local_particles(particles);

  PART_TRACE(fprintf(stderr, "%d: recv_particles expecting %d bond ints\n", this_node, local_dyn.n));
  if (local_dyn.n > 0) {
    alloc_intlist(&local_dyn, local_dyn.n);
    MPI_Recv(local_dyn.e, local_dyn.n*sizeof(int), MPI_BYTE, node,
	     REQ_SNDRCV_PART, comm_cart, MPI_STATUS_IGNORE);
  }
  read = 0;
  for (pc = particles->n - transfer; pc < particles->n; pc++) {
    Particle *p = &particles->part[pc];
    if (p->bl.n > 0) {
      alloc_intlist(&p->bl, p->bl.n);
      memcpy(p->bl.e, &local_dyn.e[read], p->bl.n*sizeof(int));
      read += p->bl.n;
    }
    else
      p->bl.e = NULL;
#ifdef EXCLUSIONS
    if (p->el.n > 0) {
      alloc_intlist(&p->el, p->el.n);
      memcpy(p->el.e, &local_dyn.e[read], p->el.n*sizeof(int));
      read += p->el.n;
    }
    else
      p->el.e = NULL;
#endif
  }
  if (local_dyn.n > 0)
    realloc_intlist(&local_dyn, 0);
}
Пример #18
0
void init_particle(Particle *part)
{
  /* ParticleProperties */
  part->p.identity = -1;
  part->p.type     = 0;
  part->p.mol_id   = -1;

#ifdef MASS
  part->p.mass     = 1.0;
#endif

#ifdef SHANCHEN
  int ii;
  for(ii=0;ii<2*LB_COMPONENTS;ii++){ 
    part->p.solvation[ii]=0.0;
  }
  for(ii=0;ii<LB_COMPONENTS;ii++){ 
    part->r.composition[ii]=0.0;
  }
#endif

#ifdef ROTATIONAL_INERTIA
  part->p.rinertia[0] = 1.0;
  part->p.rinertia[1] = 1.0;
  part->p.rinertia[2] = 1.0;
#endif
#ifdef ROTATION_PER_PARTICLE
  part->p.rotation =1;
#endif


#ifdef ELECTROSTATICS
  part->p.q        = 0.0;
#endif

#ifdef LB_ELECTROHYDRODYNAMICS
  part->p.mu_E[0]   = 0.0;
  part->p.mu_E[1]   = 0.0;
  part->p.mu_E[2]   = 0.0;
#endif

#ifdef CATALYTIC_REACTIONS
  part->p.catalyzer_count = 0;
#endif

  /* ParticlePosition */
  part->r.p[0]     = 0.0;
  part->r.p[1]     = 0.0;
  part->r.p[2]     = 0.0;

#ifdef BOND_CONSTRAINT
  part->r.p_old[0] = 0.0;
  part->r.p_old[1] = 0.0;
  part->r.p_old[2] = 0.0;
#endif

#ifdef ROTATION
  part->r.quat[0]  = 1.0;
  part->r.quat[1]  = 0.0;
  part->r.quat[2]  = 0.0;
  part->r.quat[3]  = 0.0;

  part->r.quatu[0]  = 0.0;
  part->r.quatu[1]  = 0.0;
  part->r.quatu[2]  = 1.0;
#endif

#ifdef DIPOLES
  part->r.dip[0]    = 0.0;
  part->r.dip[1]    = 0.0;
  part->r.dip[2]    = 0.0;
  part->p.dipm      = 0.0;
#endif

  /* ParticleMomentum */
  part->m.v[0]     = 0.0;
  part->m.v[1]     = 0.0;
  part->m.v[2]     = 0.0;
#ifdef ROTATION
  part->m.omega[0] = 0.0;
  part->m.omega[1] = 0.0;
  part->m.omega[2] = 0.0;
#endif

  /* ParticleForce */
  part->f.f[0]     = 0.0;
  part->f.f[1]     = 0.0;
  part->f.f[2]     = 0.0;
#ifdef ROTATION
  part->f.torque[0] = 0.0;
  part->f.torque[1] = 0.0;
  part->f.torque[2] = 0.0;
#endif

  /* ParticleLocal */
  part->l.p_old[0]   = 0.0;
  part->l.p_old[1]   = 0.0;
  part->l.p_old[2]   = 0.0;
  part->l.i[0]       = 0;
  part->l.i[1]       = 0;
  part->l.i[2]       = 0;

  #ifdef GHMC

    /* Last Saved ParticlePosition */
    part->l.r_ls.p[0]     = 0.0;
    part->l.r_ls.p[1]     = 0.0;
    part->l.r_ls.p[2]     = 0.0;

  #ifdef BOND_CONSTRAINT
    part->l.r_ls.p_old[0] = 0.0;
    part->l.r_ls.p_old[1] = 0.0;
    part->l.r_ls.p_old[2] = 0.0;
  #endif

  #ifdef ROTATION
    part->l.r_ls.quat[0]  = 1.0;
    part->l.r_ls.quat[1]  = 0.0;
    part->l.r_ls.quat[2]  = 0.0;
    part->l.r_ls.quat[3]  = 0.0;

    part->l.r_ls.quatu[0]  = 0.0;
    part->l.r_ls.quatu[1]  = 0.0;
    part->l.r_ls.quatu[2]  = 1.0;
  #endif

  #ifdef DIPOLES
    part->l.r_ls.dip[0]    = 0.0;
    part->l.r_ls.dip[1]    = 0.0;
    part->l.r_ls.dip[2]    = 0.0;
    //part->l.p_ls.dipm      = 0.0;
  #endif

    /* Last Saved ParticleMomentum */
    part->l.m_ls.v[0]     = 0.0;
    part->l.m_ls.v[1]     = 0.0;
    part->l.m_ls.v[2]     = 0.0;
  #ifdef ROTATION
    part->l.m_ls.omega[0] = 0.0;
    part->l.m_ls.omega[1] = 0.0;
    part->l.m_ls.omega[2] = 0.0;
  #endif

#endif

#ifdef EXTERNAL_FORCES
  part->l.ext_flag   = 0;
  part->l.ext_force[0] = 0.0;
  part->l.ext_force[1] = 0.0;
  part->l.ext_force[2] = 0.0;
  #ifdef ROTATION
    part->l.ext_torque[0] = 0.0;
    part->l.ext_torque[1] = 0.0;
    part->l.ext_torque[2] = 0.0;
  #endif
#endif

  init_intlist(&(part->bl));
#ifdef EXCLUSIONS
  init_intlist(&(part->el));
#endif

#ifdef VIRTUAL_SITES
  part->p.isVirtual      = 0;
#endif

#ifdef VIRTUAL_SITES_RELATIVE
  part->p.vs_relative_to_particle_id      = 0;
  part->p.vs_relative_distance =0;
#endif

#ifdef GHOST_FLAG
  part->l.ghost        = 0;
#endif

#ifdef LANGEVIN_PER_PARTICLE
  part->p.T = -1.0;
  part->p.gamma = -1.0;
#endif

}
Пример #19
0
int tclcommand_inter_coulomb_parse_ewaldgpu_tunealpha(Tcl_Interp * interp, int argc, char ** argv)
{
	double r_cut;
	double alpha;
	int num_kx;
	int num_ky;
	int num_kz;
	double precision=0.000001;
	IntList il;
	init_intlist(&il);

  //PARSE EWALD COMMAND LINE
  if (argc < 3)
  {
    Tcl_AppendResult(interp, "\nWrong # arguments: <r_cut> (<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) <precision>", (char *) NULL);
    return TCL_ERROR;
  }
  if (! ARG0_IS_D(r_cut))
  {
    Tcl_AppendResult(interp, "\n<r_cut> should be a double",(char *) NULL);
    return TCL_ERROR;
  }
  if(! ARG_IS_I(1, num_kx))
  {
    if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) )
    {
      Tcl_AppendResult(interp, "\n(<K_cut> | {<K_cut,x> <K_cut,y><K_cut,z>}) integer or integer list of length 3 expected", (char *) NULL);
      return TCL_ERROR;
    }
    else
    {
      num_kx = il.e[0];
      num_ky = il.e[1];
      num_kz = il.e[2];
    }
  }
  else
  {
  	num_kz = num_ky = num_kx;
  }
  if (! ARG_IS_D(2, precision))
  {
    Tcl_AppendResult(interp, "\n<precision> should be a double", (char *) NULL);
    return TCL_ERROR;
  }

  //Compute alpha
	Particle *particle;
	particle = (Particle*)Utils::malloc(n_part*sizeof(Particle));
	mpi_get_particles(particle, NULL);
	double q_sqr = ewaldgpuForce->compute_q_sqare(particle);
  alpha = ewaldgpuForce->compute_optimal_alpha(r_cut, num_kx, num_ky, num_kz, q_sqr, box_l, precision);

  //Turn on ewaldgpu
  if (!ewaldgpuForce) // inter coulomb ewaldgpu was never called before
  {
	  ewaldgpuForce = new EwaldgpuForce(espressoSystemInterface, r_cut, num_kx, num_ky, num_kz, alpha);
	  forceActors.add(ewaldgpuForce);
	  energyActors.add(ewaldgpuForce);
  }
  //Broadcast parameters
  coulomb.method = COULOMB_EWALD_GPU;
  ewaldgpu_params.isTunedFlag = false;
  ewaldgpu_params.isTuned = true;
  rebuild_verletlist = 1;
  mpi_bcast_coulomb_params();
  return TCL_OK;
}
Пример #20
0
int tclcommand_inter_coulomb_parse_p3m_tune(Tcl_Interp * interp, int argc, char ** argv, int adaptive)
{
  int cao = -1, n_interpol = -1;
  double r_cut = -1, accuracy = -1;
  int mesh[3];
  IntList il;
  init_intlist(&il);
  mesh[0] = -1;
  mesh[1] = -1;
  mesh[2] = -1;
  
  while(argc > 0) {
    if(ARG0_IS_S("r_cut")) {
      if (! (argc > 1 && ARG1_IS_D(r_cut) && r_cut >= -1)) {
	Tcl_AppendResult(interp, "r_cut expects a positive double",
			 (char *) NULL);
	return TCL_ERROR;
      }
      
    } else if(ARG0_IS_S("mesh")) {
      if(! ARG_IS_I(1, mesh[0])) {
        Tcl_ResetResult(interp);
        if( ! ARG_IS_INTLIST(1, il) || !(il.n == 3) ) {
          Tcl_AppendResult(interp, "integer or integer list of length 3 expected", (char *) NULL);
          return TCL_ERROR;
        } else {
            mesh[0] = il.e[0];
            mesh[1] = il.e[1];
            mesh[2] = il.e[2];
        }
      } else if(! (argc > 1 && mesh[0] >= -1)) {
  Tcl_AppendResult(interp, "mesh expects an integer >= -1",
          (char *) NULL);
  return TCL_ERROR;
        }
    } else if(ARG0_IS_S("cao")) {
      if(! (argc > 1 && ARG1_IS_I(cao) && cao >= -1 && cao <= 7)) {
        Tcl_AppendResult(interp, "cao expects an integer between -1 and 7",
              (char *) NULL);
        return TCL_ERROR;
      } 
    } else if(ARG0_IS_S("accuracy")) {
      if(! (argc > 1 && ARG1_IS_D(accuracy) && accuracy > 0)) {
        Tcl_AppendResult(interp, "accuracy expects a positive double",
              (char *) NULL);
        return TCL_ERROR;
      }

    } else if (ARG0_IS_S("n_interpol")) {
      if (! (argc > 1 && ARG1_IS_I(n_interpol) && n_interpol >= 0)) {
        Tcl_AppendResult(interp, "n_interpol expects an nonnegative integer", (char *) NULL);
        return TCL_ERROR;
      }
    }
    /* unknown parameter. Probably one of the optionals */
    else break;
    
    argc -= 2;
    argv += 2;
  }
  
  
  if ( (mesh[0]%2 != 0 && mesh[0] != -1) || (mesh[1]%2 != 0 && mesh[1] != -1) || (mesh[2]%2 != 0 && mesh[2] != -1) ) {
        printf ("y cond me %d %d %d\n", mesh[1], mesh[1]%2 != 0, mesh[1] != -1);
 // if ( ( mesh[0]%2 != 0) && (mesh[0] != -1) ) {
    Tcl_AppendResult(interp, "P3M requires an even number of mesh points in all directions", (char *) NULL);
    return TCL_ERROR;
  }
  p3m_set_tune_params(r_cut, mesh, cao, -1.0, accuracy, n_interpol);

  /* check for optional parameters */
  if (argc > 0) {
    if (tclcommand_inter_coulomb_parse_p3m_opt_params(interp, argc, argv) == TCL_ERROR)
      return TCL_ERROR;
  }

  /* do the tuning */
  char *log = NULL;
  if (p3m_adaptive_tune(&log) == ES_ERROR) {  
    Tcl_AppendResult(interp, log, "\nfailed to tune P3M parameters to required accuracy", (char *) NULL);
    if (log)
      free(log);
    return TCL_ERROR;
  }
  
  /* Tell the user about the tuning outcome */
  Tcl_AppendResult(interp, log, (char *) NULL);

  if (log)
    free(log);

  return TCL_OK;
}