ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysbuilder/latticeBilayer.cpp
Revision: 821
Committed: Fri Oct 24 22:17:45 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 20013 byte(s)
Log Message:
put QuickBass, MoLocator, and latticeBuilder into a Builder Library
overhauled latticeBilayer into its own program. Removed sysBuild from the Makefile

File Contents

# User Rev Content
1 mmeineke 821 #include <iostream>
2     #include <stdio.h>
3     #include <stdlib.h>
4     #include <string.h>
5     #include <math.h>
6    
7     #include "simError.h"
8     #include "SimInfo.hpp"
9     #include "ReadWrite.hpp"
10    
11     #include "MoLocator.hpp"
12     #include "latticeBuilder.hpp"
13     #include "QuickBass.hpp"
14    
15     #define VERSION_MAJOR 0
16     #define VERSION_MINOR 1
17    
18     char *programName; /*the name of the program */
19     void usage(void);
20     int buildLatticeBilayer( double aLat,
21     double bLat,
22     double leafSpacing);
23     using namespace std;
24    
25     int main(int argC,char* argV[]){
26    
27     int i,j; // loop counters
28    
29     char* outPrefix; // the output prefix
30    
31     char* conversionCheck;
32     bool conversionError;
33     bool optionError;
34    
35     char currentFlag; // used in parsing the flags
36     bool done = false; // multipurpose boolean
37     bool havePrefix; // boolean for the output prefix
38    
39     char* lipidName;
40     char* waterName;
41     bool haveWaterName, haveLipidName;
42    
43     bool haveSpacing, haveAlat, haveBlat;
44     double aLat, bLat, leafSpacing;
45    
46     char* inName;
47    
48     // first things first, all of the initializations
49    
50     fflush(stdout);
51     srand48( 1337 ); // the random number generator.
52     initSimError(); // the error handler
53    
54     outPrefix = NULL;
55     inName = NULL;
56    
57     conversionError = false;
58     optionError = false;
59    
60     havePrefix = false;
61     haveAlat = false;
62     haveBlat = false;
63     haveSpacing = false;
64    
65     programName = argV[0]; /*save the program name in case we need it*/
66    
67     for( i = 1; i < argC; i++){
68    
69     if(argV[i][0] =='-'){
70    
71     // parse the option
72    
73     if(argV[i][1] == '-' ){
74    
75     // parse long word options
76    
77     if( !strcmp( argV[i], "--version") ){
78    
79     printf("\n"
80     "staticProps version %d.%d\n"
81     "\n",
82     VERSION_MAJOR, VERSION_MINOR );
83     exit(0);
84    
85     }
86    
87     else if( !strcmp( argV[i], "--help") ){
88    
89     usage();
90     exit(0);
91     }
92    
93     // anything else is an error
94    
95     else{
96     fprintf( stderr,
97     "Invalid option \"%s\"\n", argV[i] );
98     usage();
99     exit(0);
100     }
101     }
102    
103     else{
104    
105     // parse single character options
106    
107     done =0;
108     j = 1;
109     currentFlag = argV[i][j];
110     while( (currentFlag != '\0') && (!done) ){
111    
112     switch(currentFlag){
113    
114     case 'o':
115     // -o <prefix> => the output prefix.
116    
117     j++;
118     currentFlag = argV[i][j];
119    
120     if( currentFlag != '\0' ) optionError = true;
121    
122     if( optionError ){
123     sprintf( painCave.errMsg,
124     "\n"
125     "The -o flag should end an option sequence.\n"
126     " example: -r <outname> *NOT* -or <outname>\n" );
127     usage();
128     painCave.isFatal = 1;
129     simError();
130     }
131    
132     i++;
133     if( i>=argC ){
134     sprintf( painCave.errMsg,
135     "\n"
136     "not enough arguments for -o\n");
137     usage();
138     painCave.isFatal = 1;
139     simError();
140     }
141    
142     outPrefix = argV[i];
143     if( outPrefix[0] == '-' ) optionError = true;
144    
145     if( optionError ){
146     sprintf( painCave.errMsg,
147     "\n"
148     "\"%s\" is not a valid out prefix/name.\n"
149     "Out prefix/name should not begin with a dash.\n",
150     outPrefix );
151     usage();
152     painCave.isFatal = 1;
153     simError();
154     }
155    
156     havePrefix = true;
157     done = true;
158     break;
159    
160     case 'l':
161     // -l <lipidName> => the lipid name.
162    
163     j++;
164     currentFlag = argV[i][j];
165    
166     if( currentFlag != '\0' ) optionError = true;
167    
168     if( optionError ){
169     sprintf( painCave.errMsg,
170     "\n"
171     "The -l flag should end an option sequence.\n"
172     " example: -rl <lipidName> *NOT* -lr <lipidName>\n" );
173     usage();
174     painCave.isFatal = 1;
175     simError();
176     }
177    
178     i++;
179     if( i>=argC ){
180     sprintf( painCave.errMsg,
181     "\n"
182     "not enough arguments for -l\n");
183     usage();
184     painCave.isFatal = 1;
185     simError();
186     }
187    
188     lipidName = argV[i];
189     if( lipidName[0] == '-' ) optionError = true;
190    
191     if( optionError ){
192     sprintf( painCave.errMsg,
193     "\n"
194     "\"%s\" is not a valid lipidName.\n"
195     "lipidName should not begin with a dash.\n",
196     lipidName );
197     usage();
198     painCave.isFatal = 1;
199     simError();
200     }
201    
202     haveLipidName = true;
203     done = true;
204     break;
205    
206     case 'w':
207     // -w <waterName> => the water name.
208    
209     j++;
210     currentFlag = argV[i][j];
211    
212     if( currentFlag != '\0' ) optionError = true;
213    
214     if( optionError ){
215     sprintf( painCave.errMsg,
216     "\n"
217     "The -w flag should end an option sequence.\n"
218     " example: -rw <waterName> *NOT* -lw <waterName>\n" );
219     usage();
220     painCave.isFatal = 1;
221     simError();
222     }
223    
224     i++;
225     if( i>=argC ){
226     sprintf( painCave.errMsg,
227     "\n"
228     "not enough arguments for -w\n");
229     usage();
230     painCave.isFatal = 1;
231     simError();
232     }
233    
234     waterName = argV[i];
235     if( waterName[0] == '-' ) optionError = true;
236    
237     if( optionError ){
238     sprintf( painCave.errMsg,
239     "\n"
240     "\"%s\" is not a valid waterName.\n"
241     "waterName should not begin with a dash.\n",
242     waterName );
243     usage();
244     painCave.isFatal = 1;
245     simError();
246     }
247    
248     haveWaterName = true;
249     done = true;
250     break;
251    
252    
253     case 'h':
254     // -h <double> set <double> to the hex lattice spacing
255    
256     haveAlat = true;
257     haveBlat = true;
258     j++;
259     currentFlag = argV[i][j];
260    
261     if( currentFlag != '\0' ) optionError = true;
262    
263     if( optionError ){
264     sprintf( painCave.errMsg,
265     "\n"
266     "The -h flag should end an option sequence.\n"
267     " example: -sh <double> *NOT* -hs <double>\n" );
268     usage();
269     painCave.isFatal = 1;
270     simError();
271     }
272    
273     i++;
274     if( i>=argC ){
275     sprintf( painCave.errMsg,
276     "\n"
277     "not enough arguments for -h\n");
278     usage();
279     painCave.isFatal = 1;
280     simError();
281     }
282    
283     bLat = strtod( argV[i], &conversionCheck);
284     if( conversionCheck == argV[i] ) conversionError = true;
285     if( *conversionCheck != '\0' ) conversionError = true;
286    
287     if( conversionError ){
288     sprintf( painCave.errMsg,
289     "Error converting \"%s\" to a double for \"h\".\n",
290     argV[i] );
291     usage();
292     painCave.isFatal = 1;
293     simError();
294     }
295    
296     aLat = sqrt( 3.0 ) * bLat;
297    
298     done = true;
299    
300     break;
301    
302     case 'a':
303     // -a <double> set <double> to the aLat
304    
305     haveAlat = true;
306     j++;
307     currentFlag = argV[i][j];
308    
309     if( currentFlag != '\0' ) optionError = true;
310    
311     if( optionError ){
312     sprintf( painCave.errMsg,
313     "\n"
314     "The -a flag should end an option sequence.\n"
315     " example: -sa <double> *NOT* -as <double>\n" );
316     usage();
317     painCave.isFatal = 1;
318     simError();
319     }
320    
321     i++;
322     if( i>=argC ){
323     sprintf( painCave.errMsg,
324     "\n"
325     "not enough arguments for -a\n");
326     usage();
327     painCave.isFatal = 1;
328     simError();
329     }
330    
331     aLat = strtod( argV[i], &conversionCheck);
332     if( conversionCheck == argV[i] ) conversionError = true;
333     if( *conversionCheck != '\0' ) conversionError = true;
334    
335     if( conversionError ){
336     sprintf( painCave.errMsg,
337     "Error converting \"%s\" to a double for \"a\".\n",
338     argV[i] );
339     usage();
340     painCave.isFatal = 1;
341     simError();
342     }
343    
344     done = true;
345    
346     break;
347    
348     case 'b':
349     // -b <double> set <double> to the bLat
350    
351     haveBlat = true;
352     j++;
353     currentFlag = argV[i][j];
354    
355     if( currentFlag != '\0' ) optionError = true;
356    
357     if( optionError ){
358     sprintf( painCave.errMsg,
359     "\n"
360     "The -b flag should end an option sequence.\n"
361     " example: -sb <double> *NOT* -bs <double>\n" );
362     usage();
363     painCave.isFatal = 1;
364     simError();
365     }
366    
367     i++;
368     if( i>=argC ){
369     sprintf( painCave.errMsg,
370     "\n"
371     "not enough arguments for -b\n");
372     usage();
373     painCave.isFatal = 1;
374     simError();
375     }
376    
377     bLat = strtod( argV[i], &conversionCheck);
378     if( conversionCheck == argV[i] ) conversionError = true;
379     if( *conversionCheck != '\0' ) conversionError = true;
380    
381     if( conversionError ){
382     sprintf( painCave.errMsg,
383     "Error converting \"%s\" to a double for \"a\".\n",
384     argV[i] );
385     usage();
386     painCave.isFatal = 1;
387     simError();
388     }
389    
390     done = true;
391    
392     break;
393    
394     case 's':
395     // -s <double> set <double> to the leafSpacing
396    
397     haveSpacing = true;
398     j++;
399     currentFlag = argV[i][j];
400    
401     if( currentFlag != '\0' ) optionError = true;
402    
403     if( optionError ){
404     sprintf( painCave.errMsg,
405     "\n"
406     "The -s flag should end an option sequence.\n"
407     " example: -rs <double> *NOT* -sr <double>\n" );
408     usage();
409     painCave.isFatal = 1;
410     simError();
411     }
412    
413     i++;
414     if( i>=argC ){
415     sprintf( painCave.errMsg,
416     "\n"
417     "not enough arguments for -s\n");
418     usage();
419     painCave.isFatal = 1;
420     simError();
421     }
422    
423     leafSpacing = strtod( argV[i], &conversionCheck);
424     if( conversionCheck == argV[i] ) conversionError = true;
425     if( *conversionCheck != '\0' ) conversionError = true;
426    
427     if( conversionError ){
428     sprintf( painCave.errMsg,
429     "Error converting \"%s\" to a double for \"s\".\n",
430     argV[i] );
431     usage();
432     painCave.isFatal = 1;
433     simError();
434     }
435    
436     done = true;
437    
438     break;
439    
440     default:
441    
442     sprintf(painCave.errMsg,
443     "\n"
444     "Bad option \"-%c\"\n", currentFlag);
445     usage();
446     painCave.isFatal = 1;
447     simError();
448     }
449     j++;
450     currentFlag = argV[i][j];
451     }
452     }
453     }
454    
455     else{
456    
457     if( inName != NULL ){
458     sprintf( painCave.errMsg,
459     "Error at \"%s\", program does not currently support\n"
460     "more than one input bass file.\n"
461     "\n",
462     argV[i]);
463     usage();
464     painCave.isFatal = 1;
465     simError();
466     }
467    
468     inName = argV[i];
469    
470     }
471     }
472    
473     if( inName == NULL ){
474     sprintf( painCave.errMsg,
475     "Error, bass file is needed to run.\n" );
476     usage();
477     painCave.isFatal = 1;
478     simError();
479     }
480    
481     // if no output prefix is given default to "donkey".
482    
483     if( !havePrefix ){
484     outPrefix = strdup( "donkey" );
485     }
486    
487    
488     if( !haveWaterName ){
489     sprintf( painCave.errMsg,
490     "Error, the water name is needed to run.\n"
491     );
492     usage();
493     painCave.isFatal = 1;
494     simError();
495     }
496    
497     if( !haveLipidName ){
498     sprintf( painCave.errMsg,
499     "Error, the lipid name is needed to run.\n"
500     );
501     usage();
502     painCave.isFatal = 1;
503     simError();
504     }
505    
506     if( !haveAlat ){
507     sprintf( painCave.errMsg,
508     "Error, the hexagonal lattice parameter, a, is needed to run.\n"
509     );
510     usage();
511     painCave.isFatal = 1;
512     simError();
513     }
514    
515     if( !haveBlat ){
516     sprintf( painCave.errMsg,
517     "Error, the hexagonal lattice parameter, b, is needed to run.\n"
518     );
519     usage();
520     painCave.isFatal = 1;
521     simError();
522     }
523    
524    
525     if( !haveSpacing ){
526     sprintf( painCave.errMsg,
527     "Error, the leaf spaceing is needed to run.\n"
528     );
529     usage();
530     painCave.isFatal = 1;
531     simError();
532     }
533    
534     bsInfo.outPrefix = outPrefix;
535     strcpy(bsInfo.waterName, waterName);
536     strcpy(bsInfo.lipidName, lipidName);
537    
538     parseBuildBass( inName );
539    
540     buildLatticeBilayer( aLat, bLat, leafSpacing );
541    
542     return 0;
543     }
544    
545     int buildLatticeBilayer(double aLat,
546     double bLat,
547     double leafSpacing){
548    
549     typedef struct{
550     double rot[3][3];
551     double pos[3];
552     } coord;
553    
554     const double waterRho = 0.0334; // number density per cubic angstrom
555     const double waterVol = 4.0 / waterRho; // volume occupied by 4 waters
556    
557     double waterCell[3];
558    
559     double *posX, *posY, *posZ;
560     double pos[3], posA[3], posB[3];
561    
562     const double waterFudge = 5.0;
563    
564     int i,j,k,l;
565     int nAtoms, atomIndex, molIndex, molID;
566     int* molSeq;
567     int* molMap;
568     int* molStart;
569     int testTot, done;
570     int nCells, nCellsX, nCellsY, nCellsZ;
571     int nx, ny;
572     double boxX, boxY, boxZ;
573     double unitVector[3];
574     int which;
575     int targetWaters;
576    
577     Atom** atoms;
578     SimInfo* simnfo;
579     SimInfo* testInfo;
580     coord testSite;
581     SimState* theConfig;
582     DumpWriter* writer;
583    
584     MoleculeStamp* lipidStamp;
585     MoleculeStamp* waterStamp;
586     MoLocator *lipidLocate;
587     MoLocator *waterLocate;
588     int foundLipid, foundWater;
589     int nLipids, lipidNatoms, nWaters, waterNatoms;
590     int targetNlipids, targetNwaters;
591     double targetWaterLipidRatio;
592     double maxZ, minZ, zHeight;
593    
594     // create the simInfo objects
595    
596     simnfo = new SimInfo;
597    
598     // set the the lipidStamp
599    
600     foundLipid = 0;
601     foundWater = 0;
602     for(i=0; i<bsInfo.nComponents; i++){
603     if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.lipidName ) ){
604    
605     foundLipid = 1;
606     lipidStamp = bsInfo.compStamps[i];
607     targetNlipids = bsInfo.componentsNmol[i];
608     lipidNatoms = lipidStamp->getNAtoms();
609     }
610     if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.waterName ) ){
611    
612     foundWater = 1;
613    
614     waterStamp = bsInfo.compStamps[i];
615     targetNwaters = bsInfo.componentsNmol[i];
616     waterNatoms = waterStamp->getNAtoms();
617     }
618     }
619     if( !foundLipid ){
620     sprintf(painCave.errMsg,
621     "Could not find lipid \"%s\" in the bass file.\n",
622     bsInfo.lipidName );
623     painCave.isFatal = 1;
624     simError();
625     }
626     if( !foundWater ){
627     sprintf(painCave.errMsg,
628     "Could not find solvent \"%s\" in the bass file.\n",
629     bsInfo.waterName );
630     painCave.isFatal = 1;
631     simError();
632     }
633    
634     //create the Molocator arrays
635    
636     lipidLocate = new MoLocator( lipidStamp );
637     waterLocate = new MoLocator( waterStamp );
638    
639     // gather info about the lipid
640    
641     testInfo = new SimInfo();
642     testInfo->n_atoms = lipidNatoms;
643     theConfig = testInfo->getConfiguration();
644     theConfig->createArrays( lipidNatoms );
645     testInfo->atoms = new Atom*[lipidNatoms];
646     atoms = testInfo->atoms;
647    
648     testSite.pos[0] = 0.0;
649     testSite.pos[1] = 0.0;
650     testSite.pos[2] = 0.0;
651    
652     unitVector[0] = 0.0;
653     unitVector[1] = 0.0;
654     unitVector[2] = 1.0;
655    
656     getUnitRot(unitVector, testSite.rot );
657     lipidLocate->placeMol( testSite.pos, testSite.rot, atoms, 0, theConfig );
658    
659     minZ = 0.0;
660     maxZ = 0.0;
661     double myPos[3];
662     for(i=0;i<lipidNatoms;i++){
663     atoms[i]->getPos( myPos );
664     minZ = (minZ > myPos[2]) ? myPos[2] : minZ;
665     maxZ = (maxZ < myPos[2]) ? myPos[2] : maxZ;
666     }
667     zHeight = maxZ - minZ;
668    
669     nCells = (int) sqrt( (double)targetNlipids * bLat / (4.0 * aLat) );
670    
671     nx = nCells;
672     ny = (int) ((double)nCells * aLat / bLat);
673    
674     boxX = nx * aLat;
675     boxY = ny * bLat;
676    
677     nLipids = 4 * nx * ny;
678     coord* lipidSites = new coord[nLipids];
679    
680     unitVector[0] = 0.0;
681     unitVector[1] = 0.0;
682    
683     which = 0;
684    
685     for (i = 0; i < nx; i++) {
686     for (j = 0; j < ny; j++ ) {
687     for (k = 0; k < 2; k++) {
688    
689     lipidSites[which].pos[0] = (double)i * aLat;
690     lipidSites[which].pos[1] = (double)j * bLat;
691     lipidSites[which].pos[2] = ((double)k - 0.5) * (leafSpacing - maxZ);
692    
693     unitVector[2] = 2.0 * (double)k - 1.0;
694    
695     getUnitRot( unitVector, lipidSites[which].rot );
696    
697     which++;
698    
699     lipidSites[which].pos[0] = aLat * ((double)i + 0.5);
700     lipidSites[which].pos[1] = bLat * ((double)j + 0.5);
701     lipidSites[which].pos[2] = ((double)k - 0.5) * (leafSpacing - maxZ);
702    
703     unitVector[2] = 2.0 * (double)k - 1.0;
704    
705     getUnitRot( unitVector, lipidSites[which].rot );
706    
707     which++;
708     }
709     }
710     }
711    
712     targetWaterLipidRatio = (double)targetNwaters / (double)targetNlipids;
713    
714     targetWaters = targetWaterLipidRatio * nLipids;
715    
716     // guess the size of the water box
717    
718     nCellsX = (int)ceil(boxX / pow(waterVol, ( 1.0 / 3.0 )) );
719     nCellsY = (int)ceil(boxY / pow(waterVol, ( 1.0 / 3.0 )) );
720    
721     done = 0;
722     nCellsZ = 0;
723     while( !done ){
724    
725     nCellsZ++;
726     testTot = 4 * nCellsX * nCellsY * nCellsZ;
727    
728     if( testTot >= targetWaters ) done = 1;
729     }
730    
731     nWaters = nCellsX * nCellsY * nCellsZ * 4;
732    
733     coord* waterSites = new coord[nWaters];
734    
735     waterCell[0] = boxX / nCellsX;
736     waterCell[1] = boxY / nCellsY;
737     waterCell[2] = 4.0 / (waterRho * waterCell[0] * waterCell[1]);
738    
739     Lattice *myORTHO;
740     myORTHO = new Lattice( ORTHORHOMBIC_LATTICE_TYPE, waterCell);
741     myORTHO->setStartZ( leafSpacing / 2.0 + waterFudge);
742    
743     boxZ = waterCell[2] * nCellsZ + leafSpacing;
744    
745     // create an fcc lattice in the water box.
746    
747     which = 0;
748     for( i=0; i < nCellsX; i++ ){
749     for( j=0; j < nCellsY; j++ ){
750     for( k=0; k < nCellsZ; k++ ){
751    
752     myORTHO->getLatticePoints(&posX, &posY, &posZ, i, j, k);
753     for(l=0; l<4; l++){
754     waterSites[which].pos[0] = posX[l];
755     waterSites[which].pos[1] = posY[l];
756     waterSites[which].pos[2] = posZ[l];
757     which++;
758     }
759     }
760     }
761     }
762    
763     // create the real Atom arrays
764    
765     nAtoms = 0;
766     molIndex = 0;
767     molStart = new int[nLipids + nWaters];
768    
769     for(j=0; j<nLipids; j++){
770     molStart[molIndex] = nAtoms;
771     molIndex++;
772     nAtoms += lipidNatoms;
773     }
774    
775     for(j=0; j<nWaters; j++){
776     molStart[molIndex] = nAtoms;
777     molIndex++;
778     nAtoms += waterNatoms;
779     }
780    
781     theConfig = simnfo->getConfiguration();
782     theConfig->createArrays( nAtoms );
783     simnfo->atoms = new Atom*[nAtoms];
784     atoms = simnfo->atoms;
785    
786    
787     // wrap back to <0,0,0> as center
788    
789     double Hmat[3][3];
790    
791     Hmat[0][0] = boxX;
792     Hmat[0][1] = 0.0;
793     Hmat[0][2] = 0.0;
794    
795     Hmat[1][0] = 0.0;
796     Hmat[1][1] = boxY;
797     Hmat[1][2] = 0.0;
798    
799     Hmat[2][0] = 0.0;
800     Hmat[2][1] = 0.0;
801     Hmat[2][2] = boxZ;
802    
803     bsInfo.boxX = boxX;
804     bsInfo.boxY = boxY;
805     bsInfo.boxZ = boxZ;
806    
807     simnfo->setBoxM( Hmat );
808    
809     for(j=0;j<nLipids;j++)
810     simnfo->wrapVector( lipidSites[j].pos );
811    
812     for(j=0;j<nWaters;j++)
813     simnfo->wrapVector( waterSites[j].pos );
814    
815     // initialize lipid positions
816    
817     molIndex = 0;
818     for(i=0; i<nLipids; i++ ){
819     lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
820     molStart[molIndex], theConfig );
821     molIndex++;
822     }
823    
824     // initialize the water positions
825    
826     for(i=0; i<nWaters; i++){
827    
828     getRandomRot( waterSites[i].rot );
829     waterLocate->placeMol( waterSites[i].pos, waterSites[i].rot, atoms,
830     molStart[molIndex], theConfig );
831     molIndex++;
832     }
833    
834     // set up the SimInfo object
835    
836     Hmat[0][0] = boxX;
837     Hmat[0][1] = 0.0;
838     Hmat[0][2] = 0.0;
839    
840     Hmat[1][0] = 0.0;
841     Hmat[1][1] = boxY;
842     Hmat[1][2] = 0.0;
843    
844     Hmat[2][0] = 0.0;
845     Hmat[2][1] = 0.0;
846     Hmat[2][2] = boxZ;
847    
848    
849     bsInfo.boxX = boxX;
850     bsInfo.boxY = boxY;
851     bsInfo.boxZ = boxZ;
852    
853     simnfo->setBoxM( Hmat );
854    
855     sprintf( simnfo->sampleName, "%s.dump", bsInfo.outPrefix );
856     sprintf( simnfo->finalName, "%s.init", bsInfo.outPrefix );
857    
858     // set up the writer and write out
859    
860     writer = new DumpWriter( simnfo );
861     writer->writeFinal( 0.0 );
862    
863     return 1;
864     }
865    
866    
867     /***************************************************************************
868     * prints out the usage for the command line arguments, then exits.
869     ***************************************************************************/
870    
871     void usage(){
872     (void)fprintf(stdout,
873     "\n"
874     "The proper usage is: %s [options] <input_file>\n"
875     "\n"
876     "Options:\n"
877     "\n"
878     " short:\n"
879     " ------\n"
880     " -o <name> The output prefix\n"
881     " -l <lipidName> The name of the lipid molecule specified in the BASS file.\n"
882     " -w <waterName> The name of the water molecule specified in the BASS file.\n"
883     " -s <double> The leaf spaceing of the bilayer.\n"
884     " -a <double> The hexagonal lattice constant, a, for the bilayer leaf.\n"
885     " -b <double> The hexagonal lattice constant, b, for the bilayer leaf.\n"
886     " -h <double> Use to set a and b for a normal hex lattice with spacing <double>\n"
887    
888     "\n"
889     " long:\n"
890     " -----\n"
891    
892     " --version displays the version number\n"
893     " --help displays this help message.\n"
894     "\n"
895     "\n",
896     programName);
897     }