ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/UseTheForce/ForceField.cpp
Revision: 1530
Committed: Tue Dec 28 21:47:55 2010 UTC (14 years, 4 months ago) by gezelter
File size: 19285 byte(s)
Log Message:
Moved switching functions and force options over to the C++ side, and
removed them from Fortran.

File Contents

# User Rev Content
1 gezelter 507 /*
2 gezelter 246 * 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 gezelter 1390 * 1. Redistributions of source code must retain the above copyright
10 gezelter 246 * notice, this list of conditions and the following disclaimer.
11     *
12 gezelter 1390 * 2. Redistributions in binary form must reproduce the above copyright
13 gezelter 246 * 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 gezelter 1390 *
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, 24107 (2008).
39     * [4] Vardeman & Gezelter, in progress (2009).
40 gezelter 246 */
41    
42 gezelter 507 /**
43     * @file ForceField.cpp
44     * @author tlin
45     * @date 11/04/2004
46     * @time 22:51am
47     * @version 1.0
48     */
49 gezelter 246
50 gezelter 1269 #include <algorithm>
51 gezelter 206 #include "UseTheForce/ForceField.hpp"
52 gezelter 246 #include "utils/simError.h"
53 gezelter 1269 #include "utils/Tuple.hpp"
54 tim 475 #include "UseTheForce/DarkSide/atype_interface.h"
55 gezelter 1390 namespace OpenMD {
56 gezelter 206
57 gezelter 507 ForceField::ForceField() {
58 gezelter 1460
59 gezelter 246 char* tempPath;
60     tempPath = getenv("FORCE_PARAM_PATH");
61 gezelter 1460
62 gezelter 246 if (tempPath == NULL) {
63 gezelter 1460 //convert a macro from compiler to a string in c++
64     STR_DEFINE(ffPath_, FRC_PATH );
65 gezelter 246 } else {
66 gezelter 507 ffPath_ = tempPath;
67 gezelter 246 }
68 gezelter 507 }
69 gezelter 206
70 tim 475
71 gezelter 507 ForceField::~ForceField() {
72 tim 475 deleteAtypes();
73 gezelter 507 }
74 tim 475
75 gezelter 507 AtomType* ForceField::getAtomType(const std::string &at) {
76 gezelter 246 std::vector<std::string> keys;
77     keys.push_back(at);
78     return atomTypeCont_.find(keys);
79 gezelter 507 }
80 gezelter 206
81 cpuglis 1195 BondType* ForceField::getBondType(const std::string &at1,
82     const std::string &at2) {
83 gezelter 246 std::vector<std::string> keys;
84     keys.push_back(at1);
85     keys.push_back(at2);
86 gezelter 206
87 gezelter 246 //try exact match first
88     BondType* bondType = bondTypeCont_.find(keys);
89     if (bondType) {
90 gezelter 507 return bondType;
91 gezelter 246 } else {
92 gezelter 1269 AtomType* atype1;
93     AtomType* atype2;
94     std::vector<std::string> at1key;
95     at1key.push_back(at1);
96     atype1 = atomTypeCont_.find(at1key);
97    
98     std::vector<std::string> at2key;
99     at2key.push_back(at2);
100     atype2 = atomTypeCont_.find(at2key);
101    
102     // query atom types for their chains of responsibility
103     std::vector<AtomType*> at1Chain = atype1->allYourBase();
104     std::vector<AtomType*> at2Chain = atype2->allYourBase();
105    
106     std::vector<AtomType*>::iterator i;
107     std::vector<AtomType*>::iterator j;
108    
109     int ii = 0;
110     int jj = 0;
111     int bondTypeScore;
112    
113     std::vector<std::pair<int, std::vector<std::string> > > foundBonds;
114    
115     for (i = at1Chain.begin(); i != at1Chain.end(); i++) {
116     jj = 0;
117     for (j = at2Chain.begin(); j != at2Chain.end(); j++) {
118    
119     bondTypeScore = ii + jj;
120    
121     std::vector<std::string> myKeys;
122     myKeys.push_back((*i)->getName());
123     myKeys.push_back((*j)->getName());
124    
125     BondType* bondType = bondTypeCont_.find(myKeys);
126     if (bondType) {
127     foundBonds.push_back(std::make_pair(bondTypeScore, myKeys));
128     }
129     jj++;
130     }
131     ii++;
132     }
133    
134    
135 gezelter 1277 if (foundBonds.size() > 0) {
136     // sort the foundBonds by the score:
137     std::sort(foundBonds.begin(), foundBonds.end());
138    
139     int bestScore = foundBonds[0].first;
140     std::vector<std::string> theKeys = foundBonds[0].second;
141    
142     BondType* bestType = bondTypeCont_.find(theKeys);
143    
144     return bestType;
145     } else {
146     //if no exact match found, try wild card match
147     return bondTypeCont_.find(keys, wildCardAtomTypeName_);
148 gezelter 1269 }
149 gezelter 246 }
150 gezelter 507 }
151 gezelter 1269
152 cpuglis 1195 BendType* ForceField::getBendType(const std::string &at1,
153     const std::string &at2,
154 gezelter 507 const std::string &at3) {
155 gezelter 246 std::vector<std::string> keys;
156     keys.push_back(at1);
157     keys.push_back(at2);
158     keys.push_back(at3);
159 gezelter 206
160 gezelter 246 //try exact match first
161     BendType* bendType = bendTypeCont_.find(keys);
162     if (bendType) {
163 gezelter 507 return bendType;
164 gezelter 246 } else {
165 gezelter 1269
166     AtomType* atype1;
167     AtomType* atype2;
168     AtomType* atype3;
169     std::vector<std::string> at1key;
170     at1key.push_back(at1);
171     atype1 = atomTypeCont_.find(at1key);
172    
173     std::vector<std::string> at2key;
174     at2key.push_back(at2);
175     atype2 = atomTypeCont_.find(at2key);
176    
177     std::vector<std::string> at3key;
178     at3key.push_back(at3);
179     atype3 = atomTypeCont_.find(at3key);
180    
181     // query atom types for their chains of responsibility
182     std::vector<AtomType*> at1Chain = atype1->allYourBase();
183     std::vector<AtomType*> at2Chain = atype2->allYourBase();
184     std::vector<AtomType*> at3Chain = atype3->allYourBase();
185    
186     std::vector<AtomType*>::iterator i;
187     std::vector<AtomType*>::iterator j;
188     std::vector<AtomType*>::iterator k;
189    
190     int ii = 0;
191     int jj = 0;
192     int kk = 0;
193     int IKscore;
194    
195     std::vector<tuple3<int, int, std::vector<std::string> > > foundBends;
196    
197     for (j = at2Chain.begin(); j != at2Chain.end(); j++) {
198     ii = 0;
199     for (i = at1Chain.begin(); i != at1Chain.end(); i++) {
200     kk = 0;
201     for (k = at3Chain.begin(); k != at3Chain.end(); k++) {
202    
203     IKscore = ii + kk;
204    
205     std::vector<std::string> myKeys;
206     myKeys.push_back((*i)->getName());
207     myKeys.push_back((*j)->getName());
208     myKeys.push_back((*k)->getName());
209    
210     BendType* bendType = bendTypeCont_.find(myKeys);
211     if (bendType) {
212     foundBends.push_back( make_tuple3(jj, IKscore, myKeys) );
213     }
214     kk++;
215     }
216     ii++;
217     }
218     jj++;
219     }
220    
221 gezelter 1277 if (foundBends.size() > 0) {
222     std::sort(foundBends.begin(), foundBends.end());
223     int jscore = foundBends[0].first;
224     int ikscore = foundBends[0].second;
225 cli2 1289 std::vector<std::string> theKeys = foundBends[0].third;
226 gezelter 1277
227     BendType* bestType = bendTypeCont_.find(theKeys);
228     return bestType;
229     } else {
230 gezelter 1269 //if no exact match found, try wild card match
231     return bendTypeCont_.find(keys, wildCardAtomTypeName_);
232     }
233 gezelter 246 }
234 gezelter 507 }
235 gezelter 206
236 cpuglis 1195 TorsionType* ForceField::getTorsionType(const std::string &at1,
237     const std::string &at2,
238     const std::string &at3,
239     const std::string &at4) {
240 gezelter 246 std::vector<std::string> keys;
241     keys.push_back(at1);
242     keys.push_back(at2);
243     keys.push_back(at3);
244     keys.push_back(at4);
245 gezelter 206
246 gezelter 1269
247     //try exact match first
248 gezelter 246 TorsionType* torsionType = torsionTypeCont_.find(keys);
249     if (torsionType) {
250 gezelter 507 return torsionType;
251 gezelter 246 } else {
252 gezelter 1269
253     AtomType* atype1;
254     AtomType* atype2;
255     AtomType* atype3;
256     AtomType* atype4;
257     std::vector<std::string> at1key;
258     at1key.push_back(at1);
259     atype1 = atomTypeCont_.find(at1key);
260    
261     std::vector<std::string> at2key;
262     at2key.push_back(at2);
263     atype2 = atomTypeCont_.find(at2key);
264    
265     std::vector<std::string> at3key;
266     at3key.push_back(at3);
267     atype3 = atomTypeCont_.find(at3key);
268    
269     std::vector<std::string> at4key;
270     at4key.push_back(at4);
271     atype4 = atomTypeCont_.find(at4key);
272    
273     // query atom types for their chains of responsibility
274     std::vector<AtomType*> at1Chain = atype1->allYourBase();
275     std::vector<AtomType*> at2Chain = atype2->allYourBase();
276     std::vector<AtomType*> at3Chain = atype3->allYourBase();
277     std::vector<AtomType*> at4Chain = atype4->allYourBase();
278    
279     std::vector<AtomType*>::iterator i;
280     std::vector<AtomType*>::iterator j;
281     std::vector<AtomType*>::iterator k;
282     std::vector<AtomType*>::iterator l;
283    
284     int ii = 0;
285     int jj = 0;
286     int kk = 0;
287     int ll = 0;
288     int ILscore;
289     int JKscore;
290    
291     std::vector<tuple3<int, int, std::vector<std::string> > > foundTorsions;
292    
293     for (j = at2Chain.begin(); j != at2Chain.end(); j++) {
294     kk = 0;
295     for (k = at3Chain.begin(); k != at3Chain.end(); k++) {
296     ii = 0;
297     for (i = at1Chain.begin(); i != at1Chain.end(); i++) {
298     ll = 0;
299     for (l = at4Chain.begin(); l != at4Chain.end(); l++) {
300    
301     ILscore = ii + ll;
302     JKscore = jj + kk;
303    
304     std::vector<std::string> myKeys;
305     myKeys.push_back((*i)->getName());
306     myKeys.push_back((*j)->getName());
307     myKeys.push_back((*k)->getName());
308     myKeys.push_back((*l)->getName());
309    
310     TorsionType* torsionType = torsionTypeCont_.find(myKeys);
311     if (torsionType) {
312     foundTorsions.push_back( make_tuple3(JKscore, ILscore, myKeys) );
313     }
314     ll++;
315     }
316     ii++;
317     }
318     kk++;
319     }
320     jj++;
321     }
322    
323 gezelter 1277 if (foundTorsions.size() > 0) {
324     std::sort(foundTorsions.begin(), foundTorsions.end());
325     int jkscore = foundTorsions[0].first;
326     int ilscore = foundTorsions[0].second;
327     std::vector<std::string> theKeys = foundTorsions[0].third;
328    
329     TorsionType* bestType = torsionTypeCont_.find(theKeys);
330     return bestType;
331 gezelter 1269 } else {
332     //if no exact match found, try wild card match
333     return torsionTypeCont_.find(keys, wildCardAtomTypeName_);
334     }
335 gezelter 246 }
336 gezelter 507 }
337 gezelter 206
338 cli2 1275 InversionType* ForceField::getInversionType(const std::string &at1,
339     const std::string &at2,
340     const std::string &at3,
341     const std::string &at4) {
342     std::vector<std::string> keys;
343     keys.push_back(at1);
344     keys.push_back(at2);
345     keys.push_back(at3);
346     keys.push_back(at4);
347    
348     //try exact match first
349 cli2 1303 InversionType* inversionType = inversionTypeCont_.permutedFindSkippingFirstElement(keys);
350 cli2 1275 if (inversionType) {
351     return inversionType;
352     } else {
353    
354     AtomType* atype1;
355     AtomType* atype2;
356     AtomType* atype3;
357     AtomType* atype4;
358     std::vector<std::string> at1key;
359     at1key.push_back(at1);
360     atype1 = atomTypeCont_.find(at1key);
361    
362     std::vector<std::string> at2key;
363     at2key.push_back(at2);
364     atype2 = atomTypeCont_.find(at2key);
365    
366     std::vector<std::string> at3key;
367     at3key.push_back(at3);
368     atype3 = atomTypeCont_.find(at3key);
369    
370     std::vector<std::string> at4key;
371     at4key.push_back(at4);
372     atype4 = atomTypeCont_.find(at4key);
373    
374     // query atom types for their chains of responsibility
375     std::vector<AtomType*> at1Chain = atype1->allYourBase();
376     std::vector<AtomType*> at2Chain = atype2->allYourBase();
377     std::vector<AtomType*> at3Chain = atype3->allYourBase();
378     std::vector<AtomType*> at4Chain = atype4->allYourBase();
379    
380     std::vector<AtomType*>::iterator i;
381     std::vector<AtomType*>::iterator j;
382     std::vector<AtomType*>::iterator k;
383     std::vector<AtomType*>::iterator l;
384    
385     int ii = 0;
386     int jj = 0;
387     int kk = 0;
388     int ll = 0;
389     int Iscore;
390     int JKLscore;
391    
392     std::vector<tuple3<int, int, std::vector<std::string> > > foundInversions;
393    
394     for (j = at2Chain.begin(); j != at2Chain.end(); j++) {
395     kk = 0;
396     for (k = at3Chain.begin(); k != at3Chain.end(); k++) {
397     ii = 0;
398     for (i = at1Chain.begin(); i != at1Chain.end(); i++) {
399     ll = 0;
400     for (l = at4Chain.begin(); l != at4Chain.end(); l++) {
401    
402     Iscore = ii;
403     JKLscore = jj + kk + ll;
404    
405     std::vector<std::string> myKeys;
406     myKeys.push_back((*i)->getName());
407     myKeys.push_back((*j)->getName());
408     myKeys.push_back((*k)->getName());
409     myKeys.push_back((*l)->getName());
410    
411 cli2 1303 InversionType* inversionType = inversionTypeCont_.permutedFindSkippingFirstElement(myKeys);
412 cli2 1275 if (inversionType) {
413     foundInversions.push_back( make_tuple3(Iscore, JKLscore, myKeys) );
414     }
415     ll++;
416     }
417     ii++;
418     }
419     kk++;
420     }
421     jj++;
422     }
423 gezelter 1277
424     if (foundInversions.size() > 0) {
425     std::sort(foundInversions.begin(), foundInversions.end());
426     int iscore = foundInversions[0].first;
427     int jklscore = foundInversions[0].second;
428     std::vector<std::string> theKeys = foundInversions[0].third;
429    
430 cli2 1303 InversionType* bestType = inversionTypeCont_.permutedFindSkippingFirstElement(theKeys);
431 gezelter 1277 return bestType;
432 cli2 1275 } else {
433     //if no exact match found, try wild card match
434     return inversionTypeCont_.find(keys, wildCardAtomTypeName_);
435     }
436     }
437     }
438    
439 chuckv 1151 NonBondedInteractionType* ForceField::getNonBondedInteractionType(const std::string &at1, const std::string &at2) {
440     std::vector<std::string> keys;
441     keys.push_back(at1);
442     keys.push_back(at2);
443 cpuglis 1195
444 chuckv 1151 //try exact match first
445     NonBondedInteractionType* nbiType = nonBondedInteractionTypeCont_.find(keys);
446     if (nbiType) {
447     return nbiType;
448     } else {
449     //if no exact match found, try wild card match
450     return nonBondedInteractionTypeCont_.find(keys, wildCardAtomTypeName_);
451 cpuglis 1195 }
452 chuckv 1151 }
453 cpuglis 1195
454     BondType* ForceField::getExactBondType(const std::string &at1,
455     const std::string &at2){
456 gezelter 246 std::vector<std::string> keys;
457     keys.push_back(at1);
458     keys.push_back(at2);
459     return bondTypeCont_.find(keys);
460 gezelter 507 }
461 cpuglis 1195
462     BendType* ForceField::getExactBendType(const std::string &at1,
463     const std::string &at2,
464 gezelter 507 const std::string &at3){
465 gezelter 246 std::vector<std::string> keys;
466     keys.push_back(at1);
467     keys.push_back(at2);
468     keys.push_back(at3);
469     return bendTypeCont_.find(keys);
470 gezelter 507 }
471 cpuglis 1195
472     TorsionType* ForceField::getExactTorsionType(const std::string &at1,
473     const std::string &at2,
474     const std::string &at3,
475     const std::string &at4){
476 gezelter 246 std::vector<std::string> keys;
477     keys.push_back(at1);
478     keys.push_back(at2);
479     keys.push_back(at3);
480     keys.push_back(at4);
481     return torsionTypeCont_.find(keys);
482 gezelter 507 }
483 cli2 1275
484     InversionType* ForceField::getExactInversionType(const std::string &at1,
485     const std::string &at2,
486     const std::string &at3,
487     const std::string &at4){
488     std::vector<std::string> keys;
489     keys.push_back(at1);
490     keys.push_back(at2);
491     keys.push_back(at3);
492     keys.push_back(at4);
493     return inversionTypeCont_.find(keys);
494     }
495    
496 chuckv 1151 NonBondedInteractionType* ForceField::getExactNonBondedInteractionType(const std::string &at1, const std::string &at2){
497     std::vector<std::string> keys;
498     keys.push_back(at1);
499     keys.push_back(at2);
500     return nonBondedInteractionTypeCont_.find(keys);
501     }
502 cli2 1275
503 chuckv 1151
504 gezelter 507 bool ForceField::addAtomType(const std::string &at, AtomType* atomType) {
505 gezelter 246 std::vector<std::string> keys;
506     keys.push_back(at);
507     return atomTypeCont_.add(keys, atomType);
508 gezelter 507 }
509 gezelter 206
510 gezelter 1282 bool ForceField::replaceAtomType(const std::string &at, AtomType* atomType) {
511     std::vector<std::string> keys;
512     keys.push_back(at);
513     return atomTypeCont_.replace(keys, atomType);
514     }
515    
516 cpuglis 1195 bool ForceField::addBondType(const std::string &at1, const std::string &at2,
517     BondType* bondType) {
518 gezelter 246 std::vector<std::string> keys;
519     keys.push_back(at1);
520     keys.push_back(at2);
521 cpuglis 1195 return bondTypeCont_.add(keys, bondType);
522 gezelter 507 }
523 cpuglis 1195
524 gezelter 507 bool ForceField::addBendType(const std::string &at1, const std::string &at2,
525     const std::string &at3, BendType* bendType) {
526 gezelter 246 std::vector<std::string> keys;
527     keys.push_back(at1);
528     keys.push_back(at2);
529     keys.push_back(at3);
530     return bendTypeCont_.add(keys, bendType);
531 gezelter 507 }
532 cpuglis 1195
533     bool ForceField::addTorsionType(const std::string &at1,
534     const std::string &at2,
535     const std::string &at3,
536     const std::string &at4,
537     TorsionType* torsionType) {
538 gezelter 246 std::vector<std::string> keys;
539     keys.push_back(at1);
540     keys.push_back(at2);
541     keys.push_back(at3);
542     keys.push_back(at4);
543     return torsionTypeCont_.add(keys, torsionType);
544 gezelter 507 }
545 gezelter 206
546 cli2 1275 bool ForceField::addInversionType(const std::string &at1,
547     const std::string &at2,
548     const std::string &at3,
549     const std::string &at4,
550     InversionType* inversionType) {
551     std::vector<std::string> keys;
552     keys.push_back(at1);
553     keys.push_back(at2);
554     keys.push_back(at3);
555     keys.push_back(at4);
556     return inversionTypeCont_.add(keys, inversionType);
557     }
558    
559 cpuglis 1195 bool ForceField::addNonBondedInteractionType(const std::string &at1,
560     const std::string &at2,
561     NonBondedInteractionType* nbiType) {
562 chuckv 1151 std::vector<std::string> keys;
563     keys.push_back(at1);
564     keys.push_back(at2);
565     return nonBondedInteractionTypeCont_.add(keys, nbiType);
566     }
567 cpuglis 1195
568 tim 963 RealType ForceField::getRcutFromAtomType(AtomType* at) {
569 gezelter 246 /**@todo */
570     GenericData* data;
571 tim 963 RealType rcut = 0.0;
572 cpuglis 1195
573 gezelter 246 if (at->isLennardJones()) {
574 gezelter 507 data = at->getPropertyByName("LennardJones");
575     if (data != NULL) {
576     LJParamGenericData* ljData = dynamic_cast<LJParamGenericData*>(data);
577 cpuglis 1195
578 gezelter 507 if (ljData != NULL) {
579     LJParam ljParam = ljData->getData();
580 cpuglis 1195
581 gezelter 507 //by default use 2.5*sigma as cutoff radius
582     rcut = 2.5 * ljParam.sigma;
583 cpuglis 1195
584 gezelter 507 } else {
585     sprintf( painCave.errMsg,
586     "Can not cast GenericData to LJParam\n");
587 gezelter 1390 painCave.severity = OPENMD_ERROR;
588 gezelter 507 painCave.isFatal = 1;
589     simError();
590     }
591     } else {
592     sprintf( painCave.errMsg, "Can not find Parameters for LennardJones\n");
593 gezelter 1390 painCave.severity = OPENMD_ERROR;
594 gezelter 507 painCave.isFatal = 1;
595     simError();
596     }
597 gezelter 246 }
598     return rcut;
599 gezelter 507 }
600 cpuglis 1195
601 gezelter 206
602 gezelter 507 ifstrstream* ForceField::openForceFieldFile(const std::string& filename) {
603 gezelter 246 std::string forceFieldFilename(filename);
604     ifstrstream* ffStream = new ifstrstream();
605    
606     //try to open the force filed file in current directory first
607     ffStream->open(forceFieldFilename.c_str());
608     if(!ffStream->is_open()){
609    
610 gezelter 507 forceFieldFilename = ffPath_ + "/" + forceFieldFilename;
611     ffStream->open( forceFieldFilename.c_str() );
612 gezelter 246
613 gezelter 507 //if current directory does not contain the force field file,
614     //try to open it in the path
615     if(!ffStream->is_open()){
616 gezelter 246
617 gezelter 507 sprintf( painCave.errMsg,
618     "Error opening the force field parameter file:\n"
619     "\t%s\n"
620     "\tHave you tried setting the FORCE_PARAM_PATH environment "
621     "variable?\n",
622     forceFieldFilename.c_str() );
623 gezelter 1390 painCave.severity = OPENMD_ERROR;
624 gezelter 507 painCave.isFatal = 1;
625     simError();
626     }
627 gezelter 246 }
628     return ffStream;
629 gezelter 507 }
630 gezelter 246
631 gezelter 1390 } //end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date