static void prepare_ghost_cell(Cell *cell, int size) { #ifdef GHOSTS_HAVE_BONDS // free all allocated information, will be resent { int np = cell->n; Particle *part = cell->part; for (int p = 0; p < np; p++) { free_particle(part + p); } } #endif realloc_particlelist(cell, cell->n = size); // invalidate pointers etc { int np = cell->n; Particle *part = cell->part; for (int p = 0; p < np; p++) { Particle *pt = &part[p]; // no bonds or exclusions pt->bl.e = 0; pt->bl.n = 0; pt->bl.max = 0; #ifdef EXCLUSIONS pt->el.e = 0; pt->el.n = 0; pt->el.max = 0; #endif #ifdef GHOST_FLAG //init ghost variable pt->l.ghost=1; #endif } } }
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); }
void local_remove_particle(int part) { int ind, c; Particle *p = local_particles[part]; ParticleList *pl = NULL, *tmp; /* the tricky - say ugly - part: determine the cell the particle is located in by checking wether the particle address is inside the array */ for (c = 0; c < local_cells.n; c++) { tmp = local_cells.cell[c]; ind = p - tmp->part; if (ind >= 0 && ind < tmp->n) { pl = tmp; break; } } if (!pl) { fprintf(stderr, "%d: INTERNAL ERROR: could not find cell of particle %d, exiting\n", this_node, part); errexit(); } free_particle(p); /* remove local_particles entry */ local_particles[p->p.identity] = NULL; if (&pl->part[pl->n - 1] != p) { /* move last particle to free position */ memcpy(p, &pl->part[pl->n - 1], sizeof(Particle)); /* update the local_particles array for the moved particle */ local_particles[p->p.identity] = p; } pl->n--; }
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; }