예제 #1
0
  PotDiff::PotDiff(SimInfo* info, const std::string& filename, 
                   const std::string& sele)
    : StaticAnalyser(info, filename), selectionScript_(sele), 
      seleMan_(info), evaluator_(info) {
    
    StuntDouble* sd;
    int i;
    
    setOutputName(getPrefix(filename) + ".potDiff");

    // The PotDiff is computed by negating the charge on the atom type
    // using fluctuating charge values.  If we don't have any
    // fluctuating charges in the simulation, we need to expand
    // storage to hold them.
    int storageLayout = info_->getStorageLayout();
    storageLayout |= DataStorage::dslFlucQPosition;
    storageLayout |= DataStorage::dslFlucQVelocity;
    storageLayout |= DataStorage::dslFlucQForce;
    info_->setStorageLayout(storageLayout);
    info_->setSnapshotManager(new SimSnapshotManager(info_, storageLayout));

    // now we have to figure out which AtomTypes to convert to fluctuating
    // charges
    evaluator_.loadScriptString(sele);    
    seleMan_.setSelectionSet(evaluator_.evaluate());
    for (sd = seleMan_.beginSelected(i); sd != NULL;
         sd = seleMan_.nextSelected(i)) {      
      AtomType* at = static_cast<Atom*>(sd)->getAtomType();
      FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(at);
      if (fqa.isFluctuatingCharge()) {
        selectionWasFlucQ_.push_back(true);
      } else {
        selectionWasFlucQ_.push_back(false);                
        // make a fictitious fluctuating charge with an unphysical
        // charge mass and slaterN, but we need to zero out the
        // electronegativity and hardness to remove the self
        // contribution:
        fqa.makeFluctuatingCharge(1.0e9, 0.0, 0.0, 1);
        sd->setFlucQPos(0.0);
      }
    }
    info_->getSnapshotManager()->advance();
  }
예제 #2
0
파일: EAM.cpp 프로젝트: hsidky/OpenMD
  void EAM::addType(AtomType* atomType){

    EAMAdapter ea = EAMAdapter(atomType);
    EAMAtomData eamAtomData;

    eamAtomData.rho = ea.getRho();
    eamAtomData.F = ea.getF();
    eamAtomData.Z = ea.getZ();
    eamAtomData.rcut = ea.getRcut();

    FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType);
    if (fqa.isFluctuatingCharge()) {
      if (fqa.isMetallic()) {
        eamAtomData.isFluctuatingCharge = true;
        eamAtomData.nValence = fqa.getNValence();
      } else {
        eamAtomData.isFluctuatingCharge = false;
      }
    }

    // add it to the map:
    int atid = atomType->getIdent();
    int eamtid = EAMtypes.size();

    pair<set<int>::iterator,bool> ret;
    ret = EAMtypes.insert( atid );
    if (ret.second == false) {
      sprintf( painCave.errMsg,
               "EAM already had a previous entry with ident %d\n",
               atid);
      painCave.severity = OPENMD_INFO;
      painCave.isFatal = 0;
      simError();
    }


    EAMtids[atid] = eamtid;
    EAMdata[eamtid] = eamAtomData;
    MixingMap[eamtid].resize(nEAM_);

    // Now, iterate over all known types and add to the mixing map:

    std::set<int>::iterator it;
    for( it = EAMtypes.begin(); it != EAMtypes.end(); ++it) {

      int eamtid2 = EAMtids[ (*it) ];
      AtomType* atype2 = forceField_->getAtomType( (*it) );

      EAMInteractionData mixer;
      mixer.phi = getPhi(atomType, atype2);
      mixer.rcut = mixer.phi->getLimits().second;
      mixer.explicitlySet = false;

      MixingMap[eamtid2].resize( nEAM_ );

      MixingMap[eamtid][eamtid2] = mixer;
      if (eamtid2 != eamtid) {
        MixingMap[eamtid2][eamtid] = mixer;
      }
    }
    return;
  }
예제 #3
0
  void PotDiff::process() {
    Molecule* mol;
    RigidBody* rb;
    SimInfo::MoleculeIterator mi;
    Molecule::RigidBodyIterator rbIter;
    StuntDouble* sd;
    int j;
  
    diff_.clear();
    DumpReader reader(info_, dumpFilename_);
    int nFrames = reader.getNFrames();

    // We'll need the force manager to compute the potential
    
    ForceManager* forceMan = new ForceManager(info_);

    // We'll need thermo to report the potential
    
    Thermo* thermo =  new Thermo(info_);

    for (int i = 0; i < nFrames; i += step_) {
      reader.readFrame(i);
      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
    
      for (mol = info_->beginMolecule(mi); mol != NULL; 
	   mol = info_->nextMolecule(mi)) {
	//change the positions of atoms which belong to the rigidbodies
	for (rb = mol->beginRigidBody(rbIter); rb != NULL; 
	     rb = mol->nextRigidBody(rbIter)) {
	  rb->updateAtoms();        
	}      
      }

      for (sd = seleMan_.beginSelected(j); sd != NULL;
           sd = seleMan_.nextSelected(j)) {
        if (!selectionWasFlucQ_[j])  {
          sd->setFlucQPos(0.0);
        }
      }
            
      forceMan->calcForces();
      RealType pot1 = thermo->getPotential();    

      if (evaluator_.isDynamic()) {
        seleMan_.setSelectionSet(evaluator_.evaluate());
      }

      for (sd = seleMan_.beginSelected(j); sd != NULL;
           sd = seleMan_.nextSelected(j)) {

        AtomType* at = static_cast<Atom*>(sd)->getAtomType();

        FixedChargeAdapter fca = FixedChargeAdapter(at);
        FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(at);

        RealType charge = 0.0;
        
        if (fca.isFixedCharge()) charge += fca.getCharge();
        if (fqa.isFluctuatingCharge()) charge += sd->getFlucQPos();

        sd->setFlucQPos(-charge);
      }

      currentSnapshot_->clearDerivedProperties();
      forceMan->calcForces();
      RealType pot2 = thermo->getPotential();
      RealType diff = pot2-pot1;
      
      data_.add(diff);
      diff_.push_back(diff);
      times_.push_back(currentSnapshot_->getTime());

      info_->getSnapshotManager()->advance();
    }
   
    writeDiff();   
  }