ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/UseTheForce/Shapes_FF.cpp
Revision: 1672
Committed: Thu Oct 28 17:20:22 2004 UTC (19 years, 8 months ago) by gezelter
File size: 15170 byte(s)
Log Message:
forgot to advance lines in the shapeFile

File Contents

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