int populate_lattice(PdbParser::PdbParser &parser, double scale) { /* * This routine will populate the lattice using the * values read from the pdb and itp files. * WARNING: It contains much logic and interpolation stuff! */ #ifdef DEBUG printf("pdb_n_particles=%u, itp_n_particles=%u, itp_n_parameters=%u\n",atom_data->pdb_n_particles,atom_data->itp_n_particles,atom_data->itp_n_parameters); #endif // TODO: Check if bounding box fits into simbox const PdbParser::BoundingBox bbox = parser.calc_bounding_box(); float center[3]; center[0] = ( bbox.urx + bbox.llx )/2 / scale; center[1] = ( bbox.ury + bbox.lly )/2 / scale; center[2] = ( bbox.urz + bbox.llz )/2 / scale; // calculate the shift of the bounding box float shift[3]; shift[0] = ek_parameters.agrid / 2.0 * ek_parameters.dim_x - center[0]; shift[1] = ek_parameters.agrid / 2.0 * ek_parameters.dim_y - center[1]; shift[2] = ek_parameters.agrid / 2.0 * ek_parameters.dim_z - center[2]; #ifdef DEBUG printf("agrid=%f, dim_x=%d, dim_y=%d, dim_z=%d\n",ek_parameters.agrid, ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z); printf("shift=[%f; %f; %f]\n",shift[0], shift[1], shift[2]); #endif // joining the array int lowernode[3]; float cellpos[3]; float gridpos; float a_x_shifted, a_y_shifted, a_z_shifted; float a_x_scaled, a_y_scaled, a_z_scaled; for (std::vector<PdbParser::pdb_atom>::const_iterator a = parser.pdb_atoms.begin(); a != parser.pdb_atoms.end(); ++a) { PdbParser::itp_atom b = parser.itp_atoms[a->i]; PdbParser::itp_atomtype c = parser.itp_atomtypes[b.type]; #ifdef DEBUG printf("i=%d x=%f y=%f z=%f type=%s charge=%f sigma=%f epsilon=%f\n",a->i,a->x,a->y,a->z,b.type,b.charge,c.sigma,c.epsilon); #endif a_x_scaled = a->x / scale; a_y_scaled = a->y / scale; a_z_scaled = a->z / scale; // Interpolate the charge to the lattice gridpos = (a_x_scaled + shift[0]) / ek_parameters.agrid - 0.5f; lowernode[0] = (int) floorf( gridpos ); cellpos[0] = gridpos - lowernode[0]; gridpos = (a_y_scaled + shift[1]) / ek_parameters.agrid - 0.5f; lowernode[1] = (int) floorf( gridpos ); cellpos[1] = gridpos - lowernode[1]; gridpos = (a_z_scaled + shift[2]) / ek_parameters.agrid - 0.5f; lowernode[2] = (int) floorf( gridpos ); cellpos[2] = gridpos - lowernode[2]; lowernode[0] = (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; lowernode[1] = (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; lowernode[2] = (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],lowernode[1],lowernode[2] )] += b.charge * ( 1 - cellpos[0] ) * ( 1 - cellpos[1] ) * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,lowernode[1],lowernode[2] )] += b.charge * cellpos[0] * ( 1 - cellpos[1] ) * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],( lowernode[1] + 1 ) % ek_parameters.dim_y,lowernode[2] )] += b.charge * ( 1 - cellpos[0] ) * cellpos[1] * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],lowernode[1],( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b.charge * ( 1 - cellpos[0] ) * ( 1 - cellpos[1] ) * cellpos[2]; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,( lowernode[1] + 1 ) % ek_parameters.dim_y,lowernode[2] )] += b.charge * cellpos[0] * cellpos[1] * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,lowernode[1],( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b.charge * cellpos[0] * ( 1 - cellpos[1] ) * cellpos[2]; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],( lowernode[1] + 1 ) % ek_parameters.dim_y,( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b.charge * ( 1 - cellpos[0] ) * cellpos[1] * cellpos[2]; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,( lowernode[1] + 1 ) % ek_parameters.dim_y,( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b.charge * cellpos[0] * cellpos[1] * cellpos[2]; // Interpolate lennard-jones parameters to boundary float r = pow(2,1./6.)*c.sigma * 10 / scale; a_x_shifted = (a_x_scaled + shift[0]) / ek_parameters.agrid - 0.5f; a_y_shifted = (a_y_scaled + shift[1]) / ek_parameters.agrid - 0.5f; a_z_shifted = (a_z_scaled + shift[2]) / ek_parameters.agrid - 0.5f; for (float z = a_z_scaled - r; z <= a_z_scaled + r + ek_parameters.agrid; z += ek_parameters.agrid) { for (float y = a_y_scaled - r; y <= a_y_scaled + r + ek_parameters.agrid; y += ek_parameters.agrid) { for (float x = a_x_scaled - r; x <= a_x_scaled + r + ek_parameters.agrid; x += ek_parameters.agrid) { gridpos = (x + shift[0]) / ek_parameters.agrid - 0.5f; lowernode[0] = (int) floorf( gridpos ); gridpos = (y + shift[1]) / ek_parameters.agrid - 0.5f; lowernode[1] = (int) floorf( gridpos ); gridpos = (z + shift[2]) / ek_parameters.agrid - 0.5f; lowernode[2] = (int) floorf( gridpos ); lowernode[0] = (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; lowernode[1] = (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; lowernode[2] = (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; #ifdef DEBUG printf("shifted: %f %f %f\n", a_x_shifted, a_y_shifted, a_z_shifted); printf("lowernode: %d %d %d\n", lowernode[0], lowernode[1], lowernode[2]); printf("distance: %f %f %f\n", lowernode[0] - a_x_shifted, lowernode[1] - a_y_shifted, lowernode[2] - a_z_shifted); printf("distance: %f <= %f\n\n", pow(lowernode[0] - a_x_shifted,2) + pow(lowernode[1] - a_y_shifted,2) + pow(lowernode[2] - a_z_shifted,2), pow(r/ek_parameters.agrid,2)); #endif if ( pow(lowernode[0] - a_x_shifted,2) + pow(lowernode[1] - a_y_shifted,2) + pow(lowernode[2] - a_z_shifted,2) <= pow(r/ek_parameters.agrid,2) ) { pdb_boundary_lattice[ek_parameters.dim_y*ek_parameters.dim_x*lowernode[2] + ek_parameters.dim_x*lowernode[1] + lowernode[0]] = 1; } } } } } return pdb_SUCCESS; }
int populate_lattice(particle_data* atom_data) { /* * This routine will populate the lattice using the * values read from the pdb and itp files. * WARNING: It contains much logic and interpolation stuff! */ #ifdef DEBUG printf("pdb_n_particles=%u, itp_n_particles=%u, itp_n_parameters=%u\n",atom_data->pdb_n_particles,atom_data->itp_n_particles,atom_data->itp_n_parameters); #endif // TODO: Check if bounding box fits into simbox bounding_box bbox; calculate_bounding_box(&bbox, atom_data); // calculate the shift of the bounding box float shift[3]; shift[0] = ek_parameters.agrid / 2.0 * ek_parameters.dim_x - bbox.center[0]; shift[1] = ek_parameters.agrid / 2.0 * ek_parameters.dim_y - bbox.center[1]; shift[2] = ek_parameters.agrid / 2.0 * ek_parameters.dim_z - bbox.center[2]; #ifdef DEBUG printf("bbox.max_x=%f, bbox.max_y=%f, bbox.max_z=%f, bbox.min_x=%f, bbox.min_y=%f, bbox.min_z=%f, bbox->center=[%f; %f; %f]\n", bbox.max_x, bbox.max_y, bbox.max_z, bbox.min_x, bbox.min_y, bbox.min_z, bbox.center[0], bbox.center[1], bbox.center[2]); printf("agrid=%f, dim_x=%d, dim_y=%d, dim_z=%d\n",ek_parameters.agrid, ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z); printf("shift=[%f; %f; %f]\n",shift[0], shift[1], shift[2]); #endif // joining the array int lowernode[3]; float cellpos[3]; float gridpos; float a_x_shifted, a_y_shifted, a_z_shifted; for (unsigned int i = 0; i <= atom_data->pdb_n_particles-1; i++) { pdb_ATOM* a = &atom_data->pdb_array_ATOM[i]; itp_atoms* b; itp_atomtypes* c; for (unsigned int j = 0; j <= atom_data->itp_n_particles-1; j++) { b = &atom_data->itp_array_atoms[j]; if (a->i == b->i) { for (unsigned int k = 0; k <= atom_data->itp_n_parameters-1; k++) { c = &atom_data->itp_array_atomtypes[k]; if (strcmp(b->type,c->type) == 0) { #ifdef DEBUG printf("i=%d x=%f y=%f z=%f type=%s charge=%f sigma=%f epsilon=%f\n",a->i,a->x,a->y,a->z,b->type,b->charge,c->sigma,c->epsilon); #endif // Interpolate the charge to the lattice gridpos = (a->x + shift[0]) / ek_parameters.agrid - 0.5f; lowernode[0] = (int) floorf( gridpos ); cellpos[0] = gridpos - lowernode[0]; gridpos = (a->y + shift[1]) / ek_parameters.agrid - 0.5f; lowernode[1] = (int) floorf( gridpos ); cellpos[1] = gridpos - lowernode[1]; gridpos = (a->z + shift[2]) / ek_parameters.agrid - 0.5f; lowernode[2] = (int) floorf( gridpos ); cellpos[2] = gridpos - lowernode[2]; lowernode[0] = (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; lowernode[1] = (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; lowernode[2] = (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],lowernode[1],lowernode[2] )] += b->charge * ( 1 - cellpos[0] ) * ( 1 - cellpos[1] ) * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,lowernode[1],lowernode[2] )] += b->charge * cellpos[0] * ( 1 - cellpos[1] ) * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],( lowernode[1] + 1 ) % ek_parameters.dim_y,lowernode[2] )] += b->charge * ( 1 - cellpos[0] ) * cellpos[1] * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],lowernode[1],( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b->charge * ( 1 - cellpos[0] ) * ( 1 - cellpos[1] ) * cellpos[2]; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,( lowernode[1] + 1 ) % ek_parameters.dim_y,lowernode[2] )] += b->charge * cellpos[0] * cellpos[1] * ( 1 - cellpos[2] ); pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,lowernode[1],( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b->charge * cellpos[0] * ( 1 - cellpos[1] ) * cellpos[2]; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],( lowernode[1] + 1 ) % ek_parameters.dim_y,( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b->charge * ( 1 - cellpos[0] ) * cellpos[1] * cellpos[2]; pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,( lowernode[1] + 1 ) % ek_parameters.dim_y,( lowernode[2] + 1 ) % ek_parameters.dim_z )] += b->charge * cellpos[0] * cellpos[1] * cellpos[2]; // Interpolate lennard-jones parameters to boundary float r = pow(2,1./6.)*c->sigma; a_x_shifted = (a->x + shift[0]) / ek_parameters.agrid - 0.5f; a_y_shifted = (a->y + shift[1]) / ek_parameters.agrid - 0.5f; a_z_shifted = (a->z + shift[2]) / ek_parameters.agrid - 0.5f; for (float z = a->z - r; z <= a->z + r + ek_parameters.agrid; z += ek_parameters.agrid) { for (float y = a->y - r; y <= a->y + r + ek_parameters.agrid; y += ek_parameters.agrid) { for (float x = a->x - r; x <= a->x + r + ek_parameters.agrid; x += ek_parameters.agrid) { gridpos = (x + shift[0]) / ek_parameters.agrid - 0.5f; lowernode[0] = (int) floorf( gridpos ); gridpos = (y + shift[1]) / ek_parameters.agrid - 0.5f; lowernode[1] = (int) floorf( gridpos ); gridpos = (z + shift[2]) / ek_parameters.agrid - 0.5f; lowernode[2] = (int) floorf( gridpos ); lowernode[0] = (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; lowernode[1] = (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; lowernode[2] = (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; #ifdef DEBUG printf("shifted: %f %f %f\n", a_x_shifted, a_y_shifted, a_z_shifted); printf("lowernode: %d %d %d\n", lowernode[0], lowernode[1], lowernode[2]); printf("distance: %f %f %f\n", lowernode[0] - a_x_shifted, lowernode[1] - a_y_shifted, lowernode[2] - a_z_shifted); printf("distance: %f <= %f\n\n", pow(lowernode[0] - a_x_shifted,2) + pow(lowernode[1] - a_y_shifted,2) + pow(lowernode[2] - a_z_shifted,2), pow(r/ek_parameters.agrid,2)); #endif if ( pow(lowernode[0] - a_x_shifted,2) + pow(lowernode[1] - a_y_shifted,2) + pow(lowernode[2] - a_z_shifted,2) <= pow(r/ek_parameters.agrid,2) ) { pdb_boundary_lattice[ek_parameters.dim_y*ek_parameters.dim_x*lowernode[2] + ek_parameters.dim_x*lowernode[1] + lowernode[0]] = 1; } } } } break; } } } } } return pdb_SUCCESS; }