ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/LJ_FF.cpp
Revision: 378
Committed: Fri Mar 21 17:42:12 2003 UTC (21 years, 3 months ago) by mmeineke
File size: 12520 byte(s)
Log Message:
This commit was generated by cvs2svn to compensate for changes in r377,
which included commits to RCS files with non-trunk default branches.

File Contents

# Content
1 #include <cstdlib>
2 #include <cstdio>
3 #include <cstring>
4
5 #include <iostream>
6 using namespace std;
7
8 #ifdef IS_MPI
9 #include <mpi.h>
10 #include <mpi++.h>
11 #endif //is_mpi
12
13 #include "ForceFields.hpp"
14 #include "SRI.hpp"
15 #include "simError.h"
16
17 #include "fortranWrappers.hpp"
18
19 #ifdef IS_MPI
20 #include "mpiForceField.h"
21 #endif // is_mpi
22
23
24
25 namespace LJ_NS{
26
27 // Declare the structures that will be passed by the parser and MPI
28
29 typedef struct{
30 char name[15];
31 double mass;
32 double epslon;
33 double sigma;
34 int ident;
35 int last; // 0 -> default
36 // 1 -> in MPI: tells nodes to stop listening
37 } atomStruct;
38
39 int parseAtom( char *lineBuffer, int lineNum, atomStruct &info );
40
41 #ifdef IS_MPI
42
43 MPI_Datatype mpiAtomStructType;
44
45 #endif
46 }
47
48 using namespace LJ_NS;
49
50 //****************************************************************
51 // begins the actual forcefield stuff.
52 //****************************************************************
53
54
55 LJ_FF::LJ_FF(){
56
57 char fileName[200];
58 char* ffPath_env = "FORCE_PARAM_PATH";
59 char* ffPath;
60 char temp[200];
61 char errMsg[1000];
62
63 // do the funtion wrapping
64 wrapMeFF( this );
65
66 #ifdef IS_MPI
67 int i;
68
69 // **********************************************************************
70 // Init the atomStruct mpi type
71
72 atomStruct atomProto; // mpiPrototype
73 int atomBC[3] = {15,3,2}; // block counts
74 MPI_Aint atomDspls[3]; // displacements
75 MPI_Datatype atomMbrTypes[3]; // member mpi types
76
77 MPI_Address(&atomProto.name, &atomDspls[0]);
78 MPI_Address(&atomProto.mass, &atomDspls[1]);
79 MPI_Address(&atomProto.ident, &atomDspls[2]);
80
81 atomMbrTypes[0] = MPI_CHAR;
82 atomMbrTypes[1] = MPI_DOUBLE;
83 atomMbrTypes[2] = MPI_INT;
84
85 for (i=2; i >= 0; i--) atomDspls[i] -= atomDspls[0];
86
87 MPI_Type_struct(3, atomBC, atomDspls, atomMbrTypes, &mpiAtomStructType);
88 MPI_Type_commit(&mpiAtomStructType);
89
90 // ***********************************************************************
91
92 if( worldRank == 0 ){
93 #endif
94
95 // generate the force file name
96
97 strcpy( fileName, "LJ_FF.frc" );
98 // fprintf( stderr,"Trying to open %s\n", fileName );
99
100 // attempt to open the file in the current directory first.
101
102 frcFile = fopen( fileName, "r" );
103
104 if( frcFile == NULL ){
105
106 // next see if the force path enviorment variable is set
107
108 ffPath = getenv( ffPath_env );
109 if( ffPath == NULL ) {
110 STR_DEFINE(ffPath, FRC_PATH );
111 }
112
113
114 strcpy( temp, ffPath );
115 strcat( temp, "/" );
116 strcat( temp, fileName );
117 strcpy( fileName, temp );
118
119 frcFile = fopen( fileName, "r" );
120
121 if( frcFile == NULL ){
122
123 sprintf( painCave.errMsg,
124 "Error opening the force field parameter file: %s\n"
125 "Have you tried setting the FORCE_PARAM_PATH environment "
126 "vairable?\n",
127 fileName );
128 painCave.isFatal = 1;
129 simError();
130 }
131 }
132
133 #ifdef IS_MPI
134 }
135
136 sprintf( checkPointMsg, "LJ_FF file opened sucessfully." );
137 MPIcheckPoint();
138
139 #endif // is_mpi
140 }
141
142
143 LJ_FF::~LJ_FF(){
144
145 #ifdef IS_MPI
146 if( worldRank == 0 ){
147 #endif // is_mpi
148
149 fclose( frcFile );
150
151 #ifdef IS_MPI
152 }
153 #endif // is_mpi
154 }
155
156 void LJ_FF::initForceField( int ljMixRule ){
157
158 initFortran( ljMixRule, 0 );
159 }
160
161
162 void LJ_FF::initializeAtoms( void ){
163
164 class LinkedType {
165 public:
166 LinkedType(){
167 next = NULL;
168 name[0] = '\0';
169 }
170 ~LinkedType(){ if( next != NULL ) delete next; }
171
172 LinkedType* find(char* key){
173 if( !strcmp(name, key) ) return this;
174 if( next != NULL ) return next->find(key);
175 return NULL;
176 }
177
178
179 void add( atomStruct &info ){
180
181 // check for duplicates
182
183 if( !strcmp( info.name, name ) ){
184 sprintf( painCave.errMsg,
185 "Duplicate LJ atom type \"%s\" found in "
186 "the LJ_FF param file./n",
187 name );
188 painCave.isFatal = 1;
189 simError();
190 }
191
192 if( next != NULL ) next->add(info);
193 else{
194 next = new LinkedType();
195 strcpy(next->name, info.name);
196 next->mass = info.mass;
197 next->epslon = info.epslon;
198 next->sigma = info.sigma;
199 next->ident = info.ident;
200 }
201 }
202
203
204 #ifdef IS_MPI
205
206 void duplicate( atomStruct &info ){
207 strcpy(info.name, name);
208 info.mass = mass;
209 info.epslon = epslon;
210 info.sigma = sigma;
211 info.ident = ident;
212 info.last = 0;
213 }
214
215
216 #endif
217
218 char name[15];
219 double mass;
220 double epslon;
221 double sigma;
222 int ident;
223 LinkedType* next;
224 };
225
226 LinkedType* headAtomType;
227 LinkedType* currentAtomType;
228 atomStruct info;
229 info.last = 1; // initialize last to have the last set.
230 // if things go well, last will be set to 0
231
232 int i;
233 int identNum;
234
235 Atom** the_atoms;
236 int nAtoms;
237 the_atoms = entry_plug->atoms;
238 nAtoms = entry_plug->n_atoms;
239
240
241 #ifdef IS_MPI
242 if( worldRank == 0 ){
243 #endif
244
245 // read in the atom types.
246
247 headAtomType = new LinkedType;
248
249 fastForward( "AtomTypes", "initializeAtoms" );
250
251 // we are now at the AtomTypes section.
252
253 eof_test = fgets( readLine, sizeof(readLine), frcFile );
254 lineNum++;
255
256
257 // read a line, and start parseing out the atom types
258
259 if( eof_test == NULL ){
260 sprintf( painCave.errMsg,
261 "Error in reading Atoms from force file at line %d.\n",
262 lineNum );
263 painCave.isFatal = 1;
264 simError();
265 }
266
267 identNum = 1;
268 // stop reading at end of file, or at next section
269 while( readLine[0] != '#' && eof_test != NULL ){
270
271 // toss comment lines
272 if( readLine[0] != '!' ){
273
274 // the parser returns 0 if the line was blank
275 if( parseAtom( readLine, lineNum, info ) ){
276 info.ident = identNum;
277 headAtomType->add( info );;
278 identNum++;
279 }
280 }
281 eof_test = fgets( readLine, sizeof(readLine), frcFile );
282 lineNum++;
283 }
284
285 #ifdef IS_MPI
286
287 // send out the linked list to all the other processes
288
289 sprintf( checkPointMsg,
290 "LJ_FF atom structures read successfully." );
291 MPIcheckPoint();
292
293 currentAtomType = headAtomType->next; //skip the first element who is a place holder.
294 while( currentAtomType != NULL ){
295 currentAtomType->duplicate( info );
296
297
298
299 sendFrcStruct( &info, mpiAtomStructType );
300
301 sprintf( checkPointMsg,
302 "successfully sent lJ force type: \"%s\"\n",
303 info.name );
304 MPIcheckPoint();
305
306 currentAtomType = currentAtomType->next;
307 }
308 info.last = 1;
309 sendFrcStruct( &info, mpiAtomStructType );
310
311 }
312
313 else{
314
315 // listen for node 0 to send out the force params
316
317 MPIcheckPoint();
318
319 headAtomType = new LinkedType;
320 recieveFrcStruct( &info, mpiAtomStructType );
321
322 while( !info.last ){
323
324
325
326 headAtomType->add( info );
327
328 MPIcheckPoint();
329
330 recieveFrcStruct( &info, mpiAtomStructType );
331 }
332 }
333 #endif // is_mpi
334
335 // call new A_types in fortran
336
337 int isError;
338
339 // dummy variables
340 int isLJ = 1;
341 int isDipole = 0;
342 int isSSD = 0;
343 int isGB = 0;
344 double w0 = 0.0;
345 double v0 = 0.0;
346 double dipole = 0.0;
347 double GB_dummy = 0.0;
348
349
350 currentAtomType = headAtomType;
351 while( currentAtomType != NULL ){
352
353 if( currentAtomType->name[0] != '\0' ){
354 isError = 0;
355 makeAtype( &(currentAtomType->ident),
356 &isLJ,
357 &isSSD,
358 &isDipole,
359 &isGB,
360 &(currentAtomType->epslon),
361 &(currentAtomType->sigma),
362 &dipole,
363 &w0,
364 &v0,
365 &GB_dummy,
366 &GB_dummy,
367 &GB_dummy,
368 &GB_dummy,
369 &GB_dummy,
370 &GB_dummy,
371 &isError );
372 if( isError ){
373 sprintf( painCave.errMsg,
374 "Error initializing the \"%s\" atom type in fortran\n",
375 currentAtomType->name );
376 painCave.isFatal = 1;
377 simError();
378 }
379 }
380 currentAtomType = currentAtomType->next;
381 }
382
383 #ifdef IS_MPI
384 sprintf( checkPointMsg,
385 "LJ_FF atom structures successfully sent to fortran\n" );
386 MPIcheckPoint();
387 #endif // is_mpi
388
389
390
391 // initialize the atoms
392
393 double bigSigma = 0.0;
394 Atom* thisAtom;
395
396 for( i=0; i<nAtoms; i++ ){
397
398 currentAtomType = headAtomType->find( the_atoms[i]->getType() );
399 if( currentAtomType == NULL ){
400 sprintf( painCave.errMsg,
401 "AtomType error, %s not found in force file.\n",
402 the_atoms[i]->getType() );
403 painCave.isFatal = 1;
404 simError();
405 }
406
407 the_atoms[i]->setMass( currentAtomType->mass );
408 the_atoms[i]->setEpslon( currentAtomType->epslon );
409 the_atoms[i]->setSigma( currentAtomType->sigma );
410 the_atoms[i]->setIdent( currentAtomType->ident );
411 the_atoms[i]->setLJ();
412
413 if( bigSigma < currentAtomType->sigma ) bigSigma = currentAtomType->sigma;
414 }
415
416
417 #ifdef IS_MPI
418 double tempBig = bigSigma;
419 MPI::COMM_WORLD.Allreduce( &tempBig, &bigSigma, 1, MPI_DOUBLE, MPI_MAX );
420 #endif //is_mpi
421
422 //calc rCut and rList
423
424 entry_plug->rCut = 2.5 * bigSigma;
425 if(entry_plug->rCut > (entry_plug->box_x / 2.0))
426 entry_plug->rCut = entry_plug->box_x / 2.0;
427 if(entry_plug->rCut > (entry_plug->box_y / 2.0))
428 entry_plug->rCut = entry_plug->box_y / 2.0;
429 if(entry_plug->rCut > (entry_plug->box_z / 2.0))
430 entry_plug->rCut = entry_plug->box_z / 2.0;
431
432 entry_plug->rList = entry_plug->rCut + 1.0;
433
434 entry_plug->useLJ = 1;
435
436 // clean up the memory
437
438 delete headAtomType;
439
440 #ifdef IS_MPI
441 sprintf( checkPointMsg, "LJ_FF atoms initialized succesfully" );
442 MPIcheckPoint();
443 #endif // is_mpi
444
445 }
446
447 void LJ_FF::initializeBonds( bond_pair* the_bonds ){
448
449 if( entry_plug->n_bonds ){
450 sprintf( painCave.errMsg,
451 "LJ_FF does not support bonds.\n" );
452 painCave.isFatal = 1;
453 simError();
454 }
455 #ifdef IS_MPI
456 MPIcheckPoint();
457 #endif // is_mpi
458
459 }
460
461 void LJ_FF::initializeBends( bend_set* the_bends ){
462
463 if( entry_plug->n_bends ){
464 sprintf( painCave.errMsg,
465 "LJ_FF does not support bends.\n" );
466 painCave.isFatal = 1;
467 simError();
468 }
469 #ifdef IS_MPI
470 MPIcheckPoint();
471 #endif // is_mpi
472
473 }
474
475 void LJ_FF::initializeTorsions( torsion_set* the_torsions ){
476
477 if( entry_plug->n_torsions ){
478 sprintf( painCave.errMsg,
479 "LJ_FF does not support torsions.\n" );
480 painCave.isFatal = 1;
481 simError();
482 }
483 #ifdef IS_MPI
484 MPIcheckPoint();
485 #endif // is_mpi
486
487 }
488
489 void LJ_FF::fastForward( char* stopText, char* searchOwner ){
490
491 int foundText = 0;
492 char* the_token;
493
494 rewind( frcFile );
495 lineNum = 0;
496
497 eof_test = fgets( readLine, sizeof(readLine), frcFile );
498 lineNum++;
499 if( eof_test == NULL ){
500 sprintf( painCave.errMsg, "Error fast forwarding force file for %s: "
501 " file is empty.\n",
502 searchOwner );
503 painCave.isFatal = 1;
504 simError();
505 }
506
507
508 while( !foundText ){
509 while( eof_test != NULL && readLine[0] != '#' ){
510 eof_test = fgets( readLine, sizeof(readLine), frcFile );
511 lineNum++;
512 }
513 if( eof_test == NULL ){
514 sprintf( painCave.errMsg,
515 "Error fast forwarding force file for %s at "
516 "line %d: file ended unexpectedly.\n",
517 searchOwner,
518 lineNum );
519 painCave.isFatal = 1;
520 simError();
521 }
522
523 the_token = strtok( readLine, " ,;\t#\n" );
524 foundText = !strcmp( stopText, the_token );
525
526 if( !foundText ){
527 eof_test = fgets( readLine, sizeof(readLine), frcFile );
528 lineNum++;
529
530 if( eof_test == NULL ){
531 sprintf( painCave.errMsg,
532 "Error fast forwarding force file for %s at "
533 "line %d: file ended unexpectedly.\n",
534 searchOwner,
535 lineNum );
536 painCave.isFatal = 1;
537 simError();
538 }
539 }
540 }
541 }
542
543
544
545 int LJ_NS::parseAtom( char *lineBuffer, int lineNum, atomStruct &info ){
546
547 char* the_token;
548
549 the_token = strtok( lineBuffer, " \n\t,;" );
550 if( the_token != NULL ){
551
552 strcpy( info.name, the_token );
553
554 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
555 sprintf( painCave.errMsg,
556 "Error parseing AtomTypes: line %d\n", lineNum );
557 painCave.isFatal = 1;
558 simError();
559 }
560
561 info.mass = atof( the_token );
562
563 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
564 sprintf( painCave.errMsg,
565 "Error parseing AtomTypes: line %d\n", lineNum );
566 painCave.isFatal = 1;
567 simError();
568 }
569
570 info.epslon = atof( the_token );
571
572 if( ( the_token = strtok( NULL, " \n\t,;" ) ) == NULL ){
573 sprintf( painCave.errMsg,
574 "Error parseing AtomTypes: line %d\n", lineNum );
575 painCave.isFatal = 1;
576 simError();
577 }
578
579 info.sigma = atof( the_token );
580
581 return 1;
582 }
583 else return 0;
584 }