ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysBuild.cpp
Revision: 589
Committed: Thu Jul 10 19:53:50 2003 UTC (21 years ago) by chuckv
File size: 12523 byte(s)
Log Message:
Added nanoBuilder and a general Lattice builder.

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