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;
}
예제 #2
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);
}
예제 #3
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);
  
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
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;
}
예제 #8
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;
}
예제 #9
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;
}