ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/NitrileFrequencyMap.cpp
Revision: 2071
Committed: Sat Mar 7 21:41:51 2015 UTC (10 years, 1 month ago) by gezelter
File size: 10193 byte(s)
Log Message:
Reducing the number of warnings when using g++ to compile.

File Contents

# Content
1 /*
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), info_(info),
58 selectionScript1_(sele1), seleMan1_(info_), evaluator1_(info_),
59 nBins_(nbins) {
60
61 setOutputName(getPrefix(filename) + ".freqs");
62
63 evaluator1_.loadScriptString(sele1);
64 if (!evaluator1_.isDynamic()) {
65 seleMan1_.setSelectionSet(evaluator1_.evaluate());
66 }
67
68 count_.resize(nBins_);
69 histogram_.resize(nBins_);
70
71 freqs_.resize(info_->getNGlobalMolecules());
72
73 minFreq_ = -50;
74 maxFreq_ = 50;
75
76 // Values from Choi et. al. "Nitrile and thiocyanate IR probes:
77 // Quantum chemistry calculation studies and multivariate
78 // least-square fitting analysis," J. Chem. Phys. 128, 134506 (2008).
79 //
80 // These map site electrostatic potentials onto frequency shifts
81 // in the same energy units that one computes the total potential.
82
83 frequencyMap_["CN"] = 0.0801;
84 frequencyMap_["NC"] = 0.00521;
85 frequencyMap_["RCHar3"] = -0.00182;
86 frequencyMap_["SigmaN"] = 0.00157;
87 frequencyMap_["PiN"] = -0.00167;
88 frequencyMap_["PiC"] = -0.00896;
89
90 ForceField* forceField_ = info_->getForceField();
91 set<AtomType*> atypes = info_->getSimulatedAtomTypes();
92 PairList* excludes = info_->getExcludedInteractions();
93 int nAtoms = info->getSnapshotManager()->getCurrentSnapshot()->getNumberOfAtoms();
94
95 RealType rcut;
96 if (info_->getSimParams()->haveCutoffRadius()) {
97 rcut = info_->getSimParams()->getCutoffRadius();
98 } else {
99 rcut = 12.0;
100 }
101
102 EF_ = V3Zero;
103
104 std::vector<RealType> ef;
105 bool efSpec = false;
106
107 if (info_->getSimParams()->haveElectricField()) {
108 efSpec = true;
109 ef = info_->getSimParams()->getElectricField();
110 }
111 if (info_->getSimParams()->haveUniformField()) {
112 efSpec = true;
113 ef = info_->getSimParams()->getUniformField();
114 }
115 if (efSpec) {
116 if (ef.size() != 3) {
117 sprintf(painCave.errMsg,
118 "NitrileFrequencyMap: Incorrect number of parameters specified for uniformField.\n"
119 "\tthere should be 3 parameters, but %lu were specified.\n", ef.size());
120 painCave.isFatal = 1;
121 simError();
122 }
123 EF_.x() = ef[0];
124 EF_.y() = ef[1];
125 EF_.z() = ef[2];
126 }
127
128 excludesForAtom.clear();
129 excludesForAtom.resize(nAtoms);
130
131 for (int i = 0; i < nAtoms; i++) {
132 for (int j = 0; j < nAtoms; j++) {
133 if (excludes->hasPair(i, j))
134 excludesForAtom[i].push_back(j);
135 }
136 }
137
138 electrostatic_ = new Electrostatic();
139 electrostatic_->setSimInfo(info_);
140 electrostatic_->setForceField(forceField_);
141 electrostatic_->setSimulatedAtomTypes(atypes);
142 electrostatic_->setCutoffRadius(rcut);
143 }
144
145 bool NitrileFrequencyMap::excludeAtomPair(int atom1, int atom2) {
146
147 for (vector<int>::iterator i = excludesForAtom[atom1].begin();
148 i != excludesForAtom[atom1].end(); ++i) {
149 if ( (*i) == atom2 ) return true;
150 }
151
152 return false;
153 }
154
155 void NitrileFrequencyMap::process() {
156 Molecule* mol;
157 RigidBody* rb;
158 Atom* atom;
159 AtomType* atype;
160 SimInfo::MoleculeIterator mi;
161 Molecule::RigidBodyIterator rbIter;
162 Molecule::AtomIterator ai2;
163 Atom* atom2;
164 StuntDouble* sd1;
165 int ii, sdID, molID, sdID2;
166 RealType li(0.0);
167 RealType sPot, s1, s2;
168 RealType freqShift;
169 std::string name;
170 map<string,RealType>::iterator fi;
171 bool excluded;
172 const RealType chrgToKcal = 23.0609;
173
174 DumpReader reader(info_, dumpFilename_);
175 int nFrames = reader.getNFrames();
176
177 nProcessed_ = nFrames/step_;
178
179 std::fill(histogram_.begin(), histogram_.end(), 0.0);
180 std::fill(count_.begin(), count_.end(), 0);
181
182 for (int istep = 0; istep < nFrames; istep += step_) {
183 reader.readFrame(istep);
184 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
185
186 std::fill(freqs_.begin(), freqs_.end(), 0.0);
187
188 for (mol = info_->beginMolecule(mi); mol != NULL;
189 mol = info_->nextMolecule(mi)) {
190 //change the positions of atoms which belong to the rigidbodies
191 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
192 rb = mol->nextRigidBody(rbIter)) {
193 rb->updateAtoms();
194 }
195 }
196
197 if (evaluator1_.isDynamic()) {
198 seleMan1_.setSelectionSet(evaluator1_.evaluate());
199 }
200
201 for (sd1 = seleMan1_.beginSelected(ii);
202 sd1 != NULL;
203 sd1 = seleMan1_.nextSelected(ii)) {
204
205 sdID = sd1->getGlobalIndex();
206 molID = info_->getGlobalMolMembership(sdID);
207 mol = info_->getMoleculeByGlobalIndex(molID);
208
209 Vector3d CNcentroid = mol->getRigidBodyAt(2)->getPos();
210 Vector3d ra = sd1->getPos();
211
212 atom = dynamic_cast<Atom *>(sd1);
213 atype = atom->getAtomType();
214 name = atype->getName();
215 fi = frequencyMap_.find(name);
216 if ( fi != frequencyMap_.end() ) {
217 li = (*fi).second;
218 } else {
219 // throw error
220 sprintf( painCave.errMsg,
221 "NitrileFrequencyMap::process: Unknown atype requested.\n"
222 "\t(Selection specified %s .)\n",
223 name.c_str() );
224 painCave.isFatal = 1;
225 simError();
226 }
227
228 sPot = sd1->getSitePotential();
229
230 // Subtract out the contribution from every other site on this
231 // molecule:
232 for(atom2 = mol->beginAtom(ai2); atom2 != NULL;
233 atom2 = mol->nextAtom(ai2)) {
234
235 sdID2 = atom2->getGlobalIndex();
236 if (sdID == sdID2) {
237 excluded = true;
238 } else {
239 excluded = excludeAtomPair(sdID, sdID2);
240 }
241
242 electrostatic_->getSitePotentials(atom, atom2, excluded, s1, s2);
243
244 sPot -= s1;
245 }
246
247 // Add the contribution from the electric field:
248
249 sPot += dot(EF_, ra - CNcentroid) * chrgToKcal ;
250
251 freqShift = sPot * li;
252
253 // convert the kcal/mol energies to wavenumbers:
254 freqShift *= 349.757;
255
256 freqs_[molID] += freqShift;
257 }
258
259 for (int i = 0; i < info_->getNGlobalMolecules(); ++i) {
260 int binNo = int(nBins_ * (freqs_[i] - minFreq_)/(maxFreq_-minFreq_));
261
262 count_[binNo]++;
263 }
264 }
265
266 processHistogram();
267 writeProbs();
268
269 }
270
271 void NitrileFrequencyMap::processHistogram() {
272
273 int atot = 0;
274 for(unsigned int i = 0; i < count_.size(); ++i)
275 atot += count_[i];
276
277 for(unsigned int i = 0; i < count_.size(); ++i) {
278 histogram_[i] = double(count_[i] / double(atot));
279 }
280 }
281
282 void NitrileFrequencyMap::writeProbs() {
283
284 std::ofstream rdfStream(outputFilename_.c_str());
285 if (rdfStream.is_open()) {
286 rdfStream << "#NitrileFrequencyMap\n";
287 rdfStream << "#nFrames:\t" << nProcessed_ << "\n";
288 rdfStream << "#selection1: (" << selectionScript1_ << ")";
289 rdfStream << "\n";
290 rdfStream << "#nu\tp(nu))\n";
291 for (unsigned int i = 0; i < histogram_.size(); ++i) {
292 RealType freq = minFreq_ + (RealType)(i)*(maxFreq_-minFreq_) /
293 (RealType)histogram_.size();
294 rdfStream << freq << "\t" << histogram_[i] << "\n";
295 }
296
297 } else {
298
299 sprintf(painCave.errMsg, "NitrileFrequencyMap: unable to open %s\n",
300 outputFilename_.c_str());
301 painCave.isFatal = 1;
302 simError();
303 }
304
305 rdfStream.close();
306 }
307
308 }
309

Properties

Name Value
svn:eol-style native