ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysBuild.cpp
Revision: 598
Committed: Mon Jul 14 21:35:45 2003 UTC (21 years ago) by chuckv
File size: 13366 byte(s)
Log Message:
added a nanoSysBuilder that takes different cmd line arguments.

File Contents

# Content
1
2 #include <cstdlib>
3 #include <cstdio>
4 #include <cstring>
5 #include <cmath>
6
7 #include "simError.h"
8 #include "parse_me.h"
9 #include "MakeStamps.hpp"
10 #include "Globals.hpp"
11 #include "SimInfo.hpp"
12
13 #include "sysBuild.hpp"
14 #include "bilayerSys.hpp"
15 #include "nanoBuilder.hpp"
16
17 // this routine is defined in BASS_interface.cpp
18 extern void set_interface_stamps( MakeStamps* ms, Globals* g );
19
20
21 // case asignments
22 #define BILAYER 1
23 #define NANOPARTICLE 2
24
25 char* program_name;
26 bassInfo bsInfo;
27 void usage(void);
28
29
30 int main( int argc, char* argv[]){
31
32 int i,j,k;
33 int sysType;
34 int done, have_prefix, isRandom;
35 char current_flag;
36 char* out_prefix;
37 char* in_name;
38 char* id;
39
40 includeLinked* headInc;
41 includeLinked* prevInc;
42 includeLinked* currInc;
43
44 MakeStamps* the_stamps = NULL;
45 Globals* the_globals = NULL;
46 Component** the_components = NULL;
47 LinkedMolStamp* headStamp = NULL;
48 LinkedMolStamp* currStamp;
49
50 // initialize all functions and variables
51
52 initSimError();
53 program_name = argv[0];
54 sysType = -1;
55 have_prefix = 0;
56 isRandom = 0;
57 in_name = NULL;
58 headInc = NULL;
59
60 bsInfo.includes = NULL;
61 bsInfo.componentsNmol = NULL;
62 bsInfo.compStamps = NULL;
63 bsInfo.havePressure = 0;
64 bsInfo.haveTauBarostat = 0;
65 bsInfo.haveTauThermostat = 0;
66 bsInfo.haveQmass = 0;
67
68 headStamp = new LinkedMolStamp();
69 the_stamps = new MakeStamps();
70 the_globals = new Globals();
71 set_interface_stamps( the_stamps, the_globals );
72
73 // parse command line arguments
74
75 for( i = 1; i < argc; i++){
76
77 if(argv[i][0] =='-'){
78
79 // parse the option
80
81 if(argv[i][1] == '-' ){
82
83 // parse long word options
84
85 if( !strcmp( argv[i], "--bilayer" ) ){
86 if( sysType > 0 ){
87 sprintf( painCave.errMsg,
88 "You cannot specify more than one system to build.\n" );
89 painCave.isFatal = 0;
90 simError();
91 usage();
92 }
93
94 sysType = BILAYER;
95
96 i++;
97 if( i>=argc ){
98 sprintf( painCave.errMsg,
99 "\n"
100 "not enough arguments for bilayer\n");
101 painCave.isFatal = 0;
102 simError();
103 usage();
104 }
105 strcpy( bsInfo.lipidName, argv[i] );
106
107 i++;
108 if( i>=argc ){
109 sprintf( painCave.errMsg,
110 "\n"
111 "not enough arguments for bilayer\n");
112 painCave.isFatal = 0;
113 simError();
114 usage();
115 }
116 strcpy( bsInfo.waterName, argv[i] );
117
118 }
119
120 else{
121 sprintf( painCave.errMsg,
122 "Invalid option \"%s\"\n", argv[i] );
123 painCave.isFatal = 0;
124 simError();
125 usage();
126 }
127 }
128 else if( !strcmp( argv[i], "--nanoparticle" ) ){
129 if( sysType > 0 ){
130 sprintf( painCave.errMsg,
131 "You cannot specify more than one system to build.\n" );
132 painCave.isFatal = 0;
133 simError();
134 usage();
135 }
136
137 sysType = NANOPARTICLE;
138
139 i++;
140 if( i>=argc ){
141 sprintf( painCave.errMsg,
142 "\n"
143 "not enough arguments for nanoparticle\n");
144 painCave.isFatal = 0;
145 simError();
146 usage();
147 }
148 strcpy( bsInfo.coreName, argv[i] );
149
150 i++;
151 if( i>=argc ){
152 sprintf( painCave.errMsg,
153 "\n"
154 "not enough arguments for nanoparticle\n");
155 painCave.isFatal = 0;
156 simError();
157 usage();
158 }
159 strcpy( bsInfo.shellName, argv[i] );
160
161 }
162
163 else{
164 sprintf( painCave.errMsg,
165 "Invalid option \"%s\"\n", argv[i] );
166 painCave.isFatal = 0;
167 simError();
168 usage();
169 }
170 }
171
172 else{
173
174 // parse single character options
175
176 done =0;
177 j = 1;
178 current_flag = argv[i][j];
179 while( (current_flag != '\0') && (!done) ){
180
181 switch(current_flag){
182
183 case 'o':
184 // -o <prefix> => the output prefix.
185
186 i++;
187 out_prefix = argv[i];
188 have_prefix = 1;
189 done = 1;
190 break;
191
192 case 'I':
193 // -I <include> => the include file.
194
195 i++;
196 if( headInc == NULL ){
197 headInc = new includeLinked;
198 headInc->next = NULL;
199 strcpy( headInc->name, argv[i] );
200 }
201 else{
202 prevInc = headInc;
203 currInc = headInc->next;
204 while( currInc != NULL ){
205 prevInc = currInc;
206 currInc = prevInc->next;
207 }
208 currInc = new includeLinked;
209 currInc->next = NULL;
210 strcpy( currInc->name, argv[i] );
211 prevInc->next = currInc;
212 }
213
214 done = 1;
215 break;
216
217 case 'h':
218 // -h => give the usage
219
220 usage();
221 break;
222
223 case 'r':
224 // toggle random
225
226 isRandom = 1;;
227 break;
228
229 default:
230 sprintf(painCave.errMsg,
231 "Bad option \"-%c\"\n", current_flag);
232 painCave.isFatal = 0;
233 simError();
234 usage();
235 }
236 j++;
237 current_flag = argv[i][j];
238 }
239 }
240 }
241
242 else{
243
244 if( in_name != NULL ){
245 sprintf( painCave.errMsg,
246 "Error at \"%s\", program does not support\n"
247 "more than one input file.\n"
248 "\n",
249 argv[i]);
250 painCave.isFatal = 0;
251 simError();
252 usage();
253 }
254
255 in_name = argv[i];
256 }
257 }
258
259 if(in_name == NULL){
260 sprintf( painCave.errMsg,
261 "No input bass file was specified.\n");
262 painCave.isFatal = 0;
263 simError();
264 usage();
265 }
266
267 if( sysType < 0 ){
268 sprintf( painCave.errMsg,
269 "No system type was specified.\n");
270 painCave.isFatal = 0;
271 simError();
272 usage();
273 }
274
275
276 // if no output prefix is given default to "donkey".
277
278 if( !have_prefix ){
279 out_prefix = strdup( "donkey" );
280 }
281
282 // set command line info into the bassInfo struct
283
284 bsInfo.outPrefix = out_prefix;
285 bsInfo.includes = headInc;
286
287
288 // open and parse the bass file.
289
290 set_interface_stamps( the_stamps, the_globals );
291 yacc_BASS( in_name );
292
293 // set the easy ones first
294 bsInfo.targetTemp = the_globals->getTargetTemp();
295 bsInfo.dt = the_globals->getDt();
296 bsInfo.runTime = the_globals->getRunTime();
297
298 // get the ones we know are there, yet still may need some work.
299 bsInfo.nComponents = the_globals->getNComponents();
300 strcpy( bsInfo.forceField, the_globals->getForceField() );
301
302 // get the ensemble:
303 strcpy( bsInfo.ensemble, the_globals->getEnsemble() );
304 if( !strcasecmp( bsInfo.ensemble, "NPT" ) ) {
305
306 if (the_globals->haveTargetPressure()){
307 bsInfo.targetPressure = the_globals->getTargetPressure();
308 bsInfo.havePressure = 1;
309 }
310 else {
311 sprintf( painCave.errMsg,
312 "sysBuild error: If you use the constant pressure\n"
313 " ensemble, you must set targetPressure.\n"
314 " This was found in the BASS file.\n");
315 painCave.isFatal = 1;
316 simError();
317 }
318
319 if (the_globals->haveTauThermostat()){
320 bsInfo.tauThermostat = the_globals->getTauThermostat();
321 bsInfo.haveTauThermostat = 1;;
322 }
323 else if (the_globals->haveQmass()){
324 bsInfo.Qmass = the_globals->getQmass();
325 bsInfo.haveQmass = 1;
326 }
327 else {
328 sprintf( painCave.errMsg,
329 "sysBuild error: If you use one of the constant temperature\n"
330 " ensembles, you must set either tauThermostat or qMass.\n"
331 " Neither of these was found in the BASS file.\n");
332 painCave.isFatal = 1;
333 simError();
334 }
335
336 if (the_globals->haveTauBarostat()){
337 bsInfo.tauBarostat = the_globals->getTauBarostat();
338 bsInfo.haveTauBarostat = 1;
339 }
340 else {
341 sprintf( painCave.errMsg,
342 "sysBuild error: If you use the constant pressure\n"
343 " ensemble, you must set tauBarostat.\n"
344 " This was found in the BASS file.\n");
345 painCave.isFatal = 1;
346 simError();
347 }
348
349 }
350 else if ( !strcasecmp( bsInfo.ensemble, "NVT") ) {
351
352 if (the_globals->haveTauThermostat()){
353 bsInfo.tauThermostat = the_globals->getTauThermostat();
354 bsInfo.haveTauThermostat = 1;
355 }
356 else if (the_globals->haveQmass()){
357 bsInfo.Qmass = the_globals->getQmass();
358 bsInfo.haveQmass = 1;
359 }
360 else {
361 sprintf( painCave.errMsg,
362 "sysBuild error: If you use one of the constant temperature\n"
363 " ensembles, you must set either tauThermostat or qMass.\n"
364 " Neither of these was found in the BASS file.\n");
365 painCave.isFatal = 1;
366 simError();
367 }
368
369 }
370 else if ( !strcasecmp( bsInfo.ensemble, "NVE") ) {
371
372 // nothing special for now
373 }
374 else {
375 sprintf( painCave.errMsg,
376 "sysBuild Warning. Unrecognized Ensemble -> %s, "
377 "reverting to NVE for this simulation.\n",
378 bsInfo.ensemble );
379 painCave.isFatal = 0;
380 simError();
381 strcpy( bsInfo.ensemble, "NVE" );
382 }
383
384
385 // get the components and calculate the tot_nMol and indvidual n_mol
386
387 the_components = the_globals->getComponents();
388 bsInfo.componentsNmol = new int[bsInfo.nComponents];
389 bsInfo.compStamps = new MoleculeStamp*[bsInfo.nComponents];
390 bsInfo.totNmol = 0;
391 for( i=0; i<bsInfo.nComponents; i++ ){
392
393 if( !the_components[i]->haveNMol() ){
394 // we have a problem
395 sprintf( painCave.errMsg,
396 "sysBuild Error. No component NMol"
397 " given. Cannot calculate the number of atoms.\n" );
398 painCave.isFatal = 1;
399 simError();
400 }
401
402 bsInfo.totNmol += the_components[i]->getNMol();
403 bsInfo.componentsNmol[i] = the_components[i]->getNMol();
404 }
405
406 // make an array of molecule stamps that match the components used.
407 // also extract the used stamps out into a separate linked list
408
409 for( i=0; i<bsInfo.nComponents; i++ ){
410
411 id = the_components[i]->getType();
412 bsInfo.compStamps[i] = NULL;
413
414 // check to make sure the component isn't already in the list
415
416 bsInfo.compStamps[i] = headStamp->match( id );
417 if( bsInfo.compStamps[i] == NULL ){
418
419 // extract the component from the list;
420
421 currStamp = the_stamps->extractMolStamp( id );
422 if( currStamp == NULL ){
423 sprintf( painCave.errMsg,
424 "sysBuild error: Component \"%s\" was not found in the "
425 "list of declared molecules\n",
426 id );
427 painCave.isFatal = 1;
428 simError();
429 }
430
431 headStamp->add( currStamp );
432 bsInfo.compStamps[i] = headStamp->match( id );
433 }
434 }
435
436 // get and set the boxSize
437
438 if( the_globals->haveBox() ){
439 bsInfo.boxX = the_globals->getBox();
440 bsInfo.boxY = the_globals->getBox();
441 bsInfo.boxZ = the_globals->getBox();
442 }
443 else if( the_globals->haveDensity() ){
444
445 double vol;
446 vol = (double)bsInfo.totNmol / the_globals->getDensity();
447 bsInfo.boxX = pow( vol, ( 1.0 / 3.0 ) );
448 bsInfo.boxY = bsInfo.boxX;
449 bsInfo.boxZ = bsInfo.boxY;
450 }
451 else{
452 if( !the_globals->haveBoxX() ){
453 sprintf( painCave.errMsg,
454 "sysBuild error, no periodic BoxX size given.\n" );
455 painCave.isFatal = 1;
456 simError();
457 }
458 bsInfo.boxX = the_globals->getBoxX();
459
460 if( !the_globals->haveBoxY() ){
461 sprintf( painCave.errMsg,
462 "sysBuild error, no periodic BoxY size given.\n" );
463 painCave.isFatal = 1;
464 simError();
465 }
466 bsInfo.boxY = the_globals->getBoxY();
467
468 if( !the_globals->haveBoxZ() ){
469 sprintf( painCave.errMsg,
470 "SimSetup error, no periodic BoxZ size given.\n" );
471 painCave.isFatal = 1;
472 simError();
473 }
474 bsInfo.boxZ = the_globals->getBoxZ();
475 }
476
477
478 //************************************************************
479 // that should be all we need from bass. now to switch to the
480 // appropriate system builder.
481 // ***********************************************************
482
483
484 switch( sysType ){
485
486 case BILAYER:
487
488 buildBilayer( isRandom );
489 break;
490
491 case NANO:
492
493
494 break;
495
496 default:
497 sprintf( painCave.errMsg,
498 "Unknown system type: %d\n", sysType );
499 painCave.isFatal = 1;
500 simError();
501
502 }
503
504
505
506 // clean up memory;
507
508 if( headStamp!= NULL ) delete headStamp;
509 if( the_stamps != NULL ) delete the_stamps;
510 if( the_globals != NULL ) delete the_globals;
511 if( the_components != NULL ) delete[] the_components;
512
513 if( bsInfo.componentsNmol != NULL ) delete[] bsInfo.componentsNmol;
514 if( bsInfo.compStamps != NULL ) delete[] bsInfo.compStamps;
515 if( bsInfo.includes != NULL ){
516 prevInc = bsInfo.includes;
517 while( prevInc != NULL ){
518 currInc = prevInc->next;
519 delete prevInc;
520 prevInc = currInc;
521 }
522 }
523
524 return 0;
525 }
526
527
528 /***************************************************************************
529 * prints out the usage for the command line arguments, then exits.
530 ***************************************************************************/
531
532 void usage(){
533 (void)fprintf(stdout,
534 "The proper usage is: %s [options] <input bass>\n"
535 "\n"
536 "Options:\n"
537 "\n"
538 " short:\n"
539 " ------\n"
540 " -h Display this message\n"
541 " -o <prefix> The output prefix\n"
542 " -I <include> File name that should be included at the top of the\n"
543 " output bass file.\n"
544 " -r toggle the random option\n"
545 "\n"
546 " long:\n"
547 " -----\n"
548 " --bilayer <lipid> <water> Tries to build a basic bilayer with the specified number\n"
549 " of lipids in the input bass file. The bilayer will be\n"
550 " surrounded by the number of solvent molecules given\n"
551 " in the bass file.\n"
552 " -note: combined with \"-r\" the simulation will start\n"
553 " the lipids randomly oriented in a sea of waters.\n"
554 "\n"
555 "\n",
556 program_name);
557 exit(8);
558 }