ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysbuilder/latticeBilayer.cpp
Revision: 855
Committed: Thu Nov 6 22:01:37 2003 UTC (21 years, 5 months ago) by mmeineke
File size: 23053 byte(s)
Log Message:
added the following parameters to BASS:
   * useInitialExtendedSystemState
   * orthoBoxTolerance
   * useIntiTime => useInitialTime

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