ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/NitrileFrequencyMap.cpp
Revision: 2026
Committed: Wed Oct 22 12:23:59 2014 UTC (10 years, 6 months ago) by gezelter
File size: 10169 byte(s)
Log Message:
Starting to add support for UniformGradient. 
Changed Vector3d input type to a more general std::vector<RealType> input.  This change alters RNEMD and UniformField inputs.

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 gezelter 2026 std::vector<RealType> ef;
104     bool efSpec = false;
105 gezelter 1994
106 gezelter 2026 if (info_->getSimParams()->haveElectricField()) {
107     efSpec = true;
108     ef = info_->getSimParams()->getElectricField();
109     }
110     if (info_->getSimParams()->haveUniformField()) {
111     efSpec = true;
112     ef = info_->getSimParams()->getUniformField();
113     }
114     if (efSpec) {
115     if (ef.size() != 3) {
116     sprintf(painCave.errMsg,
117     "NitrileFrequencyMap: Incorrect number of parameters specified for uniformField.\n"
118     "\tthere should be 3 parameters, but %lu were specified.\n", ef.size());
119     painCave.isFatal = 1;
120     simError();
121     }
122     EF_.x() = ef[0];
123     EF_.y() = ef[1];
124     EF_.z() = ef[2];
125     }
126    
127 gezelter 1994 excludesForAtom.clear();
128     excludesForAtom.resize(nAtoms);
129    
130     for (int i = 0; i < nAtoms; i++) {
131     for (int j = 0; j < nAtoms; j++) {
132     if (excludes->hasPair(i, j))
133     excludesForAtom[i].push_back(j);
134     }
135     }
136    
137     electrostatic_ = new Electrostatic();
138     electrostatic_->setSimInfo(info_);
139     electrostatic_->setForceField(forceField_);
140     electrostatic_->setSimulatedAtomTypes(atypes);
141     electrostatic_->setCutoffRadius(rcut);
142     }
143    
144     bool NitrileFrequencyMap::excludeAtomPair(int atom1, int atom2) {
145    
146     for (vector<int>::iterator i = excludesForAtom[atom1].begin();
147     i != excludesForAtom[atom1].end(); ++i) {
148     if ( (*i) == atom2 ) return true;
149     }
150    
151     return false;
152     }
153    
154     void NitrileFrequencyMap::process() {
155     Molecule* mol;
156     RigidBody* rb;
157     Atom* atom;
158     AtomType* atype;
159     SimInfo::MoleculeIterator mi;
160     Molecule::RigidBodyIterator rbIter;
161     Molecule::AtomIterator ai2;
162     Atom* atom2;
163     StuntDouble* sd1;
164     int ii, sdID, molID, sdID2;
165     RealType li;
166     RealType sPot, s1, s2;
167     RealType freqShift;
168     std::string name;
169     map<string,RealType>::iterator fi;
170     bool excluded;
171     const RealType chrgToKcal = 23.0609;
172    
173     DumpReader reader(info_, dumpFilename_);
174     int nFrames = reader.getNFrames();
175    
176     nProcessed_ = nFrames/step_;
177    
178     std::fill(histogram_.begin(), histogram_.end(), 0.0);
179     std::fill(count_.begin(), count_.end(), 0);
180    
181     for (int istep = 0; istep < nFrames; istep += step_) {
182     reader.readFrame(istep);
183     currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
184    
185     std::fill(freqs_.begin(), freqs_.end(), 0.0);
186    
187     for (mol = info_->beginMolecule(mi); mol != NULL;
188     mol = info_->nextMolecule(mi)) {
189     //change the positions of atoms which belong to the rigidbodies
190     for (rb = mol->beginRigidBody(rbIter); rb != NULL;
191     rb = mol->nextRigidBody(rbIter)) {
192     rb->updateAtoms();
193     }
194     }
195    
196     if (evaluator1_.isDynamic()) {
197     seleMan1_.setSelectionSet(evaluator1_.evaluate());
198     }
199    
200     for (sd1 = seleMan1_.beginSelected(ii);
201     sd1 != NULL;
202     sd1 = seleMan1_.nextSelected(ii)) {
203    
204     sdID = sd1->getGlobalIndex();
205     molID = info_->getGlobalMolMembership(sdID);
206     mol = info_->getMoleculeByGlobalIndex(molID);
207    
208     Vector3d CNcentroid = mol->getRigidBodyAt(2)->getPos();
209     Vector3d ra = sd1->getPos();
210    
211     atom = dynamic_cast<Atom *>(sd1);
212     atype = atom->getAtomType();
213     name = atype->getName();
214     fi = frequencyMap_.find(name);
215     if ( fi != frequencyMap_.end() ) {
216     li = (*fi).second;
217     } else {
218     // throw error
219     sprintf( painCave.errMsg,
220     "NitrileFrequencyMap::process: Unknown atype requested.\n"
221     "\t(Selection specified %s .)\n",
222     name.c_str() );
223     painCave.isFatal = 1;
224     simError();
225     }
226    
227     sPot = sd1->getSitePotential();
228    
229     // Subtract out the contribution from every other site on this molecule:
230     for(atom2 = mol->beginAtom(ai2); atom2 != NULL;
231     atom2 = mol->nextAtom(ai2)) {
232    
233     sdID2 = atom2->getGlobalIndex();
234     if (sdID == sdID2) {
235     excluded = true;
236     } else {
237     excluded = excludeAtomPair(sdID, sdID2);
238     }
239    
240     electrostatic_->getSitePotentials(atom, atom2, excluded, s1, s2);
241    
242     sPot -= s1;
243     }
244    
245     // Add the contribution from the electric field:
246    
247     sPot += dot(EF_, ra - CNcentroid) * chrgToKcal ;
248    
249     freqShift = sPot * li;
250    
251     // convert the kcal/mol energies to wavenumbers:
252     freqShift *= 349.757;
253    
254     freqs_[molID] += freqShift;
255     }
256    
257     for (int i = 0; i < info_->getNGlobalMolecules(); ++i) {
258     int binNo = int(nBins_ * (freqs_[i] - minFreq_)/(maxFreq_-minFreq_));
259    
260     count_[binNo]++;
261     }
262     }
263    
264     processHistogram();
265     writeProbs();
266    
267     }
268    
269     void NitrileFrequencyMap::processHistogram() {
270    
271     int atot = 0;
272     for(unsigned int i = 0; i < count_.size(); ++i)
273     atot += count_[i];
274    
275     for(unsigned int i = 0; i < count_.size(); ++i) {
276     histogram_[i] = double(count_[i] / double(atot));
277     }
278     }
279    
280     void NitrileFrequencyMap::writeProbs() {
281    
282     std::ofstream rdfStream(outputFilename_.c_str());
283     if (rdfStream.is_open()) {
284     rdfStream << "#NitrileFrequencyMap\n";
285     rdfStream << "#nFrames:\t" << nProcessed_ << "\n";
286     rdfStream << "#selection1: (" << selectionScript1_ << ")";
287     rdfStream << "\n";
288     rdfStream << "#nu\tp(nu))\n";
289     for (unsigned int i = 0; i < histogram_.size(); ++i) {
290     RealType freq = minFreq_ + (RealType)(i)*(maxFreq_-minFreq_) /
291     (RealType)histogram_.size();
292     rdfStream << freq << "\t" << histogram_[i] << "\n";
293     }
294    
295     } else {
296    
297     sprintf(painCave.errMsg, "NitrileFrequencyMap: unable to open %s\n",
298     outputFilename_.c_str());
299     painCave.isFatal = 1;
300     simError();
301     }
302    
303     rdfStream.close();
304     }
305    
306     }
307    

Properties

Name Value
svn:eol-style native