예제 #1
0
/* A list of trapped molecules present on this node is created (local_trapped_mols)*/
void get_local_trapped_mols (IntList *local_trapped_mols)
{
  int c, i, mol, j, fixed;

  for (c = 0; c < local_cells.n; c++) {
    for(i = 0; i < local_cells.cell[c]->n; i++) {
      mol = local_cells.cell[c]->part[i].p.mol_id;
      if ( mol >= n_molecules ) {
      ostringstream msg;
      msg <<"can't calculate molforces no such molecule as " << mol ;
      runtimeError(msg);
	return;
      }

      /* Check to see if this molecule is fixed */
      fixed =0;
      for(j = 0; j < 3; j++) {
#ifdef EXTERNAL_FORCES
	if (topology[mol].trap_flag & COORD_FIXED(j)) fixed = 1;
	if (topology[mol].noforce_flag & COORD_FIXED(j)) fixed = 1;
#endif
      }  
      if (fixed) {
	/* if this molecule isn't already in local_trapped_mols then add it in */
	if (!intlist_contains(local_trapped_mols,mol)) {
	  realloc_intlist(local_trapped_mols, local_trapped_mols->max + 1);
	  local_trapped_mols->e[local_trapped_mols->max-1] = mol;
	  local_trapped_mols->n = local_trapped_mols->max;
	}
      }
    }
  }
}
예제 #2
0
/* A list of trapped molecules present on this node is created (local_trapped_mols)*/
void get_local_trapped_mols (IntList *local_trapped_mols)
{
  int c, i, mol, j, fixed;

  for (c = 0; c < local_cells.n; c++) {
    for(i = 0; i < local_cells.cell[c]->n; i++) {
      mol = local_cells.cell[c]->part[i].p.mol_id;
      if ( mol >= n_molecules ) {
	char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE);
	ERROR_SPRINTF(errtxt, "{ 094 can't calculate molforces no such molecule as %d }",mol);
	return;
      }

      /* Check to see if this molecule is fixed */
      fixed =0;
      for(j = 0; j < 3; j++) {
#ifdef EXTERNAL_FORCES
	if (topology[mol].trap_flag & COORD_FIXED(j)) fixed = 1;
	if (topology[mol].noforce_flag & COORD_FIXED(j)) fixed = 1;
#endif
      }  
      if (fixed) {
	/* if this molecule isn't already in local_trapped_mols then add it in */
	if (!intlist_contains(local_trapped_mols,mol)) {
	  realloc_intlist(local_trapped_mols, local_trapped_mols->max + 1);
	  local_trapped_mols->e[local_trapped_mols->max-1] = mol;
	  local_trapped_mols->n = local_trapped_mols->max;
	}
      }
    }
  }
}
예제 #3
0
/* calculates the force applies by traps on all molecules */
void calc_trap_force()
{
  Molecule *m;
  int mi,j;
#ifdef EXTERNAL_FORCES
  double trappos;
#endif
  

  if ( !topo_part_info_synced ) {
      ostringstream msg;
      msg <<"can't calculate moltrap: must execute analyse set topo_part_sync first";
      runtimeError(msg);
    return;
  } else {
    
    m = &topology[0];
    
    for (mi = 0; mi < n_molecules; mi++) {
      m = &topology[mi];
      for(j = 0; j < 3; j++) {
#ifdef EXTERNAL_FORCES
	if (m->trap_flag & COORD_FIXED(j)) {
	  /* Is the molecule trapped at a certain position in space? */
	  if (m->isrelative == 1) {
	    /* Is the trap set to absolute coordinates... */
	    trappos = m->trap_center[j]*box_l[j];
	  } else {
	    /* or to relative ones? */
	    trappos = m->trap_center[j];
	  }
	  m->trap_force[j] = 0;
	  /* the trap_force holding the molecule to the set position in calculated */
	  m->trap_force[j] += -((m->com[j]-trappos)*m->trap_spring_constant)/(double)(m->part.n);
	  /* the drag force applied to the molecule is calculated */
	  m->trap_force[j] += -(m->v[j]*m->drag_constant)/(double)(m->part.n);
	  /* the force applies by the traps is added to fav */
	  /* favcounter counts how many times we have added the force to fav since last time "analyze mol force" was called */
	  /* upon Espresso initialization it is set to -1 because in the first call of "integrate" there is an extra initial time step */
	  /* calling "analyze mol force" resets favcounter to 0 */
	  if (m->favcounter > -1) m->fav[j] -= m->v[j]*m->drag_constant + (m->com[j]-trappos)*m->trap_spring_constant;
	}
	if (m->noforce_flag & COORD_FIXED(j)) {
	  /* the trap force required to cancel out the total force acting on the molecule is calculated */
	  m->trap_force[j] -= m->f[j]/(double)m->part.n;
	  if (m->favcounter > -1) m->fav[j] -= m->f[j];
	}
#endif
      }
      m->favcounter++;
    }
  }
}
예제 #4
0
bool steepest_descent_step(void) {
  Cell *cell;
  Particle *p;
  int c, i, j, np;
  double f_max = -std::numeric_limits<double>::max();
  double f;
  /* Verlet list criterion */
  const double skin2 = SQR(0.5*skin);
  double f_max_global;
  double dx[3], dx2;
  const double max_dx2 = SQR(params->max_displacement);

  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++) {
      f = 0.0;
      dx2 = 0.0;
#ifdef VIRTUAL_SITES
      if (ifParticleIsVirtual(&p[i])) continue;
#endif
      for(j=0; j < 3; j++){
#ifdef EXTERNAL_FORCES
        if (!(p[i].p.ext_flag & COORD_FIXED(j)))
#endif
          {
            f += SQR(p[i].f.f[j]);	    	    
	    dx[j] = params->gamma * p[i].f.f[j];	    
	    dx2 += SQR(dx[j]);
	    MINIMIZE_ENERGY_TRACE(printf("part %d dim %d dx %e gamma*f %e\n", i, j, dx[j], params->gamma * p[i].f.f[j]));
	  }
#ifdef EXTERNAL_FORCES
	else {
	  dx[j] = 0.0;	  
	}
#endif
      }

      if(dx2 <= max_dx2) {
	p[i].r.p[0] += dx[0];
	p[i].r.p[1] += dx[1];
	p[i].r.p[2] += dx[2];
      } else {
	const double c = params->max_displacement/std::sqrt(dx2);
	p[i].r.p[0] += c*dx[0];
	p[i].r.p[1] += c*dx[1];
	p[i].r.p[2] += c*dx[2];
      }
      if(distance2(p[i].r.p,p[i].l.p_old) > skin2 ) resort_particles = 1;
      f_max = std::max(f_max, f);
    }
  }
  MINIMIZE_ENERGY_TRACE(printf("f_max %e resort_particles %d\n", f_max, resort_particles));
  announce_resort_particles();
  MPI_Allreduce(&f_max, &f_max_global, 1, MPI_DOUBLE, MPI_MAX, comm_cart);
  return (sqrt(f_max_global) < params->f_max);
}
예제 #5
0
파일: integrate.c 프로젝트: roehm/cython
void rescale_forces_propagate_vel()
{
  Cell *cell;
  Particle *p;
  int i, j, np, c;
  double scale;

#ifdef NPT
  if(integ_switch == INTEG_METHOD_NPT_ISO){
    nptiso.p_vel[0] = nptiso.p_vel[1] = nptiso.p_vel[2] = 0.0;}
#endif

  scale = 0.5 * time_step * time_step;
  INTEG_TRACE(fprintf(stderr,"%d: rescale_forces_propagate_vel:\n",this_node));

  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++) {
      check_particle_force(&p[i]);
      /* Rescale forces: f_rescaled = 0.5*dt*dt * f_calculated * (1/mass) */
      p[i].f.f[0] *= scale/PMASS(p[i]);
      p[i].f.f[1] *= scale/PMASS(p[i]);
      p[i].f.f[2] *= scale/PMASS(p[i]);

      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: SCAL f = (%.3e,%.3e,%.3e) v_old = (%.3e,%.3e,%.3e)\n",this_node,p[i].f.f[0],p[i].f.f[1],p[i].f.f[2],p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
#ifdef VIRTUAL_SITES
       // Virtual sites are not propagated during integration
       if (ifParticleIsVirtual(&p[i])) continue; 
#endif
      for(j = 0; j < 3 ; j++) {
#ifdef EXTERNAL_FORCES
	if (!(p[i].l.ext_flag & COORD_FIXED(j))) {
#endif
#ifdef NPT
	  if(integ_switch == INTEG_METHOD_NPT_ISO && ( nptiso.geometry & nptiso.nptgeom_dir[j] )) {
	    nptiso.p_vel[j] += SQR(p[i].m.v[j])*PMASS(p[i]);
	    p[i].m.v[j] += p[i].f.f[j] + friction_therm0_nptiso(p[i].m.v[j])/PMASS(p[i]);
	  }
	  else
#endif
	    /* Propagate velocity: v(t+dt) = v(t+0.5*dt) + 0.5*dt * f(t+dt) */
	    { p[i].m.v[j] += p[i].f.f[j]; }
#ifdef EXTERNAL_FORCES
	}
#endif
      }

      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PV_2 v_new = (%.3e,%.3e,%.3e)\n",this_node,p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
    }
  }
#ifdef NPT
  finalize_p_inst_npt();
#endif
}
예제 #6
0
파일: integrate.c 프로젝트: roehm/cython
void propagate_press_box_pos_and_rescale_npt()
{
#ifdef NPT
  if(integ_switch == INTEG_METHOD_NPT_ISO) {
    Cell *cell;
    Particle *p;
    int i, j, np, c;
    double scal[3]={0.,0.,0.}, L_new=0.0;

    /* finalize derivation of p_inst */
    finalize_p_inst_npt();

    /* adjust \ref nptiso_struct::nptiso.volume; prepare pos- and vel-rescaling */
    if (this_node == 0) {
      nptiso.volume += nptiso.inv_piston*nptiso.p_diff*0.5*time_step;
      scal[2] = SQR(box_l[nptiso.non_const_dim])/pow(nptiso.volume,2.0/nptiso.dimension);
      nptiso.volume += nptiso.inv_piston*nptiso.p_diff*0.5*time_step;
      if (nptiso.volume < 0.0) {
	char *errtxt = runtime_error(128 + 3*TCL_DOUBLE_SPACE);
        ERROR_SPRINTF(errtxt, "{015 your choice of piston=%g, dt=%g, p_diff=%g just caused the volume to become negative, decrease dt} ",
                nptiso.piston,time_step,nptiso.p_diff);
	nptiso.volume = box_l[0]*box_l[1]*box_l[2];
	scal[2] = 1;
      }

      L_new = pow(nptiso.volume,1.0/nptiso.dimension);
      //      printf(stdout,"Lnew, %f: volume, %f: dim, %f: press, %f \n", L_new, nptiso.volume, nptiso.dimension,nptiso.p_inst );
      //    fflush(stdout);

      scal[1] = L_new/box_l[nptiso.non_const_dim];
      scal[0] = 1/scal[1];
    }
    MPI_Bcast(scal,  3, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    /* propagate positions while rescaling positions and velocities */
    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++) {	
#ifdef VIRTUAL_SITES
	if (ifParticleIsVirtual(&p[i])) continue;
#endif
	for(j=0; j < 3; j++){
#ifdef EXTERNAL_FORCES
	  if (!(p[i].l.ext_flag & COORD_FIXED(j))) {
#endif	    
	    if(nptiso.geometry & nptiso.nptgeom_dir[j]) {
	      p[i].r.p[j]      = scal[1]*(p[i].r.p[j] + scal[2]*p[i].m.v[j]);
	      p[i].l.p_old[j] *= scal[1];
	      p[i].m.v[j]     *= scal[0];
	    } else {
	      p[i].r.p[j] += p[i].m.v[j];
	    }

#ifdef EXTERNAL_FORCES
	  }
#endif
	}
	ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT:PV_1 v_new=(%.3e,%.3e,%.3e)\n",this_node,p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
	ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT:PPOS p=(%.3f,%.3f,%.3f)\n",this_node,p[i].r.p[0],p[i].r.p[1],p[i].r.p[2])); 
#ifdef ADDITIONAL_CHECKS
	force_and_velocity_check(&p[i]); 
#endif
      }
    }

    resort_particles = 1; 

    /* Apply new volume to the box-length, communicate it, and account for necessary adjustments to the cell geometry */
    if (this_node == 0) {
      for ( i = 0 ; i < 3 ; i++ ){ 
	if ( nptiso.geometry & nptiso.nptgeom_dir[i] ) {
	  box_l[i] = L_new;
	} else if ( nptiso.cubic_box ) {
	  box_l[i] = L_new;
	}
      }
    }
    MPI_Bcast(box_l, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    on_NpT_boxl_change();
  }
예제 #7
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);
  
}
예제 #8
0
/* This is only done for the trapped molecules to save time */
void calc_local_mol_info (IntList *local_trapped_mols)
{
  int mi, i,j, mol;
  Particle *p;
  int np, c;
  Cell *cell;
  int lm;
  int fixed;

  /* First reset all molecule masses,forces,centers of mass*/
  for ( mi = 0 ; mi < n_molecules ; mi++ ) {
    topology[mi].mass = 0;
    for ( i = 0 ; i < 3 ; i++) {
      topology[mi].f[i] = 0.0;
      topology[mi].com[i] = 0.0;
      topology[mi].v[i] = 0.0;
    }
  }

  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++) {
      mol = p[i].p.mol_id;
      if ( mol >= n_molecules ) {
	char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE);
	ERROR_SPRINTF(errtxt, "{ 094 can't calculate molforces no such molecule as %d }",mol);
	return;
      }

      /* Check to see if this molecule is fixed */
      fixed =0;
      for(j = 0; j < 3; j++) {
#ifdef EXTERNAL_FORCES
	if (topology[mol].trap_flag & COORD_FIXED(j)) fixed = 1;
	if (topology[mol].noforce_flag & COORD_FIXED(j)) fixed = 1;
#endif
      }  
      if (fixed) {
	topology[mol].mass += PMASS(p[i]);
	/* Unfold the particle */
	unfold_position(p[i].r.p,p[i].l.i);
	for ( j = 0 ; j < 3 ; j++ ) {
	  topology[mol].f[j] += p[i].f.f[j];
	  topology[mol].com[j] += p[i].r.p[j]*PMASS(p[i]); 
	  topology[mol].v[j] += p[i].m.v[j]*PMASS(p[i]); 
	}
	/* Fold the particle back */
	fold_position(p[i].r.p,p[i].l.i);

      }
    }
  }

  /* Final normalisation of centers of mass and velocity*/
  for ( lm = 0 ; lm < local_trapped_mols->n; lm++ ) {
    mi = local_trapped_mols->e[lm];
    for ( i = 0 ; i < 3 ; i++) {
      topology[mi].com[i] = topology[mi].com[i]/(double)(topology[mi].mass);
      topology[mi].v[i] = topology[mi].v[i]/(double)(topology[mi].mass);
    }
  }

}
예제 #9
0
void propagate_pos_sd()
{
  /* Verlet list criterion */
  double skin2 = SQR(0.5 * skin);

  INTEG_TRACE(fprintf(stderr,"%d: propagate_pos:\n",this_node));
  Cell *cell;
  Particle *p;
  int c, i, np;
  //get total number of particles
  int N=sd_get_particle_num();
  // gather all the data for mobility calculation
  real * pos=NULL;
  pos=(real *)Utils::malloc(DIM*N*sizeof(double));
  assert(pos!=NULL);
  real * force=NULL;
  force=(real *)Utils::malloc(DIM*N*sizeof(double));
  assert(force!=NULL);
  real * velocity=NULL;
  velocity=(real *)Utils::malloc(DIM*N*sizeof(real));
  assert(velocity!=NULL);
#ifdef EXTERNAL_FORCES
  const int COORD_ALL=COORD_FIXED(0)&COORD_FIXED(1)&COORD_FIXED(2);
#endif
  int j=0; // total particle counter
  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++) { // only count nonVirtual Particles
#ifdef EXTERNAL_FORCES
      if (p[i].p.ext_flag & COORD_ALL)
	{
	  fprintf (stderr, "Warning: Fixing particle in StokesDynamics this way with EXTERNAL_FORCES is not possible (and will be ignored). Please try to bind them e.g. harmonicaly.\n");
	}
#endif
#ifdef  VIRTUAL_SITES
      if (!ifParticleIsVirtual(&p[i]))
#endif
      {
#ifdef SD_USE_FLOAT
	for (int d=0;d<3;d++){
	  pos[3*j+d]        = p[i].r.p[d];
	  pos[3*j+d]        -=rint(pos[3*j+d]/box_l[d])*box_l[d];
	  force[3*j+d]      = p[i].f.f[d];
	}
#else
        memmove(&pos[3*j], p[i].r.p, 3*sizeof(double));
        memmove(&force[3*j], p[i].f.f, 3*sizeof(double));
	for (int d=0;d<3;d++){
	  pos[3*j+d]        -=rint(pos[3*j+d]/box_l[d])*box_l[d];
	}
#endif
	j++;
      }
    }
  }
  if (!(thermo_switch & THERMO_SD) && thermo_switch & THERMO_BD){
    propagate_pos_bd(N,pos,force, velocity);
  } else {
    // cuda part
#ifdef CUDA
    //void propagate_pos_sd_cuda(double * box_l_h, int N,double * pos_h, double * force_h, double * velo_h){
#ifdef SD_USE_FLOAT
    real box_size[3];
    for (int d=0;d<3;d++){
      box_size[d]=box_l[d];
    }
#else
    real * box_size = box_l;
#endif
    if (!(thermo_switch & THERMO_SD)){
      temperature*=-1;
    }
  propagate_pos_sd_cuda(box_size,N,pos,force, velocity);
  if (!(thermo_switch & THERMO_SD)){
    temperature*=-1;
  }
#else
  fprintf(stderr, "Warning - CUDA is currently required for SD\n");
  fprintf(stderr, "So i am just sitting here and copying stupidly stuff :'(\n");
#endif
}
  

#ifdef NEMD
  /* change momentum of each particle in top and bottom slab */
  fprintf (stderr, "Warning: NEMD is in SD not supported.\n");
#endif
  j=0;
  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++) {
#ifdef VIRTUAL_SITES
      if (ifParticleIsVirtual(&p[i])) continue;
#endif
      // write back of position and velocity data
#ifdef SD_USE_FLOAT
      for (int d=0;d<3;d++){
	p[i].r.p[d] = pos[3*j+d]+box_l[d]*rint(p[i].r.p[d]/box_l[d]);
	p[i].m.v[d] = velocity[3*j+d];
	//p[i].f.f[d] *= (0.5*time_step*time_step)/(*part).p.mass;
      }
#else
      for (int d=0;d<3;d++){
	p[i].r.p[d] = pos[3*j+d]+box_l[d]*rint(p[i].r.p[d]/box_l[d]);
      }
      memmove(p[i].m.v, &velocity[DIM*j], 3*sizeof(double));
#endif
      // somehow this does not effect anything, although it is called ...
      for (int d=0;d<3;d++){
	p[i].f.f[d] *= (0.5*time_step*time_step)/(*p).p.mass;
      }
      for (int d=0;d<DIM;d++){
        assert(!isnan(pos[DIM*i+d]));
      }
      j++;
      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PV_1 v_new = (%.3e,%.3e,%.3e)\n",this_node,p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PPOS p = (%.3f,%.3f,%.3f)\n",this_node,p[i].r.p[0],p[i].r.p[1],p[i].r.p[2]));
   

#ifdef ROTATION
      propagate_omega_quat_particle(&p[i]);
#endif

      /* Verlet criterion check */
      if(distance2(p[i].r.p,p[i].l.p_old) > skin2 ) resort_particles = 1;
    }
  }
  free(pos);
  free(force);
  free(velocity);
  announce_resort_particles();
}
예제 #10
0
/** overwrite the forces of a particle with
    the friction term, i.e. \f$ F_i= -\gamma v_i + \xi_i\f$.
*/
inline void friction_thermo_langevin(Particle *p)
{
    extern double langevin_pref1, langevin_pref2;

    double langevin_pref1_temp, langevin_pref2_temp;

#ifdef MULTI_TIMESTEP
    extern double langevin_pref1_small;
#ifndef LANGEVIN_PER_PARTICLE
    extern double langevin_pref2_small;
#endif /* LANGEVIN_PER_PARTICLE */
#endif /* MULTI_TIMESTEP */

    int j;
    double switch_trans = 1.0;
    if ( langevin_trans == false )
    {
        switch_trans = 0.0;
    }

    // Virtual sites related decision making
#ifdef VIRTUAL_SITES
#ifndef VIRTUAL_SITES_THERMOSTAT
    // In this case, virtual sites are NOT thermostated
    if (ifParticleIsVirtual(p))
    {
        for (j=0; j<3; j++)
            p->f.f[j]=0;

        return;
    }
#endif /* VIRTUAL_SITES_THERMOSTAT */
#ifdef THERMOSTAT_IGNORE_NON_VIRTUAL
    // In this case NON-virtual particles are NOT thermostated
    if (!ifParticleIsVirtual(p))
    {
        for (j=0; j<3; j++)
            p->f.f[j]=0;

        return;
    }
#endif /* THERMOSTAT_IGNORE_NON_VIRTUAL */
#endif /* VIRTUAL_SITES */

    // Get velocity effective in the thermostatting
    double velocity[3];
    for (int i = 0; i < 3; i++) {
        // Particle velocity
        velocity[i] = p->m.v[i];
#ifdef ENGINE
        // In case of the engine feature, the velocity is relaxed
        // towards a swimming velocity oriented parallel to the
        // particles director
        velocity[i] -= (p->swim.v_swim*time_step)*p->r.quatu[i];
#endif

        // Local effective velocity for leeds-edwards boundary conditions
        velocity[i]=le_frameV(i,velocity,p->r.p);
    } // for

    // Determine prefactors for the friction and the noise term

    // first, set defaults
    langevin_pref1_temp = langevin_pref1;
    langevin_pref2_temp = langevin_pref2;

    // Override defaults if per-particle values for T and gamma are given
#ifdef LANGEVIN_PER_PARTICLE
    // If a particle-specific gamma is given
    if(p->p.gamma >= 0.)
    {
        langevin_pref1_temp = -p->p.gamma/time_step;
        // Is a particle-specific temperature also specified?
        if(p->p.T >= 0.)
            langevin_pref2_temp = sqrt(24.0*p->p.T*p->p.gamma/time_step);
        else
            // Default temperature but particle-specific gamma
            langevin_pref2_temp = sqrt(24.0*temperature*p->p.gamma/time_step);

    } // particle specific gamma
    else
    {
        langevin_pref1_temp = -langevin_gamma/time_step;
        // No particle-specific gamma, but is there particle-specific temperature
        if(p->p.T >= 0.)
            langevin_pref2_temp = sqrt(24.0*p->p.T*langevin_gamma/time_step);
        else
            // Defaut values for both
            langevin_pref2_temp = langevin_pref2;
    }
#endif /* LANGEVIN_PER_PARTICLE */

    // Multi-timestep handling
    // This has to be last, as it may set the prefactors to 0.
#ifdef MULTI_TIMESTEP
    if (smaller_time_step > 0.) {
        langevin_pref1_temp *= time_step/smaller_time_step;
        if (p->p.smaller_timestep==1 && current_time_step_is_small==1)
            langevin_pref2_temp *= sqrt(time_step/smaller_time_step);
        else if (p->p.smaller_timestep != current_time_step_is_small) {
            langevin_pref1_temp  = 0.;
            langevin_pref2_temp  = 0.;
        }
    }
#endif /* MULTI_TIMESTEP */


    // Do the actual thermostatting
    for ( j = 0 ; j < 3 ; j++)
    {
#ifdef EXTERNAL_FORCES
        // If individual coordinates are fixed, set force to 0.
        if ((p->p.ext_flag & COORD_FIXED(j)))
            p->f.f[j] = 0;
        else
#endif
        {
            // Apply the force
            p->f.f[j] = langevin_pref1_temp*velocity[j] + switch_trans*langevin_pref2_temp*noise;
        }
    } // END LOOP OVER ALL COMPONENTS


    // printf("%d: %e %e %e %e %e %e\n",p->p.identity, p->f.f[0],p->f.f[1],p->f.f[2], p->m.v[0],p->m.v[1],p->m.v[2]);
    ONEPART_TRACE(if(p->p.identity==check_id) fprintf(stderr,"%d: OPT: LANG f = (%.3e,%.3e,%.3e)\n",this_node,p->f.f[0],p->f.f[1],p->f.f[2]));
    THERMO_TRACE(fprintf(stderr,"%d: Thermo: P %d: force=(%.3e,%.3e,%.3e)\n",this_node,p->p.identity,p->f.f[0],p->f.f[1],p->f.f[2]));
}
예제 #11
0
bool steepest_descent_step(void) {
  Cell *cell;
  Particle *p;
  int c, i, j, np;
  
  // Maximal force encountered on node
  double f_max = -std::numeric_limits<double>::max();
  // and globally
  double f_max_global;
  
  // Square of force,torque on particle
  double f,t;
  
  // Positional increments
  double dp, dp2, dp2_max = -std::numeric_limits<double>::max();
    
  // Iteration over all local particles
  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++) {
      f = 0.0;
      t = 0.0;
      dp2 = 0.0;
#ifdef EXTERNAL_FORCES
        // Skip, if coordinate is fixed
        if (!(p[i].p.ext_flag & COORD_FIXED(j)))
#endif
      // For all Cartesian coordinates
      for(j=0; j < 3; j++){
#ifdef VIRTUAL_SITES
      // Skip positional increments of virtual particles
      if (!ifParticleIsVirtual(&p[i])) 
#endif
        {
            // Square of force on particle
	    f += SQR(p[i].f.f[j]);	    	    
	    
	    // Positional increment
	    dp = params->gamma * p[i].f.f[j];
	    if(fabs(dp) > params->max_displacement)
	      // Crop to maximum allowed by user
	      dp = sgn<double>(dp)*params->max_displacement;
	    dp2 += SQR(dp);
            
	    // Move particle
	    p[i].r.p[j] += dp;
	    MINIMIZE_ENERGY_TRACE(printf("part %d dim %d dp %e gamma*f %e\n", i, j, dp, params->gamma * p[i].f.f[j]));
          }
	}
#ifdef ROTATION
	// Rotational increment
	double dq[3]; // Vector parallel to torque

        for (int j=0;j<3;j++){
          dq[j]=0;
          // Square of torque
	  t += SQR(p[i].f.torque[j]);	    	    
	    
	  // Rotational increment
	  dq[j] = params->gamma * p[i].f.torque[j];
	    
      }
      // Normalize rotation axis and compute amount of rotation
      double l=normr(dq);
      if (l>0.0)
      {
        for (j=0;j<3;j++)
          dq[j]/=l;
  
        if(fabs(l) > params->max_displacement)
          // Crop to maximum allowed by user
  	l=sgn(l)*params->max_displacement;
        
        
//        printf("dq: %g %g %g, l=%g\n",dq[0],dq[1],dq[2],l);
        // Rotate the particle around axis dq by amount l
        rotate_particle(&(p[i]),dq,l);
      }
#endif

      // Note maximum force/torque encountered
      f_max = std::max(f_max, f);
      f_max = std::max(f_max, t);
      dp2_max = std::max(dp2_max, dp2);
      resort_particles = 1;
    }
  }
  MINIMIZE_ENERGY_TRACE(printf("f_max %e resort_particles %d\n", f_max, resort_particles));
  announce_resort_particles();
  
  // Synchronize maximum force/torque encountered
  MPI_Allreduce(&f_max, &f_max_global, 1, MPI_DOUBLE, MPI_MAX, comm_cart);
  
  // Return true, if the maximum force/torque encountered is below the user limit.
  return (sqrt(f_max_global) < params->f_max);
}