コード例 #1
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);
    }
コード例 #2
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;
    }
コード例 #3
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;
    }
コード例 #4
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;
        }
コード例 #5
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;
        }