ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/UseTheForce/Shapes_FF.cpp
Revision: 2189
Committed: Wed Apr 13 20:36:45 2005 UTC (19 years, 4 months ago) by chuckv
File size: 18385 byte(s)
Log Message:
Added destroy methods for Fortran modules.

File Contents

# User Rev Content
1 gezelter 1930 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 chrisfen 1646 *
4 gezelter 1930 * 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 chrisfen 1646 *
9 gezelter 1930 * 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 chrisfen 1646 */
41 gezelter 1930
42 gezelter 1520 #include <stdlib.h>
43     #include <stdio.h>
44     #include <string.h>
45 chrisfen 1646 #include <map>
46 gezelter 1650 #include <cmath>
47 chrisfen 1646 #include <iostream>
48 gezelter 1520
49     #ifdef IS_MPI
50     #include <mpi.h>
51     #endif //is_mpi
52    
53     #include "UseTheForce/ForceFields.hpp"
54     #include "primitives/SRI.hpp"
55     #include "utils/simError.h"
56 gezelter 1650 #include "utils/StringUtils.hpp"
57 chrisfen 1646 #include "io/basic_ifstrstream.hpp"
58     #include "math/RealSphericalHarmonic.hpp"
59     #include "math/SquareMatrix3.hpp"
60 gezelter 1650 #include "types/ShapeAtomType.hpp"
61 chrisfen 1646 #include "UseTheForce/DarkSide/atype_interface.h"
62 gezelter 1613 #include "UseTheForce/DarkSide/shapes_interface.h"
63 gezelter 1520
64     #ifdef IS_MPI
65     #include "UseTheForce/mpiForceField.h"
66     #endif // is_mpi
67    
68 gezelter 1930
69 gezelter 1650 using namespace oopse;
70 gezelter 1520
71     Shapes_FF::~Shapes_FF(){
72    
73 chuckv 2189 destroyShapeTypes();
74 gezelter 1520 #ifdef IS_MPI
75     if( worldRank == 0 ){
76     #endif // is_mpi
77    
78 gezelter 1650 forceFile.close();
79 gezelter 1520
80     #ifdef IS_MPI
81     }
82     #endif // is_mpi
83     }
84    
85    
86     void Shapes_FF::calcRcut( void ){
87    
88     #ifdef IS_MPI
89 chrisfen 1688 double tempShapesRcut = bigContact;
90 gezelter 1520 MPI_Allreduce( &tempShapesRcut, &shapesRcut, 1, MPI_DOUBLE, MPI_MAX,
91     MPI_COMM_WORLD);
92 chrisfen 1688 #else
93     shapesRcut = bigContact;
94 gezelter 1520 #endif //is_mpi
95     entry_plug->setDefaultRcut(shapesRcut);
96     }
97    
98    
99 gezelter 1628 void Shapes_FF::initForceField(){
100     initFortran(0);
101 gezelter 1520 }
102    
103    
104 gezelter 1650 void Shapes_FF::readParams( void ){
105 gezelter 1520
106 chrisfen 1646 char readLine[1024];
107 gezelter 1650
108 gezelter 1930 std::string fileName;
109     std::string shapeFileName;
110     std::string tempString;
111 gezelter 1650
112 chrisfen 1646 char *nameToken;
113     char *delim = " ,;\t\n";
114     int nTokens, i;
115     int nContact = 0;
116     int nRange = 0;
117     int nStrength = 0;
118     int myATID;
119 gezelter 1650 int isError;
120 gezelter 1930 std::string nameString;
121 gezelter 1650 AtomType* at;
122     DirectionalAtomType* dat;
123     ShapeAtomType* st;
124    
125 gezelter 1930 std::map<string, AtomType*>::iterator iter;
126 gezelter 1520
127 chrisfen 1646 // vectors for shape transfer to fortran
128 gezelter 1930 std::vector<RealSphericalHarmonic*> tempSHVector;
129     std::vector<int> contactL;
130     std::vector<int> contactM;
131     std::vector<int> contactFunc;
132     std::vector<double> contactCoeff;
133     std::vector<int> rangeL;
134     std::vector<int> rangeM;
135     std::vector<int> rangeFunc;
136     std::vector<double> rangeCoeff;
137     std::vector<int> strengthL;
138     std::vector<int> strengthM;
139     std::vector<int> strengthFunc;
140     std::vector<double> strengthCoeff;
141 chrisfen 1646
142     // generate the force file name
143 gezelter 1650 fileName = "Shapes.frc";
144 chrisfen 1646
145     // attempt to open the file in the current directory first.
146 gezelter 1650 forceFile.open( fileName.c_str() );
147 chrisfen 1646
148 gezelter 1650 if( forceFile == NULL ){
149 gezelter 1520
150 gezelter 1650 tempString = ffPath;
151     tempString += "/";
152     tempString += fileName;
153     fileName = tempString;
154 gezelter 1520
155 gezelter 1650 forceFile.open( fileName.c_str() );
156 gezelter 1520
157 gezelter 1650 if( forceFile == NULL ){
158 chrisfen 1646
159     sprintf( painCave.errMsg,
160     "Error opening the force field parameter file:\n"
161     "\t%s\n"
162     "\tHave you tried setting the FORCE_PARAM_PATH environment "
163     "variable?\n",
164 gezelter 1650 fileName.c_str() );
165 chrisfen 1646 painCave.severity = OOPSE_ERROR;
166 gezelter 1520 painCave.isFatal = 1;
167     simError();
168     }
169 chrisfen 1646 }
170    
171     // read in the shape types.
172    
173 gezelter 1650 findBegin( forceFile, "ShapeTypes" );
174 chrisfen 1646
175 gezelter 1650 while( !forceFile.eof() ){
176     forceFile.getline( readLine, sizeof(readLine) );
177 gezelter 1520
178 chrisfen 1646 // toss comment lines
179     if( readLine[0] != '!' && readLine[0] != '#' ){
180    
181     if (isEndLine(readLine)) break;
182    
183 gezelter 1650 nTokens = countTokens(readLine, " ,;\t");
184 chrisfen 1646 if (nTokens != 0) {
185     if (nTokens < 2) {
186     sprintf( painCave.errMsg,
187 gezelter 1650 "Not enough data on a ShapeTypes line in file: %s\n",
188     fileName.c_str() );
189 chrisfen 1646 painCave.severity = OOPSE_ERROR;
190     painCave.isFatal = 1;
191     simError();
192     }
193 gezelter 1520
194 chrisfen 1646 nameToken = strtok( readLine, delim );
195     shapeFileName = strtok( NULL, delim );
196 gezelter 1520
197 chrisfen 1646 // strings are not char arrays!
198     nameString = nameToken;
199 gezelter 1520
200 chrisfen 1646 // does this AtomType name already exist in the map?
201     iter = atomTypeMap.find(nameString);
202     if (iter == atomTypeMap.end()) {
203     // no, it doesn't, so we may proceed:
204    
205 gezelter 1650 st = new ShapeAtomType();
206 gezelter 1520
207 chrisfen 1646 st->setName(nameString);
208 chrisfen 1688 myATID = atomTypeMap.size() + 1;
209 chrisfen 1646 st->setIdent(myATID);
210     parseShapeFile(shapeFileName, st);
211     st->complete();
212     atomTypeMap.insert(make_pair(nameString, st));
213    
214     } else {
215 gezelter 1930 // atomType map already contained this std::string (i.e. it was
216 chrisfen 1646 // declared in a previous block, and we just need to add
217     // the shape-specific information for this AtomType:
218 gezelter 1520
219 gezelter 1650 st = (ShapeAtomType*)(iter->second);
220 chrisfen 1646 parseShapeFile(shapeFileName, st);
221     }
222     }
223 gezelter 1520 }
224     }
225    
226 chrisfen 1646 #ifdef IS_MPI
227 gezelter 1520
228 chrisfen 1646 // looks like all the processors have their ShapeType vectors ready...
229     sprintf( checkPointMsg,
230     "Shapes_FF shape objects read successfully." );
231     MPIcheckPoint();
232 gezelter 1520
233 chrisfen 1646 #endif // is_mpi
234 gezelter 1520
235 chrisfen 1646 // pack up and send the necessary info to fortran
236     for (iter = atomTypeMap.begin(); iter != atomTypeMap.end(); ++iter){
237 gezelter 1520
238 gezelter 1650 at = (AtomType*)(iter->second);
239 gezelter 1520
240 chrisfen 1646 if (at->isDirectional()) {
241 gezelter 1520
242 chrisfen 1646 dat = (DirectionalAtomType*)at;
243 gezelter 1520
244 chrisfen 1646 if (dat->isShape()) {
245 gezelter 1520
246 chrisfen 1646 st = (ShapeAtomType*)at;
247    
248     contactL.clear();
249     contactM.clear();
250     contactFunc.clear();
251     contactCoeff.clear();
252    
253     tempSHVector = st->getContactFuncs();
254    
255     nContact = tempSHVector.size();
256     for (i=0; i<nContact; i++){
257 gezelter 1650 contactL.push_back(tempSHVector[i]->getL());
258     contactM.push_back(tempSHVector[i]->getM());
259     contactFunc.push_back(tempSHVector[i]->getFunctionType());
260     contactCoeff.push_back(tempSHVector[i]->getCoefficient());
261 chrisfen 1646 }
262    
263     rangeL.clear();
264     rangeM.clear();
265     rangeFunc.clear();
266     rangeCoeff.clear();
267    
268     tempSHVector = st->getRangeFuncs();
269    
270     nRange = tempSHVector.size();
271     for (i=0; i<nRange; i++){
272 gezelter 1650 rangeL.push_back(tempSHVector[i]->getL());
273     rangeM.push_back(tempSHVector[i]->getM());
274     rangeFunc.push_back(tempSHVector[i]->getFunctionType());
275     rangeCoeff.push_back(tempSHVector[i]->getCoefficient());
276 chrisfen 1646 }
277    
278     strengthL.clear();
279     strengthM.clear();
280     strengthFunc.clear();
281     strengthCoeff.clear();
282    
283     tempSHVector = st->getStrengthFuncs();
284    
285     nStrength = tempSHVector.size();
286     for (i=0; i<nStrength; i++){
287 gezelter 1650 strengthL.push_back(tempSHVector[i]->getL());
288     strengthM.push_back(tempSHVector[i]->getM());
289     strengthFunc.push_back(tempSHVector[i]->getFunctionType());
290     strengthCoeff.push_back(tempSHVector[i]->getCoefficient());
291 chrisfen 1646 }
292    
293     isError = 0;
294     myATID = at->getIdent();
295 chrisfen 1688
296 gezelter 1650 makeShape( &nContact, &contactL[0], &contactM[0], &contactFunc[0],
297     &contactCoeff[0],
298     &nRange, &rangeL[0], &rangeM[0], &rangeFunc[0],
299     &rangeCoeff[0],
300     &nStrength, &strengthL[0], &strengthM[0],
301     &strengthFunc[0], &strengthCoeff[0],
302 chrisfen 1646 &myATID,
303     &isError);
304 chrisfen 1688
305 chrisfen 1646 if( isError ){
306     sprintf( painCave.errMsg,
307     "Error initializing the \"%s\" shape in fortran\n",
308 gezelter 1650 (iter->first).c_str() );
309 chrisfen 1646 painCave.isFatal = 1;
310     simError();
311     }
312     }
313 gezelter 1520 }
314     }
315    
316 chrisfen 1688 isError = 0;
317     completeShapeFF(&isError);
318     if( isError ){
319     sprintf( painCave.errMsg,
320     "Error completing Shape FF in fortran\n");
321     painCave.isFatal = 1;
322     simError();
323     }
324    
325 gezelter 1520 #ifdef IS_MPI
326     sprintf( checkPointMsg,
327     "Shapes_FF atom structures successfully sent to fortran\n" );
328     MPIcheckPoint();
329     #endif // is_mpi
330    
331     }
332    
333 gezelter 1650 void Shapes_FF::cleanMe( void ){
334    
335     }
336    
337     void Shapes_FF::initializeAtoms( int nAtoms, Atom** the_atoms ){
338 chrisfen 1646
339     int i,j,k;
340 gezelter 1930 std::map<string, AtomType*>::iterator iter;
341 gezelter 1520
342     // initialize the atoms
343 chrisfen 1646 DirectionalAtom* dAtom;
344     AtomType* at;
345     DirectionalAtomType* dat;
346 gezelter 1650 ShapeAtomType* sat;
347 chrisfen 1688 double longCutoff;
348 chrisfen 1646 double ji[3];
349     double inertialMat[3][3];
350     Mat3x3d momInt;
351 gezelter 1930 std::string myTypeString;
352 chrisfen 1646
353 chrisfen 1688 bigContact = 0.0;
354    
355 gezelter 1520 for( i=0; i<nAtoms; i++ ){
356    
357 gezelter 1930 myTypeString = the_atoms[i]->getType().c_str();
358 chrisfen 1646 iter = atomTypeMap.find(myTypeString);
359    
360     if (iter == atomTypeMap.end()) {
361 gezelter 1520 sprintf( painCave.errMsg,
362     "AtomType error, %s not found in force file.\n",
363 gezelter 1930 the_atoms[i]->getType().c_str() );
364 gezelter 1520 painCave.isFatal = 1;
365     simError();
366 chrisfen 1646 } else {
367 gezelter 1520
368 chrisfen 1646 at = (AtomType*)(iter->second);
369 gezelter 1520
370 chrisfen 1646 the_atoms[i]->setMass( at->getMass() );
371     the_atoms[i]->setIdent( at->getIdent() );
372 gezelter 1650
373     if ( at->isShape() ) {
374    
375     sat = (ShapeAtomType*)at;
376 chrisfen 1688 longCutoff = findCutoffDistance(sat);
377     if (longCutoff > bigContact) bigContact = longCutoff;
378     cout << bigContact << " is the cutoff value\n";
379    
380     entry_plug->useShapes = 1;
381 chrisfen 1646 }
382 gezelter 1520
383 chrisfen 1646 the_atoms[i]->setHasCharge(at->isCharge());
384 gezelter 1520
385 chrisfen 1646 if( at->isDirectional() ){
386 gezelter 1520
387 chrisfen 1646 dat = (DirectionalAtomType*)at;
388     dAtom = (DirectionalAtom *) the_atoms[i];
389 gezelter 1672
390 chrisfen 1646 momInt = dat->getI();
391 gezelter 1520
392 chrisfen 1646 // zero out the moments of inertia matrix
393     for( j=0; j<3; j++ )
394     for( k=0; k<3; k++ )
395     inertialMat[j][k] = momInt(j,k);
396     dAtom->setI( inertialMat );
397 gezelter 1520
398 chrisfen 1646 ji[0] = 0.0;
399     ji[1] = 0.0;
400     ji[2] = 0.0;
401     dAtom->setJ( ji );
402 gezelter 1520
403 chrisfen 1646 if (dat->isDipole()) {
404     dAtom->setHasDipole( dat->isDipole() );
405     entry_plug->n_dipoles++;
406     }
407     }
408 gezelter 1520 }
409     }
410     }
411    
412 chrisfen 1646 void Shapes_FF::initializeBonds( int nBonds, Bond** BondArray,
413     bond_pair* the_bonds ){
414 gezelter 1520
415 chrisfen 1646 if( nBonds ){
416 gezelter 1520 sprintf( painCave.errMsg,
417 chrisfen 1646 "Shapes_FF does not support bonds.\n" );
418 gezelter 1520 painCave.isFatal = 1;
419     simError();
420     }
421 chrisfen 1646 }
422 gezelter 1520
423 chrisfen 1646 void Shapes_FF::initializeBends( int nBends, Bend** bendArray,
424     bend_set* the_bends ){
425    
426     if( nBends ){
427 gezelter 1520 sprintf( painCave.errMsg,
428 chrisfen 1646 "Shapes_FF does not support bends.\n" );
429 gezelter 1520 painCave.isFatal = 1;
430     simError();
431     }
432 chrisfen 1646 }
433 gezelter 1520
434 chrisfen 1646 void Shapes_FF::initializeTorsions( int nTorsions, Torsion** torsionArray,
435     torsion_set* the_torsions ){
436 gezelter 1520
437 chrisfen 1646 if( nTorsions ){
438 gezelter 1520 sprintf( painCave.errMsg,
439 chrisfen 1646 "Shapes_FF does not support torsions.\n" );
440 gezelter 1520 painCave.isFatal = 1;
441     simError();
442     }
443 chrisfen 1646 }
444 gezelter 1520
445 gezelter 1650 void Shapes_FF::parseShapeFile(string shapeFileName, ShapeAtomType* st){
446 chrisfen 1646 const int MAXLEN = 1024;
447     char inLine[MAXLEN];
448     char *token;
449     char *delim = " ,;\t\n";
450 gezelter 1650 int nTokens;
451 chrisfen 1646 Mat3x3d momInert;
452 gezelter 1650 RealSphericalHarmonic* rsh;
453 gezelter 1930 std::vector<RealSphericalHarmonic*> functionVector;
454 gezelter 1650 ifstrstream shapeFile;
455 gezelter 1930 std::string tempString;
456 gezelter 1520
457 gezelter 1650 shapeFile.open( shapeFileName.c_str() );
458 gezelter 1520
459 gezelter 1650 if( shapeFile == NULL ){
460    
461     tempString = ffPath;
462     tempString += "/";
463     tempString += shapeFileName;
464     shapeFileName = tempString;
465    
466     shapeFile.open( shapeFileName.c_str() );
467    
468     if( shapeFile == NULL ){
469    
470     sprintf( painCave.errMsg,
471     "Error opening the shape file:\n"
472     "\t%s\n"
473     "\tHave you tried setting the FORCE_PARAM_PATH environment "
474     "variable?\n",
475     shapeFileName.c_str() );
476     painCave.severity = OOPSE_ERROR;
477     painCave.isFatal = 1;
478     simError();
479     }
480     }
481    
482     // read in the shape types.
483    
484 chrisfen 1646 // first grab the values in the ShapeInfo section
485 gezelter 1650 findBegin( shapeFile, "ShapeInfo");
486 gezelter 1520
487 chrisfen 1646 shapeFile.getline(inLine, MAXLEN);
488     while( !shapeFile.eof() ) {
489     // toss comment lines
490     if( inLine[0] != '!' && inLine[0] != '#' ){
491     // end marks section completion
492     if (isEndLine(inLine)) break;
493    
494 gezelter 1650 nTokens = countTokens(inLine, delim);
495 chrisfen 1646 if (nTokens != 0) {
496     if (nTokens < 5) {
497     sprintf( painCave.errMsg,
498 gezelter 1650 "Not enough data on a ShapeInfo line in file: %s\n",
499     shapeFileName.c_str() );
500 chrisfen 1646 painCave.severity = OOPSE_ERROR;
501     painCave.isFatal = 1;
502     simError();
503 chrisfen 1688 } else {
504 chrisfen 1646 token = strtok(inLine, delim);
505     token = strtok(NULL, delim);
506     st->setMass(atof(token));
507     token = strtok(NULL, delim);
508     momInert(0,0) = atof(token);
509     token = strtok(NULL, delim);
510     momInert(1,1) = atof(token);
511     token = strtok(NULL, delim);
512     momInert(2,2) = atof(token);
513     st->setI(momInert);
514     }
515     }
516 gezelter 1520 }
517 gezelter 1672 shapeFile.getline(inLine, MAXLEN);
518 gezelter 1520 }
519    
520 chrisfen 1646 // now grab the contact functions
521     findBegin(shapeFile, "ContactFunctions");
522     functionVector.clear();
523 gezelter 1520
524 chrisfen 1646 shapeFile.getline(inLine, MAXLEN);
525     while( !shapeFile.eof() ) {
526     // toss comment lines
527     if( inLine[0] != '!' && inLine[0] != '#' ){
528     // end marks section completion
529     if (isEndLine(inLine)) break;
530 gezelter 1650 nTokens = countTokens(inLine, delim);
531 chrisfen 1646 if (nTokens != 0) {
532     if (nTokens < 4) {
533     sprintf( painCave.errMsg,
534 gezelter 1650 "Not enough data on a ContactFunctions line in file: %s\n",
535     shapeFileName.c_str() );
536 chrisfen 1646 painCave.severity = OOPSE_ERROR;
537     painCave.isFatal = 1;
538     simError();
539 chrisfen 1688 } else {
540 chrisfen 1646 // read in a spherical harmonic function
541     token = strtok(inLine, delim);
542 gezelter 1650 rsh = new RealSphericalHarmonic();
543     rsh->setL(atoi(token));
544 chrisfen 1646 token = strtok(NULL, delim);
545 gezelter 1650 rsh->setM(atoi(token));
546 chrisfen 1646 token = strtok(NULL, delim);
547     if (!strcasecmp("sin",token))
548 gezelter 1650 rsh->makeSinFunction();
549 chrisfen 1646 else
550 gezelter 1650 rsh->makeCosFunction();
551 chrisfen 1646 token = strtok(NULL, delim);
552 gezelter 1650 rsh->setCoefficient(atof(token));
553 chrisfen 1646
554 gezelter 1650 functionVector.push_back(rsh);
555 chrisfen 1646 }
556     }
557 gezelter 1520 }
558 gezelter 1672 shapeFile.getline(inLine, MAXLEN);
559 gezelter 1520 }
560    
561 chrisfen 1646 // pass contact functions to ShapeType
562 chrisfen 1688
563 chrisfen 1646 st->setContactFuncs(functionVector);
564 gezelter 1520
565 chrisfen 1646 // now grab the range functions
566     findBegin(shapeFile, "RangeFunctions");
567     functionVector.clear();
568 gezelter 1520
569 chrisfen 1646 shapeFile.getline(inLine, MAXLEN);
570     while( !shapeFile.eof() ) {
571     // toss comment lines
572     if( inLine[0] != '!' && inLine[0] != '#' ){
573     // end marks section completion
574     if (isEndLine(inLine)) break;
575    
576 gezelter 1650 nTokens = countTokens(inLine, delim);
577 chrisfen 1646 if (nTokens != 0) {
578     if (nTokens < 4) {
579     sprintf( painCave.errMsg,
580 gezelter 1650 "Not enough data on a RangeFunctions line in file: %s\n",
581     shapeFileName.c_str() );
582 chrisfen 1646 painCave.severity = OOPSE_ERROR;
583     painCave.isFatal = 1;
584     simError();
585 chrisfen 1688 } else {
586 chrisfen 1646
587     // read in a spherical harmonic function
588     token = strtok(inLine, delim);
589 gezelter 1650
590     rsh = new RealSphericalHarmonic();
591     rsh->setL(atoi(token));
592 chrisfen 1646 token = strtok(NULL, delim);
593 gezelter 1650 rsh->setM(atoi(token));
594 chrisfen 1646 token = strtok(NULL, delim);
595     if (!strcasecmp("sin",token))
596 gezelter 1650 rsh->makeSinFunction();
597 chrisfen 1646 else
598 gezelter 1650 rsh->makeCosFunction();
599 chrisfen 1646 token = strtok(NULL, delim);
600 gezelter 1650 rsh->setCoefficient(atof(token));
601 chrisfen 1646
602 gezelter 1650 functionVector.push_back(rsh);
603 chrisfen 1646 }
604     }
605 gezelter 1520 }
606 gezelter 1672 shapeFile.getline(inLine, MAXLEN);
607 chrisfen 1646 }
608 gezelter 1520
609 chrisfen 1646 // pass range functions to ShapeType
610     st->setRangeFuncs(functionVector);
611 gezelter 1520
612 chrisfen 1646 // finally grab the strength functions
613     findBegin(shapeFile, "StrengthFunctions");
614     functionVector.clear();
615 gezelter 1520
616 chrisfen 1646 shapeFile.getline(inLine, MAXLEN);
617     while( !shapeFile.eof() ) {
618     // toss comment lines
619     if( inLine[0] != '!' && inLine[0] != '#' ){
620     // end marks section completion
621     if (isEndLine(inLine)) break;
622    
623 gezelter 1650 nTokens = countTokens(inLine, delim);
624 chrisfen 1646 if (nTokens != 0) {
625     if (nTokens < 4) {
626     sprintf( painCave.errMsg,
627 gezelter 1650 "Not enough data on a StrengthFunctions line in file: %s\n",
628     shapeFileName.c_str() );
629 chrisfen 1646 painCave.severity = OOPSE_ERROR;
630     painCave.isFatal = 1;
631     simError();
632 chrisfen 1688 } else {
633 chrisfen 1646
634     // read in a spherical harmonic function
635     token = strtok(inLine, delim);
636 gezelter 1650 rsh = new RealSphericalHarmonic();
637     rsh->setL(atoi(token));
638 chrisfen 1646 token = strtok(NULL, delim);
639 gezelter 1650 rsh->setM(atoi(token));
640 chrisfen 1646 token = strtok(NULL, delim);
641     if (!strcasecmp("sin",token))
642 gezelter 1650 rsh->makeSinFunction();
643 chrisfen 1646 else
644 gezelter 1650 rsh->makeCosFunction();
645 chrisfen 1646 token = strtok(NULL, delim);
646 gezelter 1650 rsh->setCoefficient(atof(token));
647 chrisfen 1646
648 gezelter 1650 functionVector.push_back(rsh);
649 chrisfen 1646 }
650     }
651 gezelter 1520 }
652 gezelter 1672 shapeFile.getline(inLine, MAXLEN);
653 gezelter 1520 }
654    
655 chrisfen 1646 // pass strength functions to ShapeType
656     st->setStrengthFuncs(functionVector);
657    
658     // we're done reading from this file
659     shapeFile.close();
660 gezelter 1520 }
661 chrisfen 1646
662 gezelter 1650 double Shapes_FF::findLargestContactDistance(ShapeAtomType* st) {
663     int i, j, nSteps;
664     double theta, thetaStep, thetaMin, costheta;
665     double phi, phiStep;
666 chrisfen 1688 double sigma, bs;
667    
668 gezelter 1650 nSteps = 16;
669    
670     thetaStep = M_PI / nSteps;
671     thetaMin = thetaStep / 2.0;
672     phiStep = thetaStep * 2.0;
673 chrisfen 1688 bs = 0.0;
674 gezelter 1650
675     for (i = 0; i < nSteps; i++) {
676    
677     theta = thetaMin + i * thetaStep;
678     costheta = cos(theta);
679    
680     for (j = 0; j < nSteps; j++) {
681    
682     phi = j*phiStep;
683    
684     sigma = st->getContactValueAt(costheta, phi);
685    
686 chrisfen 1688 if (sigma > bs) bs = sigma;
687 gezelter 1650 }
688     }
689    
690 chrisfen 1688 return bs;
691 gezelter 1650 }
692 chrisfen 1688
693    
694     double Shapes_FF::findCutoffDistance(ShapeAtomType* st) {
695     int i, j, nSteps;
696     double theta, thetaStep, thetaMin, costheta;
697     double phi, phiStep;
698     double sigma, range;
699     double bigCut, tempCut;
700    
701     nSteps = 16;
702    
703     thetaStep = M_PI / nSteps;
704     thetaMin = thetaStep / 2.0;
705     phiStep = thetaStep * 2.0;
706     bigCut = 0.0;
707    
708     for (i = 0; i < nSteps; i++) {
709    
710     theta = thetaMin + i * thetaStep;
711     costheta = cos(theta);
712    
713     for (j = 0; j < nSteps; j++) {
714    
715     phi = j*phiStep;
716    
717     sigma = st->getContactValueAt(costheta, phi);
718     range = st->getRangeValueAt(costheta, phi);
719    
720 chrisfen 2175 // cutoff for a shape is taken to be (1.5*rangeVal + contactVal)
721 chrisfen 1729 tempCut = 1.5*range + sigma;
722 chrisfen 1688
723     if (tempCut > bigCut) bigCut = tempCut;
724     }
725     }
726    
727     return bigCut;
728     }