ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/NitrileFrequencyMap.cpp
Revision: 1994
Committed: Wed Apr 30 18:50:45 2014 UTC (11 years ago) by gezelter
File size: 9528 byte(s)
Log Message:
Added NitrileFrequencyMap module to staticProps

File Contents

# User Rev Content
1 gezelter 1994 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     *
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31     *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39     * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [4] , Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011). *
41     */
42    
43     #include <algorithm>
44     #include <fstream>
45     #include "applications/staticProps/NitrileFrequencyMap.hpp"
46     #include "utils/simError.h"
47     #include "io/DumpReader.hpp"
48     #include "primitives/Molecule.hpp"
49     #include "brains/Thermo.hpp"
50    
51     namespace OpenMD {
52    
53     NitrileFrequencyMap::NitrileFrequencyMap(SimInfo* info,
54     const std::string& filename,
55     const std::string& sele1,
56     int nbins)
57     : StaticAnalyser(info, filename), selectionScript1_(sele1),
58     evaluator1_(info), seleMan1_(info), nBins_(nbins), info_(info) {
59    
60     setOutputName(getPrefix(filename) + ".freqs");
61    
62     evaluator1_.loadScriptString(sele1);
63     if (!evaluator1_.isDynamic()) {
64     seleMan1_.setSelectionSet(evaluator1_.evaluate());
65     }
66    
67     count_.resize(nBins_);
68     histogram_.resize(nBins_);
69    
70     freqs_.resize(info_->getNGlobalMolecules());
71    
72     minFreq_ = -50;
73     maxFreq_ = 50;
74    
75     // Values from Choi et. al. "Nitrile and thiocyanate IR probes:
76     // Quantum chemistry calculation studies and multivariate
77     // least-square fitting analysis," J. Chem. Phys. 128, 134506 (2008).
78     //
79     // These map site electrostatic potentials onto frequency shifts
80     // in the same energy units that one computes the total potential.
81    
82     frequencyMap_["CN"] = 0.0801;
83     frequencyMap_["NC"] = 0.00521;
84     frequencyMap_["RCHar3"] = -0.00182;
85     frequencyMap_["SigmaN"] = 0.00157;
86     frequencyMap_["PiN"] = -0.00167;
87     frequencyMap_["PiC"] = -0.00896;
88    
89     ForceField* forceField_ = info_->getForceField();
90     set<AtomType*> atypes = info_->getSimulatedAtomTypes();
91     PairList* excludes = info_->getExcludedInteractions();
92     int nAtoms = info->getSnapshotManager()->getCurrentSnapshot()->getNumberOfAtoms();
93    
94     RealType rcut;
95     if (info_->getSimParams()->haveCutoffRadius()) {
96     rcut = info_->getSimParams()->getCutoffRadius();
97     } else {
98     rcut = 12.0;
99     }
100    
101     EF_ = V3Zero;
102    
103     if (info_->getSimParams()->haveElectricField())
104     EF_ = info_->getSimParams()->getElectricField();
105    
106     excludesForAtom.clear();
107     excludesForAtom.resize(nAtoms);
108    
109     for (int i = 0; i < nAtoms; i++) {
110     for (int j = 0; j < nAtoms; j++) {
111     if (excludes->hasPair(i, j))
112     excludesForAtom[i].push_back(j);
113     }
114     }
115    
116     electrostatic_ = new Electrostatic();
117     electrostatic_->setSimInfo(info_);
118     electrostatic_->setForceField(forceField_);
119     electrostatic_->setSimulatedAtomTypes(atypes);
120     electrostatic_->setCutoffRadius(rcut);
121     }
122    
123     bool NitrileFrequencyMap::excludeAtomPair(int atom1, int atom2) {
124    
125     for (vector<int>::iterator i = excludesForAtom[atom1].begin();
126     i != excludesForAtom[atom1].end(); ++i) {
127     if ( (*i) == atom2 ) return true;
128     }
129    
130     return false;
131     }
132    
133     void NitrileFrequencyMap::process() {
134     Molecule* mol;
135     RigidBody* rb;
136     Atom* atom;
137     AtomType* atype;
138     SimInfo::MoleculeIterator mi;
139     Molecule::RigidBodyIterator rbIter;
140     Molecule::AtomIterator ai2;
141     Atom* atom2;
142     StuntDouble* sd1;
143     int ii, sdID, molID, sdID2;
144     RealType li;
145     RealType sPot, s1, s2;
146     RealType freqShift;
147     std::string name;
148     map<string,RealType>::iterator fi;
149     bool excluded;
150     const RealType chrgToKcal = 23.0609;
151    
152     DumpReader reader(info_, dumpFilename_);
153     int nFrames = reader.getNFrames();
154    
155     nProcessed_ = nFrames/step_;
156    
157     std::fill(histogram_.begin(), histogram_.end(), 0.0);
158     std::fill(count_.begin(), count_.end(), 0);
159    
160     for (int istep = 0; istep < nFrames; istep += step_) {
161     reader.readFrame(istep);
162     currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
163    
164     std::fill(freqs_.begin(), freqs_.end(), 0.0);
165    
166     for (mol = info_->beginMolecule(mi); mol != NULL;
167     mol = info_->nextMolecule(mi)) {
168     //change the positions of atoms which belong to the rigidbodies
169     for (rb = mol->beginRigidBody(rbIter); rb != NULL;
170     rb = mol->nextRigidBody(rbIter)) {
171     rb->updateAtoms();
172     }
173     }
174    
175     if (evaluator1_.isDynamic()) {
176     seleMan1_.setSelectionSet(evaluator1_.evaluate());
177     }
178    
179     for (sd1 = seleMan1_.beginSelected(ii);
180     sd1 != NULL;
181     sd1 = seleMan1_.nextSelected(ii)) {
182    
183     sdID = sd1->getGlobalIndex();
184     molID = info_->getGlobalMolMembership(sdID);
185     mol = info_->getMoleculeByGlobalIndex(molID);
186    
187     Vector3d CNcentroid = mol->getRigidBodyAt(2)->getPos();
188     Vector3d ra = sd1->getPos();
189    
190     atom = dynamic_cast<Atom *>(sd1);
191     atype = atom->getAtomType();
192     name = atype->getName();
193     fi = frequencyMap_.find(name);
194     if ( fi != frequencyMap_.end() ) {
195     li = (*fi).second;
196     } else {
197     // throw error
198     sprintf( painCave.errMsg,
199     "NitrileFrequencyMap::process: Unknown atype requested.\n"
200     "\t(Selection specified %s .)\n",
201     name.c_str() );
202     painCave.isFatal = 1;
203     simError();
204     }
205    
206     sPot = sd1->getSitePotential();
207    
208     // Subtract out the contribution from every other site on this molecule:
209     for(atom2 = mol->beginAtom(ai2); atom2 != NULL;
210     atom2 = mol->nextAtom(ai2)) {
211    
212     sdID2 = atom2->getGlobalIndex();
213     if (sdID == sdID2) {
214     excluded = true;
215     } else {
216     excluded = excludeAtomPair(sdID, sdID2);
217     }
218    
219     electrostatic_->getSitePotentials(atom, atom2, excluded, s1, s2);
220    
221     sPot -= s1;
222     }
223    
224     // Add the contribution from the electric field:
225    
226     sPot += dot(EF_, ra - CNcentroid) * chrgToKcal ;
227    
228     freqShift = sPot * li;
229    
230     // convert the kcal/mol energies to wavenumbers:
231     freqShift *= 349.757;
232    
233     freqs_[molID] += freqShift;
234     }
235    
236     for (int i = 0; i < info_->getNGlobalMolecules(); ++i) {
237     int binNo = int(nBins_ * (freqs_[i] - minFreq_)/(maxFreq_-minFreq_));
238    
239     count_[binNo]++;
240     }
241     }
242    
243     processHistogram();
244     writeProbs();
245    
246     }
247    
248     void NitrileFrequencyMap::processHistogram() {
249    
250     int atot = 0;
251     for(unsigned int i = 0; i < count_.size(); ++i)
252     atot += count_[i];
253    
254     for(unsigned int i = 0; i < count_.size(); ++i) {
255     histogram_[i] = double(count_[i] / double(atot));
256     }
257     }
258    
259     void NitrileFrequencyMap::writeProbs() {
260    
261     std::ofstream rdfStream(outputFilename_.c_str());
262     if (rdfStream.is_open()) {
263     rdfStream << "#NitrileFrequencyMap\n";
264     rdfStream << "#nFrames:\t" << nProcessed_ << "\n";
265     rdfStream << "#selection1: (" << selectionScript1_ << ")";
266     rdfStream << "\n";
267     rdfStream << "#nu\tp(nu))\n";
268     for (unsigned int i = 0; i < histogram_.size(); ++i) {
269     RealType freq = minFreq_ + (RealType)(i)*(maxFreq_-minFreq_) /
270     (RealType)histogram_.size();
271     rdfStream << freq << "\t" << histogram_[i] << "\n";
272     }
273    
274     } else {
275    
276     sprintf(painCave.errMsg, "NitrileFrequencyMap: unable to open %s\n",
277     outputFilename_.c_str());
278     painCave.isFatal = 1;
279     simError();
280     }
281    
282     rdfStream.close();
283     }
284    
285     }
286    

Properties

Name Value
svn:eol-style native