Example #1
0
   /*
   * Attempt to place an atom.
   */
   bool Generator::attemptPlaceAtom(Atom& atom,
                             const DArray<double>& diameters, 
                             CellList& cellList)
   {
      // Shift atom position to primary image within boundary
      boundary().shift(atom.position());
      Vector& pos = atom.position();

      // Loop over neighbors, check distance to each.
      // Return false immediately if any neighbor is too close.
      CellList::NeighborArray neighbors;
      cellList.getNeighbors(pos, neighbors);
      double di = diameters[atom.typeId()];
      double rSq, dj, dSq;
      Atom* neighborPtr;
      int n = neighbors.size();
      for (int j = 0; j < n; ++j) {
         neighborPtr = neighbors[j];
         rSq = boundary().distanceSq(neighborPtr->position(), pos);
         dj = diameters[neighborPtr->typeId()];
         dSq = 0.5*(di + dj);
         dSq *= dSq;
         if (rSq < dSq) {
            return false;
         }
      }

      // If all neighbors are allowed, add atom to cellList
      cellList.addAtom(atom);
      return true;
   }
Example #2
0
   /*
   * Pop and process the next molecule on the workStack (private).
   */
   void ClusterIdentifier::processNextMolecule(Cluster& cluster)
   {
      CellList::NeighborArray neighborArray;
      Molecule::AtomIterator atomIter;
      ClusterLink* thisLinkPtr;
      ClusterLink* otherLinkPtr;
      Atom* otherAtomPtr;
      Boundary& boundary = system().boundary();
      double cutoffSq = cutoff_*cutoff_;
      double rsq;
      int thisMolId, otherMolId, otherClusterId;

      // Pop this molecule off the stack
      thisLinkPtr = &workStack_.pop();
      thisMolId = thisLinkPtr->molecule().id();
      if (thisLinkPtr->clusterId() != cluster.id()) {
         UTIL_THROW("Top ClusterLink not marked with this cluster id");
      }

      /*
      * Loop over atoms of this molecule.
      * For each atom of type atomTypeId_, find neighboring molecules.
      * Add each new neighbor to the cluster, and to the workStack.
      */
      thisLinkPtr->molecule().begin(atomIter); 
      for ( ; atomIter.notEnd(); ++atomIter) {
         if (atomIter->typeId() == atomTypeId_) {
            cellList_.getNeighbors(atomIter->position(), neighborArray);
            for (int i = 0; i < neighborArray.size(); i++) {
               otherAtomPtr = neighborArray[i];
               otherMolId = otherAtomPtr->molecule().id();
               if (otherMolId != thisMolId) {
                  rsq = boundary.distanceSq(atomIter->position(),
                                            otherAtomPtr->position());
                  if (rsq < cutoffSq) {
                     otherLinkPtr = &(links_[otherMolId]);
                     assert(&otherLinkPtr->molecule() ==
                            &otherAtomPtr->molecule());
                     otherClusterId = otherLinkPtr->clusterId();
                     if (otherClusterId == -1) {
                        cluster.addLink(*otherLinkPtr);
                        workStack_.push(*otherLinkPtr);
                     } else
                     if (otherClusterId != cluster.id()) {
                        UTIL_THROW("Cluster Clash!");
                     }
                  }
               }
            } // neighbor atoms
         }
      } // atoms

   }
Example #3
0
   // Create links and print.
   void Crosslinker::sample(long iStep) 
   {
      if (isAtInterval(iStep)) {

         // Clear the cellList
         cellList_.clear();
         // Add every atom in this System to the CellList
         System::MoleculeIterator molIter;
         Atom*                     atomPtr;
         for (int iSpec=0; iSpec < system().simulation().nSpecies(); ++iSpec) {
            for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter) {
               for (int ia=0; ia < molIter->nAtom(); ++ia) {
                  atomPtr = &molIter->atom(ia);
                  system().boundary().shift(atomPtr->position());
                  cellList_.addAtom(*atomPtr);
               }
            }
         }

         //Use the cell list to find neighbours and create links
         CellList::NeighborArray cellNeighbor;
         Vector  iPos, jPos;
         Atom   *iAtomPtr, *jAtomPtr;
         double  dRSq, cutoffSq=cutoff_*cutoff_;
         int     nCellNeighbor, nCellAtom, totCells;
         int     ic, ip, iAtomId, jp, jAtomId;
         // Loop over cells containing primary atom. ic = cell index
         totCells = cellList_.totCells();
         for (ic = 0; ic < totCells; ++ic) {
           // Get Array cellNeighbor of Ids of neighbor atoms for cell ic.
           // Elements 0,..., nCellAtom - 1 contain Ids for atoms in cell ic.
           // Elements nCellAtom,..., nCellNeighbor-1 are from neighboring cells.
           cellList_.getCellNeighbors(ic, cellNeighbor, nCellAtom);
           nCellNeighbor = cellNeighbor.size();
           // Loop over atoms in cell ic
           for (ip = 0; ip < nCellAtom; ++ip) {
              iAtomPtr = cellNeighbor[ip]; 
              iPos     = iAtomPtr->position();
              iAtomId  = iAtomPtr->id();
              // Loop over atoms in all neighboring cells, including cell ic.
              for (jp = 0; jp < nCellNeighbor; ++jp) {
                 jAtomPtr = cellNeighbor[jp]; 
                 jPos     = jAtomPtr->position();
                 jAtomId  = jAtomPtr->id();
                 // Avoid double counting: only count pairs with jAtomId > iAtomId
                 if ( jAtomId > iAtomId ) {
                   // Exclude bonded pairs
                   if (!iAtomPtr->mask().isMasked(*jAtomPtr))  {
                      // Calculate distance between atoms i and j
                      dRSq = system().boundary().distanceSq(iPos, jPos);
                      if (dRSq < cutoffSq) {
                         if(system().simulation().random().uniform(0.0, 1.0) < probability_){ 
                          //create a link between i and j atoms
                           system().linkMaster().addLink(*iAtomPtr, *jAtomPtr, 0);
                         }
                      }
                   }
                 } // end if jAtomId > iAtomId
              } // end for jp (j atom)
           } // end for ip (i atom)
         } // end for ic (i cell)

         // Construct a string representation of integer nSample
         std::stringstream ss;
         std::string       nSampleString;
         ss << nSample_;
         nSampleString = ss.str();

         // Construct new fileName: outputFileName + char(nSample)
         std::string filename;
         filename  = outputFileName();
         filename += nSampleString; 

         // Open output file, write data, and close file
         fileMaster().openOutputFile(filename, outputFile_);
         system().writeConfig(outputFile_);
         outputFile_.close();
         nSample_++;

         // Clear the LinkMaster
         system().linkMaster().clear();

      } // end isAtInterval
   }
Example #4
0
   /**
   * Generate random molecules
   */
   void Linear::generateMolecules(int nMolecule, 
      DArray<double> exclusionRadius, System& system,
      BondPotential *bondPotentialPtr, const Boundary &boundary)
   {
      int iMol;

      // Set up a cell list with twice the maxium exclusion radius as the
      // cell size
      double maxExclusionRadius = 0.0;
      for (int iType = 0; iType < system.simulation().nAtomType(); iType++) {
         if (exclusionRadius[iType] > maxExclusionRadius)
            maxExclusionRadius = exclusionRadius[iType];
      }

      // the minimum cell size is twice the maxExclusionRadius,
      // but to save memory, we take 2 times that value 
      CellList cellList;
      cellList.allocate(system.simulation().atomCapacity(),
         boundary, 2.0*2.0*maxExclusionRadius);

      if (nMolecule > capacity())
         UTIL_THROW("nMolecule > Species.capacity()!"); 

      Simulation& sim = system.simulation();
      for (iMol = 0; iMol < nMolecule; ++iMol) {
         // Add a new molecule to the system
         Molecule &newMolecule= sim.getMolecule(id());
         system.addMolecule(newMolecule);

         // Try placing atoms
         bool moleculeHasBeenPlaced = false;
         for (int iAttempt = 0; iAttempt< maxPlacementAttempts_; iAttempt++) {
            // Place first atom
            Vector pos;
            system.boundary().randomPosition(system.simulation().random(),pos);
            Atom &thisAtom = newMolecule.atom(0);
 
            // check if the first atom can be placed at the new position
            CellList::NeighborArray neighbors;
            cellList.getNeighbors(pos, neighbors);
            int nNeighbor = neighbors.size();
            bool canBePlaced = true;
            for (int j = 0; j < nNeighbor; ++j) {
               Atom *jAtomPtr = neighbors[j];
         
               double r = sqrt(system.boundary().distanceSq(
                                        jAtomPtr->position(), pos));
               if (r < (exclusionRadius[thisAtom.typeId()] +
                  exclusionRadius[jAtomPtr->typeId()])) {
                  canBePlaced = false;
                  break;
               }
            } 
            if (canBePlaced)  {
               thisAtom.position() = pos;
               cellList.addAtom(thisAtom);

               // Try to recursively place other atoms
               if (tryPlaceAtom(newMolecule, 0, exclusionRadius, system,
                  cellList, bondPotentialPtr, system.boundary())) {
                  moleculeHasBeenPlaced = true;
                  break;
              } else {
                 cellList.deleteAtom(thisAtom); 
              }
            }
         }
         if (! moleculeHasBeenPlaced) {
           std::ostringstream oss;
           oss <<  "Failed to place molecule " << newMolecule.id();
           UTIL_THROW(oss.str().c_str());
         }

      }

      #if 0
      // Check
      for (int iMol =0; iMol < nMolecule; ++iMol) {
         Molecule::AtomIterator atomIter;
         system.molecule(id(),iMol).begin(atomIter);
         for (; atomIter.notEnd(); ++atomIter) {
            for (int jMol =0; jMol < nMolecule; ++jMol) {
               Molecule::AtomIterator atomIter2;
               system.molecule(id(),jMol).begin(atomIter2);
               for (; atomIter2.notEnd(); ++atomIter2 ) {
                  if (atomIter2->id() != atomIter->id()) {
                     double r = sqrt(boundary.distanceSq(
                        atomIter->position(),atomIter2->position()));
                     if (r < (exclusionRadius[atomIter->typeId()]+
                        exclusionRadius[atomIter2->typeId()])) {
                        std::cout << r << std::endl;
                        UTIL_THROW("ERROR");
                     }
                  }
               }
            }
         }
      }
      #endif

   } 
Example #5
0
   /**
   * Recursive function to try to place an atom.
   */
   bool Linear::tryPlaceAtom(Molecule& molecule, int atomId,
      DArray<double> exclusionRadius, System& system, CellList &cellList,
      BondPotential *bondPotentialPtr, const Boundary &boundary)
   {
      Atom& lastAtom = molecule.atom(atomId);
      Atom& thisAtom = molecule.atom(++atomId);
      Random& random = system.simulation().random();

      bool hasBeenPlaced = false;

      for (int iAttempt = 0; iAttempt < maxPlacementAttempts_; iAttempt++)
      {
         // draw a random bond vector
         int beta = 1;
         Vector v;
         random.unitVector(v);
         v *= bondPotentialPtr->randomBondLength(&random, beta,
            calculateBondTypeId(lastAtom.indexInMolecule()));

         Vector newPos;
         newPos = lastAtom.position();
         newPos += v;
         // shift into simulation cell
         boundary.shift(newPos);

         // check if the atom can be placed at the new position
         CellList::NeighborArray neighbors;
         cellList.getNeighbors(newPos, neighbors);
         int nNeighbor = neighbors.size();
         bool canBePlaced = true;
         for (int j = 0; j < nNeighbor; ++j) {
            Atom *jAtomPtr = neighbors[j];
         
            double r = sqrt(boundary.distanceSq(
               jAtomPtr->position(), newPos));
            if (r < (exclusionRadius[thisAtom.typeId()] +
               exclusionRadius[jAtomPtr->typeId()])) {
               canBePlaced = false;
               break;
            }
         } 
         if (canBePlaced) {
            // place the particle
            thisAtom.position() = newPos;

            // add to cell list
            cellList.addAtom(thisAtom);

            // are we add the end of the chain?
            if (atomId == molecule.nAtom()-1) 
              return true;
            
            // recursion step
            if (! tryPlaceAtom(molecule, atomId, exclusionRadius, system,
               cellList, bondPotentialPtr, boundary) ) {
               // If the next monomer cannot be inserted, delete this monomer
               // again
               cellList.deleteAtom(thisAtom);
            } else {
               hasBeenPlaced = true;
               break;
            }
         } 
      }

      return hasBeenPlaced;
   }