int updatePartCfg(int bonds_flag) { int j; if(partCfg) return 1; partCfg = (Particle*)malloc(n_part*sizeof(Particle)); if (bonds_flag != WITH_BONDS) mpi_get_particles(partCfg, NULL); else mpi_get_particles(partCfg,&partCfg_bl); for(j=0; j<n_part; j++) unfold_position(partCfg[j].r.p,partCfg[j].l.i); partCfgSorted = 0; #ifdef VIRTUAL_SITES if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return 0; } if (!updatePartCfg(bonds_flag)) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not update positions of virtual sites in partcfg } "); return 0; } #endif return 1; }
int observable_calc_blocked_com_position(observable* self) { double* A = self->last_value; unsigned int i; unsigned int block; unsigned int n_blocks; unsigned int blocksize; unsigned int id; double total_mass = 0; IntList* ids; if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } ids=(IntList*) self->container; n_blocks=self->n/3; blocksize=ids->n/n_blocks; for ( block = 0; block < n_blocks; block++ ) { total_mass = 0; for ( i = 0; i < blocksize; i++ ) { id = ids->e[block*blocksize+i]; if (ids->e[i] >= n_part) return 1; A[3*block+0] += PMASS(partCfg[id])*partCfg[id].r.p[0]; A[3*block+1] += PMASS(partCfg[id])*partCfg[id].r.p[1]; A[3*block+2] += PMASS(partCfg[id])*partCfg[id].r.p[2]; total_mass += PMASS(partCfg[ids->e[i]]); } A[3*block+0] /= total_mass; A[3*block+1] /= total_mass; A[3*block+2] /= total_mass; } return 0; }
int observable_calc_blocked_com_force(observable* self) { double* A = self->last_value; unsigned int i; unsigned int block; unsigned int n_blocks; unsigned int blocksize; unsigned int id; IntList* ids; if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } ids=(IntList*) self->container; n_blocks=self->n/3; blocksize=ids->n/n_blocks; for ( block = 0; block < n_blocks; block++ ) { for ( i = 0; i < blocksize; i++ ) { id = ids->e[block*blocksize+i]; if (ids->e[i] >= n_part) return 1; A[3*block+0] += partCfg[id].f.f[0]/time_step/time_step*2; A[3*block+1] += partCfg[id].f.f[1]/time_step/time_step*2; A[3*block+2] += partCfg[id].f.f[2]/time_step/time_step*2; } } return 0; }
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_blocked_com_position(void* idlist, double* A, unsigned int n_A) { unsigned int i; unsigned int block; unsigned int n_blocks; unsigned int blocksize; unsigned int id; double total_mass = 0; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; n_blocks=n_A/3; blocksize=ids->n/n_blocks; for ( block = 0; block < n_blocks; block++ ) { total_mass = 0; for ( i = 0; i < blocksize; i++ ) { id = ids->e[block*blocksize+i]; if (ids->e[i] >= n_total_particles) return 1; A[3*block+0] += PMASS(partCfg[id])*partCfg[id].r.p[0]; A[3*block+1] += PMASS(partCfg[id])*partCfg[id].r.p[1]; A[3*block+2] += PMASS(partCfg[id])*partCfg[id].r.p[2]; total_mass += PMASS(partCfg[ids->e[i]]); } A[3*block+0] /= total_mass; A[3*block+1] /= total_mass; A[3*block+2] /= total_mass; } 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; }
int observable_stress_tensor(observable* self) { if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } observable_compute_stress_tensor(1,self->last_value,self->n); return 0; }
int observable_stress_tensor_acf_obs(void* params_p, double* A, unsigned int n_A) { double stress_tensor[9]; sortPartCfg(); observable_compute_stress_tensor(1,stress_tensor,9); A[0]=stress_tensor[1]; A[1]=stress_tensor[5]; A[2]=stress_tensor[6]; A[3]=stress_tensor[0]-stress_tensor[4]; A[4]=stress_tensor[0]-stress_tensor[8]; A[5]=stress_tensor[4]-stress_tensor[8]; return 0; }
/* new version for new topology structure */ int analyze_fold_molecules(float *coord, double shift[3]) { int m,p,i, tmp; int mol_size, ind; double cm_tmp, com[3]; #ifdef LEES_EDWARDS if(lees_edwards_offset != 0.0 ){ fprintf(stderr, "Error: Folding molecules not supported under Lees-Edwards.\n"); exit(8); } #endif /* check molecule information */ if ( n_molecules < 0 ) return ES_ERROR; if (!sortPartCfg()) { ostringstream msg; msg <<"analyze_fold_molecules: could not sort particle config, particle ids not consecutive?"; runtimeError(msg); return ES_ERROR; } /* loop molecules */ for(m=0; m<n_molecules; m++) { mol_size = topology[m].part.n; if(mol_size > 0) { /* calc center of mass */ calc_mol_center_of_mass(topology[m],com); /* fold coordinates */ for(i=0; i<3; i++) { if ( PERIODIC(i) ) { tmp = (int)floor((com[i]+shift[i])*box_l_i[i]); cm_tmp =0.0; for(p=0; p<mol_size; p++) { ind = 3*topology[m].part.e[p] + i; coord[ind] -= tmp*box_l[i]; coord[ind] += shift[i]; cm_tmp += coord[ind]; } cm_tmp /= (double)mol_size; if(cm_tmp < -10e-6 || cm_tmp > box_l[i]+10e-6) { ostringstream msg; msg <<"analyze_fold_molecules: chain center of mass is out of range (coord " << i << ": " << cm_tmp << " not in box_l " << box_l[i] << ")"; runtimeError(msg); return ES_ERROR; } } } } } return ES_OK; }
/* Get a complete list of the orientations of every lipid assuming a bilayer structure. Requires grid*/ int get_lipid_orients(IntList* l_orient) { int i,gi,gj, atom; double zreflocal,zref; double dir[3]; double refdir[3] = {0,0,1}; double grid_size[2]; double* height_grid; if ( xdir + ydir + zdir == -3 || mode_grid_3d[xdir] <= 0 || mode_grid_3d[ydir] <= 0 ) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{036 cannot calculate lipid orientations with uninitialized grid} "); return ES_ERROR; } /* Allocate memory for height grid arrays and initialize these arrays */ height_grid = (double*) malloc((mode_grid_3d[xdir])*sizeof(double)*mode_grid_3d[ydir]); /* Calculate physical size of grid mesh */ grid_size[xdir] = box_l[xdir]/(double)mode_grid_3d[xdir]; grid_size[ydir] = box_l[ydir]/(double)mode_grid_3d[ydir]; /* Update particles */ updatePartCfg(WITHOUT_BONDS); //Make sure particles are sorted if (!sortPartCfg()) { fprintf(stderr,"%d,could not sort partCfg \n",this_node); return -1; } if ( !calc_fluctuations(height_grid, 1) ) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{034 calculation of height grid failed } "); return -1; } zref = calc_zref( zdir ); for ( i = 0 ; i < n_molecules ; i++) { atom = topology[i].part.e[0]; gi = floor( partCfg[atom].r.p[xdir]/grid_size[xdir] ); gj = floor( partCfg[atom].r.p[ydir]/grid_size[ydir] ); zreflocal = height_grid[gj+gi*mode_grid_3d[xdir]] + zref; l_orient->e[i] = lipid_orientation(atom,partCfg,zreflocal,dir,refdir); } free(height_grid); return 1; }
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; }
int tclcommand_analyze_parse_and_print_pressure_mol(Tcl_Interp *interp,int argc, char **argv) { char buffer[TCL_DOUBLE_SPACE]; int type1, type2; double psum; #ifdef ELECTROSTATICS #ifndef INTER_RF Tcl_ResetResult(interp); Tcl_AppendResult(interp, "parse_and_print_pressure_mol is only possible with INTER_RF ", (char *)NULL); return (TCL_ERROR); #endif #endif updatePartCfg(WITHOUT_BONDS); if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt, "{059 parse_and_print_pressure_mol: could not sort particle config, particle ids not consecutive?} "); return TCL_ERROR; } if (argc < 2) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "usage: analyze pressure_mol <type1> <type2>", (char *)NULL); return (TCL_ERROR); } if (!ARG0_IS_I(type1)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "usage: analyze pressure_mol <type1> <type2>", (char *)NULL); return (TCL_ERROR); } if (!ARG1_IS_I(type2)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "usage: analyze pressure_mol <type1> <type2>", (char *)NULL); return (TCL_ERROR); } argc-=2; argv+=2; if (n_molecules==0) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "No molecules defined !", (char *)NULL); return (TCL_ERROR); } psum=calc_pressure_mol(type1,type2); //sprintf(buffer,"%i",type1); //Tcl_AppendResult(interp,"{ analyze pressure_mol ",buffer," ",(char *)NULL); //sprintf(buffer,"%i",type2); //Tcl_AppendResult(interp,buffer," ",(char *)NULL); sprintf(buffer,"%e",psum); Tcl_AppendResult(interp, buffer,(char *)NULL); return TCL_OK; }
int observable_particle_forces(void* idlist, double* A, unsigned int n_A) { unsigned int i; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; A[3*i + 0] = partCfg[ids->e[i]].f.f[0]/time_step/time_step*2; A[3*i + 1] = partCfg[ids->e[i]].f.f[1]/time_step/time_step*2; A[3*i + 2] = partCfg[ids->e[i]].f.f[2]/time_step/time_step*2; } return 0; }
int observable_particle_positions(void* idlist, double* A, unsigned int n_A) { unsigned int i; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; A[3*i + 0] = partCfg[ids->e[i]].r.p[0]; A[3*i + 1] = partCfg[ids->e[i]].r.p[1]; A[3*i + 2] = partCfg[ids->e[i]].r.p[2]; } return 0; }
static int tclcommand_analyze_set_parse_chain_topology_check(Tcl_Interp *interp, int argc, char **argv) { if (argc > 0) if (tclcommand_analyze_set_parse_chain_topology(interp, argc, argv) != TCL_OK) return TCL_ERROR; if (!sortPartCfg()) { Tcl_AppendResult(interp, "for analyze, store particles consecutively starting with 0.", (char *) NULL); return (TCL_ERROR); } return TCL_OK; }
int observable_calc_structure_factor(observable* self) { double* A = self->last_value; // FIXME Currently scattering length is hardcoded as 1.0 int l; int order, order2, n; double twoPI_L, C_sum, S_sum, qr; // DoubleList *scattering_length; observable_sf_params* params; params = (observable_sf_params*) self->container; // scattering_length = params->scattering_length; const double scattering_length=1.0; order = params->order; order2=order*order; twoPI_L = 2*PI/box_l[0]; if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } for(int p=0; p<self->n; p++) { A[p] = 0.0; } l=0; //printf("self->n: %d, dim_sf: %d\n",n_A, params.dim_sf); fflush(stdout); for(int i=-order; i<=order; i++) { for(int j=-order; j<=order; j++) { for(int k=-order; k<=order; k++) { n = i*i + j*j + k*k; if ((n<=order2) && (n>=1)) { C_sum = S_sum = 0.0; //printf("l: %d, n: %d %d %d\n",l,i,j,k); fflush(stdout); for(int p=0; p<n_part; p++) { qr = twoPI_L * ( i*partCfg[p].r.p[0] + j*partCfg[p].r.p[1] + k*partCfg[p].r.p[2] ); C_sum+= scattering_length * cos(qr); S_sum-= scattering_length * sin(qr); } A[l] =C_sum; A[l+1] =S_sum; l=l+2; } } } } //printf("finished calculating sf\n"); fflush(stdout); return 0; }
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_particle_currents(void* idlist, double* A, unsigned int n_A) { unsigned int i; double charge; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; charge = partCfg[ids->e[i]].p.q; A[3*i + 0] = charge * partCfg[ids->e[i]].m.v[0]/time_step; A[3*i + 1] = charge * partCfg[ids->e[i]].m.v[1]/time_step; A[3*i + 2] = charge * partCfg[ids->e[i]].m.v[2]/time_step; } 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; }
int observable_calc_stress_tensor_acf_obs(observable* self) { double* A = self->last_value; double stress_tensor[9]; if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } observable_compute_stress_tensor(1,stress_tensor,9); A[0]=stress_tensor[1]; A[1]=stress_tensor[5]; A[2]=stress_tensor[6]; A[3]=stress_tensor[0]-stress_tensor[4]; A[4]=stress_tensor[0]-stress_tensor[8]; A[5]=stress_tensor[4]-stress_tensor[8]; return 0; }
/* new version for new topology structure */ int analyze_fold_molecules(float *coord, double shift[3]) { int m,p,i, tmp; int mol_size, ind; double cm_tmp, com[3]; /* check molecule information */ if ( n_molecules < 0 ) return (TCL_ERROR); if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt, "{059 analyze_fold_molecules: could not sort particle config, particle ids not consecutive?} "); return TCL_ERROR; } /* loop molecules */ for(m=0; m<n_molecules; m++) { mol_size = topology[m].part.n; if(mol_size > 0) { /* calc center of mass */ calc_mol_center_of_mass(topology[m],com); /* fold coordinates */ for(i=0; i<3; i++) { if ( PERIODIC(i) ) { tmp = (int)floor((com[i]+shift[i])*box_l_i[i]); cm_tmp =0.0; for(p=0; p<mol_size; p++) { ind = 3*topology[m].part.e[p] + i; coord[ind] -= tmp*box_l[i]; coord[ind] += shift[i]; cm_tmp += coord[ind]; } cm_tmp /= (double)mol_size; if(cm_tmp < -10e-6 || cm_tmp > box_l[i]+10e-6) { char *errtxt = runtime_error(128 + TCL_INTEGER_SPACE + 2*TCL_DOUBLE_SPACE); ERROR_SPRINTF(errtxt,"{060 analyze_fold_molecules: chain center of mass is out of range (coord %d: %.14f not in box_l %.14f)} ", i,cm_tmp,box_l[i]); return (TCL_ERROR); } } } } } return (TCL_OK); }
int observable_com_force(void* idlist, double* A, unsigned int n_A) { unsigned int i; double f_com[3] = { 0. , 0., 0. } ; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; f_com[0] += partCfg[ids->e[i]].f.f[0]/time_step/time_step*2; f_com[1] += partCfg[ids->e[i]].f.f[1]/time_step/time_step*2; f_com[2] += partCfg[ids->e[i]].f.f[2]/time_step/time_step*2; } A[0]=f_com[0]; A[1]=f_com[1]; A[2]=f_com[2]; return 0; }
int observable_calc_particle_forces(observable* self) { double* A = self->last_value; IntList* ids; if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } ids=(IntList*) self->container; for (int i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_part) return 1; A[3*i + 0] = partCfg[ids->e[i]].f.f[0]/time_step/time_step*2; A[3*i + 1] = partCfg[ids->e[i]].f.f[1]/time_step/time_step*2; A[3*i + 2] = partCfg[ids->e[i]].f.f[2]/time_step/time_step*2; } return 0; }
int observable_structure_factor(void* params_p, double* A, unsigned int n_A) { // FIXME Currently scattering length is hardcoded as 1.0 int i,j,k,l,p; int order, order2, n; double twoPI_L, C_sum, S_sum, qr; // DoubleList *scattering_length; observable_sf_params* params; params = (observable_sf_params*)params_p; // scattering_length = params->scattering_length; const double scattering_length=1.0; order = params->order; order2=order*order; twoPI_L = 2*PI/box_l[0]; sortPartCfg(); for(p=0; p<n_A; p++) { A[p] = 0.0; } l=0; //printf("n_A: %d, dim_sf: %d\n",n_A, params.dim_sf); fflush(stdout); for(i=-order; i<=order; i++) { for(j=-order; j<=order; j++) { for(k=-order; k<=order; k++) { n = i*i + j*j + k*k; if ((n<=order2) && (n>=1)) { C_sum = S_sum = 0.0; //printf("l: %d, n: %d %d %d\n",l,i,j,k); fflush(stdout); for(p=0; p<n_total_particles; p++) { qr = twoPI_L * ( i*partCfg[p].r.p[0] + j*partCfg[p].r.p[1] + k*partCfg[p].r.p[2] ); C_sum+= scattering_length * cos(qr); S_sum-= scattering_length * sin(qr); } A[l] =C_sum; A[l+1] =S_sum; l=l+2; } } } } //printf("finished calculating sf\n"); fflush(stdout); return 0; }
int observable_calc_interacts_with (observable* self) { double* A = self->last_value; iw_params *params=(iw_params*) self->container; IntList* ids1; IntList* ids2; int i,j; // double dx,dy,dz; double dist2; double cutoff2=params->cutoff*params->cutoff; double pos1[3], pos2[3], dist[3]; ids1=params->ids1; ids2=params->ids2; if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} "); return -1; } for ( i = 0; i<ids1->n; i++ ) { if (ids1->e[i] >= n_part) return 1; pos1[0]=partCfg[ids1->e[i]].r.p[0]; pos1[1]=partCfg[ids1->e[i]].r.p[1]; pos1[2]=partCfg[ids1->e[i]].r.p[2]; for ( j = 0; j<ids2->n; j++ ) { if (ids2->e[j] >= n_part) return 1; if (ids2->e[j] == ids1->e[i]) // do not count self-interaction :-) continue; A[i] = 0; pos2[0]=partCfg[ids2->e[j]].r.p[0]; pos2[1]=partCfg[ids2->e[j]].r.p[1]; pos2[2]=partCfg[ids2->e[j]].r.p[2]; get_mi_vector(dist,pos1,pos2); dist2= dist[0]*dist[0] + dist[1]*dist[1] + dist[2]*dist[2]; if(dist2<cutoff2) { A[i] = 1; break; // interaction found for i, go for next } } } return 0; }
int tclcommand_analyze_parse_and_print_energy_kinetic_mol(Tcl_Interp *interp,int argc, char **argv) { char buffer[TCL_DOUBLE_SPACE]; int type; double Ekin; updatePartCfg(WITHOUT_BONDS); if (!sortPartCfg()) { char *errtxt = runtime_error(128); ERROR_SPRINTF(errtxt, "{059 parse_and_print_energy_kinetic_mol: could not sort particle config, particle ids not consecutive?} "); return TCL_ERROR; } if (argc < 1) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "usage: analyze energy_kinetic <type>", (char *)NULL); return (TCL_ERROR); } if (!ARG0_IS_I(type)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "usage: analyze energy_kinetic <type>", (char *)NULL); return (TCL_ERROR); } argc-=1; argv+=1; if (n_molecules==0) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "No molecules defined !", (char *)NULL); return (TCL_ERROR); } Ekin=calc_energy_kinetic_mol(type); if (Ekin < 0.0) { Tcl_ResetResult(interp); sprintf(buffer,"%i",-(int)Ekin); Tcl_AppendResult(interp,"Could not fetch com in calc_energy_kinetic_mol! From mol_id",buffer, (char *)NULL); return (TCL_ERROR); } //sprintf(buffer,"%i",type); //Tcl_AppendResult(interp,"{ analyze pressure_mol ",buffer," ",(char *)NULL); sprintf(buffer,"%e",Ekin); Tcl_AppendResult(interp, buffer,(char *)NULL); return TCL_OK; }
int observable_com_position(void* idlist, double* A, unsigned int n_A) { unsigned int i; double p_com[3] = { 0. , 0., 0. } ; double total_mass = 0; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; p_com[0] += PMASS(partCfg[ids->e[i]])*partCfg[ids->e[i]].r.p[0]; p_com[1] += PMASS(partCfg[ids->e[i]])*partCfg[ids->e[i]].r.p[1]; p_com[2] += PMASS(partCfg[ids->e[i]])*partCfg[ids->e[i]].r.p[2]; total_mass += PMASS(partCfg[ids->e[i]]); } A[0]=p_com[0]/total_mass; A[1]=p_com[1]/total_mass; A[2]=p_com[2]/total_mass; return 0; }
int observable_currents(void* idlist, double* A, unsigned int n_A) { unsigned int i; double charge; double j[3] = {0. , 0., 0. } ; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] > n_total_particles) return 1; charge = partCfg[ids->e[i]].p.q; j[0] += charge * partCfg[ids->e[i]].m.v[0]/time_step; j[1] += charge * partCfg[ids->e[i]].m.v[1]/time_step; j[2] += charge * partCfg[ids->e[i]].m.v[2]/time_step; } A[0]=j[0]; A[1]=j[1]; A[2]=j[2]; return 0; }
int observable_com_velocity(void* idlist, double* A, unsigned int n_A) { unsigned int i; double v_com[3] = { 0. , 0., 0. } ; double total_mass = 0; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; v_com[0] += PMASS(partCfg[ids->e[i]])*partCfg[ids->e[i]].m.v[0]/time_step; v_com[1] += PMASS(partCfg[ids->e[i]])*partCfg[ids->e[i]].m.v[1]/time_step; v_com[2] += PMASS(partCfg[ids->e[i]])*partCfg[ids->e[i]].m.v[2]/time_step; total_mass += PMASS(partCfg[ids->e[i]]); } A[0]=v_com[0]/total_mass; A[1]=v_com[1]/total_mass; A[2]=v_com[2]/total_mass; return 0; }
int observable_particle_angular_momentum(void* idlist, double* A, unsigned int n_A) { unsigned int i; IntList* ids; sortPartCfg(); ids=(IntList*) idlist; for ( i = 0; i<ids->n; i++ ) { if (ids->e[i] >= n_total_particles) return 1; #ifdef ROTATION A[3*i + 0] = partCfg[ids->e[i]].m.omega[0]; A[3*i + 1] = partCfg[ids->e[i]].m.omega[1]; A[3*i + 2] = partCfg[ids->e[i]].m.omega[2]; #else A[3*i + 0] = 0.0; A[3*i + 1] = 0.0; A[3*i + 2] = 0.0; #endif } return 0; }