int parse_id_list(Tcl_Interp* interp, int argc, char** argv, int* change, IntList** ids ) { int i,ret; // char** temp_argv; int temp_argc; // int temp; IntList* input=(IntList*)malloc(sizeof(IntList)); IntList* output=(IntList*)malloc(sizeof(IntList)); init_intlist(input); alloc_intlist(input,1); init_intlist(output); alloc_intlist(output,1); if (argc<1) { Tcl_AppendResult(interp, "Error parsing id list\n", (char *)NULL); return TCL_ERROR; } if (ARG0_IS_S("ids")) { if (!parse_int_list(interp, argv[1],input)) { Tcl_AppendResult(interp, "Error parsing id list\n", (char *)NULL); return TCL_ERROR; } *ids=input; for (i=0; i<input->n; i++) { if (input->e[i] >= n_part) { Tcl_AppendResult(interp, "Error parsing ID list. Given particle ID exceeds the number of existing particles\n", (char *)NULL); return TCL_ERROR; } } *change=2; return TCL_OK; } else if ( ARG0_IS_S("types") ) { if (!parse_int_list(interp, argv[1],input)) { Tcl_AppendResult(interp, "Error parsing types list\n", (char *)NULL); return TCL_ERROR; } if( (ret=convert_types_to_ids(input,output))<=0){ Tcl_AppendResult(interp, "Error parsing types list. No particle with given types found.\n", (char *)NULL); return TCL_ERROR; } else { *ids=output; } *change=2; return TCL_OK; } else if ( ARG0_IS_S("all") ) { if( (ret=convert_types_to_ids(NULL,output))<=0){ Tcl_AppendResult(interp, "Error parsing keyword all. No particle found.\n", (char *)NULL); return TCL_ERROR; } else { *ids=output; } *change=1; return TCL_OK; } Tcl_AppendResult(interp, "unknown keyword given to observable: ", argv[0] , (char *)NULL); return TCL_ERROR; }
/** Calculate the center of mass, total mass, velocity, total force, and trap force on all trapped molecules */ void calc_mol_info () { /* list of trapped molecules on this node */ IntList local_trapped_mols; /* check to see if all the topology information has been synced to the various slave nodes */ if ( !topo_part_info_synced ) { char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE); ERROR_SPRINTF(errtxt, "{ 093 can't calculate molforces: must execute analyse set topo_part_sync first }"); return; } init_intlist(&local_trapped_mols); /* Find out which trapped molecules are on this node */ get_local_trapped_mols(&local_trapped_mols); /* Calculate the center of mass, mass, velocity, force of whatever fraction of each trapped molecule is on this node*/ calc_local_mol_info(&local_trapped_mols); /* Communicate all this molecular information between nodes. It is all sent to the master node which combines it, calculates the trap forces, and sends the information back */ if (this_node == 0) { mpi_comm_mol_info(&local_trapped_mols); } else { mpi_comm_mol_info_slave(&local_trapped_mols); } realloc_intlist(&local_trapped_mols,0); }
void realloc_topology(int size) { int m; for(m = size ; m < n_molecules; m++) { realloc_intlist(&topology[m].part, 0); } topology = (Molecule*)Utils::realloc(topology, size*sizeof(Molecule)); if (n_molecules < 0) n_molecules = 0; for(m = n_molecules; m < size; m++) { init_intlist(&topology[m].part); #ifdef MOLFORCES topology[m].trap_flag = 32; topology[m].noforce_flag = 32; topology[m].favcounter = -1; topology[m].fav[0] = 0; topology[m].fav[1] = 0; topology[m].fav[2] = 0; topology[m].trap_force[0] = 0; topology[m].trap_force[1] = 0; topology[m].trap_force[2] = 0; #endif /*MOLFORCES*/ } n_molecules = size; topo_part_info_synced = 0; }
void nbhood(double pt[3], double r, IntList *il, int planedims[3] ) { double d[3]; int i,j; double r2; r2 = r*r; init_intlist(il); updatePartCfg(WITHOUT_BONDS); for (i = 0; i<n_part; i++) { if ( (planedims[0] + planedims[1] + planedims[2]) == 3 ) { get_mi_vector(d, pt, partCfg[i].r.p); } else { /* Calculate the in plane distance */ for ( j= 0 ; j < 3 ; j++ ) { d[j] = planedims[j]*(partCfg[i].r.p[j]-pt[j]); } } if (sqrlen(d) < r2) { realloc_intlist(il, il->n + 1); il->e[il->n] = partCfg[i].p.identity; il->n++; } } }
void wall_sort_particles() { // 1. reallocate the boxes for the particle identities // save current number of bins int n_part_in_bin = wallstuff_boundaries.n-1; // free old boxes for (int i = 0; i < n_part_in_bin; ++i) { realloc_intlist(&wallstuff_part_in_bin[i], wallstuff_part_in_bin[i].n = 0); } wallstuff_part_in_bin = (IntList*)realloc(wallstuff_part_in_bin, (wallstuff_boundaries.n-1)*sizeof(IntList)); // initialize new ones for (int i = n_part_in_bin; i < wallstuff_boundaries.n-1; ++i) { init_intlist(&wallstuff_part_in_bin[i]); } // 2. for each particle, find the box and put its // identity there for(int i=0; i<n_part; i++) { double x = partCfg[i].r.p[0]; // ignore particles outside the wallstuff_boundaries if (x < wallstuff_boundaries.e[0] || x > wallstuff_boundaries.e[wallstuff_boundaries.n-1]) continue; // simple bisection on the particle's x-coordinate int s = 0; int e = wallstuff_boundaries.n - 1; while (e - s > 1) { int c = (e + s)/2; if (x >= wallstuff_boundaries.e[c]) s = c; else e = c; } // and add the particle to the resulting list realloc_grained_intlist(&wallstuff_part_in_bin[s], wallstuff_part_in_bin[s].n + 1, 8); wallstuff_part_in_bin[s].e[wallstuff_part_in_bin[s].n++] = i; } }
double calc_vanhove(int ptype, double rmin, double rmax, int rbins, int tmax, double *msd, double **vanhove) { int i, c1, c3, c3_max, ind, np=0; double p1[3],p2[3],dist; double bin_width, inv_bin_width; IntList p; /* create particle list */ init_intlist(&p); for(i=0; i<n_part; i++) { if( partCfg[i].p.type == ptype ) { np ++; } } if(np==0) { return 0; } alloc_intlist(&p,np); for(i=0; i<n_part; i++) { if( partCfg[i].p.type == ptype ) { p.e[p.n]=i; p.n++; } } /* preparation */ bin_width = (rmax-rmin) / (double)rbins; inv_bin_width = 1.0 / bin_width; /* calculate msd and store distribution in vanhove */ for(c1=0; c1<n_configs; c1++) { c3_max=(c1+tmax+1)>n_configs ? n_configs : c1+tmax+1; for(c3=(c1+1); c3<c3_max; c3++) { for(i=0; i<p.n; i++) { p1[0]=configs[c1][3*p.e[i] ]; p1[1]=configs[c1][3*p.e[i]+1]; p1[2]=configs[c1][3*p.e[i]+2]; p2[0]=configs[c3][3*p.e[i] ]; p2[1]=configs[c3][3*p.e[i]+1]; p2[2]=configs[c3][3*p.e[i]+2]; dist = distance(p1, p2); if(dist > rmin && dist < rmax) { ind = (int) ( (dist - rmin)*inv_bin_width ); vanhove[(c3-c1-1)][ind]++; } msd[(c3-c1-1)] += dist*dist; } } } /* normalize */ for(c1=0; c1<(tmax); c1++) { for(i=0; i<rbins; i++) { vanhove[c1][i] /= (double) (n_configs-c1-1)*p.n; } msd[c1] /= (double) (n_configs-c1-1)*p.n; } realloc_intlist(&p,0); return np; }
void send_particles(ParticleList *particles, int node) { int pc; /* Dynamic data, bonds and exclusions */ IntList local_dyn; PART_TRACE(fprintf(stderr, "%d: send_particles %d to %d\n", this_node, particles->n, node)); MPI_Send(&particles->n, 1, MPI_INT, node, REQ_SNDRCV_PART, comm_cart); MPI_Send(particles->part, particles->n*sizeof(Particle), MPI_BYTE, node, REQ_SNDRCV_PART, comm_cart); init_intlist(&local_dyn); for (pc = 0; pc < particles->n; pc++) { Particle *p = &particles->part[pc]; int size = local_dyn.n + p->bl.n; #ifdef EXCLUSIONS size += p->el.n; #endif realloc_intlist(&local_dyn, size); memcpy(local_dyn.e + local_dyn.n, p->bl.e, p->bl.n*sizeof(int)); local_dyn.n += p->bl.n; #ifdef EXCLUSIONS memcpy(local_dyn.e + local_dyn.n, p->el.e, p->el.n*sizeof(int)); local_dyn.n += p->el.n; #endif } PART_TRACE(fprintf(stderr, "%d: send_particles sending %d bond ints\n", this_node, local_dyn.n)); if (local_dyn.n > 0) { MPI_Send(local_dyn.e, local_dyn.n*sizeof(int), MPI_BYTE, node, REQ_SNDRCV_PART, comm_cart); realloc_intlist(&local_dyn, 0); } /* remove particles from this nodes local list and free data */ for (pc = 0; pc < particles->n; pc++) { local_particles[particles->part[pc].p.identity] = NULL; free_particle(&particles->part[pc]); } realloc_particlelist(particles, particles->n = 0); }
int parse_generic_structure_info(Tcl_Interp *interp, int argc, char **argv) { int arg; IntList il; init_intlist(&il); realloc_topology(argc); for (arg = 0; arg < argc; arg++) { if (!ARG_IS_INTLIST(arg, il)) { realloc_topology(0); realloc_intlist(&il, 0); return TCL_ERROR; } topology[arg].type = il.e[0]; realloc_intlist(&topology[arg].part, topology[arg].part.n = il.n - 1); memcpy(topology[arg].part.e, &il.e[1], (il.n - 1)*sizeof(int)); } realloc_intlist(&il, 0); return TCL_OK; }
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_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; }
/** This routine calculates the orientational order parameter for a lipid bilayer. */ int orient_order(double* result, double* stored_dirs) { double dir[3]; double refdir[3] = {0,0,1}; double sumdir[3] = {0,0,0}; double zref; int bilayer_cnt; int i,atom,tmpzdir; double dp; double len; IntList l_orient; init_intlist(&l_orient); realloc_intlist(&l_orient, n_molecules); bilayer_cnt = 0; *result = 0; // Check to see if the grid has been set and if not then interpret if ( xdir + ydir + zdir == -3 ) { tmpzdir = 2; } else { tmpzdir = zdir; }; /* Update particles */ updatePartCfg(WITHOUT_BONDS); /* Make sure particles are sorted */ if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt, "{035 could not sort partCfg, particles have to start at 0 and have consecutive identities} "); return ES_ERROR; } /* Calculate the reference z position as its mean.*/ zref = calc_zref( tmpzdir ); /* Calculate the orientation of all the lipids in turn and include only UP or DOWN lipids in a calculation of the overall orientation direction of the bilayer .. ie the reference vector from which we can calculate the orientational order. */ for ( i = 0 ; i < n_molecules ; i++) { atom = topology[i].part.e[0]; l_orient.e[i] = lipid_orientation(atom,partCfg,zref,dir,refdir); stored_dirs[i*3] = dir[0]; stored_dirs[i*3+1] = dir[1]; stored_dirs[i*3+2] = dir[2]; if ( l_orient.e[i] == LIPID_UP ) { sumdir[0] += dir[0]; sumdir[1] += dir[1]; sumdir[2] += dir[2]; bilayer_cnt++; } if ( l_orient.e[i] == LIPID_DOWN ) { sumdir[0] -= dir[0]; sumdir[1] -= dir[1]; sumdir[2] -= dir[2]; bilayer_cnt++; } } /* Normalise the bilayer normal vector */ len = 0.0; for ( i = 0 ; i < 3 ; i++) { sumdir[i] = sumdir[i]/(double)(bilayer_cnt); len += sumdir[i]*sumdir[i]; } for ( i = 0 ; i < 3 ; i++) { sumdir[i] = sumdir[i]/sqrt(len); } /* Calculate the orientational order */ for ( i = 0 ; i < n_molecules ; i++ ) { dir[0] = stored_dirs[i*3]; dir[1] = stored_dirs[i*3+1]; dir[2] = stored_dirs[i*3+2]; if ( l_orient.e[i] != LIPID_STRAY && l_orient.e[i] != REAL_LIPID_STRAY ) { dp = scalar(dir,sumdir); *result += dp*dp*1.5-0.5; } } realloc_intlist(&l_orient, 0); *result = *result/(double)(bilayer_cnt); return ES_OK; }
void auto_exclusion(int distance) { int count, p, i, j, p1, p2, p3, dist1, dist2; Bonded_ia_parameters *ia_params; Particle *part1; /* partners is a list containing the currently found excluded particles for each particle, and their distance, as a interleaved list */ IntList *partners; updatePartCfg(WITH_BONDS); /* setup bond partners and distance list. Since we need to identify particles via their identity, we use a full sized array */ partners = (IntList*)malloc((max_seen_particle + 1)*sizeof(IntList)); for (p = 0; p <= max_seen_particle; p++) init_intlist(&partners[p]); /* determine initial connectivity */ for (p = 0; p < n_part; p++) { part1 = &partCfg[p]; p1 = part1->p.identity; for (i = 0; i < part1->bl.n;) { ia_params = &bonded_ia_params[part1->bl.e[i++]]; if (ia_params->num == 1) { p2 = part1->bl.e[i++]; /* you never know what the user does, may bond a particle to itself...? */ if (p2 != p1) { add_partner(&partners[p1], p1, p2, 1); add_partner(&partners[p2], p2, p1, 1); } } else i += ia_params->num; } } /* calculate transient connectivity. For each of the current neighbors, also exclude their close enough neighbors. */ for (count = 1; count < distance; count++) { for (p1 = 0; p1 <= max_seen_particle; p1++) { for (i = 0; i < partners[p1].n; i += 2) { p2 = partners[p1].e[i]; dist1 = partners[p1].e[i + 1]; if (dist1 > distance) continue; /* loop over all partners of the partner */ for (j = 0; j < partners[p2].n; j += 2) { p3 = partners[p2].e[j]; dist2 = dist1 + partners[p2].e[j + 1]; if (dist2 > distance) continue; add_partner(&partners[p1], p1, p3, dist2); add_partner(&partners[p3], p3, p1, dist2); } } } } /* setup the exclusions and clear the arrays. We do not setup the exclusions up there, since on_part_change clears the partCfg, so that we would have to restore it continously. Of course this could be optimized by bundling the exclusions, but this is only done once and the overhead is as much as for setting the bonds, which the user apparently accepted. */ for (p = 0; p <= max_seen_particle; p++) { for (j = 0; j < partners[p].n; j++) if (p < partners[p].e[j]) change_exclusion(p, partners[p].e[j], 0); realloc_intlist(&partners[p], 0); } free(partners); }
void recv_particles(ParticleList *particles, int node) { int transfer=0, read, pc; IntList local_dyn; PART_TRACE(fprintf(stderr, "%d: recv_particles from %d\n", this_node, node)); MPI_Recv(&transfer, 1, MPI_INT, node, REQ_SNDRCV_PART, comm_cart, MPI_STATUS_IGNORE); PART_TRACE(fprintf(stderr, "%d: recv_particles get %d\n", this_node, transfer)); realloc_particlelist(particles, particles->n + transfer); MPI_Recv(&particles->part[particles->n], transfer*sizeof(Particle), MPI_BYTE, node, REQ_SNDRCV_PART, comm_cart, MPI_STATUS_IGNORE); particles->n += transfer; init_intlist(&local_dyn); for (pc = particles->n - transfer; pc < particles->n; pc++) { Particle *p = &particles->part[pc]; local_dyn.n += p->bl.n; #ifdef EXCLUSIONS local_dyn.n += p->el.n; #endif PART_TRACE(fprintf(stderr, "%d: recv_particles got particle %d\n", this_node, p->p.identity)); if (local_particles[p->p.identity] != NULL) { fprintf(stderr, "%d: transmitted particle %d is already here...\n", this_node, p->p.identity); errexit(); } } update_local_particles(particles); PART_TRACE(fprintf(stderr, "%d: recv_particles expecting %d bond ints\n", this_node, local_dyn.n)); if (local_dyn.n > 0) { alloc_intlist(&local_dyn, local_dyn.n); MPI_Recv(local_dyn.e, local_dyn.n*sizeof(int), MPI_BYTE, node, REQ_SNDRCV_PART, comm_cart, MPI_STATUS_IGNORE); } read = 0; for (pc = particles->n - transfer; pc < particles->n; pc++) { Particle *p = &particles->part[pc]; if (p->bl.n > 0) { alloc_intlist(&p->bl, p->bl.n); memcpy(p->bl.e, &local_dyn.e[read], p->bl.n*sizeof(int)); read += p->bl.n; } else p->bl.e = NULL; #ifdef EXCLUSIONS if (p->el.n > 0) { alloc_intlist(&p->el, p->el.n); memcpy(p->el.e, &local_dyn.e[read], p->el.n*sizeof(int)); read += p->el.n; } else p->el.e = NULL; #endif } if (local_dyn.n > 0) realloc_intlist(&local_dyn, 0); }
void init_particle(Particle *part) { /* ParticleProperties */ part->p.identity = -1; part->p.type = 0; part->p.mol_id = -1; #ifdef MASS part->p.mass = 1.0; #endif #ifdef SHANCHEN int ii; for(ii=0;ii<2*LB_COMPONENTS;ii++){ part->p.solvation[ii]=0.0; } for(ii=0;ii<LB_COMPONENTS;ii++){ part->r.composition[ii]=0.0; } #endif #ifdef ROTATIONAL_INERTIA part->p.rinertia[0] = 1.0; part->p.rinertia[1] = 1.0; part->p.rinertia[2] = 1.0; #endif #ifdef ROTATION_PER_PARTICLE part->p.rotation =1; #endif #ifdef ELECTROSTATICS part->p.q = 0.0; #endif #ifdef LB_ELECTROHYDRODYNAMICS part->p.mu_E[0] = 0.0; part->p.mu_E[1] = 0.0; part->p.mu_E[2] = 0.0; #endif #ifdef CATALYTIC_REACTIONS part->p.catalyzer_count = 0; #endif /* ParticlePosition */ part->r.p[0] = 0.0; part->r.p[1] = 0.0; part->r.p[2] = 0.0; #ifdef BOND_CONSTRAINT part->r.p_old[0] = 0.0; part->r.p_old[1] = 0.0; part->r.p_old[2] = 0.0; #endif #ifdef ROTATION part->r.quat[0] = 1.0; part->r.quat[1] = 0.0; part->r.quat[2] = 0.0; part->r.quat[3] = 0.0; part->r.quatu[0] = 0.0; part->r.quatu[1] = 0.0; part->r.quatu[2] = 1.0; #endif #ifdef DIPOLES part->r.dip[0] = 0.0; part->r.dip[1] = 0.0; part->r.dip[2] = 0.0; part->p.dipm = 0.0; #endif /* ParticleMomentum */ part->m.v[0] = 0.0; part->m.v[1] = 0.0; part->m.v[2] = 0.0; #ifdef ROTATION part->m.omega[0] = 0.0; part->m.omega[1] = 0.0; part->m.omega[2] = 0.0; #endif /* ParticleForce */ part->f.f[0] = 0.0; part->f.f[1] = 0.0; part->f.f[2] = 0.0; #ifdef ROTATION part->f.torque[0] = 0.0; part->f.torque[1] = 0.0; part->f.torque[2] = 0.0; #endif /* ParticleLocal */ part->l.p_old[0] = 0.0; part->l.p_old[1] = 0.0; part->l.p_old[2] = 0.0; part->l.i[0] = 0; part->l.i[1] = 0; part->l.i[2] = 0; #ifdef GHMC /* Last Saved ParticlePosition */ part->l.r_ls.p[0] = 0.0; part->l.r_ls.p[1] = 0.0; part->l.r_ls.p[2] = 0.0; #ifdef BOND_CONSTRAINT part->l.r_ls.p_old[0] = 0.0; part->l.r_ls.p_old[1] = 0.0; part->l.r_ls.p_old[2] = 0.0; #endif #ifdef ROTATION part->l.r_ls.quat[0] = 1.0; part->l.r_ls.quat[1] = 0.0; part->l.r_ls.quat[2] = 0.0; part->l.r_ls.quat[3] = 0.0; part->l.r_ls.quatu[0] = 0.0; part->l.r_ls.quatu[1] = 0.0; part->l.r_ls.quatu[2] = 1.0; #endif #ifdef DIPOLES part->l.r_ls.dip[0] = 0.0; part->l.r_ls.dip[1] = 0.0; part->l.r_ls.dip[2] = 0.0; //part->l.p_ls.dipm = 0.0; #endif /* Last Saved ParticleMomentum */ part->l.m_ls.v[0] = 0.0; part->l.m_ls.v[1] = 0.0; part->l.m_ls.v[2] = 0.0; #ifdef ROTATION part->l.m_ls.omega[0] = 0.0; part->l.m_ls.omega[1] = 0.0; part->l.m_ls.omega[2] = 0.0; #endif #endif #ifdef EXTERNAL_FORCES part->l.ext_flag = 0; part->l.ext_force[0] = 0.0; part->l.ext_force[1] = 0.0; part->l.ext_force[2] = 0.0; #ifdef ROTATION part->l.ext_torque[0] = 0.0; part->l.ext_torque[1] = 0.0; part->l.ext_torque[2] = 0.0; #endif #endif init_intlist(&(part->bl)); #ifdef EXCLUSIONS init_intlist(&(part->el)); #endif #ifdef VIRTUAL_SITES part->p.isVirtual = 0; #endif #ifdef VIRTUAL_SITES_RELATIVE part->p.vs_relative_to_particle_id = 0; part->p.vs_relative_distance =0; #endif #ifdef GHOST_FLAG part->l.ghost = 0; #endif #ifdef LANGEVIN_PER_PARTICLE part->p.T = -1.0; part->p.gamma = -1.0; #endif }
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; }