コード例 #1
0
ファイル: Molecule.cpp プロジェクト: Patrick-Louden/2.2
void Molecule::moveCom(const Vetor3d& delta) {
    StuntDouble* sd;
    std::vector<StuntDouble*>::iterator i;
    
    for (sd = beginIntegrableObject(i); sd != NULL; sd = nextIntegrableObject(i)){
        s->setPos(sd->getPos() + delta);
    }

}
コード例 #2
0
ファイル: DensityPlot.cpp プロジェクト: Patrick-Louden/2.2
  Vector3d DensityPlot::calcNewOrigin() {

    int i;
    Vector3d newOrigin(0.0);
    RealType totalMass = 0.0;
    for (StuntDouble* sd = seleMan_.beginSelected(i); sd != NULL; sd = seleMan_.nextSelected(i)) {
      RealType mass = sd->getMass();
      totalMass += mass;
      newOrigin += sd->getPos() * mass;        
    }
    newOrigin /= totalMass;
    return newOrigin;
  }
コード例 #3
0
ファイル: NVE.cpp プロジェクト: Patrick-Louden/2.2
  void NVE::moveB(){
    SimInfo::MoleculeIterator i;
    Molecule::IntegrableObjectIterator  j;
    Molecule* mol;
    StuntDouble* sd;
    Vector3d vel;
    Vector3d frc;
    Vector3d Tb;
    Vector3d ji;
    RealType mass;
    
    for (mol = info_->beginMolecule(i); mol != NULL; 
         mol = info_->nextMolecule(i)) {

      for (sd = mol->beginIntegrableObject(j); sd != NULL;
	   sd = mol->nextIntegrableObject(j)) {

	vel = sd->getVel();
	frc = sd->getFrc();
	mass = sd->getMass();
                
	// velocity half step
	vel += (dt2 /mass * PhysicalConstants::energyConvert) * frc;
                
	sd->setVel(vel);

	if (sd->isDirectional()){

	  // get and convert the torque to body frame

	  Tb = sd->lab2Body(sd->getTrq());

	  // get the angular momentum, and propagate a half step

	  ji = sd->getJ();

	  ji += (dt2  * PhysicalConstants::energyConvert) * Tb;

	  sd->setJ(ji);
	}

            
      }
    }
  
    flucQ_->moveB();
    rattle_->constraintB();
  }
コード例 #4
0
ファイル: Molecule.cpp プロジェクト: Patrick-Louden/2.2
Vector3d Molecule::getComVel() {
    StuntDouble* sd;
    std::vector<StuntDouble*>::iterator i;
    Vector3d velCom;
    double totalMass = 0;
    double mass;
    
    for (sd = beginIntegrableObject(i); sd != NULL; sd = nextIntegrableObject(i)){
        mass = sd->getMass();
        totalMass += mass;
        velCom += sd->getVel() * mass;    
    }

    velCom /= totalMass;

    return velCom;
}
コード例 #5
0
ファイル: RCorrFunc.cpp プロジェクト: jmichalka/OpenMD
  void RCorrFuncZ::computeFrame(int istep) {
    hmat_ = currentSnapshot_->getHmat();
    halfBoxZ_ = hmat_(2,2) / 2.0;      

    StuntDouble* sd;

    int isd1, isd2;
    unsigned int index;

    if (evaluator1_.isDynamic()) {
      seleMan1_.setSelectionSet(evaluator1_.evaluate());
    }
    
    if (uniqueSelections_ && evaluator2_.isDynamic()) {
      seleMan2_.setSelectionSet(evaluator2_.evaluate());
    }      
    
    for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
         sd = seleMan1_.nextSelected(isd1)) {

      index = computeProperty1(istep, sd);        
      if (index == sele1ToIndex_[istep].size()) {
        sele1ToIndex_[istep].push_back(sd->getGlobalIndex());
      } else {
        sele1ToIndex_[istep].resize(index+1);
        sele1ToIndex_[istep][index] = sd->getGlobalIndex();
      }
    }
   
    if (uniqueSelections_) { 
      for (sd = seleMan2_.beginSelected(isd2); sd != NULL;
           sd = seleMan2_.nextSelected(isd2)) {        

        index = computeProperty1(istep, sd);

        if (index == sele2ToIndex_[istep].size()) {
          sele2ToIndex_[istep].push_back(sd->getGlobalIndex());
        } else {
          sele2ToIndex_[istep].resize(index+1);
          sele2ToIndex_[istep][index] = sd->getGlobalIndex();
        }
      }
    }
  }
コード例 #6
0
ファイル: PotDiff.cpp プロジェクト: jmichalka/OpenMD
  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();
  }
コード例 #7
0
ファイル: PotDiff.cpp プロジェクト: jmichalka/OpenMD
  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();   
  }
コード例 #8
0
ファイル: NPT.cpp プロジェクト: xielm12/OpenMD
  void NPT::moveB(void) {
    SimInfo::MoleculeIterator i;
    Molecule::IntegrableObjectIterator  j;
    Molecule* mol;
    StuntDouble* sd;
    int index;
    Vector3d Tb;
    Vector3d ji;
    Vector3d sc;
    Vector3d vel;
    Vector3d frc;
    RealType mass;

    thermostat = snap->getThermostat();
    RealType oldChi  = thermostat.first;
    RealType prevChi;

    loadEta();
    
    //save velocity and angular momentum
    index = 0;
    for (mol = info_->beginMolecule(i); mol != NULL; 
         mol = info_->nextMolecule(i)) {

      for (sd = mol->beginIntegrableObject(j); sd != NULL;
	   sd = mol->nextIntegrableObject(j)) {
                
	oldVel[index] = sd->getVel();

        if (sd->isDirectional())
	   oldJi[index] = sd->getJ();

	++index;
      }
    }

    // do the iteration:
    instaVol =thermo.getVolume();

    for(int k = 0; k < maxIterNum_; k++) {
      instaTemp =thermo.getTemperature();
      instaPress =thermo.getPressure();

      // evolve chi another half step using the temperature at t + dt/2
      prevChi = thermostat.first;
      thermostat.first = oldChi + dt2 * (instaTemp / targetTemp - 1.0) / tt2;

      //evolve eta
      this->evolveEtaB();
      this->calcVelScale();

      index = 0;
      for (mol = info_->beginMolecule(i); mol != NULL; 
           mol = info_->nextMolecule(i)) {

	for (sd = mol->beginIntegrableObject(j); sd != NULL;
	     sd = mol->nextIntegrableObject(j)) {            

	  frc = sd->getFrc();
	  mass = sd->getMass();

	  getVelScaleB(sc, index);

	  // velocity half step
	  vel = oldVel[index] 
            + dt2*PhysicalConstants::energyConvert/mass* frc 
            - dt2*sc;

	  sd->setVel(vel);

	  if (sd->isDirectional()) {
	    // get and convert the torque to body frame
	    Tb = sd->lab2Body(sd->getTrq());

	    ji = oldJi[index] 
              + dt2*PhysicalConstants::energyConvert*Tb 
              - dt2*thermostat.first*oldJi[index];

	    sd->setJ(ji);
	  }

	  ++index;
	}
      }
        
      rattle_->constraintB();

      if ((fabs(prevChi - thermostat.first) <= chiTolerance) && 
          this->etaConverged())
	break;
    }

    //calculate integral of chidt
    thermostat.second += dt2 * thermostat.first;

    snap->setThermostat(thermostat);

    flucQ_->moveB();
    saveEta();
  }
コード例 #9
0
ファイル: NPT.cpp プロジェクト: xielm12/OpenMD
  void NPT::moveA() {
    SimInfo::MoleculeIterator i;
    Molecule::IntegrableObjectIterator  j;
    Molecule* mol;
    StuntDouble* sd;
    Vector3d Tb, ji;
    RealType mass;
    Vector3d vel;
    Vector3d pos;
    Vector3d frc;
    Vector3d sc;
    int index;

    thermostat = snap->getThermostat();
    loadEta();
    
    instaTemp =thermo.getTemperature();
    press = thermo.getPressureTensor();
    instaPress = PhysicalConstants::pressureConvert* (press(0, 0) + press(1, 1) + press(2, 2)) / 3.0;
    instaVol =thermo.getVolume();

    Vector3d  COM = thermo.getCom();

    //evolve velocity half step

    calcVelScale();

    for (mol = info_->beginMolecule(i); mol != NULL; 
         mol = info_->nextMolecule(i)) {

      for (sd = mol->beginIntegrableObject(j); sd != NULL;
	   sd = mol->nextIntegrableObject(j)) {
                
	vel = sd->getVel();
	frc = sd->getFrc();

	mass = sd->getMass();

	getVelScaleA(sc, vel);

	// velocity half step  (use chi from previous step here):

	vel += dt2*PhysicalConstants::energyConvert/mass* frc - dt2*sc;
	sd->setVel(vel);

	if (sd->isDirectional()) {

	  // get and convert the torque to body frame

	  Tb = sd->lab2Body(sd->getTrq());

	  // get the angular momentum, and propagate a half step

	  ji = sd->getJ();

	  ji += dt2*PhysicalConstants::energyConvert * Tb 
            - dt2*thermostat.first* ji;
                
	  rotAlgo_->rotate(sd, ji, dt);

	  sd->setJ(ji);
	}
            
      }
    }
    // evolve chi and eta  half step

    thermostat.first += dt2 * (instaTemp / targetTemp - 1.0) / tt2;
    
    evolveEtaA();

    //calculate the integral of chidt
    thermostat.second += dt2 * thermostat.first;
    
    flucQ_->moveA();


    index = 0;
    for (mol = info_->beginMolecule(i); mol != NULL; 
         mol = info_->nextMolecule(i)) {

      for (sd = mol->beginIntegrableObject(j); sd != NULL;
	   sd = mol->nextIntegrableObject(j)) {

	oldPos[index++] = sd->getPos();            

      }
    }
    
    //the first estimation of r(t+dt) is equal to  r(t)

    for(int k = 0; k < maxIterNum_; k++) {
      index = 0;
      for (mol = info_->beginMolecule(i); mol != NULL; 
           mol = info_->nextMolecule(i)) {

	for (sd = mol->beginIntegrableObject(j); sd != NULL;
	     sd = mol->nextIntegrableObject(j)) {

	  vel = sd->getVel();
	  pos = sd->getPos();

	  this->getPosScale(pos, COM, index, sc);

	  pos = oldPos[index] + dt * (vel + sc);
	  sd->setPos(pos);     

	  ++index;
	}
      }

      rattle_->constraintA();
    }

    // Scale the box after all the positions have been moved:

    this->scaleSimBox();

    snap->setThermostat(thermostat);

    saveEta();
  }
コード例 #10
0
ファイル: DensityPlot.cpp プロジェクト: jmichalka/OpenMD
  void DensityPlot::process() {
    Molecule* mol;
    RigidBody* rb;
    SimInfo::MoleculeIterator mi;
    Molecule::RigidBodyIterator rbIter;

    DumpReader reader(info_, dumpFilename_);    
    int nFrames = reader.getNFrames();
    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();
        }
        
      }
    
      if (evaluator_.isDynamic()) {
	seleMan_.setSelectionSet(evaluator_.evaluate());
      }

      if (cmEvaluator_.isDynamic()) {
	cmSeleMan_.setSelectionSet(cmEvaluator_.evaluate());
      }

      Vector3d origin = calcNewOrigin();

      Mat3x3d hmat = currentSnapshot_->getHmat();
      RealType slabVolume = deltaR_ * hmat(0, 0) * hmat(1, 1);
      int k; 
      for (StuntDouble* sd = seleMan_.beginSelected(k); sd != NULL; 
	   sd = seleMan_.nextSelected(k)) {


        if (!sd->isAtom()) {
          sprintf( painCave.errMsg, 
		   "Can not calculate electron density if it is not atom\n");
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError(); 
        }
            
        Atom* atom = static_cast<Atom*>(sd);
        GenericData* data = atom->getAtomType()->getPropertyByName("nelectron");
        if (data == NULL) {
          sprintf( painCave.errMsg, "Can not find Parameters for nelectron\n");
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError(); 
        }
            
        DoubleGenericData* doubleData = dynamic_cast<DoubleGenericData*>(data);
        if (doubleData == NULL) {
          sprintf( painCave.errMsg,
                   "Can not cast GenericData to DoubleGenericData\n");
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError();   
        }
            
        RealType nelectron = doubleData->getData();
        LennardJonesAdapter lja = LennardJonesAdapter(atom->getAtomType());
        RealType sigma = lja.getSigma() * 0.5;
        RealType sigma2 = sigma * sigma;
            
        Vector3d pos = sd->getPos() - origin;
        for (int j =0; j < nRBins_; ++j) {
          Vector3d tmp(pos);
          RealType zdist =j * deltaR_ - halfLen_;
          tmp[2] += zdist;
          if (usePeriodicBoundaryConditions_) 
            currentSnapshot_->wrapVector(tmp);
              
          RealType wrappedZdist = tmp.z() + halfLen_;
          if (wrappedZdist < 0.0 || wrappedZdist > len_) {
            continue;
          }
              
          int which = int(wrappedZdist / deltaR_);
          density_[which] += nelectron * exp(-zdist*zdist/(sigma2*2.0)) /(slabVolume* sqrt(2*NumericConstant::PI*sigma*sigma));
              
        }            
      }        
    }
  
    int nProcessed = nFrames /step_;
    std::transform(density_.begin(), density_.end(), density_.begin(), 
		   std::bind2nd(std::divides<RealType>(), nProcessed));  
    writeDensity();
        

  
  }
コード例 #11
0
ファイル: omd2omd.cpp プロジェクト: hsidky/OpenMD
int main(int argc, char* argv[]){
  
  gengetopt_args_info args_info;
  string dumpFileName;
  string outFileName;
  
  //parse the command line option
  if (cmdline_parser (argc, argv, &args_info) != 0) {
    exit(1) ;
  }
  
  //get the dumpfile name and meta-data file name
  if (args_info.input_given){
    dumpFileName = args_info.input_arg;
  } else {
    strcpy( painCave.errMsg,
            "No input file name was specified.\n" );
    painCave.isFatal = 1;
    simError();
  }
  
  if (args_info.output_given){
    outFileName = args_info.output_arg;
  } else {
    strcpy( painCave.errMsg,
            "No output file name was specified.\n" );
    painCave.isFatal = 1;
    simError();
  }

  Vector3i repeat = Vector3i(args_info.repeatX_arg,
                             args_info.repeatY_arg,
                             args_info.repeatZ_arg);
  Mat3x3d repeatD = Mat3x3d(0.0);
  repeatD(0,0) = repeat.x();
  repeatD(1,1) = repeat.y();
  repeatD(2,2) = repeat.z();

  Vector3d translate = Vector3d(args_info.translateX_arg,
                                args_info.translateY_arg,
                                args_info.translateZ_arg);

  //parse md file and set up the system

  SimCreator oldCreator;
  SimInfo* oldInfo = oldCreator.createSim(dumpFileName, false);
  Globals* simParams = oldInfo->getSimParams();
  std::vector<Component*> components = simParams->getComponents();
  std::vector<int> nMol;
  for (vector<Component*>::iterator i = components.begin(); 
       i !=components.end(); ++i) {
    int nMolOld = (*i)->getNMol();
    int nMolNew = nMolOld * repeat.x() * repeat.y() * repeat.z();    
    nMol.push_back(nMolNew);
  }
  
  createMdFile(dumpFileName, outFileName, nMol);

  SimCreator newCreator;
  SimInfo* newInfo = newCreator.createSim(outFileName, false);

  DumpReader* dumpReader = new DumpReader(oldInfo, dumpFileName);
  int nframes = dumpReader->getNFrames();
  
  DumpWriter* writer = new DumpWriter(newInfo, outFileName);
  if (writer == NULL) {
    sprintf(painCave.errMsg, "error in creating DumpWriter");
    painCave.isFatal = 1;
    simError();
  }

  SimInfo::MoleculeIterator miter;
  Molecule::IntegrableObjectIterator  iiter;
  Molecule::RigidBodyIterator rbIter;
  Molecule* mol;
  StuntDouble* sd;
  StuntDouble* sdNew;
  RigidBody* rb;
  Mat3x3d oldHmat;
  Mat3x3d newHmat;
  Snapshot* oldSnap;
  Snapshot* newSnap;
  Vector3d oldPos;
  Vector3d newPos;
  
  for (int i = 0; i < nframes; i++){
    cerr << "frame = " << i << "\n";
    dumpReader->readFrame(i);        
    oldSnap = oldInfo->getSnapshotManager()->getCurrentSnapshot();
    newSnap = newInfo->getSnapshotManager()->getCurrentSnapshot();

    newSnap->setID( oldSnap->getID() );
    newSnap->setTime( oldSnap->getTime() );
    
    oldHmat = oldSnap->getHmat();
    newHmat = repeatD*oldHmat;
    newSnap->setHmat(newHmat);

    newSnap->setThermostat( oldSnap->getThermostat() );
    newSnap->setBarostat( oldSnap->getBarostat() );

    int newIndex = 0;
    for (mol = oldInfo->beginMolecule(miter); mol != NULL; 
         mol = oldInfo->nextMolecule(miter)) {
      
      for (int ii = 0; ii < repeat.x(); ii++) {
        for (int jj = 0; jj < repeat.y(); jj++) {
          for (int kk = 0; kk < repeat.z(); kk++) {

            Vector3d trans = Vector3d(ii, jj, kk);
            for (sd = mol->beginIntegrableObject(iiter); sd != NULL;
                 sd = mol->nextIntegrableObject(iiter)) {
              oldPos = sd->getPos() + translate;
              oldSnap->wrapVector(oldPos);
              newPos = oldPos + trans * oldHmat;
              sdNew = newInfo->getIOIndexToIntegrableObject(newIndex);
              sdNew->setPos( newPos );
              sdNew->setVel( sd->getVel() );
              if (sd->isDirectional()) {
                sdNew->setA( sd->getA() );
                sdNew->setJ( sd->getJ() );
              }
              newIndex++;
            }
          }
        }
      }      
    }
  
    //update atoms of rigidbody
    for (mol = newInfo->beginMolecule(miter); mol != NULL; 
         mol = newInfo->nextMolecule(miter)) {
      
      //change the positions of atoms which belong to the rigidbodies
      for (rb = mol->beginRigidBody(rbIter); rb != NULL; 
           rb = mol->nextRigidBody(rbIter)) {
        
        rb->updateAtoms();
        rb->updateAtomVel();
      }
    }

    writer->writeDump();    
  }
  // deleting the writer will put the closing at the end of the dump file.
  delete writer;
  delete oldInfo;
}
コード例 #12
0
ファイル: DistanceFinder.cpp プロジェクト: Patrick-Louden/2.2
  SelectionSet DistanceFinder::find(const SelectionSet& bs, RealType distance, int frame ) {
    StuntDouble * center;
    Vector3d centerPos;
    Snapshot* currSnapshot = info_->getSnapshotManager()->getSnapshot(frame);
    SelectionSet bsResult(nObjects_);   
    assert(bsResult.size() == bs.size());

#ifdef IS_MPI
    int mol;
    int proc;
    RealType data[3];
    int worldRank = MPI::COMM_WORLD.Get_rank();
#endif
 
    for (unsigned int j = 0; j < stuntdoubles_.size(); ++j) {
      if (stuntdoubles_[j]->isRigidBody()) {
        RigidBody* rb = static_cast<RigidBody*>(stuntdoubles_[j]);
        rb->updateAtoms(frame);
      }
    }
       
    SelectionSet bsTemp(nObjects_);
    bsTemp = bs;
    bsTemp.parallelReduce();

    for (int i = bsTemp.bitsets_[STUNTDOUBLE].firstOnBit(); i != -1; 
         i = bsTemp.bitsets_[STUNTDOUBLE].nextOnBit(i)) {

      // Now, if we own stuntdouble i, we can use the position, but in
      // parallel, we'll need to let everyone else know what that
      // position is!

#ifdef IS_MPI
      mol = info_->getGlobalMolMembership(i);
      proc = info_->getMolToProc(mol);
     
      if (proc == worldRank) {
        center = stuntdoubles_[i];
        centerPos = center->getPos(frame);
        data[0] = centerPos.x();
        data[1] = centerPos.y();
        data[2] = centerPos.z();          
        MPI::COMM_WORLD.Bcast(data, 3, MPI::REALTYPE, proc);
      } else {
        MPI::COMM_WORLD.Bcast(data, 3, MPI::REALTYPE, proc);
        centerPos = Vector3d(data);
      }
#else
      center = stuntdoubles_[i];
      centerPos = center->getPos(frame);
#endif
      for (unsigned int j = 0; j < stuntdoubles_.size(); ++j) {
	Vector3d r =centerPos - stuntdoubles_[j]->getPos(frame);
	currSnapshot->wrapVector(r);
	if (r.length() <= distance) {
	  bsResult.bitsets_[STUNTDOUBLE].setBitOn(j);
	}
      }
      for (unsigned int j = 0; j < bonds_.size(); ++j) {       
        Vector3d loc = bonds_[j]->getAtomA()->getPos(frame);
        loc += bonds_[j]->getAtomB()->getPos(frame);
        loc = loc / 2.0;
	Vector3d r = centerPos - loc;
	currSnapshot->wrapVector(r);
	if (r.length() <= distance) {
	  bsResult.bitsets_[BOND].setBitOn(j);
	}
      }
      for (unsigned int j = 0; j < bends_.size(); ++j) {
        Vector3d loc = bends_[j]->getAtomA()->getPos(frame);
        loc += bends_[j]->getAtomB()->getPos(frame);
        loc += bends_[j]->getAtomC()->getPos(frame);
        loc = loc / 3.0;
	Vector3d r = centerPos - loc;
	currSnapshot->wrapVector(r);
	if (r.length() <= distance) {
	  bsResult.bitsets_[BEND].setBitOn(j);
	}
      }
      for (unsigned int j = 0; j < torsions_.size(); ++j) {
        Vector3d loc = torsions_[j]->getAtomA()->getPos(frame);
        loc += torsions_[j]->getAtomB()->getPos(frame);
        loc += torsions_[j]->getAtomC()->getPos(frame);
        loc += torsions_[j]->getAtomD()->getPos(frame);
        loc = loc / 4.0;
	Vector3d r = centerPos - loc;
	currSnapshot->wrapVector(r);
	if (r.length() <= distance) {
	  bsResult.bitsets_[TORSION].setBitOn(j);
	}
      }
      for (unsigned int j = 0; j < inversions_.size(); ++j) {
        Vector3d loc = inversions_[j]->getAtomA()->getPos(frame);
        loc += inversions_[j]->getAtomB()->getPos(frame);
        loc += inversions_[j]->getAtomC()->getPos(frame);
        loc += inversions_[j]->getAtomD()->getPos(frame);
        loc = loc / 4.0;
	Vector3d r = centerPos - loc;
	currSnapshot->wrapVector(r);
	if (r.length() <= distance) {
	  bsResult.bitsets_[INVERSION].setBitOn(j);
	}
      }
    }
    return bsResult;
  }
コード例 #13
0
  void BondAngleDistribution::process() {
    Molecule* mol;
    Atom* atom;
    RigidBody* rb;
    int myIndex;
    SimInfo::MoleculeIterator mi;
    Molecule::RigidBodyIterator rbIter;
    Molecule::AtomIterator ai;
    StuntDouble* sd;
    Vector3d vec;
    std::vector<Vector3d> bondvec;
    RealType r;    
    int nBonds;    
    int i;

    bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions();
    
    DumpReader reader(info_, dumpFilename_);    
    int nFrames = reader.getNFrames();
    frameCounter_ = 0;
    
    nTotBonds_ = 0;
    
    for (int istep = 0; istep < nFrames; istep += step_) {
      reader.readFrame(istep);
      frameCounter_++;
      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
      
      if (evaluator_.isDynamic()) {
        seleMan_.setSelectionSet(evaluator_.evaluate());
      }

      // update the positions of atoms which belong to the rigidbodies
      
      for (mol = info_->beginMolecule(mi); mol != NULL; 
           mol = info_->nextMolecule(mi)) {
        for (rb = mol->beginRigidBody(rbIter); rb != NULL; 
             rb = mol->nextRigidBody(rbIter)) {
          rb->updateAtoms();
        }        
      }           
            
      // outer loop is over the selected StuntDoubles:

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

        myIndex = sd->getGlobalIndex();
        nBonds = 0;
        bondvec.clear();
        
        // inner loop is over all other atoms in the system:
        
        for (mol = info_->beginMolecule(mi); mol != NULL; 
             mol = info_->nextMolecule(mi)) {
          for (atom = mol->beginAtom(ai); atom != NULL; 
               atom = mol->nextAtom(ai)) {

            if (atom->getGlobalIndex() != myIndex) {

              vec = sd->getPos() - atom->getPos();       

              if (usePeriodicBoundaryConditions_) 
                currentSnapshot_->wrapVector(vec);
              
              // Calculate "bonds" and make a pair list 
              
              r = vec.length();
              
              // Check to see if neighbor is in bond cutoff 
              
              if (r < rCut_) { 
                // Add neighbor to bond list's
                bondvec.push_back(vec);
                nBonds++;
                nTotBonds_++;
              }  
            }
          }
          
          
          for (int i = 0; i < nBonds-1; i++ ){
            Vector3d vec1 = bondvec[i];
            vec1.normalize();
            for(int j = i+1; j < nBonds; j++){
              Vector3d vec2 = bondvec[j];
              
              vec2.normalize();
	      
              RealType theta = acos(dot(vec1,vec2))*180.0/NumericConstant::PI;
              
              
              if (theta > 180.0){
                theta = 360.0 - theta;
              }
              int whichBin = int(theta/deltaTheta_);
              
              histogram_[whichBin] += 2;
            }
          }           
        }
      }
    }
    
    writeBondAngleDistribution();    
  }
コード例 #14
0
ファイル: Hydro.cpp プロジェクト: jmichalka/OpenMD
int main(int argc, char* argv[]){
  registerHydrodynamicsModels();
  
  gengetopt_args_info args_info;
  std::string dumpFileName;
  std::string mdFileName;
  std::string prefix;
  
  //parse the command line option
  if (cmdline_parser (argc, argv, &args_info) != 0) {
    exit(1) ;
  }
  
  //get the dumpfile name and meta-data file name
  if (args_info.input_given){
    dumpFileName = args_info.input_arg;
  } else {
    strcpy( painCave.errMsg,
            "No input file name was specified.\n" );
    painCave.isFatal = 1;
    simError();
  }
  
  if (args_info.output_given){
    prefix = args_info.output_arg;
  } else {
    prefix = getPrefix(dumpFileName);    
  }
  std::string outputFilename = prefix + ".diff";
    
  //parse md file and set up the system
  SimCreator creator;
  SimInfo* info = creator.createSim(dumpFileName, true);
    
  SimInfo::MoleculeIterator mi;
  Molecule* mol;
  Molecule::IntegrableObjectIterator  ii;
  StuntDouble* sd;
  Mat3x3d identMat;
  identMat(0,0) = 1.0;
  identMat(1,1) = 1.0;
  identMat(2,2) = 1.0;

  Globals* simParams = info->getSimParams();
  RealType temperature(0.0);
  RealType viscosity(0.0);

  if (simParams->haveViscosity()) {
    viscosity = simParams->getViscosity();
  } else {
    sprintf(painCave.errMsg, "viscosity must be set\n");
    painCave.isFatal = 1;
    simError();  
  }

  if (simParams->haveTargetTemp()) {
    temperature = simParams->getTargetTemp();
  } else {
    sprintf(painCave.errMsg, "target temperature must be set\n");
    painCave.isFatal = 1;
    simError();  
  }
 
  std::map<std::string, SDShape> uniqueStuntDoubles;
  
  for (mol = info->beginMolecule(mi); mol != NULL; 
       mol = info->nextMolecule(mi)) {
    
    for (sd = mol->beginIntegrableObject(ii); sd != NULL;
         sd = mol->nextIntegrableObject(ii)) {
      
      if (uniqueStuntDoubles.find(sd->getType()) ==  uniqueStuntDoubles.end()) {
        
        sd->setPos(V3Zero);
        sd->setA(identMat);
        if (sd->isRigidBody()) {
          RigidBody* rb = static_cast<RigidBody*>(sd);
          rb->updateAtoms();
        }
        
        SDShape tmp;
        tmp.shape = ShapeBuilder::createShape(sd);
        tmp.sd = sd;    
        uniqueStuntDoubles.insert(std::map<std::string, SDShape>::value_type(sd->getType(), tmp));
        
      }
    }
  }
  
  
  
  std::map<std::string, SDShape>::iterator si;
  for (si = uniqueStuntDoubles.begin(); si != uniqueStuntDoubles.end(); ++si) {
    HydrodynamicsModel* model;
    Shape* shape = si->second.shape;
    StuntDouble* sd = si->second.sd;;
    if (args_info.model_given) {  
      model = HydrodynamicsModelFactory::getInstance()->createHydrodynamicsModel(args_info.model_arg, sd, info);
    } else if (shape->hasAnalyticalSolution()) {
      model = new AnalyticalModel(sd, info);
    } else {
      model = new BeadModel(sd, info);
    }
    
    model->init();
    
    std::ofstream ofs;
    std::stringstream outputBeads;
    outputBeads << prefix << "_" << model->getStuntDoubleName() << ".xyz";
    ofs.open(outputBeads.str().c_str());        
    model->writeBeads(ofs);
    ofs.close();
    
    //if beads option is turned on, skip the calculation
    if (!args_info.beads_flag) {
      model->calcHydroProps(shape, viscosity, temperature);
      std::ofstream outputDiff;
      outputDiff.open(outputFilename.c_str());
      model->writeHydroProps(outputDiff);
      outputDiff.close();
    }
        
    delete model;
  }


  //MemoryUtils::deletePointers(shapes);
  delete info;
   
}
コード例 #15
0
ファイル: ContactAngle1.cpp プロジェクト: hsidky/OpenMD
  void ContactAngle1::doFrame(int frame) {
    StuntDouble* sd;
    int i;
    
    if (evaluator1_.isDynamic()) {
      seleMan1_.setSelectionSet(evaluator1_.evaluate());
    }
    
    
    RealType mtot = 0.0;
    Vector3d com(V3Zero);
    RealType mass;
    
    for (sd = seleMan1_.beginSelected(i); sd != NULL;
         sd = seleMan1_.nextSelected(i)) {      
      mass = sd->getMass();
      mtot += mass;
      com += sd->getPos() * mass;
    }
    
    com /= mtot;

    RealType dz = com.z() - solidZ_;

    if (dz < 0.0) {
      sprintf(painCave.errMsg, 
              "ContactAngle1: Z-center of mass of selection, %lf, was\n"
              "\tlocated below the solid reference plane, %lf\n",
              com.z(), solidZ_);
      painCave.isFatal = 1;
      painCave.severity = OPENMD_ERROR;
      simError();
    }

    if (dz > dropletRadius_) {
      values_.push_back(180.0);
    } else {
    
      RealType k = pow(2.0, -4.0/3.0) * dropletRadius_;
      
      RealType z2 = dz*dz;
      RealType z3 = z2 * dz;
      RealType k2 = k*k;
      RealType k3 = k2*k;
      
      Polynomial<RealType> poly;
      poly.setCoefficient(4,      z3 +      k3);
      poly.setCoefficient(3,  8.0*z3 +  8.0*k3);
      poly.setCoefficient(2, 24.0*z3 + 18.0*k3);
      poly.setCoefficient(1, 32.0*z3          );
      poly.setCoefficient(0, 16.0*z3 - 27.0*k3);
      vector<RealType> realRoots = poly.FindRealRoots();

      RealType ct;
      
      vector<RealType>::iterator ri;


      RealType maxct = -1.0;
      for (ri = realRoots.begin(); ri !=realRoots.end(); ++ri) {
        ct = *ri;
        if (ct > 1.0)  ct = 1.0;
        if (ct < -1.0) ct = -1.0;

        // use the largest magnitude of ct that it finds:
        if (ct > maxct) {
          maxct = ct;
        }                  
      }
      
      values_.push_back( acos(maxct)*(180.0/M_PI) );
    }
  }    
コード例 #16
0
void TetrahedralityParamXYZ::process() {
    Molecule* mol;
    StuntDouble* sd;
    StuntDouble* sd2;
    StuntDouble* sdi;
    StuntDouble* sdj;
    RigidBody* rb;
    int myIndex;
    SimInfo::MoleculeIterator mi;
    Molecule::RigidBodyIterator rbIter;
    Vector3d vec;
    Vector3d ri, rj, rk, rik, rkj;
    RealType r;
    RealType cospsi;
    RealType Qk;
    std::vector<std::pair<RealType,StuntDouble*> > myNeighbors;
    //std::vector<std::pair<Vector3d, RealType> > qvals;
    //std::vector<std::pair<Vector3d, RealType> >::iterator qiter;
    int isd1;
    int isd2;


    int kMax = int(5.0 * gaussWidth_ / voxelSize_);
    int kSqLim = kMax*kMax;
    cerr << "gw = " << gaussWidth_ << " vS = " << voxelSize_ << " kMax = "
         << kMax << " kSqLim = " << kSqLim << "\n";

    DumpReader reader(info_, dumpFilename_);
    int nFrames = reader.getNFrames();

    for (int istep = 0; istep < nFrames; istep += step_) {
        reader.readFrame(istep);

        currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
        Mat3x3d hmat = currentSnapshot_->getHmat();
        Vector3d halfBox = Vector3d(hmat(0,0), hmat(1,1), hmat(2,2)) / 2.0;

        if (evaluator1_.isDynamic()) {
            seleMan1_.setSelectionSet(evaluator1_.evaluate());
        }

        if (evaluator2_.isDynamic()) {
            seleMan2_.setSelectionSet(evaluator2_.evaluate());
        }

        // update the positions of atoms which belong to the rigidbodies
        for (mol = info_->beginMolecule(mi); mol != NULL;
                mol = info_->nextMolecule(mi)) {
            for (rb = mol->beginRigidBody(rbIter); rb != NULL;
                    rb = mol->nextRigidBody(rbIter)) {
                rb->updateAtoms();
            }
        }

        //qvals.clear();

        // outer loop is over the selected StuntDoubles:
        for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
                sd = seleMan1_.nextSelected(isd1)) {

            myIndex = sd->getGlobalIndex();

            Qk = 1.0;
            myNeighbors.clear();

            for (sd2 = seleMan2_.beginSelected(isd2); sd2 != NULL;
                    sd2 = seleMan2_.nextSelected(isd2)) {

                if (sd2->getGlobalIndex() != myIndex) {

                    vec = sd->getPos() - sd2->getPos();

                    if (usePeriodicBoundaryConditions_)
                        currentSnapshot_->wrapVector(vec);

                    r = vec.length();

                    // Check to see if neighbor is in bond cutoff

                    if (r < rCut_) {
                        myNeighbors.push_back(std::make_pair(r,sd2));
                    }
                }
            }

            // Sort the vector using predicate and std::sort
            std::sort(myNeighbors.begin(), myNeighbors.end());

            // Use only the 4 closest neighbors to do the rest of the work:

            int nbors =  myNeighbors.size()> 4 ? 4 : myNeighbors.size();
            int nang = int (0.5 * (nbors * (nbors - 1)));

            rk = sd->getPos();

            for (int i = 0; i < nbors-1; i++) {

                sdi = myNeighbors[i].second;
                ri = sdi->getPos();
                rik = rk - ri;
                if (usePeriodicBoundaryConditions_)
                    currentSnapshot_->wrapVector(rik);

                rik.normalize();

                for (int j = i+1; j < nbors; j++) {

                    sdj = myNeighbors[j].second;
                    rj = sdj->getPos();
                    rkj = rk - rj;
                    if (usePeriodicBoundaryConditions_)
                        currentSnapshot_->wrapVector(rkj);
                    rkj.normalize();

                    cospsi = dot(rik,rkj);

                    // Calculates scaled Qk for each molecule using calculated
                    // angles from 4 or fewer nearest neighbors.
                    Qk -=  (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
                }
            }

            if (nang > 0) {
                if (usePeriodicBoundaryConditions_)
                    currentSnapshot_->wrapVector(rk);
                //qvals.push_back(std::make_pair(rk, Qk));

                Vector3d pos = rk + halfBox;


                Vector3i whichVoxel(int(pos[0] / voxelSize_),
                                    int(pos[1] / voxelSize_),
                                    int(pos[2] / voxelSize_));

                for (int l = -kMax; l <= kMax; l++) {
                    for (int m = -kMax; m <= kMax; m++) {
                        for (int n = -kMax; n <= kMax; n++) {
                            int kk = l*l + m*m + n*n;
                            if(kk <= kSqLim) {

                                int ll = (whichVoxel[0] + l) % nBins_(0);
                                ll = ll < 0 ? nBins_(0) + ll : ll;
                                int mm = (whichVoxel[1] + m) % nBins_(1);
                                mm = mm < 0 ? nBins_(1) + mm : mm;
                                int nn = (whichVoxel[2] + n) % nBins_(2);
                                nn = nn < 0 ? nBins_(2) + nn : nn;

                                Vector3d bPos = Vector3d(ll,mm,nn) * voxelSize_ - halfBox;
                                Vector3d d = bPos - rk;
                                currentSnapshot_->wrapVector(d);
                                RealType denom = pow(2.0 * sqrt(M_PI) * gaussWidth_, 3);
                                RealType exponent = -dot(d,d) / pow(2.0*gaussWidth_, 2);
                                RealType weight = exp(exponent) / denom;
                                count_[ll][mm][nn] += weight;
                                hist_[ll][mm][nn] += weight * Qk;
                            }
                        }
                    }
                }
            }
        }

        // for (int i = 0; i < nBins_(0); ++i) {
        //   for(int j = 0; j < nBins_(1); ++j) {
        //     for(int k = 0; k < nBins_(2); ++k) {
        //       Vector3d pos = Vector3d(i, j, k) * voxelSize_ - halfBox;
        //       for(qiter = qvals.begin(); qiter != qvals.end(); ++qiter) {
        //         Vector3d d = pos - (*qiter).first;
        //         currentSnapshot_->wrapVector(d);
        //         RealType denom = pow(2.0 * sqrt(M_PI) * gaussWidth_, 3);
        //         RealType exponent = -dot(d,d) / pow(2.0*gaussWidth_, 2);
        //         RealType weight = exp(exponent) / denom;
        //         count_[i][j][k] += weight;
        //         hist_[i][j][k] += weight * (*qiter).second;
        //       }
        //     }
        //   }
        // }
    }
    writeQxyz();
}
コード例 #17
0
ファイル: TetrahedralityParam.cpp プロジェクト: hsidky/OpenMD
  void TetrahedralityParam::process() {
    Molecule* mol;
    StuntDouble* sd;
    StuntDouble* sd2;
    StuntDouble* sdi;
    StuntDouble* sdj;
    RigidBody* rb;
    int myIndex;
    SimInfo::MoleculeIterator mi;
    Molecule::RigidBodyIterator rbIter;
    Molecule::IntegrableObjectIterator ioi;
    Vector3d vec;
    Vector3d ri, rj, rk, rik, rkj, dposition, tposition;
    RealType r;
    RealType cospsi;
    RealType Qk;
    std::vector<std::pair<RealType,StuntDouble*> > myNeighbors;
    int isd;
    bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions();

    DumpReader reader(info_, dumpFilename_);    
    int nFrames = reader.getNFrames();
    frameCounter_ = 0;

    Distorted_.clear();
    Tetrahedral_.clear();

    for (int istep = 0; istep < nFrames; istep += step_) {
      reader.readFrame(istep);
      frameCounter_++;
      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
      
      if (evaluator_.isDynamic()) {
        seleMan_.setSelectionSet(evaluator_.evaluate());
      }

      // update the positions of atoms which belong to the rigidbodies
      
      for (mol = info_->beginMolecule(mi); mol != NULL; 
           mol = info_->nextMolecule(mi)) {
        for (rb = mol->beginRigidBody(rbIter); rb != NULL; 
             rb = mol->nextRigidBody(rbIter)) {
          rb->updateAtoms();
        }        
      }           
            

      // outer loop is over the selected StuntDoubles:

      for (sd = seleMan_.beginSelected(isd); sd != NULL; 
           sd = seleMan_.nextSelected(isd)) {
	
        myIndex = sd->getGlobalIndex();
	Qk = 1.0;

	myNeighbors.clear();
                
        // inner loop is over all StuntDoubles in the system:
        
        for (mol = info_->beginMolecule(mi); mol != NULL; 
             mol = info_->nextMolecule(mi)) {

          for (sd2 = mol->beginIntegrableObject(ioi); sd2 != NULL; 
               sd2 = mol->nextIntegrableObject(ioi)) {
	    
            if (sd2->getGlobalIndex() != myIndex) {
	      
              vec = sd->getPos() - sd2->getPos();       
	      
              if (usePeriodicBoundaryConditions_) 
                currentSnapshot_->wrapVector(vec);
	      
              r = vec.length();             

              // Check to see if neighbor is in bond cutoff 
              
              if (r < rCut_) { 
		
		myNeighbors.push_back(std::make_pair(r,sd2));
	      }
	    }
	  }
	}

	// Sort the vector using predicate and std::sort
	std::sort(myNeighbors.begin(), myNeighbors.end());

	//std::cerr << myNeighbors.size() <<  " neighbors within " 
	//          << rCut_  << " A" << " \n";
	
	// Use only the 4 closest neighbors to do the rest of the work:
	
	int nbors =  myNeighbors.size()> 4 ? 4 : myNeighbors.size();
	int nang = int (0.5 * (nbors * (nbors - 1)));

	rk = sd->getPos();
	//std::cerr<<nbors<<endl;
	for (int i = 0; i < nbors-1; i++) {	  

	  sdi = myNeighbors[i].second;
	  ri = sdi->getPos();
	  rik = rk - ri;
	  if (usePeriodicBoundaryConditions_) 
	    currentSnapshot_->wrapVector(rik);
	  
	  rik.normalize();

	  for (int j = i+1; j < nbors; j++) {	    

	    sdj = myNeighbors[j].second;
	    rj = sdj->getPos();
	    rkj = rk - rj;
	    if (usePeriodicBoundaryConditions_) 
	      currentSnapshot_->wrapVector(rkj);
	    rkj.normalize();
	    
	    cospsi = dot(rik,rkj);

	    //std::cerr << "cos(psi) = " << cospsi << " \n";

	    // Calculates scaled Qk for each molecule using calculated
	    // angles from 4 or fewer nearest neighbors.
	    Qk = Qk - (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);
	    //std::cerr<<Qk<<"\t"<<nang<<endl;
	  }
	}
	//std::cerr<<nang<<endl;
	if (nang > 0) {
	  collectHistogram(Qk);

	  // Saves positions of StuntDoubles & neighbors with distorted
	  // coordination (low Qk value)
	  if ((Qk < 0.55) && (Qk > 0.45)) {
	    //std::cerr<<Distorted_.size()<<endl;
	    Distorted_.push_back(sd);
	    //std::cerr<<Distorted_.size()<<endl;
	    dposition = sd->getPos();
	    //std::cerr << "distorted position \t" << dposition << "\n";
	  }

	  // Saves positions of StuntDoubles & neighbors with
	  // tetrahedral coordination (high Qk value)
	  if (Qk > 0.05) { 

	    Tetrahedral_.push_back(sd);

	    tposition = sd->getPos();
	    //std::cerr << "tetrahedral position \t" << tposition << "\n";
	  }

	  //std::cerr<<Tetrahedral_.size()<<endl;
       
	}

      }
    }
    
    writeOrderParameter();
    std::cerr << "number of distorted StuntDoubles = " 
	      << Distorted_.size() << "\n";
    std::cerr << "number of tetrahedral StuntDoubles = " 
	      << Tetrahedral_.size() << "\n";
  }
コード例 #18
0
ファイル: ContactAngle2.cpp プロジェクト: hsidky/OpenMD
  void ContactAngle2::doFrame(int frame) {
    StuntDouble* sd;
    int i;

    // set up the bins for density analysis

    Mat3x3d hmat = info_->getSnapshotManager()->getCurrentSnapshot()->getHmat();
    RealType len = std::min(hmat(0, 0), hmat(1, 1));
    RealType zLen = hmat(2,2);

    RealType dr = len / (RealType) nRBins_;
    RealType dz = zLen / (RealType) nZBins_;

    std::vector<std::vector<RealType> > histo;
    histo.resize(nRBins_);
    for (unsigned int i = 0; i < histo.size(); ++i){
      histo[i].resize(nZBins_);
      std::fill(histo[i].begin(), histo[i].end(), 0.0);
    }      
        
    if (evaluator1_.isDynamic()) {
      seleMan1_.setSelectionSet(evaluator1_.evaluate());
    }
    
    Vector3d com(centroidX_, centroidY_, solidZ_);

    // now that we have the centroid, we can make cylindrical density maps
    Vector3d pos;
    RealType r;
    RealType z;
    
    for (sd = seleMan1_.beginSelected(i); sd != NULL;
         sd = seleMan1_.nextSelected(i)) {      
      pos = sd->getPos() - com;

      // r goes from zero upwards
      r = sqrt(pow(pos.x(), 2) + pow(pos.y(), 2));
      // z is possibly symmetric around 0
      z = pos.z();
          
      int whichRBin = int(r / dr);
      int whichZBin = int( (zLen/2.0 + z) / dz);
      
      if ((whichRBin < int(nRBins_)) && (whichZBin >= 0)
          && (whichZBin < int(nZBins_))) {
        histo[whichRBin][whichZBin] += sd->getMass();
      }
      
    }
    
    for(unsigned int i = 0 ; i < histo.size(); ++i){

      RealType rL = i * dr;
      RealType rU = rL + dr;
      RealType volSlice = NumericConstant::PI * dz * (( rU*rU ) - ( rL*rL ));

      for (unsigned int j = 0; j < histo[i].size(); ++j) {
        histo[i][j] *= PhysicalConstants::densityConvert / volSlice;
      }
    }

    std::vector<Vector<RealType, 2> > points;
    points.clear();
    
    for (unsigned int j = 0; j < nZBins_;  ++j) {

      // The z coordinates were measured relative to the selection
      // center of mass.  However, we're interested in the elevation
      // above the solid surface.  Also, the binning was done around
      // zero with enough bins to cover the zLength of the box:
      
      RealType thez =  com.z() - solidZ_  - zLen/2.0 + dz * (j + 0.5);
      bool aboveThresh = false;
      bool foundThresh = false;
      int rloc = 0;
      
      for (std::size_t i = 0; i < nRBins_;  ++i) {

        if (histo[i][j] >= threshDens_) aboveThresh = true;

        if (aboveThresh && (histo[i][j] <= threshDens_)) {
          rloc = i;
          foundThresh = true;
          aboveThresh = false;
        }

      }
      if (foundThresh) {
        Vector<RealType,2> point;
        point[0] = dr*(rloc+0.5);
        point[1] = thez;

        if (thez > bufferLength_) {
          points.push_back( point );
        }
      }      
    }

    int numPoints = points.size();

    // Compute the average of the data points.
    Vector<RealType, 2> average = points[0];
    int i0;
    for (i0 = 1; i0 < numPoints; ++i0) {
      average += points[i0];
    }
    RealType invNumPoints = ((RealType)1)/(RealType)numPoints;
    average *= invNumPoints;
    
    DynamicRectMatrix<RealType> mat(4, 4);
    int row, col;
    for (row = 0; row < 4; ++row) {
      for (col = 0; col < 4; ++col){
        mat(row,col) = 0.0;        
      }
    }
    for (int i = 0; i < numPoints; ++i) {
      RealType x = points[i][0];
      RealType y = points[i][1];
      RealType x2 = x*x;
      RealType y2 = y*y;
      RealType xy = x*y;
      RealType r2 = x2+y2;
      RealType xr2 = x*r2;
      RealType yr2 = y*r2;
      RealType r4 = r2*r2;

      mat(0,1) += x;
      mat(0,2) += y;
      mat(0,3) += r2;
      mat(1,1) += x2;
      mat(1,2) += xy;
      mat(1,3) += xr2;
      mat(2,2) += y2;
      mat(2,3) += yr2;
      mat(3,3) += r4;
    }
    mat(0,0) = (RealType)numPoints;

    for (row = 0; row < 4; ++row) {
      for (col = 0; col < row; ++col) {
        mat(row,col) = mat(col,row);
      }
    }

    for (row = 0; row < 4; ++row) {
      for (col = 0; col < 4; ++col) {
        mat(row,col) *= invNumPoints;
      }
    }

    JAMA::Eigenvalue<RealType> eigensystem(mat);
    DynamicRectMatrix<RealType> evects(4, 4);
    DynamicVector<RealType> evals(4);

    eigensystem.getRealEigenvalues(evals);
    eigensystem.getV(evects);

    DynamicVector<RealType> evector = evects.getColumn(0);
    RealType inv = ((RealType)1)/evector[3];  // beware zero divide
    RealType coeff[3];
    for (row = 0; row < 3; ++row) {
      coeff[row] = inv*evector[row];
    }

    Vector<RealType, 2> center;
    
    center[0] = -((RealType)0.5)*coeff[1];
    center[1] = -((RealType)0.5)*coeff[2];
    RealType radius = sqrt(fabs(center[0]*center[0] + center[1]*center[1]
                                - coeff[0]));

    int i1;
    for (i1 = 0; i1 < 100; ++i1) {
      // Update the iterates.
      Vector<RealType, 2> current = center;
      
      // Compute average L, dL/da, dL/db.
      RealType lenAverage = (RealType)0;
      Vector<RealType, 2> derLenAverage = Vector<RealType, 2>(0.0);
      for (i0 = 0; i0 < numPoints; ++i0) {
        Vector<RealType, 2> diff = points[i0] - center;
        RealType length = diff.length();
        if (length > 1e-6) {
          lenAverage += length;
          RealType invLength = ((RealType)1)/length;
          derLenAverage -= invLength*diff;
        }
      }
      lenAverage *= invNumPoints;
      derLenAverage *= invNumPoints;

      center = average + lenAverage*derLenAverage;
      radius = lenAverage;

      Vector<RealType, 2> diff = center - current;
      if (fabs(diff[0]) <= 1e-6 &&  fabs(diff[1]) <= 1e-6) {
        break;
      }
    }

    RealType zCen = center[1];
    RealType rDrop = radius;
    RealType ca;

    if (fabs(zCen) > rDrop) {
      ca = 180.0;
    } else {
      ca = 90.0 + asin(zCen/rDrop)*(180.0/M_PI);
    }

    values_.push_back( ca );    
  }   
コード例 #19
0
  void TetrahedralityParamZ::process() {
    Molecule* mol;
    StuntDouble* sd;
    StuntDouble* sd2;
    StuntDouble* sdi;
    StuntDouble* sdj;
    RigidBody* rb;
    int myIndex;
    SimInfo::MoleculeIterator mi;
    Molecule::RigidBodyIterator rbIter;
    Vector3d vec;
    Vector3d ri, rj, rk, rik, rkj;
    RealType r;
    RealType cospsi;
    RealType Qk;
    std::vector<std::pair<RealType,StuntDouble*> > myNeighbors;
    int isd1;
    int isd2;

    DumpReader reader(info_, dumpFilename_);    
    int nFrames = reader.getNFrames();

    for (int istep = 0; istep < nFrames; istep += step_) {
      reader.readFrame(istep);
      currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
      
      Mat3x3d hmat = currentSnapshot_->getHmat();
      zBox_.push_back(hmat(2,2));
      
      RealType halfBoxZ_ = hmat(2,2) / 2.0;      

      if (evaluator1_.isDynamic()) {
        seleMan1_.setSelectionSet(evaluator1_.evaluate());
      }
      
      if (evaluator2_.isDynamic()) {
        seleMan2_.setSelectionSet(evaluator2_.evaluate());
      }
      
      // update the positions of atoms which belong to the rigidbodies
      for (mol = info_->beginMolecule(mi); mol != NULL;
           mol = info_->nextMolecule(mi)) {
        for (rb = mol->beginRigidBody(rbIter); rb != NULL;
             rb = mol->nextRigidBody(rbIter)) {
          rb->updateAtoms();
        }
      }
      
      // outer loop is over the selected StuntDoubles:
      for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
           sd = seleMan1_.nextSelected(isd1)) {
        
        myIndex = sd->getGlobalIndex();
        
        Qk = 1.0;	  
        myNeighbors.clear();       

        for (sd2 = seleMan2_.beginSelected(isd2); sd2 != NULL;
             sd2 = seleMan2_.nextSelected(isd2)) {
          
          if (sd2->getGlobalIndex() != myIndex) {
            
            vec = sd->getPos() - sd2->getPos();       
            
            if (usePeriodicBoundaryConditions_) 
              currentSnapshot_->wrapVector(vec);
            
            r = vec.length();             
            
            // Check to see if neighbor is in bond cutoff 
            
            if (r < rCut_) {                
              myNeighbors.push_back(std::make_pair(r,sd2));
            }
          }
        }
        
        // Sort the vector using predicate and std::sort
        std::sort(myNeighbors.begin(), myNeighbors.end());
        
        // Use only the 4 closest neighbors to do the rest of the work:
        
        int nbors =  myNeighbors.size()> 4 ? 4 : myNeighbors.size();
        int nang = int (0.5 * (nbors * (nbors - 1)));
        
        rk = sd->getPos();
        
        for (int i = 0; i < nbors-1; i++) {       
          
          sdi = myNeighbors[i].second;
          ri = sdi->getPos();
          rik = rk - ri;
          if (usePeriodicBoundaryConditions_) 
            currentSnapshot_->wrapVector(rik);
          
          rik.normalize();
          
          for (int j = i+1; j < nbors; j++) {       
            
            sdj = myNeighbors[j].second;
            rj = sdj->getPos();
            rkj = rk - rj;
            if (usePeriodicBoundaryConditions_) 
              currentSnapshot_->wrapVector(rkj);
            rkj.normalize();
            
            cospsi = dot(rik,rkj);           
            
            // Calculates scaled Qk for each molecule using calculated
            // angles from 4 or fewer nearest neighbors.
            Qk -=  (pow(cospsi + 1.0 / 3.0, 2) * 2.25 / nang);            
          }
        }
        
        if (nang > 0) {
          if (usePeriodicBoundaryConditions_)
            currentSnapshot_->wrapVector(rk);
          
          int binNo = int(nZBins_ * (halfBoxZ_ + rk.z()) / hmat(2,2));
          sliceQ_[binNo] += Qk;
          sliceCount_[binNo] += 1;
        }  
      }
    }
    writeQz();
  }
コード例 #20
0
  void ThermoIntegrationForceManager::calcForces(){
    Snapshot* curSnapshot;
    SimInfo::MoleculeIterator mi;
    Molecule* mol;
    Molecule::IntegrableObjectIterator ii;
    StuntDouble* sd;
    Vector3d frc;
    Vector3d trq;
    Mat3x3d tempTau;
    
    // perform the standard calcForces first
    ForceManager::calcForces();
    
    curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();

    // now scale forces and torques of all the sds
      
    for (mol = info_->beginMolecule(mi); mol != NULL; 
         mol = info_->nextMolecule(mi)) {

      for (sd = mol->beginIntegrableObject(ii); sd != NULL; 
           sd = mol->nextIntegrableObject(ii)) {

        frc = sd->getFrc();
        frc *= factor_;
        sd->setFrc(frc);
        
        if (sd->isDirectional()){
          trq = sd->getTrq();
          trq *= factor_;
          sd->setTrq(trq);
        }
      }
    }
    
    // set rawPotential to be the unmodulated potential
    lrPot_ = curSnapshot->getLongRangePotential();
    curSnapshot->setRawPotential(lrPot_);
    
    // modulate the potential and update the snapshot
    lrPot_ *= factor_;
    curSnapshot->setLongRangePotential(lrPot_);
    
    // scale the pressure tensor
    tempTau = curSnapshot->getStressTensor();
    tempTau *= factor_;
    curSnapshot->setStressTensor(tempTau);

    // now, on to the applied restraining potentials (if needed):
    RealType restPot_local = 0.0;
    RealType vHarm_local = 0.0;
    
    if (simParam->getUseRestraints()) {
      // do restraints from RestraintForceManager:
      restPot_local = doRestraints(1.0 - factor_);      
      vHarm_local = getUnscaledPotential();
    }
      
#ifdef IS_MPI
    RealType restPot;
    MPI::COMM_WORLD.Allreduce(&restPot_local, &restPot, 1, 
                              MPI::REALTYPE, MPI::SUM);
    MPI::COMM_WORLD.Allreduce(&vHarm_local, &vHarm_, 1, 
                              MPI::REALTYPE, MPI::SUM);         
    lrPot_ += restPot;
#else
    lrPot_ += restPot_local;
    vHarm_ = vHarm_local;
#endif

    // give the final values to stats
    curSnapshot->setLongRangePotential(lrPot_);
    curSnapshot->setRestraintPotential(vHarm_);
  }