コード例 #1
0
      bool _computeForceRaw(Real3D& force12,
                              Real3D& force32,
                              const Real3D& r12,
                              const Real3D& r32, real _theta0) const {

        real dist12_sqr = r12.sqr();
        real dist32_sqr = r32.sqr();
        real dist12_magn = sqrt(dist12_sqr);
        real dist32_magn = sqrt(dist32_sqr);
        real dU_dtheta, a11, a12, a22;
        real inv_dist1232 = 1.0/(dist12_magn * dist32_magn);

        real cos_theta = r12 * r32 * inv_dist1232;
        if(cos_theta < -1.0) cos_theta = -1.0;
        else if(cos_theta >  1.0) cos_theta =  1.0;
        real sin_theta = sqrt(1.0 - cos_theta * cos_theta);

        dU_dtheta = - KpK * (acos(cos_theta) - _theta0) / sin_theta;

        a11 = dU_dtheta * cos_theta / dist12_sqr;
        a12 = -dU_dtheta * inv_dist1232;
        a22 = dU_dtheta * cos_theta / dist32_sqr;

        force12 = a11 * r12 + a12 * r32;
        force32 = a22 * r32 + a12 * r12;
        return true;
      }
コード例 #2
0
ファイル: Matrix3D.cpp プロジェクト: SimoneNardi/base_math
// Returns a rotation matrix whose third column is equal to the given vector.
Matrix3D Matrix3D::rotationMatrixFromZAxis(const Real3D& dir)
{
	// Normalize the target direction
	// If it is degenerate, returns the identity matrix
	Real3D target = dir;
	REAL len = target.mod();
	if (len == 0) return Matrix3D(1);
	target /= len;
	if (!target.isfinite()) return Matrix3D(1);
	// Find a non-degenerate vector orthogonal to the target
	Real3D v1 = Real3D(1,0,0) ^ target;
	REAL l1 = v1.sqrmod();
	Real3D v2 = Real3D(0,1,0) ^ target;
	REAL l2 = v2.sqrmod();
	Real3D v3 = Real3D(0,0,1) ^ target;
	REAL l3 = v3.sqrmod();
	// Choose the largest among v1,v2,v3
	Real3D v;
	if (l1 >= l2 && l1 >= l3) v = v1.vers();
	else if (l2 >= l1 && l2 >= l3) v = v2.vers();
	else /* if (l3 >= l1 && l3 >= l2) */ v = v3.vers();
	// Build the rotation matrix
	Real3D w = (target^v).vers();
	Matrix3D rot;
	rot.setCols(v, w, target);
	// Debug Check
	assert(fabs(rot.det()-1) < Math::TOLERANCE);
	return rot;
}
コード例 #3
0
ファイル: Matrix3D.cpp プロジェクト: SimoneNardi/base_math
/// Returns a rotation matrix whose third column is equal to the given vector.
Matrix3D Matrix3D::rotationMatrixFromZAxisForDXF(const Real3D& dir)
{
	// Normalize the target direction
	// If it is degenerate, returns the identity matrix
	Real3D target = dir;
	REAL len = target.mod();
	if (len == 0) return Matrix3D(1);
	target /= len;
	if (!target.isfinite()) return Matrix3D(1);

	// Choice of xAxis: see AutoCAD documentation.
	Real3D v;
	if( fabs(target[0])*64 < 1 && fabs(target[1])*64 < 1 )
		v = Real3D(0,1,0) ^ target;
	else
		v = Real3D(0,0,1) ^ target;

	v = v.vers();
	Real3D w = (target^v).vers();
	Matrix3D rot;
	rot.setCols(v, w, target);
	// Debug Check
	assert(fabs(rot.det()-1) < Math::TOLERANCE);
	return rot;
}
コード例 #4
0
 inline real
 AngularUniquePotentialTemplate< Derived >::
 computeEnergy(const Real3D& r12, const Real3D& r32, real theta0) const {
   real dist12Sqr = r12.sqr();
   real dist32Sqr = r32.sqr();
   real cos_theta = r12 * r32 / (sqrt(dist12Sqr) * sqrt(dist32Sqr));
   return computeEnergy(acos(cos_theta), theta0);
 }
コード例 #5
0
 real _computeEnergyDeriv(const Particle& p1, const Particle& p2) const {
     Real3D dist = p1.position() - p2.position();
     real distSqr = dist.sqr();
     if (distSqr>rc2) return 0.0;
     if (checkTIpair(p1.id(),p2.id())) {
         real qq = p1.q()*p2.q();
         real dhdl = -1.0 * prefactor * qq * (1.0 / sqrt(distSqr) - B1_half*distSqr -crf);
         return dhdl;
     } else {
         return 0.0;
     }
 }
コード例 #6
0
                bool _computeForce(Real3D& force, const Particle &p1,
                         const Particle &p2) const {
                    Real3D dist = p1.position() - p2.position();
                    real r2 = dist.sqr();
                    if (r2>rc2) return true;
                    real r = sqrt(r2);
                    real qq = p1.q()*p2.q();
                    real ffactor = prefactor*qq* (1.0/(r*r2) + B1);
                    force = dist * ffactor;
                    return true;

                }
コード例 #7
0
 inline real
 AngularUniquePotentialTemplate< Derived >::
 _computeEnergy(const Real3D& r12, const Real3D& r32, real theta0) const {
   real dist12_sqr = r12.sqr();
   real dist32_sqr = r32.sqr();
   if (dist12_sqr >= cutoffSqr || dist32_sqr >= cutoffSqr )
     return 0.0;
   else{
     real cos_theta = r12 * r32 / (sqrt(dist12_sqr) * sqrt(dist32_sqr));
     return _computeEnergy(acos(cos_theta), theta0);
   }
 }
コード例 #8
0
      python::list MeanSquareInternalDist::compute() const{
                         
      python::list pyli;
      
      System& system = getSystemRef();
            
      //creating vector which stores particleIDs for each CPU
      vector<longint> localIDs; // localIDs is a vector with PID of particles in each CPU and it contains whole chains
      for (map<size_t,int>::const_iterator itr=idToCpu.begin(); itr!=idToCpu.end(); ++itr) {
        size_t i = itr->first;
        int whichCPU = itr->second;
        if(system.comm->rank()==whichCPU){
          localIDs.push_back(i); 
        }
      }
      sort(localIDs.begin(), localIDs.end()); //sorts entries from low to high - should not be necessary as long as the above iterator iterates in ascending order according to the keys
                
      // MSID calculation
      
      int M = getListSize(); //number of snapshots/configurations
                 
      real intdist_sum = 0;
                  
      int N_chains = localIDs.size() / chainlength; // N_chains is number of chains in this cpu and chainlength is a global variable from ConfigsParticleDecomp.hpp

      for (int n=1; n<chainlength;n++){ // loop over chainlength

          real intdist = 0.0;
      
          for (int j=0; j<N_chains;j++){
              
              real sumdistsq = 0.0 ;
                                    
              for (int i=j*chainlength; i<(j*chainlength)+chainlength-n;i++){
                  Real3D pos1 = getConf(M-1)->getCoordinates(localIDs[i]);   // compute the MSID of the last added snapshot
                  Real3D pos2 = getConf(M-1)->getCoordinates(localIDs[i+n]); // compute the MSID of the last added snapshot                                                     
                  Real3D delta = pos2 - pos1;   //vector with the distances from i to chainlength-n
                  sumdistsq += delta.sqr();// dx*dx+dy*dy+dz*dz
              }
              
              intdist += sumdistsq/real(chainlength-n);  //sum of the internal distances (chainlength-n) of the chains in this cpu
          }
                    
          boost::mpi::reduce(*system.comm, intdist, intdist_sum, std::plus<real>(), 0);
          
          if (system.comm->rank() == 0) { 
              int chains_total = num_of_part / chainlength;
              pyli.append( intdist_sum / real(chains_total)); 
          }          
      } 
      return pyli;
    }
コード例 #9
0
                real _computeEnergy(const Particle& p1, const Particle& p2) const {
                    Real3D dist = p1.position() - p2.position();
                    real distSqr = dist.sqr();
                    if (distSqr>rc2) return 0.0;
                    real qq = p1.q()*p2.q();
                    /* Note: this implementation counts minus integral of the force as energy
                         which is not the same as the full electrostatic energy
                         See the original paper Tironi et al J.Chem.Phys 102, 13, 1995
                         for details*/

                    real energy = prefactor*qq * (1.0 / sqrt(distSqr) - B1_half*distSqr -crf);     
                    return energy;
                }
コード例 #10
0
ファイル: Real3D.cpp プロジェクト: SimoneNardi/base_math
// Returns true if the vector belongs to triangle v1v2v3.
// Returns false otherwise.
bool Real3D::belongsToTriangle(const Real3D& v1,
								  const Real3D& v2,
								  const Real3D& v3,
								  REAL zTolerance) const
{
	// Checks that the vector belongs to the triangle's bounding box.
/*
	TODO: compare with the BB using Math::TOLERANCE.
	if((this->v[0] > v1.v[0]) &&(this->v[0] > v2.v[0]) && (this->v[0] > v3.v[0]))
		return false;
	if((this->v[0] < v1.v[0]) &&(this->v[0] < v2.v[0]) && (this->v[0] < v3.v[0]))
		return false;
	if((this->v[1] > v1.v[1]) &&(this->v[1] > v2.v[1]) && (this->v[1] > v3.v[1]))
		return false;
	if((this->v[1] < v1.v[1]) &&(this->v[1] < v2.v[1]) && (this->v[1] < v3.v[1]))
		return false;
	if((this->v[2] > v1.v[2]) &&(this->v[2] > v2.v[2]) && (this->v[2] > v3.v[2]))
		return false;
	if((this->v[2] < v1.v[2]) &&(this->v[2] < v2.v[2]) && (this->v[2] < v3.v[2]))
		return false;
*/
	// Computes the triangle normal versor.
	Real3D n = (v2-v1)^(v3-v1);
	// If the triangle is degenerate returns false;
	REAL nmod2 = n.sqrmod();
	if(nmod2 < Math::TOLERANCE2)
		return false;
	// If the point doesn't belong to the triangle's plane return false.
	REAL t = n*(*this-v1);
	if(t*t > zTolerance*zTolerance*nmod2)
		return false;

	// Computes the normals to the triangles' edges.
	Real3D normal = ( (v2-v1)^n ).vers();
	t = (*this-v1)*normal;
	if(t > Math::TOLERANCE)
		return false;

	normal = ( (v3-v2)^n ).vers();
	t = (*this-v2)*normal;
	if(t > Math::TOLERANCE)
		return false;

	normal = ( (v1-v3)^n ).vers();
	t = (*this-v3)*normal;
	if(t > Math::TOLERANCE)
		return false;

	return true;
}
コード例 #11
0
                bool _computeForce(Real3D& force, const Particle &p1,
                         const Particle &p2) const {
                    Real3D dist = p1.position() - p2.position();
                    real r2 = dist.sqr();
                    if (r2>rc2) return true;
                    real r = sqrt(r2);
                    real qq = p1.q()*p2.q();
                    if (checkTIpair(p1.id(),p2.id())) {
                      qq *= complLambdaTI; //(1-lambda)*qAi*qAj
                    }
                    real ffactor = prefactor*qq* (1.0/(r*r2) + B1);
                    force = dist * ffactor;
                    return true;

                }
コード例 #12
0
                real _computeEnergy(const Particle& p1, const Particle& p2) const {
                    Real3D dist = p1.position() - p2.position();
                    real distSqr = dist.sqr();
                    if (distSqr>rc2) return 0.0;
                    real qq = p1.q()*p2.q();
                    if (checkTIpair(p1.id(),p2.id())) {
                      qq *= complLambdaTI; //(1-lambda)*qAi*qAj
                    }
                    /* Note: this implementation counts minus integral of the force as energy
                         which is not the same as the full electrostatic energy
                         See the original paper Tironi et al, J. Chem. Phys. 102 , 5451 (1995) 
                         for details*/

                    real energy = prefactor*qq * (1.0 / sqrt(distSqr) - B1_half*distSqr -crf);     
                    return energy;
                }
コード例 #13
0
    dcomplex OrderParameter::SphHarm(int l, int m, Real3D r) {
      real d = r.abs(); // distance between two particles
      real theta, phi;

      // defining theta and phi
      theta = acos( r[2] / d );   // in radians
      
      // phi is defined as http://en.wikipedia.org/wiki/Atan2
      // problem is x = y = 0, we will define it like 0
      if(r[0] > 0.0){
        phi = atan( r[1]/r[0] );
      }
      else if( r[0] < 0.0 && r[1] >= 0.0 ){
        phi = atan( r[1]/r[0] ) + M_PIl;
      }
      else if( r[0] < 0.0 && r[1] < 0.0 ){
        phi = atan( r[1]/r[0] ) - M_PIl;
      }
      else if( r[0] == 0.0 && r[1] > 0.0 ){
        phi = M_PIl;
      }
      else if( r[0] == 0.0 && r[1] < 0.0 ){
        phi = -M_PIl;
      }
      else{
        // x = 0; y = 0;
        phi = 0.0;
      }
      
      return boost::math::spherical_harmonic(l, m, theta, phi);
    }
コード例 #14
0
    void LBInitPopUniform::createDenVel (real _rho0, Real3D _u0) {
			if (mpiWorld->rank()==0) {
				printf("Creating an initial configuration with uniform density %f and \nvelocity %f, %f, %f\n",
							 _rho0, _u0.getItem(0), _u0.getItem(1), _u0.getItem(2));
				printf("-------------------------------------\n");
			} else {
				// do nothing
			}
			
      real invCs2 = 1. / latticeboltzmann->getCs2();

      real invCs4 = invCs2*invCs2;
      real scalp, value;
			int _offset = latticeboltzmann->getHaloSkin();
			Int3D _Ni = latticeboltzmann->getMyNi();
			int _numVels = latticeboltzmann->getNumVels();	// number of velocities in the model
			
      // set initial velocity of the populations from Maxwell's distribution
#warning: check if taking care of OFFSET AT INITIALISATION () is needed
			for (int i = 0; i < _Ni.getItem(0); i++) {
      // test the damping of a sin-like initial velocities:
        real trace = _u0*_u0*invCs2;
        for (int j = 0; j < _Ni.getItem(1); j++) {
          for (int k = 0; k < _Ni.getItem(2); k++) {
            for (int l = 0; l < _numVels; l++) {
              scalp = _u0 * latticeboltzmann->getCi(l);
              value = 0.5 * latticeboltzmann->getEqWeight(l) * _rho0 * (2. + 2. * scalp * invCs2 + scalp * scalp * invCs4 - trace);
              latticeboltzmann->setLBFluid(Int3D(i,j,k),l,value);
              latticeboltzmann->setGhostFluid(Int3D(i,j,k),l,0.0);
            }
						
						/* fill in den and j values for real and halo regions */
						latticeboltzmann->setLBMom(Int3D(i,j,k),0,_rho0);
						latticeboltzmann->setLBMom(Int3D(i,j,k),1,_u0[0]*_rho0);
						latticeboltzmann->setLBMom(Int3D(i,j,k),2,_u0[1]*_rho0);
						latticeboltzmann->setLBMom(Int3D(i,j,k),3,_u0[2]*_rho0);
          }
        }
      }
//			latticeboltzmann->copyDenMomToHalo();
    }
コード例 #15
0
ファイル: Real3D.cpp プロジェクト: SimoneNardi/base_math
// Reflects a point w.r.t. a plane through "origin",
// whose normal vector is "normal".
Real3D Real3D::reflect(const Real3D& origin, const Real3D& normal) const
{
	Real3D v(*this);
	REAL sqrmod = normal.sqrmod();
	REAL scal_prod;

	// If the normal vector is null returns this with no reflection at all.
	if(sqrmod >= 1E-20) {
		v -= origin;

		if(fabs(1. - sqrmod) < Math::TOLERANCE) {
			scal_prod = normal*v;
			v -= 2*scal_prod*normal;
		} else {
			// If the normal vector is not normalized computes the normalized vector.
			Real3D actualNormal(normal.vers());
			scal_prod = actualNormal*v;
			v -= 2*scal_prod*actualNormal;
		}
	}
	return v;
}
コード例 #16
0
ファイル: LBInitPopWave.cpp プロジェクト: niktre/espressopp
    void LBInitPopWave::createDenVel (real _rho0, Real3D _u0) {
			if (mpiWorld->rank()==0) {
				printf("Creating an initial configuration with uniform density %f and \nharmonic velocity wave "
							 "v_x = %f, v_y = %f and v_z(x) = %f * sin(2 \\pi *i/Nx)\n",
							 _rho0, _u0.getItem(0), _u0.getItem(1), _u0.getItem(2));
				printf("-------------------------------------\n");
			} else {
				// do nothing
			}
			
      real invCs2 = 1. / latticeboltzmann->getCs2();

      real invCs4 = invCs2*invCs2;
      real scalp, value;
			int _offset = latticeboltzmann->getHaloSkin();
			Int3D _myPos = latticeboltzmann->getMyPos();
			Int3D _nodeGrid = latticeboltzmann->getNodeGrid();
			Int3D _Ni = latticeboltzmann->getNi();				// system size in lattice node
			Int3D _myNi = latticeboltzmann->getMyNi();		// my local nodes
			Int3D _globalNi = Int3D(0,0,0);								// index of the first real node in cpu in the global lattice
			int _numVels = latticeboltzmann->getNumVels();// number of velocities in the model
			
			for (int _dim = 0; _dim < 3; _dim++) {
				_globalNi[_dim] = floor(_myPos[_dim] * _Ni[_dim] / _nodeGrid[_dim]);
			}
			
      Real3D vel = _u0;

      // set initial velocity of the populations from Maxwell's distribution
      for (int i = _offset; i < _myNi.getItem(0) - _offset; i++) {
      // test the damping of a sin-like initial velocities:
        _u0 = Real3D(vel.getItem(0),vel.getItem(1),vel.getItem(2) * sin (2. * M_PI * (_globalNi[0] + i - _offset) / _Ni[0]));
        real trace = _u0*_u0*invCs2;
        for (int j = _offset; j < _myNi.getItem(1) - _offset; j++) {
          for (int k = _offset; k < _myNi.getItem(2) - _offset; k++) {
            for (int l = 0; l < _numVels; l++) {
              scalp = _u0 * latticeboltzmann->getCi(l);
              value = 0.5 * latticeboltzmann->getEqWeight(l) * _rho0 * (2. + 2. * scalp * invCs2 + scalp * scalp * invCs4 - trace);
              latticeboltzmann->setPops( Int3D(i,j,k), l, value );
              latticeboltzmann->setGhostFluid( Int3D(i,j,k), l, 0.0);
            }
						
						/* fill in den and j values for real and halo regions */
						latticeboltzmann->setLBMom(Int3D(i,j,k),0,_rho0);
						latticeboltzmann->setLBMom(Int3D(i,j,k),1,_u0[0]*_rho0);
						latticeboltzmann->setLBMom(Int3D(i,j,k),2,_u0[1]*_rho0);
						latticeboltzmann->setLBMom(Int3D(i,j,k),3,_u0[2]*_rho0);
          }
        }
      }
			latticeboltzmann->copyDenMomToHalo();
    }
コード例 #17
0
        python::list StaticStructF::computeArray(int nqx, int nqy, int nqz,
                real bin_factor) const {
            time_t start;
            time(&start);
            cout << "collective calc starts " << ctime(&start) << "\n";
            //fist the system coords are saved at each CPU
            System& system = getSystemRef();
            esutil::Error err(system.comm);
            Real3D Li = system.bc->getBoxL(); //Box size (Lx, Ly, Lz)

            int nprocs = system.comm->size(); // number of CPUs
            int myrank = system.comm->rank(); // current CPU's number

            if (myrank == 0) {
                cout << "collective calc starts " << ctime(&start) << "\n";
            }

            int num_part = 0;
            ConfigurationPtr config = make_shared<Configuration > ();
            // loop over all CPU-numbers - to give all CPUs all particle coords
            for (int rank_i = 0; rank_i < nprocs; rank_i++) {
                map< size_t, Real3D > conf;
                if (rank_i == myrank) {
                    CellList realCells = system.storage->getRealCells();
                    for (CellListIterator cit(realCells); !cit.isDone(); ++cit) {
                        int id = cit->id();
                        conf[id] = cit->position();
                    }
                }
                boost::mpi::broadcast(*system.comm, conf, rank_i);

                // for simplicity we will number the particles from 0
                for (map<size_t, Real3D>::iterator itr = conf.begin(); itr != conf.end(); ++itr) {
                    size_t id = itr->first;
                    Real3D p = itr->second;
                    config->set(id, p[0], p[1], p[2]);
                    //config->set(num_part, p[0], p[1], p[2]);
                    num_part++;
                }
            }
            if (myrank == 0) {
                time_t distributed;
                time(&distributed);
                cout << "particles on all CPUs " << ctime(&distributed) << "\n";
                cout << "distribution to CPUs took "
                        << difftime(distributed, start) << " seconds \n";
            }
            // now all CPUs have all particle coords and num_part is the total number
            // of particles

            // use all CPUs
            // TODO it could be a problem if   n_nodes > num_part

            // here starts calculation of the static structure factor

            //step size for qx, qy, qz
            real dqs[3];
            dqs[0] = 2. * M_PIl / Li[0];
            dqs[1] = 2. * M_PIl / Li[1];
            dqs[2] = 2. * M_PIl / Li[2];

            Real3D q;

            //calculations for binning
            real bin_size = bin_factor * min(dqs[0], (dqs[1], dqs[2]));
            real q_sqr_max = nqx * nqx * dqs[0] * dqs[0]
                    + nqy * nqy * dqs[1] * dqs[1]
                    + nqz * nqz * dqs[2] * dqs[2];
            real q_max = sqrt(q_sqr_max);
            int num_bins = (int) ceil(q_max / bin_size);
            vector<real> sq_bin;
            vector<real> q_bin;
            vector<int> count_bin;
            sq_bin.resize(num_bins);
            q_bin.resize(num_bins);
            count_bin.resize(num_bins);

            if (myrank == 0) {
                cout << nprocs << " CPUs\n\n"
                        << "bin size \t" << bin_size << "\n"
                        << "q_max    \t" << q_max << "\n";
            }

            real n_reci = 1. / num_part;
            real scos_local = 0; //will store cos-sum on each CPU
            real ssin_local = 0; //will store sin-sum on each CPU
            int ppp = (int) ceil((double) num_part / nprocs); //particles per proc

            Real3D coordP;

            python::list pyli;

            //loop over different q values
            //starting from zero because combinations with negative components 
            //will give the same result in S(q). so S(q) is the same for
            //the 8 vectors q=(x,y,z),(-x,y,z), (x,-y,z),(x,y,-z),(-x,-y,z),...
            for (int hx = -nqx; hx <= nqx; hx++) {
                for (int hy = -nqy; hy <= nqy; hy++) {
                    for (int hz = 0; hz <= nqz; hz++) {

                        //values of q-vector
                        q[0] = hx * dqs[0];
                        q[1] = hy * dqs[1];
                        q[2] = hz * dqs[2];
                        real q_abs = q.abs();

                        //determining the bin number
                        int bin_i = (int) floor(q_abs / bin_size);
                        q_bin[bin_i] += q_abs;
                        count_bin[bin_i] += 1;

                        //resetting the variables that store the local sum on each proc
                        scos_local = 0;
                        ssin_local = 0;

                        //loop over particles
                        for (int k = myrank * ppp; k < (1 + myrank) * ppp && k < num_part;
                                k++) {
                            coordP = config->getCoordinates(k);
                            scos_local += cos(q * coordP);
                            ssin_local += sin(q * coordP);
                        }
                        if (myrank != 0) {
                            boost::mpi::reduce(*system.comm, scos_local, plus<real > (), 0);
                            boost::mpi::reduce(*system.comm, ssin_local, plus<real > (), 0);
                        }

                        if (myrank == 0) {
                            real scos = 0;
                            real ssin = 0;
                            boost::mpi::reduce(*system.comm, scos_local, scos, plus<real > (), 0);
                            boost::mpi::reduce(*system.comm, ssin_local, ssin, plus<real > (), 0);
                            sq_bin[bin_i] += scos * scos + ssin * ssin;
                        }
                    }
                }
            }
            //creates the python list with the results            
            if (myrank == 0) {
                //starting with bin_i = 1 will leave out the value for q=0, otherwise start with bin_i=0
                for (int bin_i = 1; bin_i < num_bins; bin_i++) {
                    real c = (count_bin[bin_i]) ? 1 / (real) count_bin[bin_i] : 0;
                    sq_bin[bin_i] = n_reci * sq_bin[bin_i] * c;
                    q_bin[bin_i] = q_bin[bin_i] * c;

                    python::tuple q_Sq_pair;
                    q_Sq_pair = python::make_tuple(q_bin[bin_i], sq_bin[bin_i]);
                    pyli.append(q_Sq_pair);
                }
            }
            return pyli;
        }
コード例 #18
0
    // TODO currently works correctly for Lx = Ly = Lz
    // rdfN is a level of discretisation of rdf (how many elements it contains)
    python::list RDFatomistic::computeArray(int rdfN) const {

      System& system = getSystemRef();
      esutil::Error err(system.comm);
      Real3D Li = system.bc->getBoxL();
      Real3D Li_half = Li / 2.;
      
      int nprocs = system.comm->size();
      int myrank = system.comm->rank();
      
      real histogram [rdfN];
      for(int i=0;i<rdfN;i++) histogram[i]=0;
          
      real dr = Li_half[1] / (real)rdfN; // If you work with nonuniform Lx, Ly, Lz, you
                                         // should use for Li_half[XXX] the shortest side length   
      /*struct data{
          Real3D pos;
          int type;
          int molecule;
      };*/
      
      int num_part = 0;
      //ConfigurationPtr config = make_shared<Configuration> ();
      map< size_t, data > config;
      for (int rank_i=0; rank_i<nprocs; rank_i++) {
        //map< size_t, Real3D > conf;
        map< size_t, data > conf;
        if (rank_i == myrank) {
          shared_ptr<FixedTupleListAdress> fixedtupleList = system.storage->getFixedTuples();
          CellList realCells = system.storage->getRealCells();
          for(CellListIterator cit(realCells); !cit.isDone(); ++cit) {
              
                Particle &vp = *cit;
                FixedTupleListAdress::iterator it2;
                it2 = fixedtupleList->find(&vp);

                if (it2 != fixedtupleList->end()) {  // Are there atomistic particles for given CG particle? If yes, use those for calculation.
                      std::vector<Particle*> atList;
                      atList = it2->second;
                      for (std::vector<Particle*>::iterator it3 = atList.begin();
                                           it3 != atList.end(); ++it3) {
                          Particle &at = **it3;
                          int id = at.id();
                          //conf[id] = at.position();
                          data tmp = { at.position(), at.type(), vp.id() };
                          conf[id] = tmp;
                      }  
                }

                else{   // If not, use CG particle itself for calculation.
                    std::cout << "WARNING! In RDFatomistic, no atomistic AdResS particle found!\n";
                    exit(1);
                      //int id = cit->id();
                      //conf[id] = cit->position();
                }
  
          }
    	}

        boost::mpi::broadcast(*system.comm, conf, rank_i);

        // for simplicity we will number the particles from 0
        //for (map<size_t,Real3D>::iterator itr=conf.begin(); itr != conf.end(); ++itr) {
        for (map<size_t,data>::iterator itr=conf.begin(); itr != conf.end(); ++itr) {
          //size_t id = itr->first;
          //Real3D p = itr->second;
          //config->set(num_part, p[0], p[1], p[2]);
          data p = itr->second;
          config[num_part] = p;
          num_part ++;
        }
      }
      
      int num_pairs = 0;
      // now all CPUs have all particle coords and num_part is the total number of particles
      
      // use all cpus
      // TODO it could be a problem if   n_nodes > num_part
      int numi = num_part / nprocs + 1;
      int mini = myrank * numi;
      int maxi = mini + numi;
      
      if(maxi>num_part) maxi = num_part;
      
      int perc=0, perc1=0;
      for(int i = mini; i<maxi; i++){
        //Real3D coordP1 = config->getCoordinates(i);
        Real3D coordP1 = config[i].pos;
        int typeP1 = config[i].type;
        int molP1 = config[i].molecule; 
        
        if((coordP1[0] < Li_half[0]+span) && (coordP1[0] > Li_half[0]-span) ){
            for(int j = i+1; j<num_part; j++){
              //Real3D coordP2 = config->getCoordinates(j);
              Real3D coordP2 = config[j].pos;
              int typeP2 = config[j].type;
              int molP2 = config[j].molecule;

              if (molP1 != molP2){

                  if( ( (typeP1 == target1) && (typeP2 == target2) ) || ( (typeP1 == target2) && (typeP2 == target1) ) ){

                      Real3D distVector = coordP1 - coordP2;

                      // minimize the distance in simulation box
                      for(int ii=0; ii<3; ii++){
                        if( distVector[ii] < -Li_half[ii] ) distVector[ii] += Li[ii];
                        if( distVector[ii] >  Li_half[ii] ) distVector[ii] -= Li[ii];
                      }

                      int bin = (int)( distVector.abs() / dr );
                      if( bin < rdfN){
                        histogram[bin] += 1.0;
                      }
                      num_pairs += 1;                  

                  }            
              }
            }
        }
        
        /*if(system.comm->rank()==0){
          perc = (int)(100*(real)(i-mini)/(real)(maxi-mini));
          if(perc>perc1){
            cout<<"calculation progress (radial distr. func.): "<< perc << " %\r"<<flush;
            perc1 = perc;
        }
      }*/
      }
      /*if(system.comm->rank()==0)
        cout<<"calculation progress (radial distr. func.): "<< 100 << " %" <<endl;*/

      real totHistogram[rdfN];
      boost::mpi::all_reduce(*system.comm, histogram, rdfN, totHistogram, plus<real>());
    
      int tot_num_pairs = 0;
      boost::mpi::all_reduce(*system.comm, num_pairs, tot_num_pairs, plus<int>());
      //std::cout << tot_num_pairs << "\n";
      // normalizing
      int nconfigs = 1; //config - 1
      //avg_part = part_total / float(nconfigs)
      //real rho = (real)num_part / (Li[0]*Li[1]*Li[2]);
      real rho = (real)1.0 / (Li[0]*Li[1]*Li[2]);
      //real factor = 2.0 * M_PIl * dr * rho * (real)nconfigs * (real)num_part;
      real factor = 4.0 * M_PIl * dr * rho * (real)nconfigs * (real)tot_num_pairs;
      
      for(int i=0; i < rdfN; i++){
        real radius = (i + 0.5) * dr;
        totHistogram[i] /= factor * (radius*radius + dr*dr / 12.0);
      }
      
      python::list pyli;
      for(int i=0; i < rdfN; i++){
        pyli.append( totHistogram[i] );
      }
      return pyli;
    }
コード例 #19
0
ファイル: OPLS.hpp プロジェクト: Clemson-MSE/espressopp
      void _computeForceRaw(Real3D& force1,
                            Real3D& force2,
                            Real3D& force3,
                            Real3D& force4,
                            const Real3D& dist21,
                            const Real3D& dist32,
                            const Real3D& dist43) const {
                                
        /*
    real rxji, ryji, rzji;
    real rxkj, rykj, rzkj;
    real rxnk, rynk, rznk;
    real cpjikjx, cpjikjy, cpjikjz;
    real cpkjnkx, cpkjnky, cpkjnkz;
    real cpjikjn, cpkjnkn, dp, arg;
    real thijkn, costh, sinth, r1;
    real fix, fiy, fiz, fix2, fiy2, fiz2, fxi, fyi, fzi;
    real fjx, fjy, fjz, fjx1, fjy1, fjz1, fjx2, fjy2, fjz2;
    real fjx3, fjy3, fjz3, fjx4, fjy4, fjz4, fjx5, fjy5, fjz5, fxj, fyj, fzj;
    real fkx, fky, fkz, fkx2, fky2, fkz2, fkx3, fky3, fkz3;
    real fkx4, fky4, fkz4, fkx5, fky5, fkz5, fkx6, fky6, fkz6, fxk, fyk, fzk;
    real fnx, fny, fnz, fnx2, fny2, fnz2, fxn, fyn, fzn;

    rxji = dist21[0];
    ryji = dist21[1];
    rzji = dist21[2];
    
    rxkj = dist32[0];
    rykj = dist32[1];
    rzkj = dist32[2];
    
    rxnk = dist43[0];
    rynk = dist43[1];
    rznk = dist43[2];
                
    cpjikjx = rxji * rykj - ryji * rxkj;
    cpjikjy = rxji * rzkj - rzji * rxkj;
    cpjikjz = ryji * rzkj - rzji * rykj;
     
    cpkjnkx = rxkj * rynk - rykj * rxnk;
    cpkjnky = rxkj * rznk - rzkj * rxnk;
    cpkjnkz = rykj * rznk - rzkj * rynk;
     
    cpjikjn = sqrt(pow(cpjikjx, 2) + pow(cpjikjy, 2) + pow(cpjikjz, 2));
    cpkjnkn = sqrt(pow(cpkjnkx, 2) + pow(cpkjnky, 2) + pow(cpkjnkz, 2));
     
    dp = cpjikjx * cpkjnkx + cpjikjy * cpkjnky + cpjikjz * cpkjnkz;
    arg = dp / cpjikjn / cpkjnkn;
     
    if(arg < -1.0) arg = -1.0;
    if(arg > 1.0) arg = 1.0;
     
    thijkn = acos(arg);
    costh = cos(thijkn);
    sinth = sin(thijkn);
    
    r1 = -K1 + 
        2.0 * K2 * sin(2.0 * thijkn) / sinth -
        3.0 * K3 * sin(3.0 * thijkn) / sinth;
      
    // particle i
     
    fix = rxkj * (-rykj * rynk - rzkj * rznk) + rxnk * (rykj * rykj + rzkj * rzkj);
    fiy = rykj * (-rxkj * rxnk - rzkj * rznk) + rynk * (rxkj * rxkj + rzkj * rzkj);
    fiz = rzkj * (-rxkj * rxnk - rykj * rynk) + rznk * (rxkj * rxkj + rykj * rykj);
     
    fix = fix / cpjikjn / cpkjnkn;
    fiy = fiy / cpjikjn / cpkjnkn;
    fiz = fiz / cpjikjn / cpkjnkn;
     
    fix2 = 2.0 * rxji * (-rykj * rykj - rzkj * rzkj) + 2.0 * rxkj * (ryji * rykj + rzji * rzkj);
    fiy2 = 2.0 * ryji * (-rxkj * rxkj - rzkj * rzkj) + 2.0 * rykj * (rxji * rxkj + rzji * rzkj);
    fiz2 = 2.0 * rzji * (-rxkj * rxkj - rykj * rykj) + 2.0 * rzkj * (rxji * rxkj + ryji * rykj);
      
    fix2 = fix2 / pow(cpjikjn, 2);
    fiy2 = fiy2 / pow(cpjikjn, 2);
    fiz2 = fiz2 / pow(cpjikjn, 2);
     
    fxi = r1 * (fix - 0.5 * costh * fix2);
    fyi = r1 * (fiy - 0.5 * costh * fiy2);
    fzi = r1 * (fiz - 0.5 * costh * fiz2);
     
    // particle j
     
    fjx = rxji * (-rykj * rynk - rzkj * rznk) + rxkj * (rykj * rynk + rzkj * rznk);
    fjy = ryji * (-rxkj * rxnk - rzkj * rznk) + rykj * (rxkj * rxnk + rzkj * rznk);
    fjz = rzji * (-rxkj * rxnk - rykj * rynk) + rzkj * (rxkj * rxnk + rykj * rynk);
    fjx1 = rxnk * (-ryji * rykj - rzji * rzkj - rykj * rykj - rzkj * rzkj);
    fjy1 = rynk * (-rxji * rxkj - rzji * rzkj - rxkj * rxkj - rzkj * rzkj);
    fjz1 = rznk * (-rxji * rxkj - ryji * rykj - rxkj * rxkj - rykj * rykj);
    fjx2 = 2.0 * rxkj * (ryji * rynk + rzji * rznk);
    fjy2 = 2.0 * rykj * (rxji * rxnk + rzji * rznk);
    fjz2 = 2.0 * rzkj * (rxji * rxnk + ryji * rynk);
          
    fjx = (fjx + fjx1 + fjx2) / cpjikjn / cpkjnkn;
    fjy = (fjy + fjy1 + fjy2) / cpjikjn / cpkjnkn;
    fjz = (fjz + fjz1 + fjz2) / cpjikjn / cpkjnkn;
          
    fjx3 = 2.0 * rxji * (rykj * rykj + rzkj * rzkj + ryji * rykj + rzji * rzkj);
    fjy3 = 2.0 * ryji * (rxkj * rxkj + rzkj * rzkj + rxji * rxkj + rzji * rzkj);
    fjz3 = 2.0 * rzji * (rxkj * rxkj + rykj * rykj + rxji * rxkj + ryji * rykj);
    fjx4 = 2.0 * rxkj * (-ryji * ryji - rzji * rzji - ryji * rykj - rzji * rzkj);
    fjy4 = 2.0 * rykj * (-rxji * rxji - rzji * rzji - rxji * rxkj - rzji * rzkj);
    fjz4 = 2.0 * rzkj * (-rxji * rxji - ryji * ryji - rxji * rxkj - ryji * rykj);
     
    fjx3 = (fjx3 + fjx4) / pow(cpjikjn, 2);
    fjy3 = (fjy3 + fjy4) / pow(cpjikjn, 2);
    fjz3 = (fjz3 + fjz4) / pow(cpjikjn, 2);
      
    fjx5 = 2.0 * rxnk * (rykj * rynk + rzkj * rznk) + 2.0 * rxkj * (-rynk * rynk - rznk * rznk);
    fjy5 = 2.0 * rynk * (rxkj * rxnk + rzkj * rznk) + 2.0 * rykj * (-rxnk * rxnk - rznk * rznk);
    fjz5 = 2.0 * rznk * (rxkj * rxnk + rykj * rynk) + 2.0 * rzkj * (-rxnk * rxnk - rynk * rynk);
          
    fjx5 = fjx5 / pow(cpkjnkn, 2);
    fjy5 = fjy5 / pow(cpkjnkn, 2);
    fjz5 = fjz5 / pow(cpkjnkn, 2);
      
    fxj = r1 * (fjx - 0.5 * costh * (fjx3 + fjx5));
    fyj = r1 * (fjy - 0.5 * costh * (fjy3 + fjy5));
    fzj = r1 * (fjz - 0.5 * costh * (fjz3 + fjz5));
         
    // particle k
      
    fkx = rxji * (rykj * rykj + rzkj * rzkj + rykj * rynk + rzkj * rznk);
    fky = ryji * (rxkj * rxkj + rzkj * rzkj + rxkj * rxnk + rzkj * rznk);
    fkz = rzji * (rxkj * rxkj + rykj * rykj + rxkj * rxnk + rykj * rynk);
    fkx2 = rxkj * (-ryji * rykj - rzji * rzkj);
    fky2 = rykj * (-rxji * rxkj - rzji * rzkj);
    fkz2 = rzkj * (-rxji * rxkj - ryji * rykj);
    fkx3 = rxnk * (ryji * rykj + rzji * rzkj) + 2.0 * rxkj * (-ryji * rynk - rzji * rznk);
    fky3 = rynk * (rxji * rxkj + rzji * rzkj) + 2.0 * rykj * (-rxji * rxnk - rzji * rznk);
    fkz3 = rznk * (rxji * rxkj + ryji * rykj) + 2.0 * rzkj * (-rxji * rxnk - ryji * rynk);
      
    fkx = (fkx + fkx2 + fkx3) / cpjikjn / cpkjnkn;
    fky = (fky + fky2 + fky3) / cpjikjn / cpkjnkn;
    fkz = (fkz + fkz2 + fkz3) / cpjikjn / cpkjnkn;
      
    fkx4 = 2.0 * rxji * (-ryji * rykj - rzji * rzkj) + 2.0 * rxkj * (ryji * ryji + rzji * rzji);
    fky4 = 2.0 * ryji * (-rxji * rxkj - rzji * rzkj) + 2.0 * rykj * (rxji * rxji + rzji * rzji);
    fkz4 = 2.0 * rzji * (-rxji * rxkj - ryji * rykj) + 2.0 * rzkj * (rxji * rxji + ryji * ryji);
      
    fkx4 = fkx4 / pow(cpjikjn, 2);
    fky4 = fky4 / pow(cpjikjn, 2);
    fkz4 = fkz4 / pow(cpjikjn, 2);
      
    fkx5 = 2.0 * rxnk * (-rykj * rykj - rzkj * rzkj - rykj * rynk - rzkj * rznk);
    fky5 = 2.0 * rynk * (-rxkj * rxkj - rzkj * rzkj - rxkj * rxnk - rzkj * rznk);
    fkz5 = 2.0 * rznk * (-rxkj * rxkj - rykj * rykj - rxkj * rxnk - rykj * rynk);
    fkx6 = 2.0 * rxkj * (rynk * rynk + rznk * rznk + rykj * rynk + rzkj * rznk);
    fky6 = 2.0 * rykj * (rxnk * rxnk + rznk * rznk + rxkj * rxnk + rzkj * rznk);
    fkz6 = 2.0 * rzkj * (rxnk * rxnk + rynk * rynk + rxkj * rxnk + rykj * rynk);
      
    fkx5 = (fkx5 + fkx6) / pow(cpkjnkn, 2);
    fky5 = (fky5 + fky6) / pow(cpkjnkn, 2);
    fkz5 = (fkz5 + fkz6) / pow(cpkjnkn, 2);
      
    fxk = r1 * (fkx - 0.5 * costh * (fkx4 + fkx5));
    fyk = r1 * (fky - 0.5 * costh * (fky4 + fky5));
    fzk = r1 * (fkz - 0.5 * costh * (fkz4 + fkz5));
      
    // particle n
      
    fnx = rxji * (-rykj * rykj - rzkj * rzkj) + rxkj * (ryji * rykj + rzji * rzkj);
    fny = ryji * (-rxkj * rxkj - rzkj * rzkj) + rykj * (rxji * rxkj + rzji * rzkj);
    fnz = rzji * (-rxkj * rxkj - rykj * rykj) + rzkj * (rxji * rxkj + ryji * rykj);
      
    fnx = fnx / cpjikjn / cpkjnkn;
    fny = fny / cpjikjn / cpkjnkn;
    fnz = fnz / cpjikjn / cpkjnkn;
      
    fnx2 = 2.0 * rxnk * (rykj * rykj + rzkj * rzkj) + 2.0 * rxkj * (-rykj * rynk - rzkj * rznk);
    fny2 = 2.0 * rynk * (rxkj * rxkj + rzkj * rzkj) + 2.0 * rykj * (-rxkj * rxnk - rzkj * rznk);
    fnz2 = 2.0 * rznk * (rxkj * rxkj + rykj * rykj) + 2.0 * rzkj * (-rxkj * rxnk - rykj * rynk);
      
    fnx2 = fnx2 / pow(cpkjnkn, 2);
    fny2 = fny2 / pow(cpkjnkn, 2);
    fnz2 = fnz2 / pow(cpkjnkn, 2);
          
    fxn = r1 * (fnx - 0.5 * costh * fnx2);
    fyn = r1 * (fny - 0.5 * costh * fny2);
    fzn = r1 * (fnz - 0.5 * costh * fnz2);
      
    // forces i, j, k, n
    
        force1[0] = fxi;
        force1[1] = fyi;
        force1[2] = fzi;
 
        force2[0] = fxj;
        force2[1] = fyj;
        force2[2] = fzj;

        force3[0] = fxk;
        force3[1] = fyk;
        force3[2] = fzk;

        force4[0] = fxn;
        force4[1] = fxn;
        force4[2] = fxn;
        
        */
                                
                                

        // compute phi
        real dist21_sqr = dist21 * dist21;
        real dist32_sqr = dist32 * dist32;
        real dist43_sqr = dist43 * dist43;
        real dist21_magn = sqrt(dist21_sqr);
        real dist32_magn = sqrt(dist32_sqr);
        real dist43_magn = sqrt(dist43_sqr);
        
        // cos0
        real sb1 = 1.0 / dist21_sqr;
        real sb2 = 1.0 / dist32_sqr;
        real sb3 = 1.0 / dist43_sqr;
        real rb1 = sqrt(sb1);
        real rb3 = sqrt(sb3);
        real c0 = dist21 * dist43 * rb1 * rb3;
        
        
        // 1st and 2nd angle
        real ctmp = dist21 * dist32;
        real r12c1 = 1.0 / (dist21_magn * dist32_magn);
        real c1mag = ctmp * r12c1;
        
        ctmp = (-1.0 * dist32) * dist43;
        real r12c2 = 1.0 / (dist32_magn * dist43_magn);
        real c2mag = ctmp * r12c2;
        
        
        //cos and sin of 2 angles and final cos
        real sin2 = 1.0 - c1mag * c1mag;
        if (sin2 < 0) sin2 = 0.0;
        real sc1 = sqrt(sin2);
        sc1 = 1.0 / sc1;
        
        sin2 = 1.0 - c2mag * c2mag;
        if (sin2 < 0) sin2 = 0.0;
        real sc2 = sqrt(sin2);
        sc2 = 1.0 / sc2;
        
        real s1 = sc1 * sc1;
        real s2 = sc2 * sc2;
        real s12 = sc1 * sc2;
        real c = (c0 + c1mag * c2mag) * s12;
        
        Real3D cc = dist21.cross(dist32);
        real cmag = sqrt(cc * cc);
        real dx = cc * dist43 / cmag / dist43_magn;
        
        if (c > 1.0) c = 1.0;
        else if (c < -1.0) c = -1.0;
        
        // phi
        real phi = acos(c);
        if (dx < 0.0) phi *= -1.0;
        
        
        
        //phi = 1.0; //testing
        
        real si = sin(phi);
        real siinv = 1.0 / si;
        
        
        // force calculation
        real a = K1 -
                 K2 * 2.0 * sin(2.0 * phi) * siinv +
                 K3 * 3.0 * sin(3.0 * phi) * siinv -
                 K4 * 4.0 * sin(4.0 * phi) * siinv;
        
        c = c * a;
        s12 = s12 * a;
        
        real a11 = c * sb1 * s1;
        real a22 = -sb2 * (2.0 * c0 * s12 - c * (s1 + s2));
        real a33 = c * sb3 * s2;
        real a12 = -r12c1 * (c1mag * c * s1 + c2mag * s12);
        real a13 = -rb1 * rb3 * s12;
        real a23 = r12c2 * (c2mag * c * s2 + c1mag * s12);
        
        Real3D sf2 = a12 * dist21 + a22 * dist32 + a23 * dist43;
        
        force1 = a11 * dist21 + a12 * dist32 + a13 * dist43;
        force2 = (-1.0 * sf2) - force1;
        force4 = a13 * dist21 + a23 * dist32 + a33 * dist43;
        force3 = sf2 - force4;
        
        
      }
コード例 #20
0
ファイル: RDFatomistic.cpp プロジェクト: niktre/espressopp
    // TODO currently works correctly if L_y is shortest side length (it's fine if L_x and/or L_z are equal to L_y)
    // rdfN is a level of discretisation of rdf (how many elements it contains)
    python::list RDFatomistic::computeArray(int rdfN) const {

      System& system = getSystemRef();
      esutil::Error err(system.comm);
      Real3D Li = system.bc->getBoxL();
      Real3D Li_half = Li / 2.;

      int nprocs = system.comm->size();
      int myrank = system.comm->rank();

      real histogram [rdfN];
      for(int i=0;i<rdfN;i++) histogram[i]=0;

      real dr = Li_half[1] / (real)rdfN; // If you work with nonuniform Lx, Ly, Lz, you
                                         // should use for Li_half[XXX] the shortest side length. Currently using L_y

      int num_part = 0;
      map< size_t, data > config;
      for (int rank_i=0; rank_i<nprocs; rank_i++) {
        map< size_t, data > conf;
        if (rank_i == myrank) {
          shared_ptr<FixedTupleListAdress> fixedtupleList = system.storage->getFixedTuples();
          CellList realCells = system.storage->getRealCells();
          for(CellListIterator cit(realCells); !cit.isDone(); ++cit) {

                Particle &vp = *cit;
                FixedTupleListAdress::iterator it2;
                it2 = fixedtupleList->find(&vp);

                if (it2 != fixedtupleList->end()) {  // Are there atomistic particles for given CG particle? If yes, use those for calculation.
                      std::vector<Particle*> atList;
                      atList = it2->second;
                      for (std::vector<Particle*>::iterator it3 = atList.begin();
                                           it3 != atList.end(); ++it3) {
                          Particle &at = **it3;
                          int id = at.id();
                          data tmp = { at.position(), at.type(), vp.id(), vp.lambda() };
                          conf[id] = tmp;
                      }
                }

                else{   // If not, use CG particle itself for calculation.
                    std::cout << "WARNING! In RDFatomistic, no atomistic AdResS particle found!\n";
                    exit(1);
                }

          }
    	}

        boost::mpi::broadcast(*system.comm, conf, rank_i);

        // for simplicity we will number the particles from 0
        for (map<size_t,data>::iterator itr=conf.begin(); itr != conf.end(); ++itr) {
          data p = itr->second;
          config[num_part] = p;
          num_part ++;
        }
      }

      int num_pairs = 0;
      // now all CPUs have all particle coords and num_part is the total number of particles

      // use all cpus
      // TODO it could be a problem if   n_nodes > num_part
      int numi = num_part / nprocs + 1;
      int mini = myrank * numi;
      int maxi = mini + numi;

      if(maxi>num_part) maxi = num_part;

      int perc=0, perc1=0;
      for(int i = mini; i<maxi; i++){
        Real3D coordP1 = config[i].pos;
        int typeP1 = config[i].type;
        int molP1 = config[i].molecule;
        real resolutionP1 = config[i].resolution;


        if (spanbased == true){
          if((coordP1[0] < Li_half[0]+span) && (coordP1[0] > Li_half[0]-span) ){
              for(int j = i+1; j<num_part; j++){
                Real3D coordP2 = config[j].pos;
                int typeP2 = config[j].type;
                int molP2 = config[j].molecule;

                if (molP1 != molP2){

                    if( ( (typeP1 == target1) && (typeP2 == target2) ) || ( (typeP1 == target2) && (typeP2 == target1) ) ){
                        Real3D distVector = (0.0, 0.0, 0.0);
                        system.bc->getMinimumImageVector(distVector, coordP1, coordP2);

                        int bin = (int)( distVector.abs() / dr );
                        if( bin < rdfN){
                          histogram[bin] += 1.0;
                        }
                        num_pairs += 1;

                    }
                }
              }
          }
        }
        else{
          if( resolutionP1 == 1.0 ){
              for(int j = i+1; j<num_part; j++){
                Real3D coordP2 = config[j].pos;
                int typeP2 = config[j].type;
                int molP2 = config[j].molecule;
                real resolutionP2 = config[j].resolution;

                if (molP1 != molP2){

                    if( ( (typeP1 == target1) && (typeP2 == target2) ) || ( (typeP1 == target2) && (typeP2 == target1) ) ){

                        num_pairs += 1;

                        if( resolutionP2 == 1.0 ){
                          Real3D distVector = (0.0, 0.0, 0.0);
                          system.bc->getMinimumImageVector(distVector, coordP1, coordP2);

                          int bin = (int)( distVector.abs() / dr );
                          if( bin < rdfN){
                            histogram[bin] += 1.0;
                          }
                        }

                    }
                }
              }
          }
        }
      }

      real totHistogram[rdfN];
      boost::mpi::all_reduce(*system.comm, histogram, rdfN, totHistogram, plus<real>());

      int tot_num_pairs = 0;
      boost::mpi::all_reduce(*system.comm, num_pairs, tot_num_pairs, plus<int>());
      int nconfigs = 1;
      real rho = (real)1.0 / (Li[0]*Li[1]*Li[2]);
      real factor = 4.0 * M_PIl * dr * rho * (real)nconfigs * (real)tot_num_pairs;

      for(int i=0; i < rdfN; i++){
        real radius = (i + 0.5) * dr;
        totHistogram[i] /= factor * (radius*radius + dr*dr / 12.0);
      }

      python::list pyli;
      for(int i=0; i < rdfN; i++){
        pyli.append( totHistogram[i] );
      }
      return pyli;
    }
コード例 #21
0
ファイル: Rattle.cpp プロジェクト: niktre/espressopp
    void Rattle::applyPositionConstraints() {

      int iteration = 0;
      bool done = false;
      real dt = integrator->getTimeStep();
      System& system = getSystemRef();
      const bc::BC& bc = *getSystemRef().bc;  // boundary conditions

      boost::unordered_map<longint, Real3D> currPosition;
      boost::unordered_map<longint, Real3D> currVelocity;
      boost::unordered_map<longint, bool> movedLastTime; //was this particle moved last time?
      boost::unordered_map<longint, bool> movingThisTime; //is the particle being moved this time?

      if (oldPos.size() == 0) {return;} //no rigid bonds on this node

      //loop over bonds on this node
      OldPos::iterator it;
      for (it=oldPos.begin(); it != oldPos.end(); it++ ) { 
        longint pidHyd = it->first;
        longint pidHeavy = constrainedBonds[pidHyd].pidHeavy;
        //In the maps below, the values for each key pidHeavy may be initialised more than, if pidHeavy is involved in more than one constrained bond. This is not a problem
        movedLastTime[pidHyd] = true;
        movedLastTime[pidHeavy] = true;
        movingThisTime[pidHyd] = false;
        movingThisTime[pidHeavy] = false;
        currPosition[pidHyd] = system.storage->lookupAdrATParticle(pidHyd)->getPos();
        currPosition[pidHeavy] = system.storage->lookupAdrATParticle(pidHeavy)->getPos(); 
        currVelocity[pidHyd] = system.storage->lookupAdrATParticle(pidHyd)->getV();
        currVelocity[pidHeavy] = system.storage->lookupAdrATParticle(pidHeavy)->getV(); 
      }

      //constraint interations
      while (!done && iteration < maxit) {
        done = true;
        //loop over constrained bonds on this cpu
        for (it=oldPos.begin(); it != oldPos.end(); it++) {
          //get pids of the two particles in this bond
          longint a = it->first; //pidHyd
          longint b = constrainedBonds[a].pidHeavy;
          if (movedLastTime[a] || movedLastTime[b]) { 
            //compare current distance to desired constraint distance
            Real3D pab;
            bc.getMinimumImageVectorBox(pab,currPosition[a],currPosition[b]); //a-b, current positions which change during iterations
            real pabsq = pab.sqr();
            real constraint_absq = constrainedBonds[a].constraintDist2;
            real diffsq = pabsq - constraint_absq; 
            if (fabs(diffsq) > (constraint_absq*tol) ) {
              //get ab vector before unconstrained position update
              Real3D rab;
              bc.getMinimumImageVectorBox(rab,oldPos[a].second,oldPos[a].first); //pos at time t (end of last timestep), a-b;
              real rab_dot_pab = rab * pab; //r_ab(t) * r_ab,curr(t+dt)
              if (rab_dot_pab < (constraint_absq*rptol)) { //i.e. if angle is too large
                std::ostringstream msg;
                msg << "Constraint failure in RATTLE" << std::endl;
                throw std::runtime_error( msg.str() );
              }
              real rma = constrainedBonds[a].invmassHyd;
              real rmb = constrainedBonds[a].invmassHeavy;
              real gab = diffsq / (2.0 * (rma + rmb) * rab_dot_pab);
              //direct constraint along bond vector at end of previous timestep
              Real3D displ = gab * rab; 
              currPosition[a] -= rma * displ;
              currPosition[b] += rmb * displ;

              displ /= dt;
              currVelocity[a] -= rma * displ;
              currVelocity[b] += rmb * displ;

              movingThisTime[a] = true;
              movingThisTime[b] = true;
              done = false;
            }
          }
        }
        boost::unordered_map<longint, bool>::iterator it3;
        for (it3 = movedLastTime.begin(); it3 != movedLastTime.end(); it3++) {
          longint id = it3->first;
          movedLastTime[id] = movingThisTime[id];
          movingThisTime[id] = false;
        }

        iteration += 1;
      }

      if (!done) {
        std::ostringstream msg;
        msg << "Too many position constraint iterations in Rattle" << std::endl;
        throw std::runtime_error( msg.str() );
      }

      //store new values for positions
      boost::unordered_map<longint, Real3D>::iterator it2;
      for (it2 = currPosition.begin(); it2 != currPosition.end(); it2++) {
        longint id = it2->first;
        Particle* p = system.storage->lookupAdrATParticle(id);
        p->position() = currPosition[id];
        p->velocity() = currVelocity[id];
      }
    }
コード例 #22
0
 void _computeForceRaw(Real3D& force1,
                       Real3D& force2,
                       Real3D& force3,
                       Real3D& force4,
                       const Real3D& r21,
                       const Real3D& r32,
                       const Real3D& r43, const real _phi0) const {
   
   Real3D retF[4];
   
   Real3D rijjk = r21.cross(r32); // [r21 x r32]
   Real3D rjkkn = r32.cross(r43); // [r32 x r43]
   
   real rijjk_sqr = rijjk.sqr();
   real rjkkn_sqr = rjkkn.sqr();
   
   real rijjk_abs = sqrt(rijjk_sqr);
   real rjkkn_abs = sqrt(rjkkn_sqr);
   
   real inv_rijjk = 1.0 / rijjk_abs;
   real inv_rjkkn = 1.0 / rjkkn_abs;
   
   // cosine between planes
   real cos_phi = (rijjk * rjkkn) * (inv_rijjk * inv_rjkkn);
   if (cos_phi > 1.0) cos_phi = 1.0;
   else if (cos_phi < -1.0) cos_phi = -1.0;
   
   real coef1 = (-2.0) * K * (cos_phi - cos(_phi0));
   
   real A1 = inv_rijjk * inv_rjkkn;
   real A2 = inv_rijjk * inv_rijjk;
   real A3 = inv_rjkkn * inv_rjkkn;
   
   Real3D p3232 ( prod(r32,r32) );
   Real3D p3243 ( prod(r32,r43) );
   Real3D p2132 ( prod(r21,r32) );
   Real3D p2143 ( prod(r21,r43) );
   Real3D p2121 ( prod(r21,r21) );
   Real3D p4343 ( prod(r43,r43) );
   
   // we have 4 particles 1,2,3,4
   for(int l=0; l<4; l++){
     Real3D B1, B2, B3;
     
     for(int i=0; i<3; i++){
       B1[i]= r21[i] * ( p3232[i] * (d(l,2)-d(l,3)) + p3243[i] * (d(l,2)-d(l,1)) ) +
              r32[i] * ( p2132[i] * (d(l,3)-d(l,2)) + p3243[i] * (d(l,1)-d(l,0)) ) +
              r43[i] * ( p2132[i] * (d(l,2)-d(l,1)) + p3232[i] * (d(l,0)-d(l,1)) ) +
              2.0 * r32[i] * p2143[i] * (d(l,1)-d(l,2));
     
       B2[i]= 2.0 * r21[i] * ( p3232[i] * (d(l,1)-d(l,0)) + p2132[i] * (d(l,1)-d(l,2)) ) +
              2.0 * r32[i] * ( p2121[i] * (d(l,2)-d(l,1)) + p2132[i] * (d(l,0)-d(l,1)));
     
       B3[i]= 2.0 * r43[i] * ( p3232[i] * (d(l,3)-d(l,2)) + p3243[i] * (d(l,1)-d(l,2)) ) +
              2.0 * r32[i] * ( p4343[i] * (d(l,2)-d(l,1)) + p3243[i] * (d(l,2)-d(l,3)));
     }
     
     retF[l] = coef1 * ( A1*B1 - 0.5*cos_phi*(A2*B2 + A3*B3) );
   }
   
   force1 = retF[0];
   force2 = retF[1];
   force3 = retF[2];
   force4 = retF[3];
 }
コード例 #23
0
ファイル: Quaternion.hpp プロジェクト: Clemson-MSE/espressopp
 real getImagItem(int i) const { return unreal_part.getItem(i); }
コード例 #24
0
ファイル: Quaternion.hpp プロジェクト: Clemson-MSE/espressopp
 void setImagItem(int i, real v) { unreal_part.setItem(i, v); }
コード例 #25
0
ファイル: Quaternion.hpp プロジェクト: Clemson-MSE/espressopp
  // Quaternion product, p*q = [p_real*q_real - p_unreal * q_unreal, p_real * q_unreal + q_real * p_unreal + p_unreal x q_unreal]
  inline Quaternion Quaternion::operator* (const Quaternion& v) const
  { return Quaternion( real_part*v.real_part - (unreal_part * v.unreal_part), 
		       real_part * v.unreal_part + v.real_part * unreal_part + unreal_part.cross(v.unreal_part) ); }
コード例 #26
0
        python::list StaticStructF::computeArraySingleChain(int nqx, int nqy, int nqz,
                real bin_factor, int chainlength) const {
            //fist the system coords are saved at each CPU
            System& system = getSystemRef();
            esutil::Error err(system.comm);
            Real3D Li = system.bc->getBoxL(); //Box size (Lx, Ly, Lz)

            int nprocs = system.comm->size(); // number of CPUs
            int myrank = system.comm->rank(); // current CPU's number

            int num_part = 0;
            ConfigurationPtr config = make_shared<Configuration > ();
            // loop over all CPU-numbers - to give all CPUs all particle coords
            for (int rank_i = 0; rank_i < nprocs; rank_i++) {
                map< size_t, Real3D > conf;
                if (rank_i == myrank) {
                    CellList realCells = system.storage->getRealCells();
                    for (CellListIterator cit(realCells); !cit.isDone(); ++cit) {
                        int id = cit->id();
                        conf[id] = cit->position();
                    }
                }
                boost::mpi::broadcast(*system.comm, conf, rank_i);

                // for simplicity we will number the particles from 0
                for (map<size_t, Real3D>::iterator itr = conf.begin(); itr != conf.end(); ++itr) {
                    size_t id = itr->first;
                    Real3D p = itr->second;
                    config->set(id, p[0], p[1], p[2]);
                    //config->set(num_part, p[0], p[1], p[2]);
                    num_part++;
                }
            }
            cout << "particles are given to each CPU!\n";
            // now all CPUs have all particle coords and num_part is the total number
            // of particles   

            // use all CPUs
            // TODO it could be a problem if   n_nodes > num_part

            // here starts calculation of the static structure factor

            //step size for qx, qy, qz
            real dqs[3];
            dqs[0] = 2. * M_PIl / Li[0];
            dqs[1] = 2. * M_PIl / Li[1];
            dqs[2] = 2. * M_PIl / Li[2];

            Real3D q;

            //calculations for binning
            real bin_size = bin_factor * min(dqs[0], (dqs[1], dqs[2]));
            real q_sqr_max = nqx * nqx * dqs[0] * dqs[0]
                    + nqy * nqy * dqs[1] * dqs[1]
                    + nqz * nqz * dqs[2] * dqs[2];
            real q_max = sqrt(q_sqr_max);
            int num_bins = (int) ceil(q_max / bin_size);
            vector<real> sq_bin;
            vector<real> q_bin;
            vector<int> count_bin;
            sq_bin.resize(num_bins);
            q_bin.resize(num_bins);
            count_bin.resize(num_bins);

            if (myrank == 0) {
                cout << nprocs << " CPUs\n\n"
                        << "bin size \t" << bin_size << "\n"
                        << "q_max    \t" << q_max << "\n";
            }

            real n_reci = 1. / num_part;
            real chainlength_reci = 1. / chainlength;
            real scos_local = 0; //will store cos-sum on each CPU
            real ssin_local = 0; //will store sin-sum on each CPU   
            //will store the summation of the the single chain structure factor
            real singleChain_localSum = 0;
            Real3D coordP;
            python::list pyli;

            //calculations for parallelizing (over chains)
            int num_chains;
            if (num_part % chainlength == 0)
                num_chains = num_part / chainlength;
            else {
                cout << "ERROR: chainlenght does not match total number of "
                        << "particles. num_part % chainlenght is unequal 0. \n"
                        << "Calculation of SingleChain_StaticStructF aborted\n";
                return pyli;
            }
            int cpp = (int) ceil((double) num_chains / nprocs); //chains per proc
            cout << "chains per proc\t" << cpp << "\n";


            //loop over different q values
            //starting from zero because combinations with negative components 
            //will give the same result in S(q). so S(q) is the same for
            //the 8 vectors q=(x,y,z),(-x,y,z), (x,-y,z),(x,y,-z),(-x,-y,z),...
            for (int hx = -nqx; hx <= nqx; hx++) {
                for (int hy = -nqy; hy <= nqy; hy++) {
                    for (int hz = 0; hz <= nqz; hz++) {

                        //values of q-vector
                        q[0] = hx * dqs[0];
                        q[1] = hy * dqs[1];
                        q[2] = hz * dqs[2];
                        real q_abs = q.abs();

                        //determining the bin number
                        int bin_i = (int) floor(q_abs / bin_size);
                        q_bin[bin_i] += q_abs;
                        count_bin[bin_i] += 1;

                        //resetting the variable that stores the sum for each q-vector
                        singleChain_localSum = 0;

                        //loop over chains (cid is chain_id)
                        for (int cid = myrank * cpp; cid < (1 + myrank) * cpp
                                && cid < num_chains; cid++) {
                            scos_local = 0; //resetting the cos sum for the each chain
                            ssin_local = 0; //resetting the sin sum for the each chain
                            //loop over particles
                            for (int k = cid * chainlength; k < (1 + cid) * chainlength && k < num_part;
                                    k++) {
                                coordP = config->getCoordinates(k);
                                scos_local += cos(q * coordP);
                                ssin_local += sin(q * coordP);
                            }
                            //the (summation part of the) single chain structure 
                            // factors are summed up for the averaging at the 
                            // end (over the chains)
                            singleChain_localSum += scos_local * scos_local
                                    + ssin_local * ssin_local;
                        }


                        if (myrank != 0) {
                            boost::mpi::reduce(*system.comm, singleChain_localSum, plus<real > (), 0);
                        }

                        if (myrank == 0) {
                            real singleChainSum = 0;
                            boost::mpi::reduce(*system.comm, singleChain_localSum, singleChainSum, plus<real > (), 0);
                            sq_bin[bin_i] += singleChainSum;
                        }
                    }
                }
            }
            //creates the python list with the results            
            if (myrank == 0) {
                //starting with bin_i = 1 will leave out the value for q=0, otherwise start with bin_i=0
                for (int bin_i = 1; bin_i < num_bins; bin_i++) {
                    real c = (count_bin[bin_i]) ? 1 / (real) count_bin[bin_i] : 0;
                    sq_bin[bin_i] = n_reci * chainlength_reci * sq_bin[bin_i] * c;
                    q_bin[bin_i] = q_bin[bin_i] * c;

                    python::tuple q_Sq_pair;
                    q_Sq_pair = python::make_tuple(q_bin[bin_i], sq_bin[bin_i]);
                    pyli.append(q_Sq_pair);
                }
            }
            return pyli;
        }