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; }
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); }
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); }
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; }
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; }
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; }
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; }
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; }
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; }