int remove_particle(int part) { int pnode; Particle *cur_par = (Particle *) malloc (sizeof(Particle)); if (get_particle_data(part, cur_par) == ES_ERROR ) return ES_ERROR; int type = cur_par->p.type; free(cur_par); if (remove_id_type_array(part, type) == ES_ERROR ) return ES_ERROR; if (!particle_node) build_particle_node(); if (part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; particle_node[part] = -1; mpi_remove_particle(pnode, part); if (part == max_seen_particle) { while (max_seen_particle >= 0 && particle_node[max_seen_particle] == -1) max_seen_particle--; mpi_bcast_parameter(FIELD_MAXPART); } return ES_OK; }
int place_particle(int part, double p[3]) { int i; int pnode, retcode = ES_PART_OK; if (part < 0) return ES_PART_ERROR; if (!particle_node) build_particle_node(); pnode = (part <= max_seen_particle) ? particle_node[part] : -1; if (pnode == -1) { /* new particle, node by spatial position */ pnode = cell_structure.position_to_node(p); /* master node specific stuff */ realloc_particle_node(part); particle_node[part] = pnode; /* fill up possible gap */ for (i = max_seen_particle + 1; i < part; i++) particle_node[i] = -1; retcode = ES_PART_CREATED; mpi_place_new_particle(pnode, part, p); } else { mpi_place_particle(pnode, part, p); } return retcode; }
int set_particle_torque_lab(int part, double torque_lab[3]) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; /* Internal functions require the body coordinates so we need to convert to these from the lab frame */ double A[9]; double torque[3]; Particle particle; get_particle_data(part, &particle); define_rotation_matrix(&particle, A); torque[0] = A[0 + 3*0]*torque_lab[0] + A[0 + 3*1]*torque_lab[1] + A[0 + 3*2]*torque_lab[2]; torque[1] = A[1 + 3*0]*torque_lab[0] + A[1 + 3*1]*torque_lab[1] + A[1 + 3*2]*torque_lab[2]; torque[2] = A[2 + 3*0]*torque_lab[0] + A[2 + 3*1]*torque_lab[1] + A[2 + 3*2]*torque_lab[2]; mpi_send_torque(pnode, part, torque); return ES_OK; }
int change_particle_bond(int part, int *bond, int _delete) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; if(_delete != 0 || bond == NULL) _delete = 1; if (bond != NULL) { if (bond[0] < 0 || bond[0] >= n_bonded_ia) { ostringstream msg; msg <<"invalid/unknown bonded interaction type " << bond[0]; runtimeError(msg); return ES_ERROR; } } return mpi_send_bond(pnode, part, bond, _delete); }
int set_particle_fix(int part, int flag) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_ext_force(pnode, part, flag, COORDS_FIX_MASK, NULL); return ES_OK; }
int get_particle_data(int part, Particle *data) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_recv_part(pnode, part, data); return ES_OK; }
int set_particle_rotational_inertia(int part, double rinertia[3]) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_rotational_inertia(pnode, part, rinertia); return ES_OK; }
int set_particle_dipm(int part, double dipm) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_dipm(pnode, part, dipm); return ES_OK; }
int set_particle_mu_E(int part, double mu_E[3]) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_mu_E(pnode, part, mu_E); return ES_OK; }
int set_particle_virtual(int part, int isVirtual) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_virtual(pnode, part, isVirtual); return ES_OK; }
int set_particle_solvation(int part, double * solvation) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_solvation(pnode, part, solvation); return ES_OK; }
int set_particle_rotation(int part, int rot) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_rotation(pnode, part, rot); return ES_OK; }
int set_particle_quat(int part, double quat[4]) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_quat(pnode, part, quat); return ES_OK; }
int change_exclusion(int part1, int part2, int _delete) { if (!particle_node) build_particle_node(); if (part1 < 0 || part1 > max_seen_particle || part2 < 0 || part2 > max_seen_particle || part1 == part2 || particle_node[part1] == -1 || particle_node[part2] == -1) return ES_ERROR; mpi_send_exclusion(part1, part2, _delete); return ES_OK; }
int set_particle_mol_id(int part, int mid) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_mol_id(pnode, part, mid); return ES_OK; }
int set_particle_ext_force(int part, int flag, double force[3]) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_ext_force(pnode, part, flag, PARTICLE_EXT_FORCE, force); return ES_OK; }
int set_particle_temperature(int part, double T) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_set_particle_temperature(pnode, part, T); return ES_OK; }
int set_particle_type(int part, int type) { int pnode; make_particle_type_exist(type); if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; // check if the particle exists already and the type is changed, then remove it from the list which contains it Particle *cur_par = (Particle *) malloc( sizeof(Particle) ); if ( Type_array_init ) { if ( cur_par != (Particle *) 0 ) { if ( get_particle_data(part, cur_par) != ES_ERROR ) { int prev_type = cur_par->p.type; if ( prev_type != type ) { // particle existed before so delete it from the list remove_id_type_array(part, prev_type); } } } free(cur_par); } mpi_send_type(pnode, part, type); #ifdef ADDITIONAL_CHECKS if ( Type_array_init ) { if ( add_particle_to_list(part, type) == ES_ERROR ){ //Tcl_AppendResult(interp, "gc particle add failed", (char *) NULL); return ES_ERROR; } } #endif return ES_OK; }
int set_particle_vs_relative(int part, int vs_relative_to, double vs_distance) { // Find out, on what node the particle is int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; // Send the stuff mpi_send_vs_relative(pnode, part, vs_relative_to, vs_distance); return ES_OK; }
int set_particle_gamma(int part, double gamma) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_set_particle_gamma(pnode, part, gamma); return ES_OK; }
int set_particle_torque_body(int part, double torque[3]) { /* Nothing to be done but pass, since the coordinates are already in the proper frame */ int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; mpi_send_torque(pnode, part, torque); return ES_OK; }
int change_particle_bond(int part, int *bond, int _delete) { int pnode; if (!particle_node) build_particle_node(); if (part < 0 || part > max_seen_particle) return ES_ERROR; pnode = particle_node[part]; if (pnode == -1) return ES_ERROR; if(_delete != 0 || bond == NULL) _delete = 1; if (bond != NULL) { if (bond[0] < 0 || bond[0] >= n_bonded_ia) { char *errtxt = runtime_error(128 + ES_INTEGER_SPACE); ERROR_SPRINTF(errtxt, "{048 invalid/unknown bonded interaction type %d}", bond[0]); return ES_ERROR; } } return mpi_send_bond(pnode, part, bond, _delete); }
int tclcommand_readmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) { char *row; int pos_row[3] = { -1 }, v_row[3] = { -1 }, #ifdef DIPOLES dip_row[3] = { -1 }, #endif f_row[3] = { -1 }; int av_pos = 0, av_v = 0, #ifdef DIPOLES av_dip=0, #endif #ifdef MASS av_mass=0, #endif #ifdef SHANCHEN av_solvation=0, #endif av_f = 0, #ifdef ELECTROSTATICS av_q = 0, #endif av_type = 0; int node, i; struct MDHeader header; Particle data; int tcl_file_mode; Tcl_Channel channel; if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " <file>\"", (char *) NULL); return (TCL_ERROR); } if ((channel = Tcl_GetChannel(interp, argv[1], &tcl_file_mode)) == NULL) return (TCL_ERROR); /* tune channel to binary translation, e.g. none */ Tcl_SetChannelOption(interp, channel, "-translation", "binary"); Tcl_Read(channel, (char *)&header, sizeof(header)); /* check token */ if (strncmp(header.magic, MDMAGIC, 4) || header.n_rows < 0) { Tcl_AppendResult(interp, "data file \"", argv[1], "\" does not contain tcl MD data", (char *) NULL); return (TCL_ERROR); } if (!particle_node) build_particle_node(); /* parse rows */ row = (char*)malloc(header.n_rows*sizeof(char)); for (i = 0; i < header.n_rows; i++) { Tcl_Read(channel, (char *)&row[i], sizeof(char)); switch (row[i]) { case POSX: pos_row[0] = i; break; case POSY: pos_row[1] = i; break; case POSZ: pos_row[2] = i; break; case VX: v_row[0] = i; break; case VY: v_row[1] = i; break; case VZ: v_row[2] = i; break; #ifdef DIPOLES case MX: dip_row[0] = i; break; case MY: dip_row[1] = i; break; case MZ: dip_row[2] = i; break; #endif case FX: f_row[0] = i; break; case FY: f_row[1] = i; break; case FZ: f_row[2] = i; break; #ifdef MASS case MASSES: av_mass = 1; break; #endif #ifdef SHANCHEN case SOLVATION: av_solvation = 1; break; #endif #ifdef ELECTROSTATICS case Q: av_q = 1; break; #endif case TYPE: av_type = 1; break; } } /* *_row[0] tells if * data is completely available - * otherwise we ignore it */ if (pos_row[0] != -1 && pos_row[1] != -1 && pos_row[2] != -1) { av_pos = 1; } if (v_row[0] != -1 && v_row[1] != -1 && v_row[2] != -1) { av_v = 1; } if (f_row[0] != -1 && f_row[1] != -1 && f_row[2] != -1) { av_f = 1; } #ifdef DIPOLES if (dip_row[0] != -1 && dip_row[1] != -1 && dip_row[2] != -1) { av_dip = 1; } #endif while (!Tcl_Eof(channel)) { Tcl_Read(channel, (char *)&data.p.identity, sizeof(int)); if (data.p.identity == -1) break; /* printf("id=%d\n", data.identity); */ if (data.p.identity < 0) { Tcl_AppendResult(interp, "illegal data format in data file \"", argv[1], "\", perhaps wrong file?", (char *) NULL); free(row); return (TCL_ERROR); } for (i = 0; i < header.n_rows; i++) { switch (row[i]) { case POSX: Tcl_Read(channel, (char *)&data.r.p[0], sizeof(double)); break; case POSY: Tcl_Read(channel, (char *)&data.r.p[1], sizeof(double)); break; case POSZ: Tcl_Read(channel, (char *)&data.r.p[2], sizeof(double)); break; case VX: Tcl_Read(channel, (char *)&data.m.v[0], sizeof(double)); break; case VY: Tcl_Read(channel, (char *)&data.m.v[1], sizeof(double)); break; case VZ: Tcl_Read(channel, (char *)&data.m.v[2], sizeof(double)); break; case FX: Tcl_Read(channel, (char *)&data.f.f[0], sizeof(double)); break; case FY: Tcl_Read(channel, (char *)&data.f.f[1], sizeof(double)); break; case FZ: Tcl_Read(channel, (char *)&data.f.f[2], sizeof(double)); break; case MASSES: #ifdef MASS Tcl_Read(channel, (char *)&data.p.mass, sizeof(double)); break; #else { double dummy_mass; Tcl_Read(channel, (char *)&dummy_mass, sizeof(double)); break; } #endif #ifdef ELECTROSTATICS case Q: Tcl_Read(channel, (char *)&data.p.q, sizeof(double)); break; #endif #ifdef DIPOLES case MX: Tcl_Read(channel, (char *)&data.r.dip[0], sizeof(double)); break; case MY: Tcl_Read(channel, (char *)&data.r.dip[1], sizeof(double)); break; case MZ: Tcl_Read(channel, (char *)&data.r.dip[2], sizeof(double)); break; #endif case TYPE: Tcl_Read(channel, (char *)&data.p.type, sizeof(int)); break; } } node = (data.p.identity <= max_seen_particle) ? particle_node[data.p.identity] : -1; if (node == -1) { if (!av_pos) { Tcl_AppendResult(interp, "new particle without position data", (char *) NULL); free(row); return (TCL_ERROR); } } if (av_pos) place_particle(data.p.identity, data.r.p); #ifdef MASS if (av_mass) set_particle_mass(data.p.identity, data.p.mass); #endif #ifdef SHANCHEN if (av_solvation) set_particle_solvation(data.p.identity, data.p.solvation); #endif #ifdef ELECTROSTATICS if (av_q) set_particle_q(data.p.identity, data.p.q); #endif #ifdef DIPOLES if (av_dip) set_particle_dip(data.p.identity, data.r.dip); #endif if (av_v) set_particle_v(data.p.identity, data.m.v); if (av_f) set_particle_f(data.p.identity, data.f.f); if (av_type) set_particle_type(data.p.identity, data.p.type); } free(row); return TCL_OK; }
int tclcommand_writemd(ClientData data, Tcl_Interp *interp, int argc, char **argv) { static int end_num = -1; char *row; int p, i; struct MDHeader header; int tcl_file_mode; Tcl_Channel channel; if (argc < 3) { #if defined(ELECTROSTATICS) && defined(DIPOLES) Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " <file> ?posx|posy|posz|q|mx|my|mz|vx|vy|vz|fx|fy|fz|type?* ...\"", (char *) NULL); #else #ifdef ELECTROSTATICS Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " <file> ?posx|posy|posz|q|vx|vy|vz|fx|fy|fz|type?* ...\"", (char *) NULL); #endif #ifdef DIPOLES Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " <file> ?posx|posy|posz|mx|my|mz|vx|vy|vz|fx|fy|fz|type?* ...\"", (char *) NULL); #endif #endif return (TCL_ERROR); } if ((channel = Tcl_GetChannel(interp, argv[1], &tcl_file_mode)) == NULL) return (TCL_ERROR); if (!(tcl_file_mode & TCL_WRITABLE)) { Tcl_AppendResult(interp, "\"", argv[1], "\" not writeable", (char *) NULL); return (TCL_ERROR); } /* tune channel to binary translation, e.g. none */ Tcl_SetChannelOption(interp, channel, "-translation", "binary"); /* assemble rows */ argc -= 2; argv += 2; row = (char*)malloc(sizeof(char)*argc); for (i = 0; i < argc; i++) { if (!strncmp(*argv, "posx", strlen(*argv))) { row[i] = POSX; } else if (!strncmp(*argv, "posy", strlen(*argv))) { row[i] = POSY; } else if (!strncmp(*argv, "posz", strlen(*argv))) { row[i] = POSZ; } #ifdef MASS else if (!strncmp(*argv, "mass", strlen(*argv))) { row[i] = MASSES; } #endif else if (!strncmp(*argv, "q", strlen(*argv))) { row[i] = Q; } #ifdef DIPOLES else if (!strncmp(*argv, "mx", strlen(*argv))) { row[i] = MX; } else if (!strncmp(*argv, "my", strlen(*argv))) { row[i] = MY; } else if (!strncmp(*argv, "mz", strlen(*argv))) { row[i] = MZ; } #endif else if (!strncmp(*argv, "vx", strlen(*argv))) { row[i] = VX; } else if (!strncmp(*argv, "vy", strlen(*argv))) { row[i] = VY; } else if (!strncmp(*argv, "vz", strlen(*argv))) { row[i] = VZ; } else if (!strncmp(*argv, "fx", strlen(*argv))) { row[i] = FX; } else if (!strncmp(*argv, "fy", strlen(*argv))) { row[i] = FY; } else if (!strncmp(*argv, "fz", strlen(*argv))) { row[i] = FZ; } else if (!strncmp(*argv, "type", strlen(*argv))) { row[i] = TYPE; } else { Tcl_AppendResult(interp, "no particle data field \"", *argv, "\"?", (char *) NULL); free(row); return (TCL_ERROR); } argv++; } if (!particle_node) build_particle_node(); /* write header and row data */ memmove(header.magic, MDMAGIC, 4*sizeof(char)); header.n_rows = argc; Tcl_Write(channel, (char *)&header, sizeof(header)); Tcl_Write(channel, row, header.n_rows*sizeof(char)); for (p = 0; p <= max_seen_particle; p++) { Particle data; if (get_particle_data(p, &data) == ES_OK) { unfold_position(data.r.p, data.m.v, data.l.i); /* write particle index */ Tcl_Write(channel, (char *)&p, sizeof(int)); for (i = 0; i < header.n_rows; i++) { switch (row[i]) { case POSX: Tcl_Write(channel, (char *)&data.r.p[0], sizeof(double)); break; case POSY: Tcl_Write(channel, (char *)&data.r.p[1], sizeof(double)); break; case POSZ: Tcl_Write(channel, (char *)&data.r.p[2], sizeof(double)); break; case VX: Tcl_Write(channel, (char *)&data.m.v[0], sizeof(double)); break; case VY: Tcl_Write(channel, (char *)&data.m.v[1], sizeof(double)); break; case VZ: Tcl_Write(channel, (char *)&data.m.v[2], sizeof(double)); break; case FX: Tcl_Write(channel, (char *)&data.f.f[0], sizeof(double)); break; case FY: Tcl_Write(channel, (char *)&data.f.f[1], sizeof(double)); break; case FZ: Tcl_Write(channel, (char *)&data.f.f[2], sizeof(double)); break; #ifdef MASS case MASSES: Tcl_Write(channel, (char *)&data.p.mass, sizeof(double)); break; #endif #ifdef ELECTROSTATICS case Q: Tcl_Write(channel, (char *)&data.p.q, sizeof(double)); break; #endif #ifdef DIPOLES case MX: Tcl_Write(channel, (char *)&data.r.dip[0], sizeof(double)); break; case MY: Tcl_Write(channel, (char *)&data.r.dip[1], sizeof(double)); break; case MZ: Tcl_Write(channel, (char *)&data.r.dip[2], sizeof(double)); break; #endif case TYPE: Tcl_Write(channel, (char *)&data.p.type, sizeof(int)); break; } } free_particle(&data); } } /* end marker */ Tcl_Write(channel, (char *)&end_num, sizeof(int)); free(row); return TCL_OK; }