ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/rnemd/RNEMD.cpp
(Generate patch)

Comparing trunk/src/rnemd/RNEMD.cpp (file contents):
Revision 1879 by gezelter, Sun Jun 16 15:15:42 2013 UTC vs.
Revision 1940 by gezelter, Fri Nov 1 19:31:41 2013 UTC

# Line 38 | Line 38
38   * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).          
39   * [4]  Vardeman & Gezelter, in progress (2009).                        
40   */
41 + #ifdef IS_MPI
42 + #include <mpi.h>
43 + #endif
44  
45   #include <cmath>
46   #include <sstream>
# Line 54 | Line 57
57   #include "utils/Tuple.hpp"
58   #include "brains/Thermo.hpp"
59   #include "math/ConvexHull.hpp"
57 #ifdef IS_MPI
58 #include <mpi.h>
59 #endif
60  
61   #ifdef _MSC_VER
62   #define isnan(x) _isnan((x))
# Line 424 | Line 424 | namespace OpenMD {
424        OutputData angularVelocity;
425        angularVelocity.units = "angstroms^2/fs";
426        angularVelocity.title =  "AngularVelocity";  
427 <      angularVelocity.dataType = "Vector3d";
427 >      angularVelocity.dataType = "RealType";
428        angularVelocity.accumulator.reserve(nBins_);
429        for (int i = 0; i < nBins_; i++)
430 <        angularVelocity.accumulator.push_back( new VectorAccumulator() );
430 >        angularVelocity.accumulator.push_back( new Accumulator() );
431        data_[ANGULARVELOCITY] = angularVelocity;
432        outputMap_["ANGULARVELOCITY"] = ANGULARVELOCITY;
433  
# Line 547 | Line 547 | namespace OpenMD {
547      
548        if (hasSelectionB_) {
549          selectionB_ = rnemdParams->getSelectionB();
550 +
551        } else {
552          if (usePeriodicBoundaryConditions_) {    
553            Mat3x3d hmat = currentSnap_->getHmat();
# Line 573 | Line 574 | namespace OpenMD {
574              selectionB_ = selectionBstream.str();
575            } else {
576              selectionB_ = "select hull";
577 +            BisHull_ = true;
578              hasSelectionB_ = true;
579            }
580          }
# Line 1729 | Line 1731 | namespace OpenMD {
1731      Snapshot* snap = info_->getSnapshotManager()->getCurrentSnapshot();
1732  
1733      if (hasSelectionA_) {
1734 <      int isd;
1735 <      StuntDouble* sd;
1736 <      vector<StuntDouble*> aSites;
1737 <      seleManA_.setSelectionSet(evaluatorA_.evaluate());
1738 <      for (sd = seleManA_.beginSelected(isd); sd != NULL;
1739 <           sd = seleManA_.nextSelected(isd)) {
1740 <        aSites.push_back(sd);
1741 <      }
1742 < #if defined(HAVE_QHULL)
1743 <      ConvexHull* surfaceMeshA = new ConvexHull();
1744 <      surfaceMeshA->computeHull(aSites);
1745 <      areaA = surfaceMeshA->getArea();
1746 <      delete surfaceMeshA;
1747 < #else
1748 <      sprintf( painCave.errMsg,
1749 <               "RNEMD::getDividingArea : Hull calculation is not possible\n"
1750 <               "\twithout libqhull. Please rebuild OpenMD with qhull enabled.");
1751 <      painCave.severity = OPENMD_ERROR;
1752 <      painCave.isFatal = 1;
1753 <      simError();
1734 >
1735 >      if (evaluatorA_.hasSurfaceArea())
1736 >        areaA = evaluatorA_.getSurfaceArea();
1737 >      else {
1738 >        
1739 >        cerr << "selection A did not have surface area, recomputing\n";
1740 >        int isd;
1741 >        StuntDouble* sd;
1742 >        vector<StuntDouble*> aSites;
1743 >        seleManA_.setSelectionSet(evaluatorA_.evaluate());
1744 >        for (sd = seleManA_.beginSelected(isd); sd != NULL;
1745 >             sd = seleManA_.nextSelected(isd)) {
1746 >          aSites.push_back(sd);
1747 >        }
1748 > #if defined(HAVE_QHULL)
1749 >        ConvexHull* surfaceMeshA = new ConvexHull();
1750 >        surfaceMeshA->computeHull(aSites);
1751 >        areaA = surfaceMeshA->getArea();
1752 >        delete surfaceMeshA;
1753 > #else
1754 >        sprintf( painCave.errMsg,
1755 >               "RNEMD::getDividingArea : Hull calculation is not possible\n"
1756 >                 "\twithout libqhull. Please rebuild OpenMD with qhull enabled.");
1757 >        painCave.severity = OPENMD_ERROR;
1758 >        painCave.isFatal = 1;
1759 >        simError();
1760   #endif
1761 +      }
1762  
1763      } else {
1764        if (usePeriodicBoundaryConditions_) {
# Line 1765 | Line 1774 | namespace OpenMD {
1774      }
1775  
1776      if (hasSelectionB_) {
1777 <      int isd;
1778 <      StuntDouble* sd;
1779 <      vector<StuntDouble*> bSites;
1780 <      seleManB_.setSelectionSet(evaluatorB_.evaluate());
1772 <      for (sd = seleManB_.beginSelected(isd); sd != NULL;
1773 <           sd = seleManB_.nextSelected(isd)) {
1774 <        bSites.push_back(sd);
1775 <      }
1777 >      if (evaluatorB_.hasSurfaceArea())
1778 >        areaB = evaluatorB_.getSurfaceArea();
1779 >      else {
1780 >        cerr << "selection B did not have surface area, recomputing\n";
1781  
1782 < #if defined(HAVE_QHULL)
1783 <      ConvexHull* surfaceMeshB = new ConvexHull();    
1784 <      surfaceMeshB->computeHull(bSites);
1785 <      areaB = surfaceMeshB->getArea();
1786 <      delete surfaceMeshB;
1782 >        int isd;
1783 >        StuntDouble* sd;
1784 >        vector<StuntDouble*> bSites;
1785 >        seleManB_.setSelectionSet(evaluatorB_.evaluate());
1786 >        for (sd = seleManB_.beginSelected(isd); sd != NULL;
1787 >             sd = seleManB_.nextSelected(isd)) {
1788 >          bSites.push_back(sd);
1789 >        }
1790 >        
1791 > #if defined(HAVE_QHULL)
1792 >        ConvexHull* surfaceMeshB = new ConvexHull();    
1793 >        surfaceMeshB->computeHull(bSites);
1794 >        areaB = surfaceMeshB->getArea();
1795 >        delete surfaceMeshB;
1796   #else
1797 <      sprintf( painCave.errMsg,
1798 <               "RNEMD::getDividingArea : Hull calculation is not possible\n"
1799 <               "\twithout libqhull. Please rebuild OpenMD with qhull enabled.");
1800 <      painCave.severity = OPENMD_ERROR;
1801 <      painCave.isFatal = 1;
1802 <      simError();
1797 >        sprintf( painCave.errMsg,
1798 >                 "RNEMD::getDividingArea : Hull calculation is not possible\n"
1799 >                 "\twithout libqhull. Please rebuild OpenMD with qhull enabled.");
1800 >        painCave.severity = OPENMD_ERROR;
1801 >        painCave.isFatal = 1;
1802 >        simError();
1803   #endif
1804 <
1805 <
1804 >      }
1805 >      
1806      } else {
1807        if (usePeriodicBoundaryConditions_) {
1808          // in periodic boundaries, the surface area is twice the x-y
# Line 1800 | Line 1814 | namespace OpenMD {
1814          areaB = 4.0 * M_PI * pow(sphereBRadius_, 2);
1815        }
1816      }
1817 <    
1817 >      
1818      dividingArea_ = min(areaA, areaB);
1819      hasDividingArea_ = true;
1820      return dividingArea_;
# Line 1860 | Line 1874 | namespace OpenMD {
1874      RealType area = getDividingArea();
1875      areaAccumulator_->add(area);
1876      Mat3x3d hmat = currentSnap_->getHmat();
1877 +    Vector3d u = angularMomentumFluxVector_;
1878 +    u.normalize();
1879 +
1880      seleMan_.setSelectionSet(evaluator_.evaluate());
1881  
1882      int selei(0);
# Line 1870 | Line 1887 | namespace OpenMD {
1887      vector<RealType> binPx(nBins_, 0.0);
1888      vector<RealType> binPy(nBins_, 0.0);
1889      vector<RealType> binPz(nBins_, 0.0);
1890 <    vector<RealType> binOmegax(nBins_, 0.0);
1874 <    vector<RealType> binOmegay(nBins_, 0.0);
1875 <    vector<RealType> binOmegaz(nBins_, 0.0);
1890 >    vector<RealType> binOmega(nBins_, 0.0);
1891      vector<RealType> binKE(nBins_, 0.0);
1892      vector<int> binDOF(nBins_, 0);
1893      vector<int> binCount(nBins_, 0);
# Line 1912 | Line 1927 | namespace OpenMD {
1927          binNo = int(rPos.length() / binWidth_);
1928        }
1929  
1930 +
1931        RealType mass = sd->getMass();
1932        Vector3d vel = sd->getVel();
1933        Vector3d rPos = sd->getPos() - coordinateOrigin_;
1934 <      Vector3d aVel = cross(rPos, vel);
1934 >      // Project the relative position onto a plane perpendicular to
1935 >      // the angularMomentumFluxVector:
1936 >      Vector3d rProj = rPos - dot(rPos, u) * u;
1937 >      // Project the velocity onto a plane perpendicular to the
1938 >      // angularMomentumFluxVector:
1939 >      Vector3d vProj = vel  - dot(vel, u) * u;
1940 >      // Compute angular velocity vector (should be nearly parallel to
1941 >      // angularMomentumFluxVector
1942 >      Vector3d aVel = cross(rProj, vProj);
1943        
1944        if (binNo >= 0 && binNo < nBins_)  {
1945          binCount[binNo]++;
# Line 1923 | Line 1947 | namespace OpenMD {
1947          binPx[binNo] += mass*vel.x();
1948          binPy[binNo] += mass*vel.y();
1949          binPz[binNo] += mass*vel.z();
1950 <        binOmegax[binNo] += aVel.x();
1927 <        binOmegay[binNo] += aVel.y();
1928 <        binOmegaz[binNo] += aVel.z();
1950 >        binOmega[binNo] += dot(aVel, u);
1951          binKE[binNo] += 0.5 * (mass * vel.lengthSquare());
1952          binDOF[binNo] += 3;
1953          
# Line 1960 | Line 1982 | namespace OpenMD {
1982                                nBins_, MPI::REALTYPE, MPI::SUM);
1983      MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &binPz[0],
1984                                nBins_, MPI::REALTYPE, MPI::SUM);
1985 <    MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &binOmegax[0],
1964 <                              nBins_, MPI::REALTYPE, MPI::SUM);
1965 <    MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &binOmegay[0],
1966 <                              nBins_, MPI::REALTYPE, MPI::SUM);
1967 <    MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &binOmegaz[0],
1985 >    MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &binOmega[0],
1986                                nBins_, MPI::REALTYPE, MPI::SUM);
1987      MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &binKE[0],
1988                                nBins_, MPI::REALTYPE, MPI::SUM);
# Line 1973 | Line 1991 | namespace OpenMD {
1991   #endif
1992  
1993      Vector3d vel;
1994 <    Vector3d aVel;
1994 >    RealType omega;
1995      RealType den;
1996      RealType temp;
1997      RealType z;
# Line 1993 | Line 2011 | namespace OpenMD {
2011        vel.x() = binPx[i] / binMass[i];
2012        vel.y() = binPy[i] / binMass[i];
2013        vel.z() = binPz[i] / binMass[i];
2014 <      aVel.x() = binOmegax[i] / binCount[i];
1997 <      aVel.y() = binOmegay[i] / binCount[i];
1998 <      aVel.z() = binOmegaz[i] / binCount[i];
2014 >      omega = binOmega[i] / binCount[i];
2015  
2016        if (binCount[i] > 0) {
2017          // only add values if there are things to add
# Line 2018 | Line 2034 | namespace OpenMD {
2034                dynamic_cast<VectorAccumulator *>(data_[j].accumulator[i])->add(vel);
2035                break;
2036              case ANGULARVELOCITY:  
2037 <              dynamic_cast<VectorAccumulator *>(data_[j].accumulator[i])->add(aVel);
2037 >              dynamic_cast<Accumulator *>(data_[j].accumulator[i])->add(omega);
2038                break;
2039              case DENSITY:
2040                dynamic_cast<Accumulator *>(data_[j].accumulator[i])->add(den);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines