ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysBuild.cpp
Revision: 536
Committed: Fri May 16 14:28:27 2003 UTC (21 years, 2 months ago) by mmeineke
File size: 12424 byte(s)
Log Message:
doing some work to overhaul sysbuild.

File Contents

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