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

# 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), 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 std::vector<RealType> ef;
104 bool efSpec = false;
105
106 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 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