int map_position_node_array(double pos[3]) { int i, im[3]={0,0,0}; double f_pos[3]; for (i = 0; i < 3; i++) f_pos[i] = pos[i]; #ifdef LEES_EDWARDS double vel_scratch[3]={0.,0.,0.}; fold_position(f_pos, vel_scratch, im); #else fold_position(f_pos, im); #endif for (i = 0; i < 3; i++) { im[i] = (int)floor(node_grid[i]*f_pos[i]*box_l_i[i]); if (im[i] < 0) im[i] = 0; else if (im[i] >= node_grid[i]) im[i] = node_grid[i] - 1; } return map_array_node(im); }
int constraint_collision(double *p1, double *p2){ Particle part1,part2; double d1,d2,v[3]; Constraint *c; int i; double folded_pos1[3]; double folded_pos2[3]; int img[3]; #ifdef LEES_EDWARDS double vtmp[3]; #endif memcpy(folded_pos1, p1, 3*sizeof(double)); #ifdef LEES_EDWARDS fold_position(folded_pos1, vtmp, img); #else fold_position(folded_pos1, img); #endif memcpy(folded_pos2, p2, 3*sizeof(double)); #ifdef LEES_EDWARDS fold_position(folded_pos1, vtmp, img); #else fold_position(folded_pos2, img); #endif for(i=0;i<n_constraints;i++){ c=&constraints[i]; switch(c->type){ case CONSTRAINT_WAL: calculate_wall_dist(&part1,folded_pos1,&part1,&c->c.wal,&d1,v); calculate_wall_dist(&part2,folded_pos2,&part2,&c->c.wal,&d2,v); if(d1*d2<=0.0) return 1; break; case CONSTRAINT_SPH: calculate_sphere_dist(&part1,folded_pos1,&part1,&c->c.sph,&d1,v); calculate_sphere_dist(&part2,folded_pos2,&part2,&c->c.sph,&d2,v); if(d1*d2<0.0) return 1; break; case CONSTRAINT_CYL: calculate_cylinder_dist(&part1,folded_pos1,&part1,&c->c.cyl,&d1,v); calculate_cylinder_dist(&part2,folded_pos2,&part2,&c->c.cyl,&d2,v); if(d1*d2<0.0) return 1; break; case CONSTRAINT_MAZE: case CONSTRAINT_PORE: case CONSTRAINT_PLATE: case CONSTRAINT_RHOMBOID: break; //default://@TODO: handle default case // break; } } return 0; }
void local_place_particle(int part, double p[3], int _new) { Cell *cell; double pp[3]; int i[3], rl; Particle *pt; i[0] = 0; i[1] = 0; i[2] = 0; pp[0] = p[0]; pp[1] = p[1]; pp[2] = p[2]; #ifdef LEES_EDWARDS double vv[3]={0.,0.,0.}; fold_position(pp, vv, i); #else fold_position(pp, i); #endif if (_new) { /* allocate particle anew */ cell = cell_structure.position_to_cell(pp); if (!cell) { fprintf(stderr, "%d: INTERNAL ERROR: particle %d at %f(%f) %f(%f) %f(%f) does not belong on this node\n", this_node, part, p[0], pp[0], p[1], pp[1], p[2], pp[2]); errexit(); } rl = realloc_particlelist(cell, ++cell->n); pt = &cell->part[cell->n - 1]; init_particle(pt); pt->p.identity = part; if (rl) update_local_particles(cell); else local_particles[pt->p.identity] = pt; } else pt = local_particles[part]; PART_TRACE(fprintf(stderr, "%d: local_place_particle: got particle id=%d @ %f %f %f\n", this_node, part, p[0], p[1], p[2])); #ifdef LEES_EDWARDS pt->m.v[0] += vv[0]; pt->m.v[1] += vv[1]; pt->m.v[2] += vv[2]; #endif memcpy(pt->r.p, pp, 3*sizeof(double)); memcpy(pt->l.i, i, 3*sizeof(int)); #ifdef BOND_CONSTRAINT memcpy(pt->r.p_old, pp, 3*sizeof(double)); #endif }
/** Computes the bending force (Dupin2007 eqn. 20 and 21) and adds this force to the particle forces (see \ref tclcommand_inter). @param p1,p2,p3 Pointers to particles of triangle 1. @param p2,p3,p4 Pointers to particles of triangle 2. (triangles have particles p2 and p3 in common) @param iaparams bending stiffness kb, initial rest angle phi0 (see \ref tclcommand_inter). @param force1 returns force on particles of triangle 1 @param force2 returns force on particles of triangle 2 (p1 += force1; p2 += 0.5*force1+0.5*force2; p3 += 0.5*force1+0.5*force2; p4 += force2; @return 0 */ inline int calc_bending_force(Particle *p2, Particle *p1, Particle *p3, Particle *p4, Bonded_ia_parameters *iaparams, double force1[3], double force2[2])// first-fold-then-the-same approach { double n1[3],n2[3],dn1,dn2,phi,aa,fac,penal; int k; double fp1[3],fp2[3],fp3[3],fp4[3]; #ifdef LEES_EDWARDS double vv[3]; #endif int img[3]; memcpy(fp1, p1->r.p, 3*sizeof(double)); memcpy(img, p1->l.i, 3*sizeof(int)); fold_position(fp1, img); memcpy(fp2, p2->r.p, 3*sizeof(double)); memcpy(img, p2->l.i, 3*sizeof(int)); fold_position(fp2, img); memcpy(fp3, p3->r.p, 3*sizeof(double)); memcpy(img, p3->l.i, 3*sizeof(int)); fold_position(fp3, img); memcpy(fp4, p4->r.p, 3*sizeof(double)); memcpy(img, p4->l.i, 3*sizeof(int)); fold_position(fp4, img); get_n_triangle(fp2,fp1,fp3,n1); dn1=normr(n1); get_n_triangle(fp2,fp3,fp4,n2); dn2=normr(n2); phi = angle_btw_triangles(fp1,fp2,fp3,fp4); if (iaparams->p.bending_force.phi0 < 0.001 || iaparams->p.bending_force.phi0 > 2*M_PI - 0.001) printf("bending_force.h, calc_bending_force: Resting angle is close to zero!!!\n"); aa = (phi-iaparams->p.bending_force.phi0)/iaparams->p.bending_force.phi0; fac = iaparams->p.bending_force.kb * aa; penal = (1+1/pow(10*(2*M_PI-phi),2) + 1/pow(10*(phi),2)); if (penal > 5.) penal = 5.; // fac = fac*penal; // This is to penalize the angles smaller than some threshold tr and also it penalizes angles greater than 2*Pi - tr. It prevents the objects to have negative angles. if (phi < 0.001 || phi > 2*M_PI - 0.001) printf("bending_force.h, calc_bending_force: Angle approaches 0 or 2*Pi\n"); for(k=0;k<3;k++) { force1[k]=fac * n1[k]/dn1; force2[k]=fac * n2[k]/dn2; } return 0; }
/** Computes the local area force (Dupin2007 eqn. 15) and adds this force to the particle forces (see \ref tclcommand_inter). @param p1,p2,p3 Pointers to triangle particles. @param iaparams elastic area modulus ka, initial area A0 (see \ref tclcommand_inter). @param force1 returns force of particle 1 @param force2 returns force of particle 2 @param force3 returns force of particle 3 @return 0 */ inline int calc_area_force_local(Particle *p1, Particle *p2, Particle *p3, Bonded_ia_parameters *iaparams, double force1[3], double force2[3], double force3[3]) //first-fold-then-the-same approach { int k; double A, aa, h[3], rh[3], hn; double p11[3],p22[3],p33[3]; int img[3]; memcpy(p11, p1->r.p, 3*sizeof(double)); memcpy(img, p1->l.i, 3*sizeof(int)); fold_position(p11, img); memcpy(p22, p2->r.p, 3*sizeof(double)); memcpy(img, p2->l.i, 3*sizeof(int)); fold_position(p22, img); memcpy(p33, p3->r.p, 3*sizeof(double)); memcpy(img, p3->l.i, 3*sizeof(int)); fold_position(p33, img); for(k=0;k<3;k++) h[k]=1.0/3.0 *(p11[k]+p22[k]+p33[k]); //volume+=A * -n[2]/dn * h[2]; A=area_triangle(p11,p22,p33); aa=(A - iaparams->p.area_force_local.A0_l)/iaparams->p.area_force_local.A0_l; //aminusb(3,h,p11,rh); // area_forces for each triangle node vecsub(h,p11,rh); // area_forces for each triangle node hn=normr(rh); for(k=0;k<3;k++) { force1[k] = iaparams->p.area_force_local.ka_l * aa * rh[k]/hn; //(&part1)->f.f[k]+=force[k]; } //aminusb(3,h,p22,rh); // area_forces for each triangle node vecsub(h,p22,rh); // area_forces for each triangle node hn=normr(rh); for(k=0;k<3;k++) { force2[k] = iaparams->p.area_force_local.ka_l * aa * rh[k]/hn; //(&part2)->f.f[k]+=force[k]; } //aminusb(3,h,p33,rh); // area_forces for each triangle node vecsub(h,p33,rh); // area_forces for each triangle node hn=normr(rh); for(k=0;k<3;k++) { force3[k] = iaparams->p.area_force_local.ka_l * aa * rh[k]/hn; //(&part3)->f.f[k]+=force[k]; } return 0; }
void Lattice::map_position_to_lattice_global (double pos[3], int ind[3], double delta[6], double tmp_agrid) { //not sure why I don't have access to agrid here so I make a temp var and pass it to this function int i; double rel[3]; // fold the position onto the local box, note here ind is used as a dummy variable for (i=0;i<3;i++) { pos[i] = pos[i]-0.5*tmp_agrid; } fold_position (pos,ind); // convert the position into lower left grid point for (i=0;i<3;i++) { rel[i] = (pos[i])/tmp_agrid; } // calculate the index of the position for (i=0;i<3;i++) { ind[i] = floor(rel[i]); } // calculate the linear interpolation weighting for (i=0;i<3;i++) { delta[3+i] = rel[i] - ind[i]; delta[i] = 1 - delta[3+i]; } }
int observable_density_profile(void* pdata_, double* A, unsigned int n_A) { unsigned int i; int binx, biny, binz; double ppos[3]; int img[3]; IntList* ids; profile_data* pdata; sortPartCfg(); pdata=(profile_data*) pdata_; ids=pdata->id_list; double bin_volume=(pdata->maxx-pdata->minx)*(pdata->maxy-pdata->miny)*(pdata->maxz-pdata->minz)/pdata->xbins/pdata->ybins/pdata->zbins; for ( i = 0; i<n_A; i++ ) { A[i]=0; } for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; /* We use folded coordinates here */ memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); binx= (int) floor( pdata->xbins* (ppos[0]-pdata->minx)/(pdata->maxx-pdata->minx)); biny= (int) floor( pdata->ybins* (ppos[1]-pdata->miny)/(pdata->maxy-pdata->miny)); binz= (int) floor( pdata->zbins* (ppos[2]-pdata->minz)/(pdata->maxz-pdata->minz)); if (binx>=0 && binx < pdata->xbins && biny>=0 && biny < pdata->ybins && binz>=0 && binz < pdata->zbins) { A[binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz] += 1./bin_volume; } } return 0; }
int observable_calc_flux_density_profile(observable* self) { double* A = self->last_value; int binx, biny, binz; double ppos[3]; double x, y, z; int img[3]; double bin_volume; IntList* ids; #ifdef LEES_EDWARDS double v_le[3]; #endif if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } profile_data* pdata; pdata=(profile_data*) self->container; ids=pdata->id_list; double xbinsize=(pdata->maxx - pdata->minx)/pdata->xbins; double ybinsize=(pdata->maxy - pdata->miny)/pdata->ybins; double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; double v[3]; double v_x, v_y, v_z; for (int i = 0; i< self->n; i++ ) { A[i]=0; } for (int i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_part) return 1; /* We use folded coordinates here */ v[0]=partCfg[ids->e[i]].m.v[0]*time_step; v[1]=partCfg[ids->e[i]].m.v[1]*time_step; v[2]=partCfg[ids->e[i]].m.v[2]*time_step; memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); x=ppos[0]; y=ppos[1]; z=ppos[2]; binx =(int)floor((x-pdata->minx)/xbinsize); biny =(int)floor((y-pdata->miny)/ybinsize); binz =(int)floor((z-pdata->minz)/zbinsize); if (binx>=0 && binx < pdata->xbins && biny>=0 && biny < pdata->ybins && binz>=0 && binz < pdata->zbins) { bin_volume=xbinsize*ybinsize*zbinsize; v_x=v[0]; v_y=v[1]; v_z=v[2]; A[3*(binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz) + 0] += v_x/bin_volume; A[3*(binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz) + 1] += v_y/bin_volume; A[3*(binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz) + 2] += v_z/bin_volume; } } return 0; }
/// Calculates the minimum distance between a particle to any wall constraint static double calc_pwdist(Particle *p1, Bonded_ia_parameters *iaparams, int *clconstr) { int j,k,img[3]; double distwallmin=0.0, normal=0.0; double folded_pos_p1[3]; double pwdist[n_constraints]; Constraint_wall wall; /*fprintf(stdout," Entering calc_pwdist:\n");*/ /* folds coordinates of p_left into original box */ memcpy(folded_pos_p1, p1->r.p, 3*sizeof(double)); memcpy(img, p1->l.i, 3*sizeof(int)); fold_position(folded_pos_p1, img); /*fprintf(stdout," p1= %9.6f %9.6f %9.6f\n",p1->r.p[0],p1->r.p[1],p1->r.p[2]);*/ /* Gets and tests wall data */ for(k=0;k<n_constraints;k++) { switch(constraints[k].type) { case CONSTRAINT_WAL: wall=constraints[k].c.wal; /* check that constraint wall normal is normalised */ for(j=0;j<3;j++) normal += wall.n[j] * wall.n[j]; if (sqrt(normal) != 1.0) { for(j=0;j<3;j++) wall.n[j]=wall.n[j]/normal; } break; } } /* Calculate distance of end particle from closest wall */ for(k=0;k<n_constraints;k++) { switch(constraints[k].type) { case CONSTRAINT_WAL: wall=constraints[k].c.wal; /* distwallmin is distance of closest wall from p1 */ pwdist[k]=-1.0 * wall.d; for(j=0;j<3;j++) { pwdist[k] += folded_pos_p1[j] * wall.n[j]; } if (k==0) { distwallmin=pwdist[k]; } else { if (pwdist[k] < distwallmin) { distwallmin = pwdist[k]; *clconstr = k; } } /*fprintf(stdout," k=%d clconstr=%d\n",k,*clconstr);*/ break; } } /* if (distwallmin <= iaparams->p.endangledist.distmax) { fprintf(stdout," clconstr=%d distwallmin=%f distmx=%f\n",*clconstr,distwallmin,distmx); } */ return distwallmin; }
void add_external_potential_tabulated_energy(ExternalPotential* e, Particle* p) { if (p->p.type >= e->n_particle_types) { return; } double potential; double ppos[3]; #ifdef LEES_EDWARDS double dummyV[3]; #endif int img[3]; memcpy(ppos, p->r.p, 3*sizeof(double)); memcpy(img, p->r.p, 3*sizeof(int)); #ifdef LEES_EDWARDS fold_position(ppos, dummyV, img); #else fold_position(ppos, img); #endif e->tabulated.potential.interpolate(p->r.p, &potential); e->energy += e->scale[p->p.type] * potential; }
static void mpi_get_particles_slave_lb(){ int n_part; int g; LB_particle_gpu *host_data_sl; Cell *cell; int c, i; n_part = cells_get_n_particles(); COMM_TRACE(fprintf(stderr, "%d: get_particles_slave, %d particles\n", this_node, n_part)); if (n_part > 0) { /* get (unsorted) particle informations as an array of type 'particle' */ /* then get the particle information */ host_data_sl = malloc(n_part*sizeof(LB_particle_gpu)); g = 0; for (c = 0; c < local_cells.n; c++) { Particle *part; int npart; int dummy[3] = {0,0,0}; double pos[3]; cell = local_cells.cell[c]; part = cell->part; npart = cell->n; for (i=0;i<npart;i++) { memcpy(pos, part[i].r.p, 3*sizeof(double)); fold_position(pos, dummy); host_data_sl[i+g].p[0] = (float)pos[0]; host_data_sl[i+g].p[1] = (float)pos[1]; host_data_sl[i+g].p[2] = (float)pos[2]; host_data_sl[i+g].v[0] = (float)part[i].m.v[0]; host_data_sl[i+g].v[1] = (float)part[i].m.v[1]; host_data_sl[i+g].v[2] = (float)part[i].m.v[2]; #ifdef LB_ELECTROHYDRODYNAMICS host_data_sl[i+g].mu_E[0] = (float)part[i].p.mu_E[0]; host_data_sl[i+g].mu_E[1] = (float)part[i].p.mu_E[1]; host_data_sl[i+g].mu_E[2] = (float)part[i].p.mu_E[2]; #endif } g+=npart; } /* and send it back to the master node */ MPI_Send(host_data_sl, n_part*sizeof(LB_particle_gpu), MPI_BYTE, 0, REQ_GETPARTS, MPI_COMM_WORLD); free(host_data_sl); } }
int observable_flux_density_profile(void* pdata_, double* A, unsigned int n_A) { unsigned int i; int binx, biny, binz; double ppos[3]; double x, y, z; int img[3]; double bin_volume; IntList* ids; sortPartCfg(); profile_data* pdata; pdata=(profile_data*) pdata_; ids=pdata->id_list; double xbinsize=(pdata->maxx - pdata->minx)/pdata->xbins; double ybinsize=(pdata->maxy - pdata->miny)/pdata->ybins; double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; double v[3]; double v_x, v_y, v_z; for ( i = 0; i< n_A; i++ ) { A[i]=0; } for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; /* We use folded coordinates here */ v[0]=partCfg[ids->e[i]].m.v[0]*time_step; v[1]=partCfg[ids->e[i]].m.v[1]*time_step; v[2]=partCfg[ids->e[i]].m.v[2]*time_step; memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); x=ppos[0]; y=ppos[1]; z=ppos[2]; binx =(int)floor((x-pdata->minx)/xbinsize); biny =(int)floor((y-pdata->miny)/ybinsize); binz =(int)floor((z-pdata->minz)/zbinsize); if (binx>=0 && binx < pdata->xbins && biny>=0 && biny < pdata->ybins && binz>=0 && binz < pdata->zbins) { bin_volume=xbinsize*ybinsize*zbinsize; v_x=v[0]; v_y=v[1]; v_z=v[2]; A[3*(binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz) + 0] += v_x/bin_volume; A[3*(binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz) + 1] += v_y/bin_volume; A[3*(binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz) + 2] += v_z/bin_volume; } } return 0; }
void add_external_potential_tabulated_energy(ExternalPotential* e, Particle* p) { if (p->p.type >= e->n_particle_types) { return; } double potential; double ppos[3]; int img[3]; memmove(ppos, p->r.p, 3*sizeof(double)); memmove(img, p->r.p, 3*sizeof(int)); fold_position(ppos, img); e->tabulated.potential.interpolate(p->r.p, &potential); e->energy += e->scale[p->p.type] * potential; }
void add_external_potential_tabulated_forces(ExternalPotential* e, Particle* p) { if (p->p.type >= e->n_particle_types) { return; } double field[3]; double ppos[3]; #ifdef LEES_EDWARDS double dummyV[3]; #endif int img[3]; memcpy(ppos, p->r.p, 3*sizeof(double)); memcpy(img, p->r.p, 3*sizeof(int)); #ifdef LEES_EDWARDS fold_position(ppos, dummyV, img); #else fold_position(ppos, img); #endif e->tabulated.potential.interpolate_gradient(p->r.p, field); p->f.f[0]-=e->scale[p->p.type]*field[0]; p->f.f[1]-=e->scale[p->p.type]*field[1]; p->f.f[2]-=e->scale[p->p.type]*field[2]; // printf("%d %f force: %f %f %f\n", p->p.type, e->scale[p->p.type], e->scale[p->p.type]*field[0], e->scale[p->p.type]*field[1], e->scale[p->p.type]*field[2]); }
int observable_radial_flux_density_profile(void* pdata_, double* A, unsigned int n_A) { unsigned int i; int binr, binphi, binz; double ppos[3]; double r, phi, z; int img[3]; double bin_volume; IntList* ids; sortPartCfg(); radial_profile_data* pdata; pdata=(radial_profile_data*) pdata_; ids=pdata->id_list; double rbinsize=(pdata->maxr - pdata->minr)/pdata->rbins; double phibinsize=(pdata->maxphi - pdata->minphi)/pdata->phibins; double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; double v[3]; double v_r, v_phi, v_z; for ( i = 0; i< n_A; i++ ) { A[i]=0; } for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; /* We use folded coordinates here */ v[0]=partCfg[ids->e[i]].m.v[0]/time_step; v[1]=partCfg[ids->e[i]].m.v[1]/time_step; v[2]=partCfg[ids->e[i]].m.v[2]/time_step; memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); transform_to_cylinder_coordinates(ppos[0]-pdata->center[0], ppos[1]-pdata->center[1], ppos[2]-pdata->center[2], &r, &phi, &z); binr =(int)floor((r-pdata->minr)/rbinsize); binphi=(int)floor((phi-pdata->minphi)/phibinsize); binz =(int)floor((z-pdata->minz)/zbinsize); if (binr>=0 && binr < pdata->rbins && binphi>=0 && binphi < pdata->phibins && binz>=0 && binz < pdata->zbins) { bin_volume=PI*((pdata->minr+(binr+1)*rbinsize)*(pdata->minr+(binr+1)*rbinsize) - (pdata->minr+(binr)*rbinsize)*(pdata->minr+(binr)*rbinsize)) *zbinsize * phibinsize/2/PI; v_r = 1/r*((ppos[0]-pdata->center[0])*v[0] + (ppos[1]-pdata->center[1])*v[1]); v_phi = 1/r/r*((ppos[0]-pdata->center[0])*v[1]-(ppos[1]-pdata->center[1])*v[0]); v_z = v[2]; A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 0] += v_r/bin_volume; A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 1] += v_phi/bin_volume; A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 2] += v_z/bin_volume; } } return 0; }
int observable_calc_radial_density_profile(observable* self) { double* A = self->last_value; int binr, binphi, binz; double ppos[3]; double r, phi, z; int img[3]; double bin_volume; IntList* ids; #ifdef LEES_EDWARDS double v_le[3]; #endif if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } radial_profile_data* pdata; pdata=(radial_profile_data*) self->container; ids=pdata->id_list; double rbinsize=(pdata->maxr - pdata->minr)/pdata->rbins; double phibinsize=(pdata->maxphi - pdata->minphi)/pdata->phibins; double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; for (int i = 0; i< self->n; i++ ) { A[i]=0; } for (int i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_part) return 1; /* We use folded coordinates here */ memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); transform_to_cylinder_coordinates(ppos[0]-pdata->center[0], ppos[1]-pdata->center[1], ppos[2]-pdata->center[2], &r, &phi, &z); //printf("%f %f %f %f %f %f\n", ppos[0], ppos[1], ppos[2], r*cos(phi)+pdata->center[0], r*sin(phi)+pdata->center[1], z+pdata->center[2]); binr =(int)floor((r-pdata->minr)/rbinsize); binphi=(int)floor((phi-pdata->minphi)/phibinsize); binz =(int)floor((z-pdata->minz)/zbinsize); if (binr>=0 && binr < pdata->rbins && binphi>=0 && binphi < pdata->phibins && binz>=0 && binz < pdata->zbins) { bin_volume=PI*((pdata->minr+(binr+1)*rbinsize)*(pdata->minr+(binr+1)*rbinsize) - (pdata->minr+(binr)*rbinsize)*(pdata->minr+(binr)*rbinsize)) *zbinsize * phibinsize/2/PI; A[binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz] += 1./bin_volume; } } return 0; }
/* Calculate the CMS of the system */ int tclcommand_system_CMS(ClientData data, Tcl_Interp * interp, int argc, char ** argv){ char buffer[256]; double cmspos[3]; int box[3]; if (argc != 1 && argc != 2 ) { return tcl_command_system_CMS_print_usage(interp); } else { if (ARG_IS_S_EXACT(0,"system_CMS")) { if ( argc == 2 ) { if (ARG_IS_S_EXACT(1,"folded")) { mpi_system_CMS(); memmove(cmspos, gal.cms, 3*sizeof(double)); box[0] = 0; box[1] = 0; box[2] = 0; fold_position(cmspos, box); Tcl_PrintDouble(interp, cmspos[0], buffer); Tcl_AppendResult(interp, buffer, " ", (char *)NULL); Tcl_PrintDouble(interp, cmspos[1], buffer); Tcl_AppendResult(interp, buffer, " ", (char *)NULL); Tcl_PrintDouble(interp, cmspos[2], buffer); Tcl_AppendResult(interp, buffer, (char *)NULL); return TCL_OK; } else { return tcl_command_system_CMS_print_usage(interp); } } else { mpi_system_CMS(); Tcl_PrintDouble(interp, gal.cms[0], buffer); Tcl_AppendResult(interp, buffer, " ", (char *)NULL); Tcl_PrintDouble(interp, gal.cms[1], buffer); Tcl_AppendResult(interp, buffer, " ", (char *)NULL); Tcl_PrintDouble(interp, gal.cms[2], buffer); Tcl_AppendResult(interp, buffer, (char *)NULL); return TCL_OK; } } else { return tcl_command_system_CMS_print_usage(interp); } } }
void add_external_potential_tabulated_forces(ExternalPotential* e, Particle* p) { if (p->p.type >= e->n_particle_types || e->scale[p->p.type] == 0 ) { return; } double field[3]; double ppos[3]; int img[3]; memmove(ppos, p->r.p, 3*sizeof(double)); memmove(img, p->r.p, 3*sizeof(int)); fold_position(ppos, img); e->tabulated.potential.interpolate_gradient(p->r.p, field); p->f.f[0]-=e->scale[p->p.type]*field[0]; p->f.f[1]-=e->scale[p->p.type]*field[1]; p->f.f[2]-=e->scale[p->p.type]*field[2]; // printf("%d %f force: %f %f %f\n", p->p.type, e->scale[p->p.type], e->scale[p->p.type]*field[0], e->scale[p->p.type]*field[1], e->scale[p->p.type]*field[2]); }
double adress_wf_vector(double x[3]){ int topo=(int)adress_vars[0]; double dist; int dim; int img_box[3]; double temp_pos[3]; switch (topo) { case 0: return 0.0; break; case 1: return adress_vars[1]; break; case 2: dim=(int)adress_vars[3]; //dist=fabs(x[dim]-adress_vars[4]); dist = x[dim]-adress_vars[4]; if(dist>0) while(dist>box_l[dim]/2.0) dist = dist - box_l[dim]; else if(dist < 0) while(dist< -box_l[dim]/2.0) dist = dist + box_l[dim]; dist = fabs(dist); return adress_wf(dist); break; case 3: for(dim=0;dim<3;dim++){ img_box[dim]=0; temp_pos[dim]=x[dim]; } fold_position(temp_pos,img_box); dist=distance(temp_pos,&(adress_vars[3])); //printf("%f %f \n", dist, adress_wf(dist)); return adress_wf(dist); break; default: return 0.0; break; } }
int map_position_node_array(double pos[3]) { int i, im[3]={0,0,0}; double f_pos[3]; for (i = 0; i < 3; i++) f_pos[i] = pos[i]; fold_position(f_pos, im); for (i = 0; i < 3; i++) { im[i] = (int)floor(node_grid[i]*f_pos[i]*box_l_i[i]); if (im[i] < 0) im[i] = 0; else if (im[i] >= node_grid[i]) im[i] = node_grid[i] - 1; } return map_array_node(im); }
int observable_radial_density_profile(void* pdata_, double* A, unsigned int n_A) { unsigned int i; int binr, binphi, binz; double ppos[3]; double r, phi, z; int img[3]; double bin_volume; IntList* ids; sortPartCfg(); radial_profile_data* pdata; pdata=(radial_profile_data*) pdata_; ids=pdata->id_list; double rbinsize=(pdata->maxr - pdata->minr)/pdata->rbins; double phibinsize=(pdata->maxphi - pdata->minphi)/pdata->phibins; double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; for ( i = 0; i< n_A; i++ ) { A[i]=0; } for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; /* We use folded coordinates here */ memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); transform_to_cylinder_coordinates(ppos[0]-pdata->center[0], ppos[1]-pdata->center[1], ppos[2]-pdata->center[2], &r, &phi, &z); //printf("%f %f %f %f %f %f\n", ppos[0], ppos[1], ppos[2], r*cos(phi)+pdata->center[0], r*sin(phi)+pdata->center[1], z+pdata->center[2]); binr =(int)floor((r-pdata->minr)/rbinsize); binphi=(int)floor((phi-pdata->minphi)/phibinsize); binz =(int)floor((z-pdata->minz)/zbinsize); if (binr>=0 && binr < pdata->rbins && binphi>=0 && binphi < pdata->phibins && binz>=0 && binz < pdata->zbins) { bin_volume=PI*((pdata->minr+(binr+1)*rbinsize)*(pdata->minr+(binr+1)*rbinsize) - (pdata->minr+(binr)*rbinsize)*(pdata->minr+(binr)*rbinsize)) *zbinsize * phibinsize/2/PI; A[binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz] += 1./bin_volume; } } return 0; }
int observable_calc_density_profile(observable* self) { double* A = self->last_value; int binx, biny, binz; double ppos[3]; int img[3]; IntList* ids; profile_data* pdata; #ifdef LEES_EDWARDS double v_le[3]; #endif if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } pdata=(profile_data*) self->container; ids=pdata->id_list; double bin_volume=(pdata->maxx-pdata->minx)*(pdata->maxy-pdata->miny)*(pdata->maxz-pdata->minz)/pdata->xbins/pdata->ybins/pdata->zbins; for ( int i = 0; i<self->n; i++ ) { A[i]=0; } for (int i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_part) return 1; /* We use folded coordinates here */ memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); binx= (int) floor( pdata->xbins* (ppos[0]-pdata->minx)/(pdata->maxx-pdata->minx)); biny= (int) floor( pdata->ybins* (ppos[1]-pdata->miny)/(pdata->maxy-pdata->miny)); binz= (int) floor( pdata->zbins* (ppos[2]-pdata->minz)/(pdata->maxz-pdata->minz)); if (binx>=0 && binx < pdata->xbins && biny>=0 && biny < pdata->ybins && binz>=0 && binz < pdata->zbins) { A[binx*pdata->ybins*pdata->zbins + biny*pdata->zbins + binz] += 1./bin_volume; } } return 0; }
double magnetic_dipolar_direct_sum_calculations(int force_flag, int energy_flag) { Cell *cell; Particle *part; int i,c,np; double *x=NULL, *y=NULL, *z=NULL; double *mx=NULL, *my=NULL, *mz=NULL; double *fx=NULL, *fy=NULL, *fz=NULL; #ifdef ROTATION double *tx=NULL, *ty=NULL, *tz=NULL; #endif int dip_particles,dip_particles2; double ppos[3]; int img[3]; double u; if(n_nodes!=1) {fprintf(stderr,"error: magnetic Direct Sum is just for one cpu .... \n"); errexit();} if(!(force_flag) && !(energy_flag) ) {fprintf(stderr," I don't know why you call dawaanr_caclulations with all flags zero \n"); return 0;} x = (double *) malloc(sizeof(double)*n_part); y = (double *) malloc(sizeof(double)*n_part); z = (double *) malloc(sizeof(double)*n_part); mx = (double *) malloc(sizeof(double)*n_part); my = (double *) malloc(sizeof(double)*n_part); mz = (double *) malloc(sizeof(double)*n_part); if(force_flag) { fx = (double *) malloc(sizeof(double)*n_part); fy = (double *) malloc(sizeof(double)*n_part); fz = (double *) malloc(sizeof(double)*n_part); #ifdef ROTATION tx = (double *) malloc(sizeof(double)*n_part); ty = (double *) malloc(sizeof(double)*n_part); tz = (double *) malloc(sizeof(double)*n_part); #endif } dip_particles=0; for (c = 0; c < local_cells.n; c++) { cell = local_cells.cell[c]; part = cell->part; np = cell->n; for(i=0;i<np;i++) { if( part[i].p.dipm > 1.e-11 ) { mx[dip_particles]=part[i].r.dip[0]; my[dip_particles]=part[i].r.dip[1]; mz[dip_particles]=part[i].r.dip[2]; /* here we wish the coordinates to be folded into the primary box */ ppos[0]=part[i].r.p[0]; ppos[1]=part[i].r.p[1]; ppos[2]=part[i].r.p[2]; img[0]=part[i].l.i[0]; img[1]=part[i].l.i[1]; img[2]=part[i].l.i[2]; fold_position(ppos, img); x[dip_particles]=ppos[0]; y[dip_particles]=ppos[1]; z[dip_particles]=ppos[2]; if(force_flag) { fx[dip_particles]=0; fy[dip_particles]=0; fz[dip_particles]=0; #ifdef ROTATION tx[dip_particles]=0; ty[dip_particles]=0; tz[dip_particles]=0; #endif } dip_particles++; } } } /*now we do the calculations */ { /* beginning of the area of calculation */ int nx,ny,nz,i,j; double r,rnx,rny,rnz,pe1,pe2,pe3,r3,r5,r2,r7; double a,b,c,d; #ifdef ROTATION double ax,ay,az,bx,by,bz; #endif double rx,ry,rz; double rnx2,rny2; int NCUT[3],NCUT2; for(i=0;i<3;i++){ NCUT[i]=Ncut_off_magnetic_dipolar_direct_sum; if(PERIODIC(i) == 0) {NCUT[i]=0;} } NCUT2=Ncut_off_magnetic_dipolar_direct_sum*Ncut_off_magnetic_dipolar_direct_sum; u=0; fprintf(stderr,"Magnetic Direct sum takes long time. Done of %d: \n",dip_particles); for(i=0;i<dip_particles;i++){ fprintf(stderr,"%d\r",i); for(j=0;j<dip_particles;j++){ pe1=mx[i]*mx[j]+my[i]*my[j]+mz[i]*mz[j]; rx=x[i]-x[j]; ry=y[i]-y[j]; rz=z[i]-z[j]; for(nx=-NCUT[0];nx<=NCUT[0];nx++){ rnx=rx+nx*box_l[0]; rnx2=rnx*rnx; for(ny=-NCUT[1];ny<=NCUT[1];ny++){ rny=ry+ny*box_l[1]; rny2=rny*rny; for(nz=-NCUT[2];nz<=NCUT[2];nz++){ if( !(i==j && nx==0 && ny==0 && nz==0) ) { if(nx*nx+ny*ny +nz*nz<= NCUT2){ rnz=rz+nz*box_l[2]; r2=rnx2+rny2+rnz*rnz; r=sqrt(r2); r3=r2*r; r5=r3*r2; r7=r5*r2; pe2=mx[i]*rnx+my[i]*rny+mz[i]*rnz; pe3=mx[j]*rnx+my[j]*rny+mz[j]*rnz; /*fprintf(stderr,"--------------------------------\n"); fprintf(stderr,"ij: %d %d\n",i,j); fprintf(stderr,"xyz[i]: %lf %lf %lf\n",x[i],y[i],z[i]); fprintf(stderr,"xyz[j]: %lf %lf %lf\n",x[j],y[j],z[j]); fprintf(stderr,"mu xyz[i]: %lf %lf %lf\n",mx[i],my[i],mz[i]); fprintf(stderr,"mu xyz[j]: %lf %lf %lf\n",mx[j],my[j],mz[j]); fprintf(stderr,"rnxyz: %lf %lf %lf\n",rnx,rny,rnz); fprintf(stderr,"--------------------------------\n");*/ //Energy ............................ u+= pe1/r3 - 3.0*pe2*pe3/r5; if(force_flag) { //force ............................ a=mx[i]*mx[j]+my[i]*my[j]+mz[i]*mz[j]; a=3.0*a/r5; b=-15.0*pe2*pe3/r7; c=3.0*pe3/r5; d=3.0*pe2/r5; fx[i]+=(a+b)*rnx+c*mx[i]+d*mx[j]; fy[i]+=(a+b)*rny+c*my[i]+d*my[j]; fz[i]+=(a+b)*rnz+c*mz[i]+d*mz[j]; #ifdef ROTATION //torque ............................ c=3.0/r5*pe3; ax=my[i]*mz[j]-my[j]*mz[i]; ay=mx[j]*mz[i]-mx[i]*mz[j]; az=mx[i]*my[j]-mx[j]*my[i]; bx=my[i]*rnz-rny*mz[i]; by=rnx*mz[i]-mx[i]*rnz; bz=mx[i]*rny-rnx*my[i]; tx[i]+=-ax/r3+bx*c; ty[i]+=-ay/r3+by*c; tz[i]+=-az/r3+bz*c; #endif } /* of force_flag */ } }/* of nx*nx+ny*ny +nz*nz< NCUT*NCUT and !(i==j && nx==0 && ny==0 && nz==0) */ }/* of for nz */ }/* of for ny */ }/* of for nx */ }} /* of j and i */ fprintf(stderr,"done \n"); }/* end of the area of calculation */ /* set the forces, and torques of the particles within Espresso */ if(force_flag) { dip_particles2=0; for (c = 0; c < local_cells.n; c++) { cell = local_cells.cell[c]; part = cell->part; np = cell->n; for(i=0;i<np;i++) { if( part[i].p.dipm > 1.e-11 ) { part[i].f.f[0]+=coulomb.Dprefactor*fx[dip_particles2]; part[i].f.f[1]+=coulomb.Dprefactor*fy[dip_particles2]; part[i].f.f[2]+=coulomb.Dprefactor*fz[dip_particles2]; #ifdef ROTATION part[i].f.torque[0]+=coulomb.Dprefactor*tx[dip_particles2]; part[i].f.torque[1]+=coulomb.Dprefactor*ty[dip_particles2]; part[i].f.torque[2]+=coulomb.Dprefactor*tz[dip_particles2]; #endif dip_particles2++; } } } /* small checking */ if(dip_particles != dip_particles2) { fprintf(stderr,"magnetic direct sum calculations: error mismatch of particles \n"); errexit();} } /*of if force_flag */ /* free memory used */ free(x); free(y); free(z); free(mx); free(my); free(mz); if(force_flag) { free(fx); free(fy); free(fz); #ifdef ROTATION free(tx); free(ty); free(tz); #endif } return 0.5*u; }
int tclcommand_imd_parse_pos(Tcl_Interp *interp, int argc, char **argv) { enum flag {NONE, UNFOLDED, FOLD_CHAINS}; double shift[3] = {0.0,0.0,0.0}; //double part_selected=n_total_particles; float *coord; int flag = NONE; int i, j; // Determine how many arguments we have and set the value of flag switch (argc) { case 2: flag = NONE; break; case 3: { if (ARG_IS_S(2,"-unfolded")) {flag = UNFOLDED;} else if (ARG_IS_S(2,"-fold_chains")) {flag = FOLD_CHAINS;} else{ Tcl_AppendResult(interp, "wrong flag to",argv[0], " positions: should be \" -fold_chains or -unfolded \"", (char *) NULL); return (TCL_ERROR); } } break; default: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " positions [-flag]\"", (char *) NULL); return (TCL_ERROR); } if (!initsock) { Tcl_AppendResult(interp, "no connection", (char *) NULL); return (TCL_OK); } if (!sock) { if (tclcommand_imd_print_check_connect(interp) == TCL_ERROR) return (TCL_ERROR); /* no VMD is ok, but tell the user */ if (!sock) { Tcl_AppendResult(interp, "no connection", (char *) NULL); return (TCL_OK); } } if (tclcommand_imd_print_drain_socket(interp) == TCL_ERROR) return (TCL_ERROR); /* we do not consider a non connected VMD as error, but tell the user */ if (!sock) { Tcl_AppendResult(interp, "no connection", (char *) NULL); return (TCL_OK); } if (!(vmdsock_selwrite(sock, 60) > 0)) { Tcl_AppendResult(interp, "could not write to IMD socket.", (char *) NULL); return (TCL_ERROR); } if (n_part != max_seen_particle + 1) { Tcl_AppendResult(interp, "for IMD, store particles consecutively starting with 0.", (char *) NULL); return (TCL_ERROR); } updatePartCfg(WITH_BONDS); coord = (float*)Utils::malloc(n_part*3*sizeof(float)); /* sort partcles according to identities */ for (i = 0; i < n_part; i++) { int dummy[3] = {0,0,0}; double tmpCoord[3]; tmpCoord[0] = partCfg[i].r.p[0]; tmpCoord[1] = partCfg[i].r.p[1]; tmpCoord[2] = partCfg[i].r.p[2]; if (flag == NONE) { // perform folding by particle fold_position(tmpCoord, dummy); } j = 3*partCfg[i].p.identity; coord[j ] = tmpCoord[0]; coord[j + 1] = tmpCoord[1]; coord[j + 2] = tmpCoord[2]; } // Use information from the analyse set command to fold chain molecules if ( flag == FOLD_CHAINS ){ if(analyze_fold_molecules(coord, shift ) != TCL_OK){ Tcl_AppendResult(interp, "could not fold chains: \"analyze set chains <chain_start> <n_chains> <chain_length>\" must be used first", (char *) NULL); return (TCL_ERROR); } } if (imd_send_fcoords(sock, n_part, coord)) { Tcl_AppendResult(interp, "could not write to IMD socket.", (char *) NULL); return (TCL_ERROR); } free(coord); Tcl_AppendResult(interp, "connected", (char *) NULL); return (TCL_OK); }
inline void calc_volume(double *volume, int molType){ //first-fold-then-the-same approach double partVol=0.,A,norm[3],dn,hz; /** loop over particles */ int c, np, i ,j; Cell *cell; Particle *p, *p1, *p2, *p3; double p11[3],p22[3],p33[3]; int img[3]; Bonded_ia_parameters *iaparams; int type_num, n_partners, id; BondedInteraction type; char *errtxt; //int test=0; //printf("rank%d, molType2: %d\n", rank,molType); /* Loop local cells */ for (c = 0; c < local_cells.n; c++) { cell = local_cells.cell[c]; p = cell->part; np = cell->n; /* Loop cell particles */ for(i=0; i < np; i++) { j = 0; p1 = &p[i]; //printf("rank%d, i=%d neigh=%d\n", rank, i, p1->bl.n); while(j<p1->bl.n){ /* bond type */ type_num = p1->bl.e[j++]; //bond_number iaparams = &bonded_ia_params[type_num]; type = iaparams->type; //type of interaction 14...volume_force n_partners = iaparams->num; //bonded_neigbours id=p1->p.mol_id; //mol_id of blood cell if(type == BONDED_IA_VOLUME_FORCE && id == molType){ // BONDED_IA_VOLUME_FORCE with correct molType !!!!!!!!!!!!! needs area force local !!!!!!!!!!!!!!!!!! p2 = local_particles[p1->bl.e[j++]]; if (!p2) { printf("broken: particles sum %d, id %d, partn %d, bond %d\n", np,id,n_partners,type_num); errtxt = runtime_error(128 + 2*ES_INTEGER_SPACE); ERROR_SPRINTF(errtxt,"{volume calc 078 bond broken between particles %d and %d (particles not stored on the same node - volume_force1)} ", p1->p.identity, p1->bl.e[j-1]); return; } /* fetch particle 3 */ p3 = local_particles[p1->bl.e[j++]]; if (!p3) { errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE); ERROR_SPRINTF(errtxt,"{volume calc 079 bond broken between particles %d, %d and %d (particles not stored on the same node); n %d max %d} ", p1->p.identity, p1->bl.e[j-2], p1->bl.e[j-1],p1->bl.n,p1->bl.max); return; } memcpy(p11, p1->r.p, 3*sizeof(double)); memcpy(img, p1->l.i, 3*sizeof(int)); fold_position(p11, img); memcpy(p22, p2->r.p, 3*sizeof(double)); memcpy(img, p2->l.i, 3*sizeof(int)); fold_position(p22, img); memcpy(p33, p3->r.p, 3*sizeof(double)); memcpy(img, p3->l.i, 3*sizeof(int)); fold_position(p33, img); get_n_triangle(p11,p22,p33,norm); dn=normr(norm); A=area_triangle(p11,p22,p33); hz=1.0/3.0 *(p11[2]+p22[2]+p33[2]); partVol += A * -1*norm[2]/dn * hz; } else{ j+=n_partners; } } } } MPI_Allreduce(&partVol, volume, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); }
inline void add_volume_force(double volume, int molType){ //first-fold-then-the-same approach double A,norm[3],dn; //partVol=0. double vv, force[3]; int k; int img[3]; /** loop over particles */ int c, np, i ,j; Cell *cell; Particle *p, *p1, *p2, *p3; double p11[3],p22[3],p33[3]; Bonded_ia_parameters *iaparams; int type_num, n_partners, id; BondedInteraction type; char *errtxt; int test=0; /* Loop local cells */ for (c = 0; c < local_cells.n; c++) { cell = local_cells.cell[c]; p = cell->part; np = cell->n; /* Loop cell particles */ for(i=0; i < np; i++) { j = 0; p1=&p[i]; //printf("i=%d neigh=%d\n", i, p1->bl.n); while(j<p1->bl.n){ /* bond type */ type_num = p1->bl.e[j++]; iaparams = &bonded_ia_params[type_num]; type = iaparams->type; n_partners = iaparams->num; id=p1->p.mol_id; if(type == BONDED_IA_VOLUME_FORCE && id == molType){ // BONDED_IA_VOLUME_FORCE with correct molType test++; /* fetch particle 2 */ p2 = local_particles[p1->bl.e[j++]]; if (!p2) { errtxt = runtime_error(128 + 2*ES_INTEGER_SPACE); ERROR_SPRINTF(errtxt,"{volume add 078 bond broken between particles %d and %d (particles not stored on the same node - volume_force2)} ", p1->p.identity, p1->bl.e[j-1]); return; } /* fetch particle 3 */ p3 = local_particles[p1->bl.e[j++]]; if (!p3) { errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE); ERROR_SPRINTF(errtxt,"{volume add 079 bond broken between particles %d, %d and %d (particles not stored on the same node); n %d max %d} ", p1->p.identity, p1->bl.e[j-2], p1->bl.e[j-1],p1->bl.n,p1->bl.max); return; } memcpy(p11, p1->r.p, 3*sizeof(double)); memcpy(img, p1->l.i, 3*sizeof(int)); fold_position(p11, img); memcpy(p22, p2->r.p, 3*sizeof(double)); memcpy(img, p2->l.i, 3*sizeof(int)); fold_position(p22, img); memcpy(p33, p3->r.p, 3*sizeof(double)); memcpy(img, p3->l.i, 3*sizeof(int)); fold_position(p33, img); get_n_triangle(p11,p22,p33,norm); dn=normr(norm); A=area_triangle(p11,p22,p33); { } vv=(volume - iaparams->p.volume_force.V0)/iaparams->p.volume_force.V0; for(k=0;k<3;k++) { force[k]=iaparams->p.volume_force.kv * vv * A * norm[k]/dn * 1.0 / 3.0; //printf("%e ",force[k]); p1->f.f[k] += force[k]; p2->f.f[k] += force[k]; p3->f.f[k] += force[k]; } } else{ j+=n_partners; } } } } }
/* This is only done for the trapped molecules to save time */ void calc_local_mol_info (IntList *local_trapped_mols) { int mi, i,j, mol; Particle *p; int np, c; Cell *cell; int lm; int fixed; /* First reset all molecule masses,forces,centers of mass*/ for ( mi = 0 ; mi < n_molecules ; mi++ ) { topology[mi].mass = 0; for ( i = 0 ; i < 3 ; i++) { topology[mi].f[i] = 0.0; topology[mi].com[i] = 0.0; topology[mi].v[i] = 0.0; } } for (c = 0; c < local_cells.n; c++) { cell = local_cells.cell[c]; p = cell->part; np = cell->n; for(i = 0; i < np; i++) { mol = p[i].p.mol_id; if ( mol >= n_molecules ) { char *errtxt = runtime_error(128 + 3*TCL_INTEGER_SPACE); ERROR_SPRINTF(errtxt, "{ 094 can't calculate molforces no such molecule as %d }",mol); return; } /* Check to see if this molecule is fixed */ fixed =0; for(j = 0; j < 3; j++) { #ifdef EXTERNAL_FORCES if (topology[mol].trap_flag & COORD_FIXED(j)) fixed = 1; if (topology[mol].noforce_flag & COORD_FIXED(j)) fixed = 1; #endif } if (fixed) { topology[mol].mass += PMASS(p[i]); /* Unfold the particle */ unfold_position(p[i].r.p,p[i].l.i); for ( j = 0 ; j < 3 ; j++ ) { topology[mol].f[j] += p[i].f.f[j]; topology[mol].com[j] += p[i].r.p[j]*PMASS(p[i]); topology[mol].v[j] += p[i].m.v[j]*PMASS(p[i]); } /* Fold the particle back */ fold_position(p[i].r.p,p[i].l.i); } } } /* Final normalisation of centers of mass and velocity*/ for ( lm = 0 ; lm < local_trapped_mols->n; lm++ ) { mi = local_trapped_mols->e[lm]; for ( i = 0 ; i < 3 ; i++) { topology[mi].com[i] = topology[mi].com[i]/(double)(topology[mi].mass); topology[mi].v[i] = topology[mi].v[i]/(double)(topology[mi].mass); } } }
static void cuda_mpi_get_particles_slave(){ int n_part; int g; CUDA_particle_data *particle_data_host_sl; Cell *cell; int c, i; n_part = cells_get_n_particles(); COMM_TRACE(fprintf(stderr, "%d: get_particles_slave, %d particles\n", this_node, n_part)); if (n_part > 0) { /* get (unsorted) particle informations as an array of type 'particle' */ /* then get the particle information */ particle_data_host_sl = (CUDA_particle_data*) Utils::malloc(n_part*sizeof(CUDA_particle_data)); g = 0; for (c = 0; c < local_cells.n; c++) { Particle *part; int npart; int dummy[3] = {0,0,0}; double pos[3]; cell = local_cells.cell[c]; part = cell->part; npart = cell->n; for (i=0;i<npart;i++) { memmove(pos, part[i].r.p, 3*sizeof(double)); fold_position(pos, dummy); particle_data_host_sl[i+g].p[0] = (float)pos[0]; particle_data_host_sl[i+g].p[1] = (float)pos[1]; particle_data_host_sl[i+g].p[2] = (float)pos[2]; particle_data_host_sl[i+g].v[0] = (float)part[i].m.v[0]; particle_data_host_sl[i+g].v[1] = (float)part[i].m.v[1]; particle_data_host_sl[i+g].v[2] = (float)part[i].m.v[2]; #ifdef IMMERSED_BOUNDARY particle_data_host_sl[i+g].isVirtual = part[i].p.isVirtual; #endif #ifdef DIPOLES particle_data_host_sl[i+g].dip[0] = (float)part[i].r.dip[0]; particle_data_host_sl[i+g].dip[1] = (float)part[i].r.dip[1]; particle_data_host_sl[i+g].dip[2] = (float)part[i].r.dip[2]; #endif #ifdef SHANCHEN // SAW TODO: does this really need to be copied every time? int ii; for(ii=0;ii<2*LB_COMPONENTS;ii++){ particle_data_host_sl[i+g].solvation[ii] = (float)part[i].p.solvation[ii]; } #endif #ifdef LB_ELECTROHYDRODYNAMICS particle_data_host_sl[i+g].mu_E[0] = (float)part[i].p.mu_E[0]; particle_data_host_sl[i+g].mu_E[1] = (float)part[i].p.mu_E[1]; particle_data_host_sl[i+g].mu_E[2] = (float)part[i].p.mu_E[2]; #endif #ifdef ELECTROSTATICS particle_data_host_sl[i+g].q = (float)part[i].p.q; #endif #ifdef ROTATION particle_data_host_sl[i+g].quatu[0] = (float)part[i].r.quatu[0]; particle_data_host_sl[i+g].quatu[1] = (float)part[i].r.quatu[1]; particle_data_host_sl[i+g].quatu[2] = (float)part[i].r.quatu[2]; #endif #ifdef ENGINE particle_data_host_sl[i+g].swim.v_swim = (float)part[i].swim.v_swim; particle_data_host_sl[i+g].swim.f_swim = (float)part[i].swim.f_swim; particle_data_host_sl[i+g].swim.quatu[0] = (float)part[i].r.quatu[0]; particle_data_host_sl[i+g].swim.quatu[1] = (float)part[i].r.quatu[1]; particle_data_host_sl[i+g].swim.quatu[2] = (float)part[i].r.quatu[2]; #if defined(LB) || defined(LB_GPU) particle_data_host_sl[i+g].swim.push_pull = part[i].swim.push_pull; particle_data_host_sl[i+g].swim.dipole_length = (float)part[i].swim.dipole_length; #endif particle_data_host_sl[i+g].swim.swimming = part[i].swim.swimming; #endif } g+=npart; } /* and send it back to the master node */ MPI_Send(particle_data_host_sl, n_part*sizeof(CUDA_particle_data), MPI_BYTE, 0, REQ_CUDAGETPARTS, comm_cart); free(particle_data_host_sl); } }
/*************** REQ_GETPARTS ************/ void cuda_mpi_get_particles(CUDA_particle_data *particle_data_host) { int n_part; int g, pnode; Cell *cell; int c; MPI_Status status; int i; int *sizes; sizes = (int*) Utils::malloc(sizeof(int)*n_nodes); n_part = cells_get_n_particles(); /* first collect number of particles on each node */ MPI_Gather(&n_part, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm_cart); /* just check if the number of particles is correct */ if(this_node > 0){ /* call slave functions to provide the slave datas */ cuda_mpi_get_particles_slave(); } else { /* master: fetch particle informations into 'result' */ g = 0; for (pnode = 0; pnode < n_nodes; pnode++) { if (sizes[pnode] > 0) { if (pnode == 0) { for (c = 0; c < local_cells.n; c++) { Particle *part; int npart; int dummy[3] = {0,0,0}; double pos[3]; cell = local_cells.cell[c]; part = cell->part; npart = cell->n; for (i=0;i<npart;i++) { memmove(pos, part[i].r.p, 3*sizeof(double)); fold_position(pos, dummy); particle_data_host[i+g].p[0] = (float)pos[0]; particle_data_host[i+g].p[1] = (float)pos[1]; particle_data_host[i+g].p[2] = (float)pos[2]; particle_data_host[i+g].v[0] = (float)part[i].m.v[0]; particle_data_host[i+g].v[1] = (float)part[i].m.v[1]; particle_data_host[i+g].v[2] = (float)part[i].m.v[2]; #ifdef IMMERSED_BOUNDARY particle_data_host[i+g].isVirtual = part[i].p.isVirtual; #endif #ifdef DIPOLES particle_data_host[i+g].dip[0] = (float)part[i].r.dip[0]; particle_data_host[i+g].dip[1] = (float)part[i].r.dip[1]; particle_data_host[i+g].dip[2] = (float)part[i].r.dip[2]; #endif #ifdef SHANCHEN // SAW TODO: does this really need to be copied every time? int ii; for(ii=0;ii<2*LB_COMPONENTS;ii++){ particle_data_host[i+g].solvation[ii] = (float)part[i].p.solvation[ii]; } #endif #ifdef LB_ELECTROHYDRODYNAMICS particle_data_host[i+g].mu_E[0] = (float)part[i].p.mu_E[0]; particle_data_host[i+g].mu_E[1] = (float)part[i].p.mu_E[1]; particle_data_host[i+g].mu_E[2] = (float)part[i].p.mu_E[2]; #endif #ifdef ELECTROSTATICS particle_data_host[i+g].q = (float)part[i].p.q; #endif #ifdef ROTATION particle_data_host[i+g].quatu[0] = (float)part[i].r.quatu[0]; particle_data_host[i+g].quatu[1] = (float)part[i].r.quatu[1]; particle_data_host[i+g].quatu[2] = (float)part[i].r.quatu[2]; #endif #ifdef ENGINE particle_data_host[i+g].swim.v_swim = (float)part[i].swim.v_swim; particle_data_host[i+g].swim.f_swim = (float)part[i].swim.f_swim; particle_data_host[i+g].swim.quatu[0] = (float)part[i].r.quatu[0]; particle_data_host[i+g].swim.quatu[1] = (float)part[i].r.quatu[1]; particle_data_host[i+g].swim.quatu[2] = (float)part[i].r.quatu[2]; #if defined(LB) || defined(LB_GPU) particle_data_host[i+g].swim.push_pull = part[i].swim.push_pull; particle_data_host[i+g].swim.dipole_length = (float)part[i].swim.dipole_length; #endif particle_data_host[i+g].swim.swimming = part[i].swim.swimming; #endif } g += npart; } } else { MPI_Recv(&particle_data_host[g], sizes[pnode]*sizeof(CUDA_particle_data), MPI_BYTE, pnode, REQ_CUDAGETPARTS, comm_cart, &status); g += sizes[pnode]; } } } } COMM_TRACE(fprintf(stderr, "%d: finished get\n", this_node)); free(sizes); }
int observable_calc_radial_flux_density_profile(observable* self) { double* A = self->last_value; int binr, binphi, binz; double ppos[3]; double unfolded_ppos[3]; double r, phi, z; int img[3]; double bin_volume; IntList* ids; #ifdef LEES_EDWARDS double v_le[3]; #endif if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } radial_profile_data* pdata; pdata=(radial_profile_data*) self->container; ids=pdata->id_list; double rbinsize=(pdata->maxr - pdata->minr)/pdata->rbins; double phibinsize=(pdata->maxphi - pdata->minphi)/pdata->phibins; double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; double v[3]; double v_r, v_phi, v_z; if (self->last_update==sim_time) { return ES_ERROR; } for (int i = 0; i< self->n; i++ ) { A[i]=0; } double* old_positions=(double*) pdata->container; if (old_positions[0] == CONST_UNITITIALIZED) { for (int i = 0; i<ids->n; i++ ) { memcpy(unfolded_ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); unfold_position(unfolded_ppos, img); old_positions[3*i+0]=unfolded_ppos[0]; old_positions[3*i+1]=unfolded_ppos[1]; old_positions[3*i+2]=unfolded_ppos[2]; } return 0; } for (int i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_part) return 1; /* We use folded coordinates here */ memcpy(unfolded_ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); unfold_position(unfolded_ppos, img); v[0]=(unfolded_ppos[0] - old_positions[3*i+0]); v[1]=(unfolded_ppos[1] - old_positions[3*i+1]); v[2]=(unfolded_ppos[2] - old_positions[3*i+2]); memcpy(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); memcpy(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); fold_position(ppos, img); // The position of the particle is by definition the middle of old and new position ppos[0]+=0.5*v[0]; ppos[1]+=0.5*v[1]; ppos[2]+=0.5*v[2]; fold_position(ppos, img); v[0]/=(sim_time - self->last_update); v[1]/=(sim_time - self->last_update); v[2]/=(sim_time - self->last_update); if (i==0) { // printf("(%3.4f) %f %f %f\n", sim_time-self->last_update, v[2], partCfg[ids->e[i]].m.v[2]/time_step,v[2]* partCfg[ids->e[i]].m.v[2]/time_step/time_step); // printf("(%3.3f) %f %f", sim_time, old_positions[3*i+2], unfolded_ppos[2]); } old_positions[3*i+0]=unfolded_ppos[0]; old_positions[3*i+1]=unfolded_ppos[1]; old_positions[3*i+2]=unfolded_ppos[2]; transform_to_cylinder_coordinates(ppos[0]-pdata->center[0], ppos[1]-pdata->center[1], ppos[2]-pdata->center[2], &r, &phi, &z); binr =(int)floor((r-pdata->minr)/rbinsize); binphi=(int)floor((phi-pdata->minphi)/phibinsize); binz =(int)floor((z-pdata->minz)/zbinsize); if (binr>=0 && binr < pdata->rbins && binphi>=0 && binphi < pdata->phibins && binz>=0 && binz < pdata->zbins) { bin_volume=PI*((pdata->minr+(binr+1)*rbinsize)*(pdata->minr+(binr+1)*rbinsize) - (pdata->minr+(binr)*rbinsize)*(pdata->minr+(binr)*rbinsize)) *zbinsize * phibinsize/2/PI; v_r = 1/r*((ppos[0]-pdata->center[0])*v[0] + (ppos[1]-pdata->center[1])*v[1]); v_phi = 1/r/r*((ppos[0]-pdata->center[0])*v[1]-(ppos[1]-pdata->center[1])*v[0]); v_z = v[2]; A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 0] += v_r/bin_volume; A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 1] += v_phi/bin_volume; A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 2] += v_z/bin_volume; } } return 0; }