ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-2.0/src/UseTheForce/DUFF.cpp
Revision: 1760
Committed: Fri Nov 19 20:23:26 2004 UTC (19 years, 9 months ago) by tim
File size: 18919 byte(s)
Log Message:
add EAM

File Contents

# User Rev Content
1 tim 1741 /*
2     * Copyright (C) 2000-2004 Object Oriented Parallel Simulation Engine (OOPSE) project
3     *
4     * Contact: oopse@oopse.org
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU Lesser General Public License
8     * as published by the Free Software Foundation; either version 2.1
9     * of the License, or (at your option) any later version.
10     * All we ask is that proper credit is given for our work, which includes
11     * - but is not limited to - adding the above copyright notice to the beginning
12     * of your source code files, and to any copyright notice that you may distribute
13     * with programs based on this work.
14     *
15     * This program is distributed in the hope that it will be useful,
16     * but WITHOUT ANY WARRANTY; without even the implied warranty of
17     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     * GNU Lesser General Public License for more details.
19     *
20     * You should have received a copy of the GNU Lesser General Public License
21     * along with this program; if not, write to the Free Software
22     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23     *
24     */
25 gezelter 1490
26 tim 1741 #include "UseTheForce/DUFF.hpp"
27 gezelter 1634 #include "UseTheForce/DarkSide/lj_interface.h"
28 tim 1758 #include "UseTheForce/DarkSide/charge_interface.h"
29     #include "UseTheForce/DarkSide/dipole_interface.h"
30     #include "UseTheForce/DarkSide/sticky_interface.h"
31 gezelter 1490
32 tim 1741 namespace oopse {
33 gezelter 1490
34 tim 1741 //definition of createDUFF
35     ForceField* createDUFF() {
36     return new DUFF();
37     }
38 gezelter 1490
39 tim 1758 //register createDUFF to ForceFieldFactory
40 tim 1741 ForceFieldFactory::getInstance()->registerForceField("DUFF", createDUFF);
41 gezelter 1490
42 tim 1757
43     ParseState DUFF::getSection(const std::string& section) {
44     ParseState result;
45    
46     switch(section) {
47     case "AtomTypes" :
48     result = DUFF::AtomTypeSection;
49     break;
50 tim 1758 case "DirectionalAtomTypes" :
51     result = DUFF::DirectionalAtomTypeSection;
52     break;
53 tim 1757
54     case "BondTypes" :
55     result = DUFF::BondTypeSection;
56     break;
57    
58     case "BendTypes" :
59     result = DUFF::BendTypeSection;
60     break;
61    
62     case "TorsionTypes" :
63     result = DUFF::TorsionTypeSection;
64     break;
65     default:
66     result = DUFF::UnknownSection;
67     }
68    
69     return result;
70     }
71    
72 tim 1741 void DUFF::parse(const std::string& filename) {
73     ifstrstream* ffStream;
74     ffStream = openForceFiledFile(filename);
75     const int bufferSize = 65535;
76 tim 1757 std::string line;
77     char buffer[bufferSize];
78 tim 1741 int lineNo = 0;
79 tim 1760 int atomIdent = getNAtomType() + 1; //atom's indent begins from 1 (since only fortran's array begins from 1)
80 tim 1757 ParseState currentSection = DUFF::UnknownSection;
81    
82     while(ffStream.getline(buffer, bufferSize)){
83 tim 1741 ++lineNo;
84 gezelter 1490
85 tim 1757 line = trimSpaces(buffer);
86     //a line begins with "//" is comment
87     if ( line.empty() || (line.size() >= 2 && line[0] == '/' && line[1] == '/')) {
88     continue;
89     } else {
90 gezelter 1490
91 tim 1757 switch(currentSection) {
92     case DUFF::AtomTypeSection :
93 tim 1759 parseAtomType(line, lineNo, atomIdent);
94 tim 1757 break;
95 gezelter 1490
96 tim 1759 case DUFF::DirectionalAtomTypeSection :
97     parseDirectionalAtomType(line, lineNo);
98     break;
99    
100 tim 1757 case DUFF::BondTypeSection :
101     parseBondType(line, lineNo);
102     break;
103 gezelter 1490
104 tim 1757 case DUFF::BendTypeSection :
105     parseBendType(line, lineNo);
106     break;
107    
108     case DUFF::TorsionTypeSection :
109     parseTorsionType(line, lineNo);
110     break;
111    
112     case DUFF::UnknownSection:
113     StringTokenizer tokenizer(line);
114    
115     std::string keyword = tokenizer.nextToken();
116     std::string section = tokenizer.nextToken();
117    
118     ParseState newSection = getSection(section);
119     if (keyword != "begin" || keyword != "end") {
120     std::cerr << "DUFF Parsing Error at line " << lineNo << ": " << line << std::endl;
121     } else if (keyword == "begin") {
122     if (newSection == DUFF::UnknownSection) {
123     std::cerr << "DUFF Parsing Error at line " << lineNo << ": " << line << std::endl;
124     } else {
125     //enter a new section
126     currentSection = newSection;
127     }
128    
129     } else if (keyword == "end"){
130     if (currentSection == newSection) ) {
131     //leave a section
132     currentSection = DUFF::UnknownSection;
133     } else {
134     std::cerr << "DUFF Parsing Error at line " << lineNo << ": " << line << std::endl;
135     }
136    
137     }
138     break;
139     default :
140 tim 1741
141     }
142 gezelter 1653
143 gezelter 1634 }
144 gezelter 1490 }
145    
146 tim 1741 delete ffStream;
147 gezelter 1490 }
148    
149    
150 tim 1758 void DUFF::parseAtomType(const std::string& line, int lineNo, int& ident){
151 tim 1757 StringTokenizer tokenizer(line);
152 tim 1758 int nTokens = tokenizer.countTokens();
153 tim 1757
154 tim 1758 //in AtomTypeSection, a line at least contains 5 tokens
155     //atomTypeName, is Directional, isLJ, isCharge and mass
156     if (nTokens < 5) {
157 tim 1759
158 tim 1758 } else {
159    
160     std::string atomTypeName = tokenizer.nextToken();
161     bool isDirectional = tokenizer.nextTokenAsBool();
162     bool isLJ = tokenizer.nextTokenAsBool();
163     bool isCharge = tokenizer.nextTokenAsBool();
164     double mass = tokenizer.nextTokenAsDouble();
165     double epsilon;
166     double sigma;
167     double charge;
168     nTokens -= 5;
169    
170     //parse epsilon and sigma
171     if (isLJ) {
172     if (nTokens >= 2) {
173     epsilon = tokenizer.nextTokenAsDouble();
174     sigma = tokenizer.nextTokenAsDouble();
175     nTokens -= 2;
176     } else {
177    
178     }
179     }
180    
181     //parse charge
182     if (isCharge) {
183     if (nTokens >= 1) {
184     charge = tokenizer.nextTokenAsDouble();
185     nTokens -= 1;
186     } else {
187    
188     }
189     }
190    
191     AtomType* atomType;
192     if (isDirectional) {
193     atomType = new DirectionalAtomType();
194     } else {
195     atomType = new AtomType();
196     }
197    
198 tim 1757 atomType->setName(atomTypeName);
199     atomType->setMass(mass);
200    
201 tim 1760 if (isLJ) {
202     atomType->setLennardJones();
203     }
204 tim 1757
205 tim 1760 if (isCharge) {
206     atomType->setCharge();
207     }
208    
209 tim 1758 atomType->setIdent(ident);
210    
211 tim 1757 atomType->complete();
212 tim 1758
213     int setLJStatus;
214    
215 tim 1757 //notify a new LJtype atom type is created
216 tim 1758 if (isLJ) {
217     newLJtype(&ident, &sigma, &epsilon, &setLJStatus);
218     }
219 tim 1757
220 tim 1758 int setChargeStatus;
221     if (isCharge) {
222     newChargeType(&ident, &charge, &setChargeStatus)
223     }
224    
225     if (setLJStatus && setChargeStatus) {
226     //add atom type to AtomTypeContainer
227     addAtomType(atomTypeName, atomType);
228     ++ident;
229     } else {
230     //error in notifying fortran
231     delete atomType;
232     }
233 tim 1757 }
234 tim 1758
235 gezelter 1490 }
236    
237 tim 1758
238     void DUFF::parseDirectionalAtomType(const std::string& line, int lineNo) {
239     StringTokenizer tokenizer(line);
240     int nTokens = tokenizer.countTokens();
241    
242     //in irectionalAtomTypeSection, a line at least contains 6 tokens
243     //AtomTypeName, isDipole, isSticky, I_xx, I_yy and I_zz
244     if (nTokens < 6) {
245    
246     } else {
247    
248    
249     std::string atomTypeName = tokenizer.nextToken();
250     bool isDipole = tokenizer.nextTokenAsBool();
251     bool isSticky = tokenizer.nextTokenAsBool();
252     double Ixx = tokenizer.nextTokenAsDouble();
253     double Iyy = tokenizer.nextTokenAsDouble();
254     double Izz = tokenizer.nextTokenAsDouble();
255     nTokens -= 6;
256    
257     AtomType* atomType = getAtomType(atomTypeName);
258     if (atomType == NULL) {
259    
260     }
261    
262     DirectionalAtomType* dAtomType = dynamic_cast<DirectionalAtomType*>(atomType);
263     if (dAtomType == NULL) {
264    
265    
266     }
267    
268 tim 1760 if (isDipole) {
269     dAtomType->setDipole();
270     }
271 tim 1758
272 tim 1760 if (isSticky) {
273     dAtomType->setSticky();
274     }
275    
276 tim 1758 Mat3x3d inertialMat;
277     inertialMat(0, 0) = Ixx;
278     inertialMat(1, 1) = Ixx;
279     inertialMat(2, 2) = Ixx;
280     dAtomType->setI(inertialMat);
281    
282     //read dipole moment
283     double dipole;
284     if (isDipole) {
285     if (nTokens >= 1) {
286     dipole = tokenizer.nextTokenAsDouble();
287     nTokens -= 1;
288     } else {
289    
290     }
291     }
292    
293     //read sticky parameters
294     double w0;
295     double v0;
296     double v0p;
297     double rl;
298     double ru;
299     double rlp;
300     double rup;
301     if (isSticky) {
302     if (nTokens >= 7) {
303     w0 = tokenizer.nextTokenAsDouble();
304     v0 = tokenizer.nextTokenAsDouble();
305     v0p = tokenizer.nextTokenAsDouble();
306     rl = tokenizer.nextTokenAsDouble();
307     ru = tokenizer.nextTokenAsDouble();
308     rlp = tokenizer.nextTokenAsDouble();
309     rup = tokenizer.nextTokenAsDouble();
310     nTokens -= 7;
311     } else {
312    
313     }
314     }
315    
316    
317     //notify fotran a newDipoleType is created
318     int ident = dAtomType->getIdent();
319     int setDipoleStatus;
320     if (isDipole) {
321     newDipoleType(&ident, &dipole, &setDipoleStatus);
322     }
323    
324     //notify fotran a StickyType is created
325     int setStickyStatus;
326     if (isSticky) {
327     makeStickyType( &w0, &v0, &v0p, &rl, &ru, &rlp, &rup);
328     }
329    
330    
331     if (!setDipoleStatus || !setStickyStatus) {
332    
333     }
334    
335     }
336     }
337    
338 tim 1757 void DUFF::parseBondType(const std::string& line, int lineNo){
339    
340     StringTokenizer tokenizer(line);
341     std::string at1;
342     std::string at2;
343     std::string bt;
344     BondType* bondType = NULL;
345     double b0;
346    
347     int nTokens = tokenizer.countTokens();
348    
349     if (nTokens < 4) {
350    
351     return;
352     }
353    
354     at1 = tokenizer.nextToken();
355     at2 = tokenizer.nextToken();
356     bt = tokenizer.nextToken();
357     b0 = tokenizer.nextTokenAsDouble();
358     nTokens -= 4;
359    
360     //switch is a maintain nightmare
361     switch(bt) {
362     case "FixedBondType" :
363     bondType = new FixedBondType();
364     break;
365    
366     case "HarmonicBondType" :
367     if (nTokens < 1) {
368    
369     } else {
370    
371     double kb = tokenizer.nextTokenAsDouble();
372     bondType = new HarmonicBondType(b0, kb);
373     }
374    
375     break;
376    
377     case "CubicBondType" :
378     if (nTokens < 4) {
379    
380     } else {
381    
382     double k3 = tokenizer.nextTokenAsDouble();
383     double k2 = tokenizer.nextTokenAsDouble();
384     double k1 = tokenizer.nextTokenAsDouble();
385     double k0 = tokenizer.nextTokenAsDouble();
386    
387     bondType = new CubicBondType(b0, k3, k2, k1, k0);
388     }
389     break;
390    
391     case "QuadraticBondType" :
392     if (nTokens < 5) {
393    
394     } else {
395    
396     b0 = tokenizer.nextTokenAsDouble();
397     double k4 = tokenizer.nextTokenAsDouble();
398     double k3 = tokenizer.nextTokenAsDouble();
399     double k2 = tokenizer.nextTokenAsDouble();
400     double k1 = tokenizer.nextTokenAsDouble();
401     double k0 = tokenizer.nextTokenAsDouble();
402    
403     bondType = new QuadraticBondType(b0, k4, k3, k2, k1, k0);
404     }
405     break;
406    
407     case "PolynomialBondType " :
408     if (nTokens < 2 || nTokens % 2 != 0) {
409    
410     } else {
411     int nPairs = nTokens / 2;
412     int power;
413     double coefficient;
414     PolynomialBondType pbt = new PolynomialBondType();
415    
416     for (int i = 0; i < nPairs; ++i) {
417     power = tokenizer.nextTokenAsInt();
418     coefficient = tokenizer.nextTokenAsDouble();
419 tim 1758 pbt->setCoefficient(power, coefficient);
420 tim 1757 }
421     }
422    
423     break;
424    
425     default:
426    
427     }
428    
429     if (bondType != NULL) {
430     addBondType(at1, at2, bondType);
431     }
432 gezelter 1490 }
433    
434 tim 1757 void DUFF::parseBendType(const std::string& line, int lineNo){
435     StringTokenizer tokenizer(line);
436     std::string at1;
437     std::string at2;
438     std::string at3;
439     std::string bt;
440     double theta0;
441     BendType* bendType = NULL;
442    
443     int nTokens = tokenizer.countTokens();
444    
445     if (nTokens < 5) {
446    
447     return;
448     }
449    
450     at1 = tokenizer.nextToken();
451     at2 = tokenizer.nextToken();
452     at3 = tokenizer.nextToken();
453     bt = tokenizer.nextToken();
454     theta0 = tokenizer.nextTokenAsDouble();
455     nTokens -= 5;
456    
457     //switch is a maintain nightmare
458     switch(bt) {
459    
460     case "HarmonicBendType" :
461    
462     if (nTokens < 1) {
463    
464     } else {
465    
466     double ktheta = tokenizer.nextTokenAsDouble();
467     bendType = new HarmonicBendType(theta0, ktheta);
468     }
469     break;
470     case "GhostBendType" :
471     if (nTokens < 1) {
472    
473     } else {
474     double ktheta = tokenizer.nextTokenAsDouble();
475     bendType = new HarmonicBendType(theta0, ktheta);
476     }
477     break;
478    
479     case "UreyBradleyBendType" :
480     if (nTokens < 3) {
481    
482     } else {
483     double ktheta = tokenizer.nextTokenAsDouble();
484     double s0 = tokenizer.nextTokenAsDouble();
485     double kub = tokenizer.nextTokenAsDouble();
486     bendType = new UreyBradleyBendType(theta0, ktheta, s0, kub);
487     }
488     break;
489    
490     case "CubicBendType" :
491     if (nTokens < 4) {
492    
493     } else {
494    
495     double k3 = tokenizer.nextTokenAsDouble();
496     double k2 = tokenizer.nextTokenAsDouble();
497     double k1 = tokenizer.nextTokenAsDouble();
498     double k0 = tokenizer.nextTokenAsDouble();
499    
500     bendType = new CubicBendType(theta0, k3, k2, k1, k0);
501     }
502     break;
503    
504     case "QuadraticBendType" :
505     if (nTokens < 5) {
506    
507     } else {
508    
509     theta0 = tokenizer.nextTokenAsDouble();
510     double k4 = tokenizer.nextTokenAsDouble();
511     double k3 = tokenizer.nextTokenAsDouble();
512     double k2 = tokenizer.nextTokenAsDouble();
513     double k1 = tokenizer.nextTokenAsDouble();
514     double k0 = tokenizer.nextTokenAsDouble();
515    
516     bendType = new QuadraticBendType(theta0, k4, k3, k2, k1, k0);
517     }
518     break;
519    
520     case "PolynomialBendType " :
521     if (nTokens < 2 || nTokens % 2 != 0) {
522    
523     } else {
524     int nPairs = nTokens / 2;
525     int power;
526     double coefficient;
527     PolynomialBendType* pbt = new PolynomialBendType();
528    
529     for (int i = 0; i < nPairs; ++i) {
530     power = tokenizer.nextTokenAsInt();
531     coefficient = tokenizer.nextTokenAsDouble();
532 tim 1758 pbt->setCoefficient(power, coefficient);
533 tim 1757 }
534     }
535    
536     break;
537    
538     default:
539    
540     }
541    
542     if (bendType != NULL) {
543     addBendType(at1, at2, at3, bendType);
544     }
545    
546 gezelter 1490 }
547    
548 tim 1757 void DUFF::parseTorsionType(const std::string& line, int lineNo){
549     StringTokenizer tokenizer(line);
550     std::string at1;
551     std::string at2;
552     std::string at3;
553     std::string at4;
554     std::string tt;
555     TorsionType* bendType = NULL;
556 gezelter 1490
557 tim 1757 int nTokens = tokenizer.countTokens();
558    
559     if (nTokens < 5) {
560    
561     return;
562     }
563    
564     at1 = tokenizer.nextToken();
565     at2 = tokenizer.nextToken();
566     at3 = tokenizer.nextToken();
567     at4 = tokenizer.nextToken();
568     tt = tokenizer.nextToken();
569    
570     nTokens -= 5;
571    
572     switch(tt) {
573    
574     case "CubicTorsionType" :
575     if (nTokens < 4) {
576    
577     } else {
578    
579     double k3 = tokenizer.nextTokenAsDouble();
580     double k2 = tokenizer.nextTokenAsDouble();
581     double k1 = tokenizer.nextTokenAsDouble();
582     double k0 = tokenizer.nextTokenAsDouble();
583    
584     bendType = new CubicTorsionType(k3, k2, k1, k0);
585     }
586     break;
587    
588     case "QuadraticTorsionType" :
589     if (nTokens < 5) {
590    
591     } else {
592    
593     theta0 = tokenizer.nextTokenAsDouble();
594     double k4 = tokenizer.nextTokenAsDouble();
595     double k3 = tokenizer.nextTokenAsDouble();
596     double k2 = tokenizer.nextTokenAsDouble();
597     double k1 = tokenizer.nextTokenAsDouble();
598     double k0 = tokenizer.nextTokenAsDouble();
599    
600     bendType = new QuadraticTorsionType( k4, k3, k2, k1, k0);
601     }
602     break;
603    
604     case "PolynomialTorsionType " :
605     if (nTokens < 2 || nTokens % 2 != 0) {
606    
607     } else {
608     int nPairs = nTokens / 2;
609     int power;
610     double coefficient;
611     PolynomialTorsionType* pbt = new PolynomialTorsionType();
612    
613     for (int i = 0; i < nPairs; ++i) {
614     power = tokenizer.nextTokenAsInt();
615     coefficient = tokenizer.nextTokenAsDouble();
616 tim 1758 pbt->setCoefficient(power, coefficient);
617 tim 1757 }
618     }
619    
620     break;
621     case "CharmmTorsionType" :
622    
623     if (nTokens < 3 || nTokens % 3 != 0) {
624    
625     } else {
626     int nSets = nTokens / 3;
627    
628     CharmmTorsionType* ctt = new CharmmTorsionType();
629    
630     for (int i = 0; i < nSets; ++i) {
631 tim 1758 double kchi = tokenizer.nextTokenAsDouble();
632     int n = tokenizer.nextTokenAsInt();
633     double delta = tokenizer.nextTokenAsDouble();
634 tim 1757
635 tim 1758 ctt->setCharmmTorsionParameter(kchi, n, delta);
636 tim 1757 }
637     }
638     default:
639    
640     }
641    
642     if (bendType != NULL) {
643     addTorsionType(at1, at2, at3, bendType);
644     }
645 gezelter 1490 }
646    
647 tim 1741 } //end namespace oopse