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

# User Rev Content
1 chuckv 598
2 mmeineke 495 #include <cstdlib>
3     #include <cstdio>
4     #include <cstring>
5 mmeineke 501 #include <cmath>
6 mmeineke 495
7     #include "simError.h"
8 mmeineke 501 #include "parse_me.h"
9     #include "MakeStamps.hpp"
10     #include "Globals.hpp"
11     #include "SimInfo.hpp"
12 mmeineke 495
13 mmeineke 501 #include "sysBuild.hpp"
14 mmeineke 498 #include "bilayerSys.hpp"
15 chuckv 598 #include "nanoBuilder.hpp"
16 mmeineke 498
17 mmeineke 501 // this routine is defined in BASS_interface.cpp
18     extern void set_interface_stamps( MakeStamps* ms, Globals* g );
19 mmeineke 495
20 mmeineke 501
21     // case asignments
22 mmeineke 495 #define BILAYER 1
23 chuckv 598 #define NANOPARTICLE 2
24 mmeineke 495
25     char* program_name;
26 mmeineke 501 bassInfo bsInfo;
27 mmeineke 495 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 mmeineke 501 char* id;
39 mmeineke 498
40 mmeineke 501 includeLinked* headInc;
41     includeLinked* prevInc;
42     includeLinked* currInc;
43 mmeineke 495
44 mmeineke 501 MakeStamps* the_stamps = NULL;
45     Globals* the_globals = NULL;
46 mmeineke 502 Component** the_components = NULL;
47 mmeineke 501 LinkedMolStamp* headStamp = NULL;
48     LinkedMolStamp* currStamp;
49 mmeineke 495
50 mmeineke 501 // initialize all functions and variables
51 mmeineke 495
52 mmeineke 501 initSimError();
53     program_name = argv[0];
54 mmeineke 495 sysType = -1;
55     have_prefix = 0;
56     isRandom = 0;
57     in_name = NULL;
58 mmeineke 501 headInc = NULL;
59    
60     bsInfo.includes = NULL;
61     bsInfo.componentsNmol = NULL;
62     bsInfo.compStamps = NULL;
63     bsInfo.havePressure = 0;
64 mmeineke 502 bsInfo.haveTauBarostat = 0;
65 mmeineke 501 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 mmeineke 495 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 mmeineke 536
94 mmeineke 495 sysType = BILAYER;
95 mmeineke 536
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 mmeineke 495 }
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 chuckv 598 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 mmeineke 495
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 mmeineke 501 case 'I':
193     // -I <include> => the include file.
194    
195     i++;
196     if( headInc == NULL ){
197     headInc = new includeLinked;
198     headInc->next = NULL;
199 mmeineke 502 strcpy( headInc->name, argv[i] );
200 mmeineke 501 }
201     else{
202     prevInc = headInc;
203     currInc = headInc->next;
204     while( currInc != NULL ){
205     prevInc = currInc;
206 mmeineke 502 currInc = prevInc->next;
207 mmeineke 501 }
208     currInc = new includeLinked;
209     currInc->next = NULL;
210 mmeineke 502 strcpy( currInc->name, argv[i] );
211 mmeineke 501 prevInc->next = currInc;
212     }
213    
214     done = 1;
215     break;
216    
217 mmeineke 495 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 mmeineke 498 "Bad option \"-%c\"\n", current_flag);
232 mmeineke 495 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 mmeineke 498 sprintf( painCave.errMsg,
261     "No input bass file was specified.\n");
262     painCave.isFatal = 0;
263     simError();
264 mmeineke 495 usage();
265     }
266 mmeineke 498
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 mmeineke 495
275    
276 mmeineke 498 // if no output prefix is given default to "donkey".
277    
278     if( !have_prefix ){
279     out_prefix = strdup( "donkey" );
280     }
281 mmeineke 495
282 mmeineke 501 // set command line info into the bassInfo struct
283    
284     bsInfo.outPrefix = out_prefix;
285     bsInfo.includes = headInc;
286    
287 mmeineke 498
288 mmeineke 501 // open and parse the bass file.
289    
290     set_interface_stamps( the_stamps, the_globals );
291 mmeineke 502 yacc_BASS( in_name );
292 mmeineke 501
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 mmeineke 502 bsInfo.Qmass = the_globals->getQmass();
325 mmeineke 501 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 mmeineke 502 bsInfo.ensemble );
379 mmeineke 501 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 mmeineke 502 bsInfo.boxZ = the_globals->getBox();
442 mmeineke 501 }
443     else if( the_globals->haveDensity() ){
444    
445     double vol;
446 mmeineke 502 vol = (double)bsInfo.totNmol / the_globals->getDensity();
447 mmeineke 501 bsInfo.boxX = pow( vol, ( 1.0 / 3.0 ) );
448 mmeineke 502 bsInfo.boxY = bsInfo.boxX;
449     bsInfo.boxZ = bsInfo.boxY;
450 mmeineke 501 }
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 mmeineke 498 switch( sysType ){
485    
486     case BILAYER:
487    
488 mmeineke 501 buildBilayer( isRandom );
489 mmeineke 498 break;
490    
491 chuckv 589 case NANO:
492 chuckv 598
493    
494 chuckv 589 break;
495    
496 mmeineke 498 default:
497     sprintf( painCave.errMsg,
498     "Unknown system type: %d\n", sysType );
499     painCave.isFatal = 1;
500     simError();
501 chuckv 589
502 mmeineke 498 }
503 mmeineke 495
504 mmeineke 501
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 mmeineke 495 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 mmeineke 501 " -I <include> File name that should be included at the top of the\n"
543     " output bass file.\n"
544 mmeineke 495 " -r toggle the random option\n"
545     "\n"
546     " long:\n"
547     " -----\n"
548 mmeineke 536 " --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 mmeineke 495 "\n"
555     "\n",
556     program_name);
557     exit(8);
558     }