예제 #1
0
파일: GofRAngle.cpp 프로젝트: hsidky/OpenMD
  RealType GofRTheta::evaluateAngle(StuntDouble* sd1, StuntDouble* sd2) {
    bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions();

    Vector3d pos1 = sd1->getPos();
    Vector3d pos2 = sd2->getPos();
    Vector3d r12 = pos2 - pos1;
  
    if (usePeriodicBoundaryConditions_)
      currentSnapshot_->wrapVector(r12);

    r12.normalize();

    Vector3d vec;    
    
    if (!sd1->isDirectional()) {
      sprintf(painCave.errMsg, 
              "GofRTheta: attempted to use a non-directional object: %s\n", 
              sd1->getType().c_str());
      painCave.isFatal = 1;
      simError();  
    }

    if (sd1->isAtom()) {
      AtomType* atype1 = static_cast<Atom*>(sd1)->getAtomType();
      MultipoleAdapter ma1 = MultipoleAdapter(atype1);
      
      if (ma1.isDipole() )
        vec = sd1->getDipole();
      else 
        vec = sd1->getA().transpose() * V3Z;
    } else {
      vec = sd1->getA().transpose() * V3Z;
    }

    vec.normalize();    
      
    return dot(r12, vec);
  }
예제 #2
0
파일: GofRAngle.cpp 프로젝트: hsidky/OpenMD
  void GofRAngle::writeRdf() {
    std::ofstream ofs(outputFilename_.c_str());
    if (ofs.is_open()) {
      Revision r;
      ofs << "# " << getAnalysisType() << "\n";
      ofs << "# OpenMD " << r.getFullRevision() << "\n";
      ofs << "# " << r.getBuildDate() << "\n";
      ofs << "# selection script1: \"" << selectionScript1_ ;
      ofs << "\"\tselection script2: \"" << selectionScript2_ << "\"";
      if (doSele3_) {
        ofs << "\tselection script3: \"" << selectionScript3_ << "\"\n";
      } else {
        ofs << "\n";
      }

      if (!paramString_.empty())
        ofs << "# parameters: " << paramString_ << "\n";

      for (unsigned int i = 0; i < avgGofr_.size(); ++i) {
	// RealType r = deltaR_ * (i + 0.5);

	for(unsigned int j = 0; j < avgGofr_[i].size(); ++j) {
	  // RealType cosAngle = -1.0 + (j + 0.5)*deltaCosAngle_;
	  ofs << avgGofr_[i][j]/nProcessed_ << "\t";
	}

	ofs << "\n";
      }
        
    } else {
      sprintf(painCave.errMsg, "GofRAngle: unable to open %s\n", 
              outputFilename_.c_str());
      painCave.isFatal = 1;
      simError();  
    }

    ofs.close();
  }
예제 #3
0
  void DensityPlot::writeDensity() {
    std::ofstream ofs(outputFilename_.c_str(), std::ios::binary);
    if (ofs.is_open()) {
      ofs << "#g(x, y, z)\n";
      ofs << "#selection: (" << selectionScript_ << ")\n";
      ofs << "#cmSelection:(" << cmSelectionScript_ << ")\n";
      ofs << "#nRBins = " << nRBins_ << "\t maxLen = " 
	  << len_ << "\tdeltaR = " << deltaR_ <<"\n";
      for (unsigned int i = 0; i < histogram_.size(); ++i) {
        ofs << i*deltaR_ - halfLen_ <<"\t" << density_[i]<< std::endl;
      }        
    } else {

      sprintf(painCave.errMsg, "DensityPlot: unable to open %s\n", 
	      outputFilename_.c_str());
      painCave.isFatal = 1;
      simError();  
    }

    ofs.close();


  }
예제 #4
0
 RealType LineSearch::update(DynamicVector<RealType>& params,
                             const DynamicVector<RealType>& direction,
                             RealType beta,
                             const Constraint& constraint) {
     
     RealType diff=beta;
     DynamicVector<RealType> newParams = params + diff*direction;
     bool valid = constraint.test(newParams);
     int icount = 0;
     while (!valid) {
         if (icount > 200) {
             sprintf(painCave.errMsg, "can't update linesearch\n");
             painCave.isFatal = 1;
             painCave.severity = OPENMD_ERROR;
             simError();
         }
         diff *= 0.5;
         icount ++;
         newParams = params + diff*direction;
         valid = constraint.test(newParams);
     }
     params += diff*direction;
     return diff;
 }
예제 #5
0
 Shape* ShapeBuilder::internalCreateShape(DirectionalAtom* datom) {
   AtomType* atomType = datom->getAtomType();
   Shape* currShape = NULL;
   LennardJonesAdapter lja = LennardJonesAdapter(atomType);
   GayBerneAdapter gba = GayBerneAdapter(atomType);
   if (gba.isGayBerne()) {
     currShape = new Ellipsoid(datom->getPos(), gba.getL()/2.0, 
                               gba.getD()/2.0, datom->getA());
   } else if (lja.isLennardJones()) {
     currShape = new Sphere(datom->getPos(), lja.getSigma()/2.0);
   } else {
     int obanum = etab.GetAtomicNum((datom->getType()).c_str());
     if (obanum != 0) {
       currShape = new Sphere(datom->getPos(), etab.GetVdwRad(obanum));
     } else {
       sprintf( painCave.errMsg,
                "Could not find atom type in default element.txt\n");
       painCave.severity = OPENMD_ERROR;
       painCave.isFatal = 1;
       simError();          
     }
   }        
   return currShape;
 }
예제 #6
0
  DirectionalAtom::DirectionalAtom(AtomType* dAtomType) 
    : Atom(dAtomType) {
    objType_= otDAtom;

    DirectionalAdapter da = DirectionalAdapter(dAtomType);
    I_ = da.getI();

    MultipoleAdapter ma = MultipoleAdapter(dAtomType);
    if (ma.isDipole()) {
      dipole_ = ma.getDipole();
    }
    if (ma.isQuadrupole()) {
      quadrupole_ = ma.getQuadrupole();
    }

    // Check if one of the diagonal inertia tensor of this directional
    // atom is zero:
    int nLinearAxis = 0;
    Mat3x3d inertiaTensor = getI();
    for (int i = 0; i < 3; i++) {    
      if (fabs(inertiaTensor(i, i)) < OpenMD::epsilon) {
        linear_ = true;
        linearAxis_ = i;
        ++ nLinearAxis;
      }
    }

    if (nLinearAxis > 1) {
      sprintf( painCave.errMsg,
               "Directional Atom warning.\n"
               "\tOpenMD found more than one axis in this directional atom with a vanishing \n"
               "\tmoment of inertia.");
      painCave.isFatal = 0;
      simError();
    }    
  }
예제 #7
0
  ConstraintWriter::ConstraintWriter(SimInfo* info, 
                                     const std::string& filename): info_(info) {
    //use master - slave mode, only master node writes to disk
#ifdef IS_MPI
    if(worldRank == 0){
#endif
      output_.open(filename.c_str());
      
      if(!output_){
	sprintf( painCave.errMsg,
		 "Could not open %s for Constraint output\n", 
                 filename.c_str());
	painCave.isFatal = 1;
	simError();
      }
      
      output_ << "#time(fs)\t"
              << "Index of atom 1\t"
              << "Index of atom 2\tconstraint force" << std::endl; 
      
#ifdef IS_MPI
    }
#endif      
  }
예제 #8
0
파일: Shake.cpp 프로젝트: jmichalka/OpenMD
  void Shake::doConstraint(ConstraintPairFuncPtr func) {
    if (!doShake_) return;

    Molecule* mol;
    SimInfo::MoleculeIterator mi;
    ConstraintElem* consElem;
    Molecule::ConstraintElemIterator cei;
    ConstraintPair* consPair;
    Molecule::ConstraintPairIterator cpi;
    
    for (mol = info_->beginMolecule(mi); mol != NULL; 
         mol = info_->nextMolecule(mi)) {
      for (consElem = mol->beginConstraintElem(cei); consElem != NULL; 
           consElem = mol->nextConstraintElem(cei)) {
	consElem->setMoved(true);
	consElem->setMoving(false);
      }
    }
    
    //main loop of constraint algorithm
    int done = 0;
    int iteration = 0;
    while(!done && iteration < maxConsIteration_){
      done = 1;

      //loop over every constraint pair

      for (mol = info_->beginMolecule(mi); mol != NULL; 
           mol = info_->nextMolecule(mi)) {
	for (consPair = mol->beginConstraintPair(cpi); consPair != NULL; 
             consPair = mol->nextConstraintPair(cpi)) {
          

	  //dispatch constraint algorithm
	  if(consPair->isMoved()) {
	    int exeStatus = (this->*func)(consPair);

	    switch(exeStatus){
	    case consFail:
	      sprintf(painCave.errMsg,
		      "Constraint failure in Shake::constrainA, "
                      "Constraint Fail\n");
	      painCave.isFatal = 1;
	      simError();                             
                            
	      break;
	    case consSuccess:
	      // constrain the pair by moving two elements
	      done = 0;
	      consPair->getConsElem1()->setMoving(true);
	      consPair->getConsElem2()->setMoving(true);
	      break;
	    case consAlready:
	      // current pair is already constrained, do not need to
	      // move the elements
	      break;
	    default:          
	      sprintf(painCave.errMsg, "ConstraintAlgorithm::doConstraint() "
                      "Error: unrecognized status");
	      painCave.isFatal = 1;
	      simError();                           
	      break;
	    }      
	  }
	}
      }//end for(iter->first())

#ifdef IS_MPI
      MPI_Allreduce(MPI_IN_PLACE, &done, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD);
#endif

      errorCheckPoint();

      for (mol = info_->beginMolecule(mi); mol != NULL; 
           mol = info_->nextMolecule(mi)) {
	for (consElem = mol->beginConstraintElem(cei); consElem != NULL; 
             consElem = mol->nextConstraintElem(cei)) {
	  consElem->setMoved(consElem->getMoving());
	  consElem->setMoving(false);
	}
      }

      iteration++;
    }//end while

    if (!done){
      sprintf(painCave.errMsg,
              "Constraint failure in Shake::constrainA, "
              "too many iterations: %d\n",
              iteration);
      painCave.isFatal = 1;
      simError();    
    }
    
    errorCheckPoint();
  }
  LangevinHullForceManager::LangevinHullForceManager(SimInfo* info) : 
    ForceManager(info) {
   
    simParams = info->getSimParams();
    veloMunge = new Velocitizer(info);
    
    // Create Hull, Convex Hull for now, other options later.
    
    stringToEnumMap_["Convex"] = hullConvex;
    stringToEnumMap_["AlphaShape"] = hullAlphaShape;
    stringToEnumMap_["Unknown"] = hullUnknown;
    
    const std::string ht = simParams->getHULL_Method();
    
    std::map<std::string, HullTypeEnum>::iterator iter;
    iter = stringToEnumMap_.find(ht);
    hullType_ = (iter == stringToEnumMap_.end()) ? 
      LangevinHullForceManager::hullUnknown : iter->second;

    switch(hullType_) {
    case hullConvex :
      surfaceMesh_ = new ConvexHull();
      break;
    case hullAlphaShape :
      surfaceMesh_ = new AlphaHull(simParams->getAlpha());
      break;
    case hullUnknown :
    default :
      sprintf(painCave.errMsg, 
              "LangevinHallForceManager: Unknown Hull_Method was requested!\n");
      painCave.isFatal = 1;
      simError();      
      break;
    }

    doThermalCoupling_ = true;
    doPressureCoupling_ = true;

    /* Check that the simulation has target pressure and target
       temperature set */    
    if (!simParams->haveTargetTemp()) {
      sprintf(painCave.errMsg, 
              "LangevinHullForceManager: no targetTemp (K) was set.\n"
              "\tOpenMD is turning off the thermal coupling to the bath.\n");
      painCave.isFatal = 0;
      painCave.severity = OPENMD_INFO;
      simError();
      doThermalCoupling_ = false;
    } else {
      targetTemp_ = simParams->getTargetTemp();

      if (!simParams->haveViscosity()) {
        sprintf(painCave.errMsg, 
                "LangevinHullForceManager: no viscosity was set.\n"
                "\tOpenMD is turning off the thermal coupling to the bath.\n");
        painCave.isFatal = 0;
        painCave.severity = OPENMD_INFO;
        simError();      
        doThermalCoupling_ = false;
      }else{
        viscosity_ = simParams->getViscosity();
        if ( fabs(viscosity_) < 1e-6 ) {
          sprintf(painCave.errMsg, 
                  "LangevinHullDynamics: The bath viscosity was set lower\n"
                  "\tthan 1e-6 poise.  OpenMD is turning off the thermal\n"
                  "\tcoupling to the bath.\n");
          painCave.isFatal = 0;
          painCave.severity = OPENMD_INFO;
          simError();
          doThermalCoupling_ = false;
        }      
      }      
    }
    if (!simParams->haveTargetPressure()) {
      sprintf(painCave.errMsg, 
              "LangevinHullForceManager: no targetPressure (atm) was set.\n"
              "\tOpenMD is turning off the pressure coupling to the bath.\n");
      painCave.isFatal = 0;
      painCave.severity = OPENMD_INFO;
      simError();
      doPressureCoupling_ = false;
    } else {
      // Convert pressure from atm -> amu/(fs^2*Ang)
      targetPressure_ = simParams->getTargetPressure() / 
        PhysicalConstants::pressureConvert;
    }
    if (simParams->getUsePeriodicBoundaryConditions()) {
      sprintf(painCave.errMsg, 
              "LangevinHallForceManager: You can't use the Langevin Hull\n"
              "\tintegrator with periodic boundary conditions turned on!\n");
      painCave.isFatal = 1;
      simError();
    } 

    dt_ = simParams->getDt();

    if (doThermalCoupling_)
      variance_ = 2.0 * PhysicalConstants::kb * targetTemp_ / dt_;

    // Build a vector of integrable objects to determine if the are
    // surface atoms
    Molecule* mol;
    StuntDouble* sd;
    SimInfo::MoleculeIterator i;
    Molecule::IntegrableObjectIterator  j;
    
    for (mol = info_->beginMolecule(i); mol != NULL; 
         mol = info_->nextMolecule(i)) {          
      for (sd = mol->beginIntegrableObject(j); 
           sd != NULL;
           sd = mol->nextIntegrableObject(j)) {	
	localSites_.push_back(sd);
      }
    }
    
    // We need to make an initial guess at the bounding box in order
    // to compute long range forces in ForceMatrixDecomposition:

    // Compute surface Mesh
    surfaceMesh_->computeHull(localSites_);
  }  
예제 #10
0
  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) );
    }
  }    
예제 #11
0
파일: SC.cpp 프로젝트: TomParsons/OpenMD
  void SC::addType(AtomType* atomType){

    SuttonChenAdapter sca = SuttonChenAdapter(atomType);
    SCAtomData scAtomData;
    
    scAtomData.c = sca.getC();
    scAtomData.m = sca.getM();
    scAtomData.n = sca.getN();
    scAtomData.alpha = sca.getAlpha();
    scAtomData.epsilon = sca.getEpsilon();
    scAtomData.rCut = 2.0 * scAtomData.alpha;
 
    // add it to the map:
    int atid = atomType->getIdent();
    int sctid = SCtypes.size();

    pair<set<int>::iterator,bool> ret;    
    ret = SCtypes.insert( atid );
    if (ret.second == false) {
      sprintf( painCave.errMsg,
               "SC already had a previous entry with ident %d\n",
               atid );
      painCave.severity = OPENMD_INFO;
      painCave.isFatal = 0;
      simError();         
    }
    
    SCtids[atid] = sctid;
    SCdata[sctid] = scAtomData;
    MixingMap[sctid].resize(nSC_);
    
    // Now, iterate over all known types and add to the mixing map:
    
    std::set<int>::iterator it;
    for( it = SCtypes.begin(); it != SCtypes.end(); ++it) {
      
      int sctid2 = SCtids[ (*it) ];
      AtomType* atype2 = forceField_->getAtomType( (*it) );
      
      SCInteractionData mixer;

      mixer.alpha = getAlpha(atomType, atype2);
      mixer.rCut = 2.0 * mixer.alpha;
      mixer.epsilon = getEpsilon(atomType, atype2);
      mixer.m = getM(atomType, atype2);
      mixer.n = getN(atomType, atype2);

      RealType dr = mixer.rCut / (np_ - 1);
      vector<RealType> rvals;
      vector<RealType> vvals;
      vector<RealType> phivals;
    
      rvals.push_back(0.0);
      vvals.push_back(0.0);
      phivals.push_back(0.0);

      for (int k = 1; k < np_; k++) {
        RealType r = dr * k;
        rvals.push_back(r);
        vvals.push_back( mixer.epsilon * pow(mixer.alpha/r, mixer.n) );
        phivals.push_back( pow(mixer.alpha/r, mixer.m) );
      }

      mixer.vCut = mixer.epsilon * pow(mixer.alpha/mixer.rCut, mixer.n);
    
      CubicSpline* V = new CubicSpline();
      V->addPoints(rvals, vvals);
      
      CubicSpline* phi = new CubicSpline();
      phi->addPoints(rvals, phivals);
      
      mixer.V = V;
      mixer.phi = phi;

      mixer.explicitlySet = false;

      MixingMap[sctid2].resize( nSC_ );
      
      MixingMap[sctid][sctid2] = mixer;
      if (sctid2 != sctid) {
        MixingMap[sctid2][sctid] = mixer;
      }
    }      
    return;
  }
  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;

    }
  }
예제 #13
0
  void InteractionManager::initialize() {

    if (initialized_) return; 

    ForceField* forceField_ = info_->getForceField();
    
    lj_->setForceField(forceField_);
    gb_->setForceField(forceField_);
    sticky_->setForceField(forceField_);
    eam_->setForceField(forceField_);
    sc_->setForceField(forceField_);
    morse_->setForceField(forceField_);
    electrostatic_->setSimInfo(info_);
    electrostatic_->setForceField(forceField_);
    maw_->setForceField(forceField_);
    repulsivePower_->setForceField(forceField_);

    ForceField::AtomTypeContainer* atomTypes = forceField_->getAtomTypes();
    int nTypes = atomTypes->size();
    sHash_.resize(nTypes);
    iHash_.resize(nTypes);
    interactions_.resize(nTypes);
    ForceField::AtomTypeContainer::MapTypeIterator i1, i2;
    AtomType* atype1;
    AtomType* atype2;
    int atid1, atid2;

    // We only need to worry about the types that are actually in the
    // simulation:
    
    set<AtomType*> atypes = info_->getSimulatedAtomTypes();

    lj_->setSimulatedAtomTypes(atypes);
    gb_->setSimulatedAtomTypes(atypes);
    sticky_->setSimulatedAtomTypes(atypes);
    eam_->setSimulatedAtomTypes(atypes);
    sc_->setSimulatedAtomTypes(atypes);
    morse_->setSimulatedAtomTypes(atypes);
    electrostatic_->setSimInfo(info_);
    electrostatic_->setSimulatedAtomTypes(atypes);
    maw_->setSimulatedAtomTypes(atypes);
    repulsivePower_->setSimulatedAtomTypes(atypes);

    set<AtomType*>::iterator at;

    for (at = atypes.begin(); at != atypes.end(); ++at) {

      atype1 = *at;
      atid1 = atype1->getIdent();
      iHash_[atid1].resize(nTypes);
      interactions_[atid1].resize(nTypes);

      // add it to the map:      
      pair<map<int,AtomType*>::iterator,bool> ret;    
      ret = typeMap_.insert( pair<int, AtomType*>(atid1, atype1) );
      if (ret.second == false) {
        sprintf( painCave.errMsg,
                 "InteractionManager already had a previous entry with ident %d\n",
                 atype1->getIdent());
        painCave.severity = OPENMD_INFO;
        painCave.isFatal = 0;
        simError();                 
      }
          
      if (atype1->isLennardJones()) {
        sHash_[atid1] |= LJ_INTERACTION;
      }
      if (atype1->isElectrostatic()) {
        sHash_[atid1] |= ELECTROSTATIC_INTERACTION;
      }
      if (atype1->isSticky()) {
        sHash_[atid1] |= STICKY_INTERACTION;
      }
      if (atype1->isStickyPower()) {
        sHash_[atid1] |= STICKY_INTERACTION;
      }
      if (atype1->isEAM()) {      
        sHash_[atid1] |= EAM_INTERACTION;
      }
      if (atype1->isSC()) {
        sHash_[atid1] |= SC_INTERACTION;
      }
      if (atype1->isGayBerne()) {
        sHash_[atid1] |= GB_INTERACTION;
      }
    }
    // Now, iterate over all known types and add to the interaction map:
    
    map<int, AtomType*>::iterator it1, it2;
    for (it1 = typeMap_.begin(); it1 != typeMap_.end(); ++it1) {
      atype1 = (*it1).second;
      atid1 = atype1->getIdent();

      for( it2 = typeMap_.begin(); it2 != typeMap_.end(); ++it2) {        
        atype2 = (*it2).second;
        atid2 = atype2->getIdent();
                               
        iHash_[atid1][atid2] = 0;
        
        if (atype1->isLennardJones() && atype2->isLennardJones()) {
          interactions_[atid1][atid2].insert(lj_);
          iHash_[atid1][atid2] |= LJ_INTERACTION;
        }
        if (atype1->isElectrostatic() && atype2->isElectrostatic() ) {
          interactions_[atid1][atid2].insert(electrostatic_);
          iHash_[atid1][atid2] |= ELECTROSTATIC_INTERACTION;
        }
        if (atype1->isSticky() && atype2->isSticky() ) {
          interactions_[atid1][atid2].insert(sticky_);
          iHash_[atid1][atid2] |= STICKY_INTERACTION;
        }
        if (atype1->isStickyPower() && atype2->isStickyPower() ) {
          interactions_[atid1][atid2].insert(sticky_);
          iHash_[atid1][atid2] |= STICKY_INTERACTION;
        }
        if (atype1->isEAM() && atype2->isEAM() ) {
          interactions_[atid1][atid2].insert(eam_);
          iHash_[atid1][atid2] |= EAM_INTERACTION;
        }
        if (atype1->isSC() && atype2->isSC() ) {
          interactions_[atid1][atid2].insert(sc_);
          iHash_[atid1][atid2] |= SC_INTERACTION;
        }
        if (atype1->isGayBerne() && atype2->isGayBerne() ) {
          interactions_[atid1][atid2].insert(gb_);
          iHash_[atid1][atid2] |= GB_INTERACTION;
        }
        if ((atype1->isGayBerne() && atype2->isLennardJones())
            || (atype1->isLennardJones() && atype2->isGayBerne())) {
          interactions_[atid1][atid2].insert(gb_);
          iHash_[atid1][atid2] |= GB_INTERACTION;
        } 
        
        // look for an explicitly-set non-bonded interaction type using the 
        // two atom types.
        NonBondedInteractionType* nbiType = forceField_->getNonBondedInteractionType(atype1->getName(), atype2->getName());
        
        if (nbiType != NULL) {

          bool vdwExplicit = false;
          bool metExplicit = false;
          // bool hbExplicit = false;

          if (nbiType->isLennardJones()) {
            // We found an explicit Lennard-Jones interaction.  
            // override all other vdw entries for this pair of atom types:
            set<NonBondedInteraction*>::iterator it;
            for (it = interactions_[atid1][atid2].begin(); 
                 it != interactions_[atid1][atid2].end(); ++it) {
              InteractionFamily ifam = (*it)->getFamily();
              if (ifam == VANDERWAALS_FAMILY) {
                interactions_[atid1][atid2].erase(*it);
                iHash_[atid1][atid2] ^= (*it)->getHash();
              }
            }
            interactions_[atid1][atid2].insert(lj_);
            iHash_[atid1][atid2] |= LJ_INTERACTION;
            LennardJonesInteractionType* ljit = dynamic_cast<LennardJonesInteractionType*>(nbiType);
            lj_->addExplicitInteraction(atype1, atype2, ljit->getSigma(),
                                        ljit->getEpsilon());
            vdwExplicit = true;
          }
          
          if (nbiType->isMorse()) {
            if (vdwExplicit) {
              sprintf( painCave.errMsg,
                       "InteractionManager::initialize found more than one "
                       "explicit \n"
                       "\tvan der Waals interaction for atom types %s - %s\n",
                       atype1->getName().c_str(), atype2->getName().c_str());
              painCave.severity = OPENMD_ERROR;
              painCave.isFatal = 1;
              simError();
            }
            // We found an explicit Morse interaction.  
            // override all other vdw entries for this pair of atom types:
            set<NonBondedInteraction*>::iterator it;
            for (it = interactions_[atid1][atid2].begin(); 
                 it != interactions_[atid1][atid2].end(); ++it) {
              InteractionFamily ifam = (*it)->getFamily();
              if (ifam == VANDERWAALS_FAMILY) {
                interactions_[atid1][atid2].erase(*it);
                iHash_[atid1][atid2] ^= (*it)->getHash();
              }
            }
            interactions_[atid1][atid2].insert(morse_);
            iHash_[atid1][atid2] |= MORSE_INTERACTION;
            MorseInteractionType* mit = dynamic_cast<MorseInteractionType*>(nbiType);
            morse_->addExplicitInteraction(atype1, atype2, mit->getD(),
                                           mit->getR(), mit->getBeta(),
                                           mit->getInteractionType());
            vdwExplicit = true;
          }

          if (nbiType->isRepulsivePower()) {
            if (vdwExplicit) {
              sprintf( painCave.errMsg,
                       "InteractionManager::initialize found more than one "
                       "explicit \n"
                       "\tvan der Waals interaction for atom types %s - %s\n",
                       atype1->getName().c_str(), atype2->getName().c_str());
              painCave.severity = OPENMD_ERROR;
              painCave.isFatal = 1;
              simError();
            }
            // We found an explicit RepulsivePower interaction.  
            // override all other vdw entries for this pair of atom types:
            set<NonBondedInteraction*>::iterator it;
            for (it = interactions_[atid1][atid2].begin(); 
                 it != interactions_[atid1][atid2].end(); ++it) {
              InteractionFamily ifam = (*it)->getFamily();
              if (ifam == VANDERWAALS_FAMILY) {
                interactions_[atid1][atid2].erase(*it);
                iHash_[atid1][atid2] ^= (*it)->getHash();
              }
            }
            interactions_[atid1][atid2].insert(repulsivePower_);
            iHash_[atid1][atid2] |= REPULSIVEPOWER_INTERACTION;
            RepulsivePowerInteractionType* rpit = dynamic_cast<RepulsivePowerInteractionType*>(nbiType);
            
            repulsivePower_->addExplicitInteraction(atype1, atype2,
                                                    rpit->getSigma(),
                                                    rpit->getEpsilon(),
                                                    rpit->getNrep());

            vdwExplicit = true;
          }
          
          
          if (nbiType->isEAM()) {
            // We found an explicit EAM interaction.  
            // override all other metallic entries for this pair of atom types:
            set<NonBondedInteraction*>::iterator it;
            for (it = interactions_[atid1][atid2].begin(); 
                 it != interactions_[atid1][atid2].end(); ++it) {
              InteractionFamily ifam = (*it)->getFamily();
              if (ifam == METALLIC_FAMILY) {
                interactions_[atid1][atid2].erase(*it);
                iHash_[atid1][atid2] ^= (*it)->getHash();
              }
            }
            interactions_[atid1][atid2].insert(eam_);
            iHash_[atid1][atid2] |= EAM_INTERACTION;
            metExplicit = true;
          }
          
          if (nbiType->isSC()) {
            if (metExplicit) {
              sprintf( painCave.errMsg,
                       "InteractionManager::initialize found more than one "
                       "explicit\n"
                       "\tmetallic interaction for atom types %s - %s\n",
                       atype1->getName().c_str(), atype2->getName().c_str());
              painCave.severity = OPENMD_ERROR;
              painCave.isFatal = 1;
              simError();
            }
            // We found an explicit Sutton-Chen interaction.  
            // override all other metallic entries for this pair of atom types:
            set<NonBondedInteraction*>::iterator it;
            for (it = interactions_[atid1][atid2].begin(); 
                 it != interactions_[atid1][atid2].end(); ++it) {
              InteractionFamily ifam = (*it)->getFamily();
              if (ifam == METALLIC_FAMILY) {
                interactions_[atid1][atid2].erase(*it);
                iHash_[atid1][atid2] ^= (*it)->getHash();
              }
            }
            interactions_[atid1][atid2].insert(sc_);
            iHash_[atid1][atid2] |= SC_INTERACTION;
            metExplicit = true;
          }
          
          if (nbiType->isMAW()) {
            if (vdwExplicit) {
              sprintf( painCave.errMsg,
                       "InteractionManager::initialize found more than one "
                       "explicit\n"
                       "\tvan der Waals interaction for atom types %s - %s\n",
                       atype1->getName().c_str(), atype2->getName().c_str());
              painCave.severity = OPENMD_ERROR;
              painCave.isFatal = 1;
              simError();
            }
            // We found an explicit MAW interaction.  
            // override all other vdw entries for this pair of atom types:
            set<NonBondedInteraction*>::iterator it;
            for (it = interactions_[atid1][atid2].begin(); 
                 it != interactions_[atid1][atid2].end(); ++it) {
              InteractionFamily ifam = (*it)->getFamily();
              if (ifam == VANDERWAALS_FAMILY) {
                interactions_[atid1][atid2].erase(*it);
                iHash_[atid1][atid2] ^= (*it)->getHash();
              }
            }
            interactions_[atid1][atid2].insert(maw_);
            iHash_[atid1][atid2] |= MAW_INTERACTION;
            MAWInteractionType* mit = dynamic_cast<MAWInteractionType*>(nbiType);
            maw_->addExplicitInteraction(atype1, atype2, mit->getD(),
                                         mit->getBeta(), mit->getR(),
                                         mit->getCA1(), mit->getCB1());
            vdwExplicit = true;
          }        
        }
      }
    }
    
    
    // Make sure every pair of atom types in this simulation has a
    // non-bonded interaction.  If not, just inform the user.

    set<AtomType*> simTypes = info_->getSimulatedAtomTypes();
    set<AtomType*>::iterator it, jt;

    for (it = simTypes.begin(); it != simTypes.end(); ++it) {
      atype1 = (*it);
      atid1 = atype1->getIdent();
      for (jt = it; jt != simTypes.end(); ++jt) {
        atype2 = (*jt);
        atid2 = atype2->getIdent();
        
        if (interactions_[atid1][atid2].size() == 0) {
          sprintf( painCave.errMsg,
                   "InteractionManager could not find a matching non-bonded\n"
                   "\tinteraction for atom types %s - %s\n"
                   "\tProceeding without this interaction.\n",
                   atype1->getName().c_str(), atype2->getName().c_str());
          painCave.severity = OPENMD_INFO;
          painCave.isFatal = 0;
          simError();
        }
      }
    }

    initialized_ = true;
  }
예제 #14
0
  void SwitchingFunction::setSwitch(RealType rinner, RealType router) {
    if (router < rinner) {
          sprintf( painCave.errMsg,
                   "SwitchingFunction::setSwitch was given rinner (%lf) which was\n" 
                   "\tlarger than router (%lf).\n", rinner, router);
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError();          
    }
    if (router < 0.0) {
          sprintf( painCave.errMsg,
                   "SwitchingFunction::setSwitch was given router (%lf) which was\n" 
                   "\tless than zero.\n", router);
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError();           
    }   
    if (rinner < 0.0) {
          sprintf( painCave.errMsg,
                   "SwitchingFunction::setSwitch was given rinner (%lf) which was\n"
                   "\tless than zero.\n", router);
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError();           
    }

    rin_ = rinner;
    rout_ = router;
    rin2_ = rin_ * rin_;
    rout2_ = rout_ * rout_;

    if ((router - rinner) < 1.0e-8) {
      // no reason to set up spline if the switching region is tiny
      return;
    }
    
    // setup r -> sw lookup spline
    if (functionType_ == fifth_order_poly) {
      isCubic_ = false;
      RealType c0 = 1.0;
      RealType c3 = -10.0;
      RealType c4 = 15.0;
      RealType c5 = -6.0;
 
      RealType dx, r, yval, rval, rval2, rval3, rval4, rval5;
      RealType rvaldi, rvaldi2, rvaldi3, rvaldi4, rvaldi5;

      dx = (rout_ - rin_) / RealType(np_-1);

      for (int i = 0; i < np_; i++) {
        r = rin_ + RealType(i)*dx;
        rval = ( r - rin_ );
        rval2 = rval*rval;
        rval3 = rval2*rval;
        rval4 = rval2*rval2;
        rval5 = rval3*rval2;
        rvaldi = 1.0 / ( rout_ - rin_ );
        rvaldi2 = rvaldi*rvaldi;
        rvaldi3 = rvaldi2*rvaldi;
        rvaldi4 = rvaldi2*rvaldi2;
        rvaldi5 = rvaldi3*rvaldi2;
        yval= c0 + c3*rval3*rvaldi3 + c4*rval4*rvaldi4 + c5*rval5*rvaldi5;
        switchSpline_->addPoint(r, yval);
      } 
    } else {
      // cubic splines only need 2 points to do a cubic switching function...
      isCubic_ = true;
      switchSpline_->addPoint(rin_, 1.0);
      switchSpline_->addPoint(rout_, 0.0);
    }
    haveSpline_ = true;
    return;
  }
예제 #15
0
  void TetrahedralityParam::writeOrderParameter() {
    
    int nSelected = 0;

    for (int i = 0; i < nBins_; ++i) {
      nSelected = nSelected + int(Q_histogram_[i]*deltaQ_);
    }
    
    std::ofstream osq((getOutputFileName() + "Q").c_str());

    if (osq.is_open()) {
      
      osq << "# Tetrahedrality Parameters\n";
      osq << "# selection: (" << selectionScript_ << ")\n";
      osq << "# \n";
      // Normalize by number of frames and write it out:
      for (int i = 0; i < nBins_; ++i) {
        RealType Qval = MinQ_ + (i + 0.5) * deltaQ_;               
        osq << Qval;
	osq << "\t" << (RealType) (Q_histogram_[i]/deltaQ_)/nSelected;        
        osq << "\n";
      }

      osq.close();
      
    }else {
      sprintf(painCave.errMsg, "TetrahedralityParam: unable to open %s\n", 
              (getOutputFileName() + "q").c_str());
      painCave.isFatal = 1;
      simError();  
    }

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

    if (nFrames == 1) {

      std::vector<StuntDouble*>::iterator iter;
      std::ofstream osd((getOutputFileName() + "dxyz").c_str());

      if (osd.is_open()) {

	osd << Distorted_.size() << "\n";
	osd << "\n";
      
	for (iter = Distorted_.begin(); iter != Distorted_.end(); ++iter) {
	  Vector3d position;
	  position = (*iter)->getPos();
	  osd << "O  " << "\t";
	  for (unsigned int z = 0; z < position.size(); z++) {
	    osd << position[z] << "  " << "\t";
	  }
	  osd << "\n";
	}
	osd.close();
      }


      std::ofstream ost((getOutputFileName() + "txyz").c_str());
    
      if (ost.is_open()) {

	ost << Tetrahedral_.size() << "\n";
	ost << "\n";
      
	for (iter = Tetrahedral_.begin(); iter != Tetrahedral_.end(); ++iter) {
	  Vector3d position;
	  position = (*iter)->getPos();

	  ost << "O  " << "\t";

	  for (unsigned int z = 0; z < position.size(); z++) {
	    ost << position[z] << "  " << "\t";
	  }
	  ost << "\n";
	}
	ost.close();
      }
    }
  }
예제 #16
0
  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();
        

  
  }
예제 #17
0
파일: EAM.cpp 프로젝트: Patrick-Louden/2.2
  void EAM::initialize() { 
    // set up the mixing method:
    ForceFieldOptions& fopts = forceField_->getForceFieldOptions();
    string EAMMixMeth = fopts.getEAMMixingMethod();
    toUpper(EAMMixMeth);
   
    if (EAMMixMeth == "JOHNSON") 
      mixMeth_ = eamJohnson;    
    else if (EAMMixMeth == "DAW")
      mixMeth_ = eamDaw;
    else
      mixMeth_ = eamUnknown;
      
    // find all of the EAM atom Types:
    EAMtypes.clear();
    EAMtids.clear();
    EAMdata.clear();
    MixingMap.clear();
    nEAM_ = 0;
    
    EAMtids.resize( forceField_->getNAtomType(), -1);

    set<AtomType*>::iterator at;
    for (at = simTypes_.begin(); at != simTypes_.end(); ++at) {
      if ((*at)->isEAM()) nEAM_++;
    }
    EAMdata.resize(nEAM_);
    MixingMap.resize(nEAM_);

    for (at = simTypes_.begin(); at != simTypes_.end(); ++at) {
      if ((*at)->isEAM()) addType(*at);
    }
    
    // find all of the explicit EAM interactions (setfl):
    ForceField::NonBondedInteractionTypeContainer* nbiTypes = forceField_->getNonBondedInteractionTypes();
    ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
    NonBondedInteractionType* nbt;

    for (nbt = nbiTypes->beginType(j); nbt != NULL; 
         nbt = nbiTypes->nextType(j)) {
      
      if (nbt->isEAM()) {
        
        pair<AtomType*, AtomType*> atypes = nbt->getAtomTypes();
        
        GenericData* data = nbt->getPropertyByName("EAM");
        if (data == NULL) {
          sprintf( painCave.errMsg, "EAM::rebuildMixingMap could not find\n"
                   "\tEAM parameters for %s - %s interaction.\n", 
                   atypes.first->getName().c_str(),
                   atypes.second->getName().c_str());
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError(); 
        }
        
        EAMMixingData* eamData = dynamic_cast<EAMMixingData*>(data);
        if (eamData == NULL) {
          sprintf( painCave.errMsg,
                   "EAM::rebuildMixingMap could not convert GenericData to\n"
                   "\tEAMMixingData for %s - %s interaction.\n", 
                   atypes.first->getName().c_str(),
                   atypes.second->getName().c_str());
          painCave.severity = OPENMD_ERROR;
          painCave.isFatal = 1;
          simError();          
        }
        
        EAMMixingParam eamParam = eamData->getData();

        vector<RealType> phiAB = eamParam.phi;
        RealType dr = eamParam.dr;
        int nr = eamParam.nr;

        addExplicitInteraction(atypes.first, atypes.second, dr, nr, phiAB);
      }
    }  
    initialized_ = true;
  }
예제 #18
0
파일: EAM.cpp 프로젝트: Patrick-Louden/2.2
  void EAM::calcForce(InteractionData &idat) {

    if (!initialized_) initialize();

    if (haveCutoffRadius_) 
      if ( *(idat.rij) > eamRcut_) return;
   

    int eamtid1 = EAMtids[idat.atid1];
    int eamtid2 = EAMtids[idat.atid2];
    
    EAMAtomData &data1 = EAMdata[eamtid1];
    EAMAtomData &data2 = EAMdata[eamtid2];
    
    // get type-specific cutoff radii
    
    RealType rci = data1.rcut;
    RealType rcj = data2.rcut;
    
    RealType rha(0.0), drha(0.0), rhb(0.0), drhb(0.0);
    RealType pha(0.0), dpha(0.0), phb(0.0), dphb(0.0);
    RealType phab(0.0), dvpdr(0.0);
    RealType drhoidr, drhojdr, dudr;
    
    if ( *(idat.rij) < rci) {
      data1.rho->getValueAndDerivativeAt( *(idat.rij), rha, drha);
      CubicSpline* phi = MixingMap[eamtid1][eamtid1].phi;
      phi->getValueAndDerivativeAt( *(idat.rij), pha, dpha);
    }
    
    if ( *(idat.rij) < rcj) {
      data2.rho->getValueAndDerivativeAt( *(idat.rij), rhb, drhb );
      CubicSpline* phi = MixingMap[eamtid2][eamtid2].phi;
      phi->getValueAndDerivativeAt( *(idat.rij), phb, dphb);
    }

    switch(mixMeth_) {
    case eamJohnson:
      
      if ( *(idat.rij) < rci) {
        phab = phab + 0.5 * (rhb / rha) * pha;
        dvpdr = dvpdr + 0.5*((rhb/rha)*dpha + 
                             pha*((drhb/rha) - (rhb*drha/rha/rha)));
      }
      
      
      
      if ( *(idat.rij) < rcj) {
        phab = phab + 0.5 * (rha / rhb) * phb;
        dvpdr = dvpdr + 0.5 * ((rha/rhb)*dphb + 
                               phb*((drha/rhb) - (rha*drhb/rhb/rhb)));
      }
      
      break;
      
    case eamDaw:
      
      if ( *(idat.rij) <  MixingMap[eamtid1][eamtid2].rcut) {
        MixingMap[eamtid1][eamtid2].phi->getValueAndDerivativeAt( *(idat.rij), 
                                                                  phab, dvpdr);
      }
      
      break;
    case eamUnknown:
    default:
      
      sprintf(painCave.errMsg,
              "EAM::calcForce hit a mixing method it doesn't know about!\n"
              );
      painCave.severity = OPENMD_ERROR;
      painCave.isFatal = 1;
      simError();        
      
    }
    
    drhoidr = drha;
    drhojdr = drhb;
    
    dudr = drhojdr* *(idat.dfrho1) + drhoidr* *(idat.dfrho2) + dvpdr; 
    
    *(idat.f1) += *(idat.d) * dudr / *(idat.rij);

        
    if (idat.doParticlePot) {
      // particlePot is the difference between the full potential and
      // the full potential without the presence of a particular
      // particle (atom1).
      //
      // This reduces the density at other particle locations, so we
      // need to recompute the density at atom2 assuming atom1 didn't
      // contribute.  This then requires recomputing the density
      // functional for atom2 as well.
      
      *(idat.particlePot1) += data2.F->getValueAt( *(idat.rho2) - rha ) 
        - *(idat.frho2);
      
      *(idat.particlePot2) += data1.F->getValueAt( *(idat.rho1) - rhb) 
        - *(idat.frho1);
    }
    
    (*(idat.pot))[METALLIC_FAMILY] += phab;
    
    *(idat.vpair) += phab;
  
    return;
    
  }
예제 #19
0
  void ElementsTable::Init() {
    if (init_)
      return;
    init_ = true;
    
    std::string buffer, subbuffer;
    ifstrstream ifs1, ifs2, ifs3, ifs4, *ifsP;
    // First, look for an environment variable
    if (getenv(envvar_.c_str()) != NULL) {
      buffer = getenv(envvar_.c_str());
      buffer += FILE_SEP_CHAR;
      



      if (!subdir_.empty()) {
        subbuffer = buffer;
        subbuffer += subdir_;
        subbuffer += FILE_SEP_CHAR;
      }
      

      
      buffer += filename_;
      subbuffer += filename_;

      
      ifs1.open(subbuffer.c_str());
      ifsP= &ifs1;
      if (!(ifsP->is_open())) {
        ifs2.open(buffer.c_str());
        ifsP = &ifs2;
      }
      
    } else {
      sprintf( painCave.errMsg,
               "ElementsTable error.\n"
               "\tunable to open datafile %s \n", filename_.c_str());
      painCave.isFatal = 0;
      simError();
    }
      

    if ((*ifsP)) {
      char charBuffer[BUFF_SIZE];
      while(ifsP->getline(charBuffer,BUFF_SIZE))
        ParseLine(charBuffer);
      
      if (ifs1)
	ifs1.close();
      if (ifs2)
	ifs2.close();
      if (ifs3)
	ifs3.close();
      if (ifs4)
	ifs4.close();
      
      if (GetSize() == 0) {
	sprintf( painCave.errMsg,
		 "ElementsTable error.\n"
		 "\tCannot initialize database %s \n", filename_.c_str());
	painCave.isFatal = 0;
	simError();
      }
    
    }
  
  }
예제 #20
0
void P2OrderParameter::process() {
    Molecule* mol;
    RigidBody* rb;
    SimInfo::MoleculeIterator mi;
    Molecule::RigidBodyIterator rbIter;
    StuntDouble* sd1;
    StuntDouble* sd2;
    int ii;
    int jj;
    int vecCount;
    bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions();

    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();
            }
        }

        Mat3x3d orderTensor(0.0);
        vecCount = 0;

        seleMan1_.setSelectionSet(evaluator1_.evaluate());

        if (doVect_) {

            for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
                    sd1 = seleMan1_.nextSelected(ii)) {
                if (sd1->isDirectional()) {
                    Vector3d vec = sd1->getA().transpose()*V3Z;

                    vec.normalize();
                    orderTensor += outProduct(vec, vec);
                    vecCount++;
                }
            }

            orderTensor /= vecCount;

        } else {

            if (doOffset_) {

                for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
                        sd1 = seleMan1_.nextSelected(ii)) {

                    // This will require careful rewriting if StaticProps is
                    // ever parallelized.  For an example, see
                    // Thermo::getTaggedAtomPairDistance

                    int sd2Index = sd1->getGlobalIndex() + seleOffset_;
                    sd2 = info_->getIOIndexToIntegrableObject(sd2Index);

                    Vector3d vec = sd1->getPos() - sd2->getPos();

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

                    vec.normalize();

                    orderTensor +=outProduct(vec, vec);
                    vecCount++;
                }

                orderTensor /= vecCount;
            } else {

                seleMan2_.setSelectionSet(evaluator2_.evaluate());

                if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount() ) {
                    sprintf( painCave.errMsg,
                             "In frame %d, the number of selected StuntDoubles are\n"
                             "\tnot the same in --sele1 and sele2\n", i);
                    painCave.severity = OPENMD_INFO;
                    painCave.isFatal = 0;
                    simError();
                }

                for (sd1 = seleMan1_.beginSelected(ii),
                        sd2 = seleMan2_.beginSelected(jj);
                        sd1 != NULL && sd2 != NULL;
                        sd1 = seleMan1_.nextSelected(ii),
                        sd2 = seleMan2_.nextSelected(jj)) {

                    Vector3d vec = sd1->getPos() - sd2->getPos();

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

                    vec.normalize();

                    orderTensor +=outProduct(vec, vec);
                    vecCount++;
                }

                orderTensor /= vecCount;
            }
        }

        if (vecCount == 0) {
            sprintf( painCave.errMsg,
                     "In frame %d, the number of selected vectors was zero.\n"
                     "\tThis will not give a meaningful order parameter.", i);
            painCave.severity = OPENMD_ERROR;
            painCave.isFatal = 1;
            simError();
        }

        orderTensor -= (RealType)(1.0/3.0) * Mat3x3d::identity();

        Vector3d eigenvalues;
        Mat3x3d eigenvectors;

        Mat3x3d::diagonalize(orderTensor, eigenvalues, eigenvectors);

        int which(-1);
        RealType maxEval = 0.0;
        for(int k = 0; k< 3; k++) {
            if(fabs(eigenvalues[k]) > maxEval) {
                which = k;
                maxEval = fabs(eigenvalues[k]);
            }
        }
        RealType p2 = 1.5 * maxEval;

        //the eigen vector is already normalized in SquareMatrix3::diagonalize
        Vector3d director = eigenvectors.getColumn(which);
        if (director[0] < 0) {
            director.negate();
        }

        RealType angle = 0.0;
        vecCount = 0;

        if (doVect_) {
            for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
                    sd1 = seleMan1_.nextSelected(ii)) {
                if (sd1->isDirectional()) {
                    Vector3d vec = sd1->getA().transpose()*V3Z;
                    vec.normalize();
                    angle += acos(dot(vec, director));
                    vecCount++;
                }
            }
            angle = angle/(vecCount*NumericConstant::PI)*180.0;

        } else {
            if (doOffset_) {

                for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
                        sd1 = seleMan1_.nextSelected(ii)) {

                    // This will require careful rewriting if StaticProps is
                    // ever parallelized.  For an example, see
                    // Thermo::getTaggedAtomPairDistance

                    int sd2Index = sd1->getGlobalIndex() + seleOffset_;
                    sd2 = info_->getIOIndexToIntegrableObject(sd2Index);

                    Vector3d vec = sd1->getPos() - sd2->getPos();
                    if (usePeriodicBoundaryConditions_)
                        currentSnapshot_->wrapVector(vec);
                    vec.normalize();
                    angle += acos(dot(vec, director)) ;
                    vecCount++;
                }
                angle = angle / (vecCount * NumericConstant::PI) * 180.0;

            } else {

                for (sd1 = seleMan1_.beginSelected(ii),
                        sd2 = seleMan2_.beginSelected(jj);
                        sd1 != NULL && sd2 != NULL;
                        sd1 = seleMan1_.nextSelected(ii),
                        sd2 = seleMan2_.nextSelected(jj)) {

                    Vector3d vec = sd1->getPos() - sd2->getPos();
                    if (usePeriodicBoundaryConditions_)
                        currentSnapshot_->wrapVector(vec);
                    vec.normalize();
                    angle += acos(dot(vec, director)) ;
                    vecCount++;
                }
                angle = angle / (vecCount * NumericConstant::PI) * 180.0;
            }
        }

        OrderParam param;
        param.p2 = p2;
        param.director = director;
        param.angle = angle;

        orderParams_.push_back(param);

    }

    writeP2();

}
예제 #21
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;
  }