ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/brains/ForceField.cpp
Revision: 1303
Committed: Mon Oct 13 21:35:22 2008 UTC (16 years, 6 months ago) by cli2
Original Path: trunk/src/UseTheForce/ForceField.cpp
File size: 19562 byte(s)
Log Message:
Fixes for Inversions for use with Amber

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