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, 9 months ago) by chuckv
File size: 12523 byte(s)
Log Message:
Added nanoBuilder and a general Lattice builder.

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 //#include "nanoBuilder.hpp"
15
16 // this routine is defined in BASS_interface.cpp
17 extern void set_interface_stamps( MakeStamps* ms, Globals* g );
18
19
20 // case asignments
21 #define BILAYER 1
22 #define NANO 2
23
24 char* program_name;
25 bassInfo bsInfo;
26 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 char* id;
38
39 includeLinked* headInc;
40 includeLinked* prevInc;
41 includeLinked* currInc;
42
43 MakeStamps* the_stamps = NULL;
44 Globals* the_globals = NULL;
45 Component** the_components = NULL;
46 LinkedMolStamp* headStamp = NULL;
47 LinkedMolStamp* currStamp;
48
49 // initialize all functions and variables
50
51 initSimError();
52 program_name = argv[0];
53 sysType = -1;
54 have_prefix = 0;
55 isRandom = 0;
56 in_name = NULL;
57 headInc = NULL;
58
59 bsInfo.includes = NULL;
60 bsInfo.componentsNmol = NULL;
61 bsInfo.compStamps = NULL;
62 bsInfo.havePressure = 0;
63 bsInfo.haveTauBarostat = 0;
64 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 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
93 sysType = BILAYER;
94
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 }
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 case 'I':
149 // -I <include> => the include file.
150
151 i++;
152 if( headInc == NULL ){
153 headInc = new includeLinked;
154 headInc->next = NULL;
155 strcpy( headInc->name, argv[i] );
156 }
157 else{
158 prevInc = headInc;
159 currInc = headInc->next;
160 while( currInc != NULL ){
161 prevInc = currInc;
162 currInc = prevInc->next;
163 }
164 currInc = new includeLinked;
165 currInc->next = NULL;
166 strcpy( currInc->name, argv[i] );
167 prevInc->next = currInc;
168 }
169
170 done = 1;
171 break;
172
173 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 "Bad option \"-%c\"\n", current_flag);
188 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 sprintf( painCave.errMsg,
217 "No input bass file was specified.\n");
218 painCave.isFatal = 0;
219 simError();
220 usage();
221 }
222
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
231
232 // if no output prefix is given default to "donkey".
233
234 if( !have_prefix ){
235 out_prefix = strdup( "donkey" );
236 }
237
238 // set command line info into the bassInfo struct
239
240 bsInfo.outPrefix = out_prefix;
241 bsInfo.includes = headInc;
242
243
244 // open and parse the bass file.
245
246 set_interface_stamps( the_stamps, the_globals );
247 yacc_BASS( in_name );
248
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 bsInfo.Qmass = the_globals->getQmass();
281 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 bsInfo.ensemble );
335 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 bsInfo.boxZ = the_globals->getBox();
398 }
399 else if( the_globals->haveDensity() ){
400
401 double vol;
402 vol = (double)bsInfo.totNmol / the_globals->getDensity();
403 bsInfo.boxX = pow( vol, ( 1.0 / 3.0 ) );
404 bsInfo.boxY = bsInfo.boxX;
405 bsInfo.boxZ = bsInfo.boxY;
406 }
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 switch( sysType ){
441
442 case BILAYER:
443
444 buildBilayer( isRandom );
445 break;
446
447 case NANO:
448 // buildNano( isRandom );
449 break;
450
451 default:
452 sprintf( painCave.errMsg,
453 "Unknown system type: %d\n", sysType );
454 painCave.isFatal = 1;
455 simError();
456
457 }
458
459
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 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 " -I <include> File name that should be included at the top of the\n"
498 " output bass file.\n"
499 " -r toggle the random option\n"
500 "\n"
501 " long:\n"
502 " -----\n"
503 " --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 "\n"
510 "\n",
511 program_name);
512 exit(8);
513 }