void FluctuatingChargeAtomTypesSectionParser::parseLine(ForceField& ff,
                                                          const string& line,
                                                          int lineNo){
    StringTokenizer tokenizer(line);
    int nTokens = tokenizer.countTokens();


    if (nTokens < 3)  {
      sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: "
              "Not enough tokens at line %d\n",
              lineNo);
      painCave.isFatal = 1;
      simError();
    }

    string atomTypeName = tokenizer.nextToken();
    AtomType* atomType = ff.getAtomType(atomTypeName);
    if (atomType != NULL) {
        FixedChargeAdapter fca = FixedChargeAdapter(atomType);

	// All fluctuating charges are charges, and if we haven't
	// already set values for the charge, then start with zero.
	if (! fca.isFixedCharge()) {
	  RealType charge = 0.0;
	  fca.makeFixedCharge(charge);
	}

      } else {
      sprintf(painCave.errMsg,
              "FluctuatingChargeAtomTypesSectionParser Error: Atom Type [%s] "
              "has not been created yet\n", atomTypeName.c_str());
      painCave.isFatal = 1;
      simError();
    }


    RealType chargeMass = tokenizer.nextTokenAsDouble();
    FluctuatingTypeEnum fqt = getFluctuatingTypeEnum(tokenizer.nextToken());

    nTokens -= 3;

    switch(fqt) {

    case fqtHardness:
      // For Rick, Stuart, Berne style fluctuating charges, there's a
      // self charge potential defined by electronegativity and
      // hardness.  On molecular structures, the slater-type overlap
      // integral is used to compute the hardness.

      // atomTypeName, chargeMass, Hardness, electronegativity,
      //   hardness (Jii), slaterN, slaterZeta

      if (nTokens < 4) {
        sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: "
                "Not enough tokens at line %d\n",
                lineNo);
        painCave.isFatal = 1;
        simError();
      } else {
        RealType chi = tokenizer.nextTokenAsDouble();
        RealType Jii = tokenizer.nextTokenAsDouble();
        int slaterN = tokenizer.nextTokenAsInt();
        RealType slaterZeta = tokenizer.nextTokenAsDouble();

        FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType);
        fqa.makeFluctuatingCharge(chargeMass, chi, Jii, slaterN, slaterZeta);
      }
      break;

    case fqtMultipleMinima:
      if (nTokens < 4 || nTokens % 2 != 0) {
        sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: "
                "Not enough tokens at line %d\n",
                lineNo);
        painCave.isFatal = 1;
        simError();

      } else {
        std::vector<std::pair<RealType, RealType> > diabaticStates;
        RealType curvature = tokenizer.nextTokenAsDouble();
        RealType coupling = tokenizer.nextTokenAsDouble();
        nTokens -= 2;
        int nStates = nTokens / 2;
        RealType charge;
        RealType ionizationEnergy;
        for (int i = 0; i < nStates; ++i) {
          charge = tokenizer.nextTokenAsDouble();
          ionizationEnergy = tokenizer.nextTokenAsDouble();
          diabaticStates.push_back( std::make_pair( charge, ionizationEnergy ));
        }

        FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType);
        fqa.makeFluctuatingCharge(chargeMass, curvature, coupling, diabaticStates);
      }
      break;

      case fqtMetal:
        if (nTokens < 5 || nTokens % 2 != 1) {
          sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: "
                  "Not enough tokens at line %d\n",
                  lineNo);
          painCave.isFatal = 1;
          simError();
        } else {
          int nValence = tokenizer.nextTokenAsInt();
          nTokens -= 1;

          std::vector<std::pair<RealType, RealType> > diabaticStates;
          RealType curvature = tokenizer.nextTokenAsDouble();
          RealType coupling = tokenizer.nextTokenAsDouble();
          nTokens -= 2;
          int nStates = nTokens / 2;
          RealType charge;
          RealType ionizationEnergy;
          for (int i = 0; i < nStates; ++i) {
            charge = tokenizer.nextTokenAsDouble();
            ionizationEnergy = tokenizer.nextTokenAsDouble();
            diabaticStates.push_back( std::make_pair( charge, ionizationEnergy ));
          }

          FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType);
          fqa.makeFluctuatingCharge(chargeMass, nValence, curvature, coupling, diabaticStates);
        }
        break;


    case fqtUnknown:
    default:
      sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: "
              "Unknown Fluctuating Charge Type at line %d\n",
              lineNo);
      painCave.isFatal = 1;
      simError();
      break;

    }
  }
示例#2
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();   
  }