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

# Content
1 #include <cstdlib>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5
6 #include "simError.h"
7 #include "parse_me.h"
8 #include "MakeStamps.hpp"
9 #include "Globals.hpp"
10 #include "SimInfo.hpp"
11
12 #include "sysBuild.hpp"
13 #include "bilayerSys.hpp"
14
15 // this routine is defined in BASS_interface.cpp
16 extern void set_interface_stamps( MakeStamps* ms, Globals* g );
17
18
19 // case asignments
20 #define BILAYER 1
21
22
23 char* program_name;
24 bassInfo bsInfo;
25 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 char* id;
37
38 includeLinked* headInc;
39 includeLinked* prevInc;
40 includeLinked* currInc;
41
42 MakeStamps* the_stamps = NULL;
43 Globals* the_globals = NULL;
44 Component** the_components = NULL;
45 LinkedMolStamp* headStamp = NULL;
46 LinkedMolStamp* currStamp;
47
48 // initialize all functions and variables
49
50 initSimError();
51 program_name = argv[0];
52 sysType = -1;
53 have_prefix = 0;
54 isRandom = 0;
55 in_name = NULL;
56 headInc = NULL;
57
58 bsInfo.includes = NULL;
59 bsInfo.componentsNmol = NULL;
60 bsInfo.compStamps = NULL;
61 bsInfo.havePressure = 0;
62 bsInfo.haveTauBarostat = 0;
63 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 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
92 sysType = BILAYER;
93
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 }
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 case 'I':
148 // -I <include> => the include file.
149
150 i++;
151 if( headInc == NULL ){
152 headInc = new includeLinked;
153 headInc->next = NULL;
154 strcpy( headInc->name, argv[i] );
155 }
156 else{
157 prevInc = headInc;
158 currInc = headInc->next;
159 while( currInc != NULL ){
160 prevInc = currInc;
161 currInc = prevInc->next;
162 }
163 currInc = new includeLinked;
164 currInc->next = NULL;
165 strcpy( currInc->name, argv[i] );
166 prevInc->next = currInc;
167 }
168
169 done = 1;
170 break;
171
172 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 "Bad option \"-%c\"\n", current_flag);
187 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 sprintf( painCave.errMsg,
216 "No input bass file was specified.\n");
217 painCave.isFatal = 0;
218 simError();
219 usage();
220 }
221
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
230
231 // if no output prefix is given default to "donkey".
232
233 if( !have_prefix ){
234 out_prefix = strdup( "donkey" );
235 }
236
237 // set command line info into the bassInfo struct
238
239 bsInfo.outPrefix = out_prefix;
240 bsInfo.includes = headInc;
241
242
243 // open and parse the bass file.
244
245 set_interface_stamps( the_stamps, the_globals );
246 yacc_BASS( in_name );
247
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 bsInfo.Qmass = the_globals->getQmass();
280 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 bsInfo.ensemble );
334 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 bsInfo.boxZ = the_globals->getBox();
397 }
398 else if( the_globals->haveDensity() ){
399
400 double vol;
401 vol = (double)bsInfo.totNmol / the_globals->getDensity();
402 bsInfo.boxX = pow( vol, ( 1.0 / 3.0 ) );
403 bsInfo.boxY = bsInfo.boxX;
404 bsInfo.boxZ = bsInfo.boxY;
405 }
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 switch( sysType ){
440
441 case BILAYER:
442
443 buildBilayer( isRandom );
444 break;
445
446 default:
447 sprintf( painCave.errMsg,
448 "Unknown system type: %d\n", sysType );
449 painCave.isFatal = 1;
450 simError();
451 }
452
453
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 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 " -I <include> File name that should be included at the top of the\n"
492 " output bass file.\n"
493 " -r toggle the random option\n"
494 "\n"
495 " long:\n"
496 " -----\n"
497 " --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 "\n"
504 "\n",
505 program_name);
506 exit(8);
507 }