ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysBuild.cpp
Revision: 502
Committed: Tue Apr 15 21:47:54 2003 UTC (21 years, 3 months ago) by mmeineke
File size: 11987 byte(s)
Log Message:
bilayerSys and sysBuild both will build now. woot!

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