ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/nanoSysBuild.cpp
Revision: 598
Committed: Mon Jul 14 21:35:45 2003 UTC (21 years, 9 months ago) by chuckv
File size: 13558 byte(s)
Log Message:
added a nanoSysBuilder that takes different cmd line arguments.

File Contents

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