void calc_cluster_volume_and_store_with_cluster_rep( Triangulation &triang, map<int, cell_cluster> &cluster_set, vector<double> &cluster_volume_vector, vector<int> &cluster_rep_vector ) { for(FCI cit = triang.finite_cells_begin(); cit != triang.finite_cells_end(); cit ++) { if( ! cluster_set[cit->id].in_cluster ) continue; if( ! cluster_set[cit->id].outside ) continue; double volume = cell_volume(cit); // see if we already computed some of the cluster volume. // in other words see if the 'rep' is there in the cluster_rep_vector. int rep = cluster_set[cit->id].find(); bool found = false; int pos = -1; for(int i = 0; i < (int)cluster_rep_vector.size(); i ++) if(cluster_rep_vector[i] == rep) { found = true; pos = i; break; } if(found) cluster_volume_vector[pos] += volume; else { cluster_volume_vector.push_back(volume); cluster_rep_vector.push_back(rep); } } CGAL_assertion(cluster_volume_vector.size() == cluster_rep_vector.size()); }
void TopologyMatrix::calculateForThreeAtoms( const unsigned& iat, const Vector& d1, const double& d1_len, HistogramBead& bead, multicolvar::AtomValuePack& myatoms ) const { // Calculate if there are atoms in the cylinder (can use delta here as pbc are done in atom setup) Vector d2 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(iat) ); // Now calculate projection of d2 on d1 double proj=dotProduct(d2,d1); // This tells us if we are outside the end of the cylinder double excess = proj - d1_len; // Return if we are outside of the cylinder as calculated based on excess if( excess>low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax() ) return; // Find the length of the cylinder double binw = binw_mat( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ); double lcylinder = (std::floor( d1_len / binw ) + 1)*binw; // Return if the projection is outside the length of interest if( proj<-bead.getCutoff() || proj>(lcylinder+bead.getCutoff()) ) return; // Calculate the excess swiching function double edf, eval = low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( excess, edf ); // Calculate the projection on the perpendicular distance from the center of the tube double cm = d2.modulo2() - proj*proj; // Now calculate the density in the cylinder if( cm<cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) { double dfuncr, val = cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).calculateSqr( cm, dfuncr ); double cellv = cell_volume( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ); Vector dc1, dc2, dc3, dd1, dd2, dd3, de1, de2, de3; if( !doNotCalculateDerivatives() ) { Tensor d1_a1; // Derivative of director connecting atom1 - atom2 wrt the position of atom 1 d1_a1(0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1_len ); // dx/dx d1_a1(0,1) = ( d1[0]*d1[1]/d1_len ); // dx/dy d1_a1(0,2) = ( d1[0]*d1[2]/d1_len ); // dx/dz d1_a1(1,0) = ( d1[1]*d1[0]/d1_len ); // dy/dx d1_a1(1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1_len ); // dy/dy d1_a1(1,2) = ( d1[1]*d1[2]/d1_len ); d1_a1(2,0) = ( d1[2]*d1[0]/d1_len ); d1_a1(2,1) = ( d1[2]*d1[1]/d1_len ); d1_a1(2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1_len ); // Calculate derivatives of dot product dd1 = matmul(d2, d1_a1) - d1; dd2 = matmul(d2, -d1_a1); dd3 = d1; // Calculate derivatives of cross product dc1 = dfuncr*( -d2 - proj*dd1 ); dc2 = dfuncr*( -proj*dd2 ); dc3 = dfuncr*( d2 - proj*dd3 ); // Calculate derivatives of excess de1 = edf*excess*( dd1 + d1 ); de2 = edf*excess*( dd2 - d1 ); de3 = edf*excess*dd3; } Vector pos1 = myatoms.getPosition(0) + d1_len*d1; Vector pos2 = myatoms.getPosition(0) + d2; Vector g1derivf,g2derivf,lderivf; Tensor vir; for(unsigned bin=0; bin<maxbins; ++bin) { bead.set( bin*binw, (bin+1)*binw, sigma ); if( proj<(bin*binw-bead.getCutoff()) || proj>binw*(bin+1)+bead.getCutoff() ) continue; double der, contr=bead.calculateWithCutoff( proj, der ) / cellv; der /= cellv; myatoms.addValue( 2+bin, contr*val*eval ); if( !doNotCalculateDerivatives() ) { g1derivf=contr*eval*dc1 + val*eval*der*dd1 + contr*val*de1; addAtomDerivatives( 2+bin, 0, g1derivf, myatoms ); g2derivf=contr*eval*dc2 + val*eval*der*dd2 + contr*val*de2; addAtomDerivatives( 2+bin, 1, g2derivf, myatoms ); lderivf=contr*eval*dc3 + val*eval*der*dd3 + contr*val*de3; addAtomDerivatives( 2+bin, iat, lderivf, myatoms ); // Virial vir = -Tensor( myatoms.getPosition(0), g1derivf ) - Tensor( pos1, g2derivf ) - Tensor( pos2, lderivf ); myatoms.addBoxDerivatives( 2+bin, vir ); } } } }