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, 2 months ago) by chuckv
File size: 13558 byte(s)
Log Message:
added a nanoSysBuilder that takes different cmd line arguments.

File Contents

# User Rev Content
1 chuckv 598
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     }