Esempio n. 1
0
int tclcommand_reaction(ClientData data, Tcl_Interp * interp, int argc, char ** argv){
#ifdef CATALYTIC_REACTIONS

  /* Determine the currently set types, to block the user from 
     trying to set up multiple reactions */

  int react_type, prdct_type, catal_type;
  react_type = reaction.reactant_type;
  prdct_type = reaction.product_type;
  catal_type = reaction.catalyzer_type;

  if (argc == 1  ) return tcl_command_reaction_print_usage(interp);

  if (argc == 2 ) { 
     if (ARG1_IS_S("off")) {
       /* We only need to set ct_rate to zero and we
          do not enter the reaction integration loop */
       reaction.ct_rate=0.0;
       mpi_setup_reaction();
       return TCL_OK;
     }
     if (ARG1_IS_S("print")) {
           return tcl_command_reaction_print(interp);
     }
  }

  if( argc!=11 && argc!=13 && argc!=15 && argc!=17 && argc!=3) {
     return tcl_command_reaction_print_usage(interp);
  }

     
  if(time_step < 0.0) {
    Tcl_AppendResult(interp, "Time step needs to be set before setting up a reaction!", (char *) NULL);
    return (TCL_ERROR);
  }

  argc--;
  argv++;
  while (argc>0){
    if (ARG_IS_S(0,"product_type")) {
      if (!ARG_IS_I(1,reaction.product_type)) 
        return tcl_command_reaction_print_usage(interp);
      argc-=2;
	    argv+=2;
    } 
    else if (ARG_IS_S(0,"reactant_type")) {
      if (!ARG_IS_I(1,reaction.reactant_type)) 
        return tcl_command_reaction_print_usage(interp);
      argc-=2;
	    argv+=2;
    } 
    else if (ARG_IS_S(0,"catalyzer_type")) {
      if (!ARG_IS_I(1,reaction.catalyzer_type)) 
        return tcl_command_reaction_print_usage(interp);
    argc-=2;
	  argv+=2;
    } 
    else if (ARG_IS_S_EXACT(0,"range")) {
      if (!ARG_IS_D(1,reaction.range)) 
        return tcl_command_reaction_print_usage(interp);
      argc-=2;
      argv+=2;
    }
    else if (ARG_IS_S_EXACT(0,"ct_rate")) {
      if (!ARG_IS_D(1,reaction.ct_rate)) 
        return tcl_command_reaction_print_usage(interp);
      argc-=2;
      argv+=2;
    } 
    else if (ARG_IS_S_EXACT(0,"eq_rate")) {
      if (!ARG_IS_D(1,reaction.eq_rate)) 
        return tcl_command_reaction_print_usage(interp);
      argc-=2;
	    argv+=2;
    } 
    else if (ARG_IS_S_EXACT(0,"react_once")) {
      if (!ARG_IS_S(1,"on")&&!ARG_IS_S(1,"off")) {
        return tcl_command_reaction_print_usage(interp);}
      if (ARG_IS_S(1,"on")) reaction.sing_mult = 1;
      if (ARG_IS_S(1,"off")) reaction.sing_mult = 0;
    argc-=2;
	  argv+=2;
    }
    else if (ARG_IS_S_EXACT(0,"swap")) {
#ifndef ROTATION
      char buffer[80];
      sprintf(buffer, "WARNING: Parameter \"swap\" has no effect when ROTATION is not compiled in.");
      Tcl_AppendResult(interp, buffer, (char *)NULL);
#endif
      if (ARG_IS_S(1,"on"))
        reaction.swap = 1;
      else if (ARG_IS_S(1,"off"))
        reaction.swap = 0;
      else
        return tcl_command_reaction_print_usage(interp);
      argc-=2;
      argv+=2;
    } else {
      return tcl_command_reaction_print_usage(interp);
    }
  }

  if( reaction.ct_rate < 0.0 ) {
    Tcl_AppendResult(interp, "Negative catalytic reaction rate constant is not allowed!", (char *) NULL);
    return (TCL_ERROR);
  }

  if( reaction.eq_rate < 0.0 && fabs(reaction.eq_rate + 1.0) > 0.001 ) {
    Tcl_AppendResult(interp, "Negative equilibrium reaction rate contstant is not allowed!", (char *) NULL);
    return (TCL_ERROR);
  }

  if( (reaction.product_type == reaction.reactant_type) || (reaction.product_type == reaction.catalyzer_type) || (reaction.catalyzer_type == reaction.reactant_type) ) {
    Tcl_AppendResult(interp, "One particle type cannot be a part more than one reaction species!", (char *) NULL);
    return (TCL_ERROR);
  }

  if ( ((react_type != reaction.reactant_type) || (prdct_type != reaction.product_type) || (catal_type != reaction.catalyzer_type)) && (react_type != prdct_type) ) {
    Tcl_AppendResult(interp, "A simulation can only contain a single reaction!", (char *) NULL);
    return (TCL_ERROR); 
  }

  mpi_setup_reaction();
  return TCL_OK;
#else
  Tcl_AppendResult(interp, "CATALYTIC_REACTIONS not compiled in!" ,(char *) NULL);
  return (TCL_ERROR);
#endif
}
Esempio n. 2
0
/** Parse integrate npt_isotropic command */
int tclcommand_integrate_set_npt_isotropic(Tcl_Interp *interp, int argc, char **argv)
{
  int xdir, ydir, zdir;
  xdir = ydir = zdir = nptiso.cubic_box = 0;

  if (argc < 4) {
    Tcl_AppendResult(interp, "wrong # args: \n", (char *)NULL);
    return tclcommand_integrate_print_usage(interp);
  }  
  /* set parameters p_ext and piston */
  if ( !ARG_IS_D(3, nptiso.p_ext) )  return tclcommand_integrate_print_usage(interp);
  tclcallback_p_ext(interp, &nptiso.p_ext);
  if ( argc > 4 ) { 
    if(!ARG_IS_D(4, nptiso.piston) ) return tclcommand_integrate_print_usage(interp);
    tclcallback_npt_piston(interp, &nptiso.piston); }
  else if ( nptiso.piston <= 0.0 ) {
    Tcl_AppendResult(interp, "You must set <piston> as well before you can use this integrator! \n", (char *)NULL);
    return tclcommand_integrate_print_usage(interp);
  }

  if ( argc > 5 ) {
    if (!ARG_IS_I(5,xdir) || !ARG_IS_I(6,ydir) || !ARG_IS_I(7,zdir) ) {
      return tclcommand_integrate_print_usage(interp);}
    else {
      /* set the geometry to include rescaling specified directions only*/
      nptiso.geometry = 0; nptiso.dimension = 0; nptiso.non_const_dim = -1;
      if ( xdir ) { 
	nptiso.geometry = ( nptiso.geometry | NPTGEOM_XDIR ); 
	nptiso.dimension += 1;
	nptiso.non_const_dim = 0;
      }
      if ( ydir ) { 
	nptiso.geometry = ( nptiso.geometry | NPTGEOM_YDIR );
	nptiso.dimension += 1;
	nptiso.non_const_dim = 1;
      }
      if ( zdir ) { 
	nptiso.geometry = ( nptiso.geometry | NPTGEOM_ZDIR );
	nptiso.dimension += 1;
	nptiso.non_const_dim = 2;
      }
    }
  } else {
    /* set the geometry to include rescaling in all directions; the default*/
    nptiso.geometry = 0;
    nptiso.geometry = ( nptiso.geometry | NPTGEOM_XDIR );
    nptiso.geometry = ( nptiso.geometry | NPTGEOM_YDIR );
    nptiso.geometry = ( nptiso.geometry | NPTGEOM_ZDIR );
    nptiso.dimension = 3; nptiso.non_const_dim = 2;
  }

  if ( argc > 8 ) {
    /* enable if the volume fluctuations should also apply to dimensions which are switched off by the above flags
       and which do not contribute to the pressure (3D) / tension (2D, 1D) */
    if (!ARG_IS_S(8,"-cubic_box")) {
      return tclcommand_integrate_print_usage(interp);
    } else {
      nptiso.cubic_box = 1;
    }
  }

  /* Sanity Checks */
#ifdef ELECTROSTATICS      
  if ( nptiso.dimension < 3 && !nptiso.cubic_box && coulomb.bjerrum > 0 ){
    fprintf(stderr,"WARNING: If electrostatics is being used you must use the -cubic_box option!\n");
    fprintf(stderr,"Automatically reverting to a cubic box for npt integration.\n");
    fprintf(stderr,"Be aware though that all of the coulombic pressure is added to the x-direction only!\n");
    nptiso.cubic_box = 1;
  }
#endif

#ifdef DIPOLES     
  if ( nptiso.dimension < 3 && !nptiso.cubic_box && coulomb.Dbjerrum > 0 ){
    fprintf(stderr,"WARNING: If magnetostatics is being used you must use the -cubic_box option!\n");
    fprintf(stderr,"Automatically reverting to a cubic box for npt integration.\n");
    fprintf(stderr,"Be aware though that all of the magnetostatic pressure is added to the x-direction only!\n");
    nptiso.cubic_box = 1;
  }
#endif


  if( nptiso.dimension == 0 || nptiso.non_const_dim == -1) {
    Tcl_AppendResult(interp, "You must enable at least one of the x y z components as fluctuating dimension(s) for box length motion!", (char *)NULL);
    Tcl_AppendResult(interp, "Cannot proceed with npt_isotropic, reverting to nvt integration... \n", (char *)NULL);
    integ_switch = INTEG_METHOD_NVT;
    mpi_bcast_parameter(FIELD_INTEG_SWITCH);
    return (TCL_ERROR);
  }

  /* set integrator switch */
  integ_switch = INTEG_METHOD_NPT_ISO;
  mpi_bcast_parameter(FIELD_INTEG_SWITCH);

  /* broadcast npt geometry information to all nodes */
  mpi_bcast_nptiso_geom();
  return (TCL_OK);
}
int tclcommand_observable(ClientData data, Tcl_Interp *interp, int argc, char **argv){
//  file_data_source* fds;
  char buffer[TCL_INTEGER_SPACE];
  int n;
  int id;
  int temp;
  //int no;

  if (argc<2) {
    Tcl_AppendResult(interp, "Usage!!!\n", (char *)NULL);
    return TCL_ERROR;
  }

  if (argc > 1 && ARG_IS_S(1, "n_observables")) {
	  sprintf(buffer, "%d", n_observables);
    Tcl_AppendResult(interp, buffer, (char *)NULL );
    return TCL_OK;
  }

  
//  if (argc > 1 && ARG1_IS_I(no)) {
// }
  if (argc > 2 && ARG1_IS_S("new") ) {

    // find the next free observable id
    for (id=0;id<n_observables;id++) 
      if ( observables+id == 0 ) break; 
    if (id==n_observables) 
      observables=(observable**) realloc(observables, (n_observables+1)*sizeof(observable*)); 

    REGISTER_OBSERVABLE(particle_velocities, tclcommand_observable_particle_velocities,id);
    REGISTER_OBSERVABLE(particle_angular_momentum, tclcommand_observable_particle_angular_momentum,id);
    REGISTER_OBSERVABLE(particle_forces, tclcommand_observable_particle_forces,id);
    REGISTER_OBSERVABLE(com_velocity, tclcommand_observable_com_velocity,id);
    REGISTER_OBSERVABLE(com_position, tclcommand_observable_com_position,id);
    REGISTER_OBSERVABLE(com_force, tclcommand_observable_com_force,id);
    REGISTER_OBSERVABLE(particle_positions, tclcommand_observable_particle_positions,id);
    REGISTER_OBSERVABLE(stress_tensor, tclcommand_observable_stress_tensor,id);
    REGISTER_OBSERVABLE(stress_tensor_acf_obs, tclcommand_observable_stress_tensor_acf_obs,id);
    REGISTER_OBSERVABLE(particle_currents, tclcommand_observable_particle_currents,id);
    REGISTER_OBSERVABLE(currents, tclcommand_observable_currents,id);
    REGISTER_OBSERVABLE(dipole_moment, tclcommand_observable_dipole_moment,id);
//    REGISTER_OBSERVABLE(structure_factor, tclcommand_observable_structure_factor,id);
    REGISTER_OBSERVABLE(interacts_with, tclcommand_observable_interacts_with,id);
  //  REGISTER_OBSERVABLE(obs_nothing, tclcommand_observable_obs_nothing,id);
  //  REGISTER_OBSERVABLE(flux_profile, tclcommand_observable_flux_profile,id);
    REGISTER_OBSERVABLE(density_profile, tclcommand_observable_density_profile,id);
    REGISTER_OBSERVABLE(lb_velocity_profile, tclcommand_observable_lb_velocity_profile,id);
    REGISTER_OBSERVABLE(radial_density_profile, tclcommand_observable_radial_density_profile,id);
    REGISTER_OBSERVABLE(radial_flux_density_profile, tclcommand_observable_radial_flux_density_profile,id);
    REGISTER_OBSERVABLE(flux_density_profile, tclcommand_observable_flux_density_profile,id);
    REGISTER_OBSERVABLE(lb_radial_velocity_profile, tclcommand_observable_lb_radial_velocity_profile,id);
    REGISTER_OBSERVABLE(tclcommand, tclcommand_observable_tclcommand,id);
    Tcl_AppendResult(interp, "Unknown observable ", argv[2] ,"\n", (char *)NULL);
    return TCL_ERROR;
  }
  
  if (ARG1_IS_I(n)) {
    if (n>=n_observables || observables+n == NULL ) {
      sprintf(buffer,"%d \n",n);
      Tcl_AppendResult(interp, "Observable with id ", buffer, (char *)NULL);
      Tcl_AppendResult(interp, "is not defined\n", (char *)NULL);
      return TCL_ERROR;
    }
    if (argc > 2 && ARG_IS_S(2,"print")) {
      return tclcommand_observable_print(interp, argc-3, argv+3, &temp, observables[n]);
    }
  }
  Tcl_AppendResult(interp, "Unknown observable ", argv[1] ,"\n", (char *)NULL);
  return TCL_ERROR;
}
Esempio n. 4
0
/************************************************************* 
 * Functions                                                 *
 * ---------                                                 *
 *************************************************************/
int tclcommand_polymer (ClientData data, Tcl_Interp *interp, int argc, char **argv) {
  int N_P, MPC; 
  double bond_length; 
  int part_id = 0; 
  double *posed = NULL; 
  double *posed2 = NULL;
  /* mode==0 equals "SAW", mode==1 equals "RW", mode==2 equals "PSAW" */
  int mode = 1; 
  double shield = 1.0; 
  int tmp_try,max_try = 30000;       
  double val_cM = 0.0; 
  int cM_dist = 1, type_nM = 0, type_cM = 1, type_bond = 0;
  double angle = -1.0, angle2 = -1.0;
  int constr = 0;
  char buffer[128 + TCL_DOUBLE_SPACE + TCL_INTEGER_SPACE];
  int i;
#ifdef CONSTRAINTS
  int j;
#endif

  if (argc < 4) { Tcl_AppendResult(interp, "Wrong # of args! Usage: polymer <N_P> <MPC> <bond_length> [start <n> | pos <x> <y> <z> | mode | charge | distance | types | bond | angle | constraints]", (char *)NULL); return (TCL_ERROR); }
  if (!ARG_IS_I(1, N_P)) {
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "Number of polymers must be integer (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR);
 }
  else {
    if(N_P < 0) {
      Tcl_AppendResult(interp, "Number of polymers must be positive (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR); }
  }
  if (!ARG_IS_I(2, MPC)) {
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "Number of monomers must be integer (got: ", argv[2],")!", (char *)NULL); return (TCL_ERROR); }
  else {
    if(MPC < 2) {
      Tcl_AppendResult(interp, "Number of monomers must be greater than 1 (got: ", argv[2],")!", (char *)NULL); return (TCL_ERROR); }
  }
  if (!ARG_IS_D(3, bond_length)) {
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "Bondlength must be double (got: ", argv[3],")!", (char *)NULL); return (TCL_ERROR); }
  else {
    if(bond_length < 0.0) {
      Tcl_AppendResult(interp, "Bondlength  must be positive (got: ", argv[3],")!", (char *)NULL); return (TCL_ERROR); }
  }
  for (i=4; i < argc; i++) {
    /* [start <part_id>] */
    if (ARG_IS_S(i, "start")) {
      if(i+1 < argc) {
	if (!ARG_IS_I(i+1, part_id)) {	
	  Tcl_ResetResult(interp);
	  Tcl_AppendResult(interp, "Index of polymer chain's first monomer must be integer (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); }
	else {
	  if (part_id < 0) {
	    Tcl_AppendResult(interp, "Index of polymer chain's first monomer must be positive (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } }
	i++;
      }
      else { Tcl_AppendResult(interp, "Not enough arguments for start", (char *)NULL); return (TCL_ERROR); }
    }
    /* [pos <x> <y> <z>] */
    else if (ARG_IS_S(i, "pos")) {
      if (i+3 < argc) { 
	posed = malloc(3*sizeof(double));
	if (!(ARG_IS_D(i+1, posed[0]) && ARG_IS_D(i+2, posed[1]) && ARG_IS_D(i+3, posed[2]))) {
	  Tcl_ResetResult(interp);
          Tcl_AppendResult(interp, "The first start monomers position must be double (got: ",argv[i+1],",",argv[i+2],",",argv[i+3],")!", (char *)NULL);
	  return (TCL_ERROR); } else { i+=3; } }
      else { Tcl_AppendResult(interp, "The first start monomers position must be 3D!", (char *)NULL); return (TCL_ERROR); }
    }
    /* [mode { SAW | RW | PSAW } [<shield> [max_try]]] */
    else if (ARG_IS_S(i, "mode")) {
      if (i+1 < argc) {
	if (ARG_IS_S(i+1, "SAW") || ARG_IS_S(i+1, "PSAW")) {
	  if (ARG_IS_S(i+1, "SAW")) mode = 0; else mode = 2;
	  if ((i+2 >= argc) || !ARG_IS_D(i+2, shield)) { Tcl_ResetResult(interp); i++; }
	  else {
	    if (shield < 0) { Tcl_AppendResult(interp, "The SAW-shield must be positive (got: ",argv[i+2],")!", (char *)NULL); return (TCL_ERROR); }
	    if ((i+3 >= argc) || !ARG_IS_I(i+3, max_try)) { Tcl_ResetResult(interp); i+=2; } else { i+=3; } } }
	else if (ARG_IS_S(i+1, "RW")) {
	  mode = 1;
	  if ((i+2 >= argc) || !ARG_IS_D(i+2, shield)) { Tcl_ResetResult(interp); i++; }
	      else if ((i+3 >= argc) || !ARG_IS_I(i+3, max_try)) { Tcl_ResetResult(interp); i+=2; } else { i+=3; } }
	else {
	  Tcl_AppendResult(interp, "The mode you specified does not exist (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); }
      }
      else {Tcl_AppendResult(interp, "Not enough arguments for mode", (char *)NULL); return (TCL_ERROR); }
    }
    /* [charge <val_cM>] */
    else if (ARG_IS_S(i, "charge")) {
      if(i+1 < argc) {
	if (!ARG_IS_D(i+1, val_cM)) {
	  Tcl_ResetResult(interp);
	  Tcl_AppendResult(interp, "The charge of the chain's monomers must be double (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); }
	else { i++; }
      }
      else { Tcl_AppendResult(interp, "Not enough arguments for charge", (char *)NULL); return (TCL_ERROR); }
    }
    /* [distance <cM_dist>] */
    else if (ARG_IS_S(i, "distance")) {
      if(i+1 <argc) {
	if (!ARG_IS_I(i+1, cM_dist)) {
	  Tcl_ResetResult(interp);
	  Tcl_AppendResult(interp, "The distance between two charged monomers' indices must be integer (got: ",argv[i+1],")!", (char *)NULL); 
	  return (TCL_ERROR); }
	else {
	  if(cM_dist < 0) { Tcl_AppendResult(interp, "The charge of the chain's monomers  must be positive (got: ",argv[i+2],")!", (char *)NULL); return (TCL_ERROR); }
	  else { i++; }
	}
      }
      else { Tcl_AppendResult(interp, "Not enough arguments for distance", (char *)NULL); return (TCL_ERROR); }
    }
    /* [types <type_nM> [<type_cM>]] */
    else if (ARG_IS_S(i, "types")) {
      if(i+1 < argc) {
	if (!ARG_IS_I(i+1, type_nM)) {
	  Tcl_ResetResult(interp);
	  Tcl_AppendResult(interp, "The type-# of neutral monomers must be integer (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); }
	else {
	  if ((i+2 >= argc) || !ARG_IS_I(i+2, type_cM)) { Tcl_ResetResult(interp); i++; } else { i+=2; } }
      }
      else {Tcl_AppendResult(interp, "Not enough arguments for types", (char *)NULL); return (TCL_ERROR); }
    }
    /* [bond <type_bond>] */
    else if (ARG_IS_S(i, "bond") || ARG_IS_S(i, "FENE")) {
      if (i+1 < argc) {
	if (!ARG_IS_I(i+1, type_bond)) {
	  Tcl_ResetResult(interp);
	  Tcl_AppendResult(interp, "The type-# of the bond-interaction must be integer (got: ", argv[i+1],")!", (char *)NULL); 
	  return (TCL_ERROR); 
	}
	else {
	  i++;
	  
	}
      } else {
	Tcl_AppendResult(interp, "Not enough arguments for bond", 
			 (char *)NULL); 
	return (TCL_ERROR); 
      }
    }
    /* [angle <angle> [\<angle2\>]] */
    else if (ARG_IS_S(i, "angle")) {
      Tcl_AppendResult(interp, "Warning: The angle definition has been changed. See RELEASE-NOTES.\n", (char *)NULL);
      if (i+1 < argc) {
	if (ARG_IS_D(i+1, angle)) {
	  if (angle < 0.0) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "The angle phi must be positive (got: ",argv[i+1],")!", (char *)NULL); 
	    return (TCL_ERROR);
	  }
	  while (angle >= 2.0*PI) angle -= 2.0*PI;
	  i++;
    	  if (i+1 < argc) {
	    if (ARG_IS_D(i+1, angle2)) {
	      if (angle2 < 0.0) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "The angle theta must be positive (got: ",argv[i+1],")!", (char *)NULL); 
		return (TCL_ERROR); 
	      }
	      while(angle2 >= 2.0*PI) angle2 -= 2.0*PI;
	      i++;
	      if (i+3 < argc) {
		posed2=malloc(3*sizeof(double));
		if (ARG_IS_D(i+1, posed2[0]) && ARG_IS_D(i+2, posed2[1]) && ARG_IS_D(i+3, posed2[2])) {
		  i+=3; 
		} else {
		  free(posed2); 
		}
	      }
	    }
	  }
	}
      }
      else {Tcl_AppendResult(interp, "Not enough arguments for angle", (char *)NULL); return (TCL_ERROR); }
    }
    /* [constraints] */
    else if (ARG_IS_S(i, "constraints")) {
#ifndef CONSTRAINTS
      Tcl_AppendResult(interp, "Constraints are not compiled in!", (char *)NULL); return (TCL_ERROR); }
#else
      constr=1;
      tmp_try=0;
      for(j=0;j<n_constraints;j++){
	if(constraints[j].type==CONSTRAINT_MAZE || constraints[j].type==CONSTRAINT_PORE || constraints[j].type==CONSTRAINT_PLATE || constraints[j].type==CONSTRAINT_RHOMBOID)
	  tmp_try++;
      }
      if (tmp_try>0) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "Warning: Only constraints of type WALL/SPHERE/CYLINDER are respected!", (char *)NULL); return (TCL_ERROR); }
      else { i++; }
    }
#endif
    /* Default */
  else { Tcl_AppendResult(interp, "The parameters you supplied do not seem to be valid (stuck at: ",argv[i],")!", (char *)NULL); return (TCL_ERROR); }
Esempio n. 5
0
int tclcommand_integrate(ClientData data, Tcl_Interp *interp, int argc, char **argv) 
{
  int  n_steps, reuse_forces = 0;
  
  INTEG_TRACE(fprintf(stderr,"%d: integrate:\n",this_node));

  if (argc < 1) {
    Tcl_AppendResult(interp, "wrong # args: \n\"", (char *) NULL);
    return tclcommand_integrate_print_usage(interp);  }
  else if (argc < 2) {                    return tclcommand_integrate_print_status(interp); }

  if (ARG1_IS_S("set")) {
    if      (argc < 3)                    return tclcommand_integrate_print_status(interp);
    if      (ARG_IS_S(2,"nvt"))           return tclcommand_integrate_set_nvt(interp, argc, argv);
#ifdef NPT
    else if (ARG_IS_S(2,"npt_isotropic")) return tclcommand_integrate_set_npt_isotropic(interp, argc, argv);
#endif
    else {
      Tcl_AppendResult(interp, "unknown integrator method:\n", (char *)NULL);
      return tclcommand_integrate_print_usage(interp);
    }
  } else {
    if ( !ARG_IS_I(1,n_steps) ) return tclcommand_integrate_print_usage(interp);

    // actual integration
    if ((argc == 3) && ARG_IS_S(2, "reuse_forces")) {
      reuse_forces = 1;
    }
    else if ((argc == 3) && ARG_IS_S(2, "recalc_forces")) {
      reuse_forces = -1;
    }
    else if (argc != 2) return tclcommand_integrate_print_usage(interp);
  }
  /* go on with integrate <n_steps> */
  if(n_steps < 0) {
    Tcl_AppendResult(interp, "illegal number of steps (must be >0) \n", (char *) NULL);
    return tclcommand_integrate_print_usage(interp);;
  }

  /* if skin wasn't set, do an educated guess now */
  if (!skin_set) {
    if (max_cut == 0.0) {
      Tcl_AppendResult(interp, "cannot automatically determine skin, please set it manually via \"setmd skin\"\n", (char *) NULL);
      return TCL_ERROR;
    }
    skin = 0.4*max_cut;
    mpi_bcast_parameter(FIELD_SKIN);
  }

  /* perform integration */
  if (!correlations_autoupdate && !observables_autoupdate) {
    if (mpi_integrate(n_steps, reuse_forces))
      return gather_runtime_errors(interp, TCL_OK);
  } else  {
    for (int i=0; i<n_steps; i++) {
      if (mpi_integrate(1, reuse_forces))
        return gather_runtime_errors(interp, TCL_OK);
      reuse_forces=1;
      autoupdate_observables();
      autoupdate_correlations();
    }
    if (n_steps == 0){
      if (mpi_integrate(0, reuse_forces))
        return gather_runtime_errors(interp, TCL_OK);
    }
  }
  return TCL_OK;
}
Esempio n. 6
0
/** Parses the ICCP3M command.
 */
int tclcommand_iccp3m(ClientData data, Tcl_Interp *interp, int argc, char **argv) {
  int last_ind_id,num_iteration,normal_args,area_args;
  char buffer[TCL_DOUBLE_SPACE];
  double e1,convergence,relax;

  Tcl_AppendResult(interp, "The ICCP3M algorithm is still experimental. Function can not be guaranteed, therefore it is still disabled.\n", (char *)NULL);
  return (TCL_ERROR);

  if(iccp3m_initialized==0){
      iccp3m_init();
      iccp3m_initialized=1;
  }

  if(argc != 9 && argc != 2 && argc != 10) { 
         Tcl_AppendResult(interp, "Wrong # of args! Usage: iccp3m { iterate | <last_ind_id> <e1> <num_iteration> <convergence> <relaxation> <area> <normal_components> <e_in/e_out>  [<ext_field>] }", (char *)NULL); 
         return (TCL_ERROR); 
   }
   if (argc == 2 ){
      if(ARG_IS_S(1,"iterate")) { 
           if (iccp3m_cfg.set_flag==0) {
                 Tcl_AppendResult(interp, "iccp3m parameters not set!", (char *)NULL);
                 return (TCL_ERROR);
           }
           else{ 
              Tcl_PrintDouble(interp,mpi_iccp3m_iteration(0),buffer); 
              Tcl_AppendResult(interp, buffer, (char *) NULL);
              return TCL_OK;
	   }
      }
   }
   else {
      if(!ARG_IS_I(1, last_ind_id)) {
          Tcl_ResetResult(interp);
          Tcl_AppendResult(interp, "Last induced id must be integer (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR);
          } else if(last_ind_id < 2) { 
          Tcl_ResetResult(interp);
          Tcl_AppendResult(interp, "Last induced id can not be smaller then 2 (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR);
       }
       if(!ARG_IS_D(2, e1)) {
          Tcl_ResetResult(interp);
          Tcl_AppendResult(interp, "Dielectric constant e1(inner) must be double(got: ", argv[2],")!", (char *)NULL); return (TCL_ERROR);
       }
       if(!ARG_IS_I(3, num_iteration)) {
          Tcl_ResetResult(interp);
          Tcl_AppendResult(interp, "Number of maximum iterations must be integer (got: ", argv[4],")!", (char *)NULL); return (TCL_ERROR);
       }
       if(!ARG_IS_D(4, convergence)) {
          Tcl_ResetResult(interp);
          Tcl_AppendResult(interp, "Convergence criterion must be double (got: ", argv[5],")!", (char *)NULL); return (TCL_ERROR);
          } else if( (convergence < 1e-10) || (convergence > 1e-1) ) { 
            Tcl_ResetResult(interp);
            Tcl_AppendResult(interp, "Convergence criterion can not be smaller then 1e-10 and greater then 1e-2(got: ", argv[5],")!", (char *)NULL); return (TCL_ERROR);
         }
          if(!ARG_IS_D(5, relax)) {
             Tcl_ResetResult(interp);
             Tcl_AppendResult(interp, "Relaxation parameter must be double (got: ", argv[6],")!", (char *)NULL); return (TCL_ERROR);
       }
   
       iccp3m_cfg.last_ind_id = last_ind_id;      /* Assign needed options */
       iccp3m_cfg.num_iteration = num_iteration; /* maximum number of iterations to go */
       iccp3m_cfg.eout = e1;
       iccp3m_cfg.convergence = convergence;
       iccp3m_cfg.relax = relax;
       iccp3m_cfg.update = 0;
       iccp3m_cfg.set_flag = 1;
       
       normal_args = (iccp3m_cfg.last_ind_id+1)*3;
       /* Now get Normal Vectors components consecutively */
       
       if( tclcommand_iccp3m_parse_params(interp,normal_args,argv[7],ICCP3M_NORMAL) == 1) { 
              Tcl_ResetResult(interp);
              Tcl_AppendResult(interp, "ICCP3M: Error in following normal vectors\n", argv[7],"\nICCP3M: Error in previous normal vectors\n", (char *)NULL); 
              return (TCL_ERROR);
       }      

       area_args=(iccp3m_cfg.last_ind_id+1);
       /* Now get area of the boundary elements */
       
       if ( tclcommand_iccp3m_parse_params(interp,area_args,argv[6],ICCP3M_AREA) == 1 ){
             Tcl_ResetResult(interp);
             Tcl_AppendResult(interp, "ICCP3M: Error in following areas\n", argv[6],"\nICCP3M: Error in previous areas\n", (char *)NULL); return (TCL_ERROR);
       }
       /* Now get the ration ein/eout for each element. 
          It's the user's duty to make sure that only disconnected 
          regions have different ratios */
      if ( tclcommand_iccp3m_parse_params(interp,area_args,argv[8],ICCP3M_EPSILON) == 1 ) {
             Tcl_ResetResult(interp);
             Tcl_AppendResult(interp, "ICCP3M: Error in following dielectric constants\n", argv[8],"\nICCP3M:  Error in previous dielectric constants\n", (char *)NULL); return (TCL_ERROR);
       } 

       if( argc == 10 ) {
         if( tclcommand_iccp3m_parse_params(interp,normal_args,argv[9],ICCP3M_EXTFIELD) == 1) { 
              Tcl_ResetResult(interp);
              Tcl_AppendResult(interp, "ICCP3M: Error in following external field vectors\n", argv[9],"\nICCP3M: Error in previous external field vectors\n", (char *)NULL); return (TCL_ERROR);
         }      
       }
       else {
         printf("allocating zeroes for external field \n");
         iccp3m_cfg.extx = (double*)calloc((last_ind_id +1), sizeof(double));
         iccp3m_cfg.exty = (double*)calloc((last_ind_id +1), sizeof(double));
         iccp3m_cfg.extz = (double*)calloc((last_ind_id +1), sizeof(double));
       }
      
       mpi_iccp3m_init(0);
       Tcl_PrintDouble(interp,mpi_iccp3m_iteration(0),buffer); 
       Tcl_AppendResult(interp, buffer, (char *) NULL);
       return TCL_OK;
   } /* else (argc==10) */
   return TCL_OK;
}
Esempio n. 7
0
int tclcommand_inter_parse_lj(Tcl_Interp * interp,
			      int part_type_a, int part_type_b,
			      int argc, char ** argv)
{
  /* parameters needed for LJ */
  double eps, sig, cut, shift, offset, cap_radius, min;
#ifdef SHANCHEN
  double *affinity=NULL;
#endif
  int compute_auto_shift, change;

  /* get lennard-jones interaction type */
  if (argc < 4) {
    Tcl_AppendResult(interp, "lennard-jones needs at least 3 parameters: "
		     "<lj_eps> <lj_sig> <lj_cut> [<lj_shift> [<lj_offset> [<lj_cap> [<lj_min>]]]]",
		     (char *) NULL);
    return 0;
  }
  change = 1;

  /* PARSE LENNARD-JONES COMMAND LINE */
  /* epsilon */
  if (! ARG_IS_D(1, eps)) {
    Tcl_AppendResult(interp, "<lj_eps> should be a double",
		     (char *) NULL);
    return 0;
  }
  change++;

  /* sigma */
  if (! ARG_IS_D(2, sig)) {
    Tcl_AppendResult(interp, "<lj_sig> should be a double",
		     (char *) NULL);
    return 0;
  }
  change++;

  /* cutoff */
  if (! ARG_IS_D(3, cut)) {
    Tcl_AppendResult(interp, "<lj_cut> should be a double",
		     (char *) NULL);
    return 0;
  }
  change++;
  
  /* shift */
  if (argc > 4) {
    if (ARG_IS_D(4, shift)) {
      /* if a shift is given, use that one */
      compute_auto_shift = 0;
      change++;
    } else if (ARG_IS_S(4, "auto")) {
      Tcl_ResetResult(interp);
      compute_auto_shift = 1;
      /* if shift is "auto", autocompute the shift */
      change++;
    } else {
      Tcl_AppendResult(interp, "<lj_shift> should be a double or \"auto\"",
		       (char *) NULL);
      return 0;
    }
  } else {
    /* by default, compute the shift automatically */
    compute_auto_shift = 1;
  }
  /* the shift can be computed automatically only when the other
     parameters have been determined, see below */

  /* offset */
  if (argc > 5) {
    if (!ARG_IS_D(5, offset)) {
      Tcl_AppendResult(interp, "<lj_off> should be a double",
		       (char *) NULL);
      return 0;
    }
    change++;
  } else {
    offset = 0.0;
  }
  
  /* cap_radius */
  if (argc > 6) {
    if (!ARG_IS_D(6, cap_radius)) {
      Tcl_AppendResult(interp, "<lj_cap> should be a double",
		       (char *) NULL);
      return 0;
    }
    change++;
  } else {
    cap_radius = -1.0;
  }

  /* minimal radius */
  if (argc > 7) {
    if (!ARG_IS_D(7, min)) {
      Tcl_AppendResult(interp, "<lj_rmin> should be a double",
		       (char *) NULL);
      return 0;
    }
    change ++;
  } else {
    min = 0.0;
  }

  /* automatically compute the shift */
  if (compute_auto_shift)
    shift = -(pow(sig/cut, 12) - pow(sig/cut, 6));

  /* now set the parameters */
  if (lennard_jones_set_params(part_type_a, part_type_b,
			       eps, sig, cut, shift, offset,
			       cap_radius, min) == ES_ERROR) {
    Tcl_AppendResult(interp, "particle types must be non-negative", 
		     (char *) NULL);
    return 0;
  }
  return change;
}