ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysbuilder/latticeBilayer.cpp
Revision: 874
Committed: Fri Nov 21 20:10:02 2003 UTC (21 years, 5 months ago) by mmeineke
File size: 23015 byte(s)
Log Message:
added a more verbose error message in SimInfo. Added a more informative error message in InitializeFromFile

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 874 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 mmeineke 874 const double waterFudge = 6.0;
585 mmeineke 821
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* testInfo;
601     coord testSite;
602     SimState* theConfig;
603     DumpWriter* writer;
604    
605     MoleculeStamp* lipidStamp;
606     MoleculeStamp* waterStamp;
607     MoLocator *lipidLocate;
608     MoLocator *waterLocate;
609     int foundLipid, foundWater;
610     int nLipids, lipidNatoms, nWaters, waterNatoms;
611     int targetNlipids, targetNwaters;
612     double targetWaterLipidRatio;
613     double maxZ, minZ, zHeight;
614 mmeineke 825 double maxY, minY;
615     double maxX, minX;
616 mmeineke 821
617 mmeineke 825 molStart = NULL;
618    
619 mmeineke 821 // set the the lipidStamp
620    
621     foundLipid = 0;
622     foundWater = 0;
623 mmeineke 825
624     for(i=0; i<mainInfo->nComponents; i++){
625    
626     if( !strcmp( mainInfo->compStamps[i]->getID(), lipidName ) ){
627 mmeineke 821
628     foundLipid = 1;
629 mmeineke 825 lipidStamp = mainInfo->compStamps[i];
630     targetNlipids = mainInfo->componentsNmol[i];
631 mmeineke 821 lipidNatoms = lipidStamp->getNAtoms();
632     }
633 mmeineke 825 if( !strcmp( mainInfo->compStamps[i]->getID(), waterName ) ){
634 mmeineke 821
635     foundWater = 1;
636    
637 mmeineke 825 waterStamp = mainInfo->compStamps[i];
638     targetNwaters = mainInfo->componentsNmol[i];
639 mmeineke 821 waterNatoms = waterStamp->getNAtoms();
640     }
641     }
642     if( !foundLipid ){
643     sprintf(painCave.errMsg,
644 mmeineke 825 "latticeBilayer error: Could not find lipid \"%s\" in the bass file.\n",
645     lipidName );
646 mmeineke 821 painCave.isFatal = 1;
647     simError();
648     }
649     if( !foundWater ){
650     sprintf(painCave.errMsg,
651 mmeineke 825 "latticeBilayer error: Could not find solvent \"%s\" in the bass file.\n",
652     waterName );
653 mmeineke 821 painCave.isFatal = 1;
654     simError();
655     }
656    
657     //create the Molocator arrays
658    
659     lipidLocate = new MoLocator( lipidStamp );
660     waterLocate = new MoLocator( waterStamp );
661    
662     // gather info about the lipid
663    
664     testInfo = new SimInfo();
665     testInfo->n_atoms = lipidNatoms;
666     theConfig = testInfo->getConfiguration();
667     theConfig->createArrays( lipidNatoms );
668     testInfo->atoms = new Atom*[lipidNatoms];
669     atoms = testInfo->atoms;
670    
671     testSite.pos[0] = 0.0;
672     testSite.pos[1] = 0.0;
673     testSite.pos[2] = 0.0;
674    
675 mmeineke 825 theta = 0.0;
676     phi = 0.0;
677     psi = 0.0;
678    
679     getEulerRot(theta, phi, psi, testSite.rot );
680 mmeineke 821 lipidLocate->placeMol( testSite.pos, testSite.rot, atoms, 0, theConfig );
681    
682     minZ = 0.0;
683     maxZ = 0.0;
684     double myPos[3];
685     for(i=0;i<lipidNatoms;i++){
686     atoms[i]->getPos( myPos );
687     minZ = (minZ > myPos[2]) ? myPos[2] : minZ;
688     maxZ = (maxZ < myPos[2]) ? myPos[2] : maxZ;
689     }
690     zHeight = maxZ - minZ;
691    
692 mmeineke 874 std::cerr << "aLat = " << aLat << "; bLat = " << bLat << "\n";
693 mmeineke 821
694 mmeineke 874 nCells = (int)ceil( sqrt( (double)targetNlipids * bLat / (4.0 * aLat) ));
695    
696 mmeineke 821 nx = nCells;
697     ny = (int) ((double)nCells * aLat / bLat);
698    
699 mmeineke 874 std::cerr << "nx = " << nx << "; ny = " << ny << "\n";
700    
701 mmeineke 821 boxX = nx * aLat;
702     boxY = ny * bLat;
703    
704     nLipids = 4 * nx * ny;
705     coord* lipidSites = new coord[nLipids];
706    
707 mmeineke 825 phi = 0.0;
708     psi = 0.0;
709 mmeineke 821
710     which = 0;
711    
712     for (i = 0; i < nx; i++) {
713     for (j = 0; j < ny; j++ ) {
714     for (k = 0; k < 2; k++) {
715    
716     lipidSites[which].pos[0] = (double)i * aLat;
717     lipidSites[which].pos[1] = (double)j * bLat;
718 mmeineke 825 lipidSites[which].pos[2] = (2.0* (double)k - 1.0) *
719     ((leafSpacing / 2.0) - maxZ);
720 mmeineke 821
721 mmeineke 825 theta = (1.0 - (double)k) * M_PI;
722 mmeineke 821
723 mmeineke 825 getEulerRot( theta, phi, psi, lipidSites[which].rot );
724 mmeineke 821
725     which++;
726    
727     lipidSites[which].pos[0] = aLat * ((double)i + 0.5);
728     lipidSites[which].pos[1] = bLat * ((double)j + 0.5);
729 mmeineke 825 lipidSites[which].pos[2] = (2.0* (double)k - 1.0) *
730     ((leafSpacing / 2.0) - maxZ);
731 mmeineke 821
732 mmeineke 825 theta = (1.0 - (double)k) * M_PI;
733 mmeineke 821
734 mmeineke 825 getEulerRot( theta, phi, psi, lipidSites[which].rot );
735 mmeineke 821
736     which++;
737     }
738     }
739     }
740    
741     targetWaterLipidRatio = (double)targetNwaters / (double)targetNlipids;
742    
743     targetWaters = targetWaterLipidRatio * nLipids;
744    
745     // guess the size of the water box
746    
747     nCellsX = (int)ceil(boxX / pow(waterVol, ( 1.0 / 3.0 )) );
748     nCellsY = (int)ceil(boxY / pow(waterVol, ( 1.0 / 3.0 )) );
749    
750     done = 0;
751     nCellsZ = 0;
752     while( !done ){
753    
754     nCellsZ++;
755     testTot = 4 * nCellsX * nCellsY * nCellsZ;
756    
757     if( testTot >= targetWaters ) done = 1;
758     }
759    
760     nWaters = nCellsX * nCellsY * nCellsZ * 4;
761    
762 mmeineke 825 // calc current system size;
763    
764     nAtoms = 0;
765     molIndex = 0;
766     if(molStart != NULL ) delete[] molStart;
767     molStart = new int[nLipids];
768    
769     for(j=0; j<nLipids; j++){
770     molStart[molIndex] = nAtoms;
771     molIndex++;
772     nAtoms += lipidNatoms;
773     }
774    
775     testInfo->n_atoms = nAtoms;
776     theConfig = testInfo->getConfiguration();
777     theConfig->destroyArrays();
778     theConfig->createArrays( nAtoms );
779     testInfo->atoms = new Atom*[nAtoms];
780     atoms = testInfo->atoms;
781    
782     molIndex = 0;
783     for(i=0; i<nLipids; i++ ){
784     lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
785     molStart[molIndex], theConfig );
786     molIndex++;
787     }
788    
789     atoms[0]->getPos( myPos );
790    
791     maxX = myPos[0];
792     minX = myPos[0];
793    
794     maxY = myPos[1];
795     minY = myPos[1];
796    
797     maxZ = myPos[2];
798     minZ = myPos[2];
799    
800     for(i=0;i<nAtoms;i++){
801     atoms[i]->getPos( myPos );
802     minX = (minX > myPos[0]) ? myPos[0] : minX;
803     maxX = (maxX < myPos[0]) ? myPos[0] : maxX;
804    
805     minY = (minY > myPos[1]) ? myPos[1] : minY;
806     maxY = (maxY < myPos[1]) ? myPos[1] : maxY;
807    
808     minZ = (minZ > myPos[2]) ? myPos[2] : minZ;
809     maxZ = (maxZ < myPos[2]) ? myPos[2] : maxZ;
810     }
811    
812     boxX = (maxX - minX)+2.0;
813     boxY = (maxY - minY)+2.0;
814     boxZ = (maxZ - minZ)+2.0;
815    
816     double centerX, centerY, centerZ;
817    
818     centerX = ((maxX - minX) / 2.0) + minX;
819     centerY = ((maxY - minY) / 2.0) + minY;
820     centerZ = ((maxZ - minZ) / 2.0) + minZ;
821    
822     // set up water coordinates
823    
824 mmeineke 821 coord* waterSites = new coord[nWaters];
825    
826     waterCell[0] = boxX / nCellsX;
827     waterCell[1] = boxY / nCellsY;
828     waterCell[2] = 4.0 / (waterRho * waterCell[0] * waterCell[1]);
829    
830     Lattice *myORTHO;
831     myORTHO = new Lattice( ORTHORHOMBIC_LATTICE_TYPE, waterCell);
832 mmeineke 825 myORTHO->setStartZ( maxZ + waterFudge);
833 mmeineke 821
834     // create an fcc lattice in the water box.
835    
836     which = 0;
837     for( i=0; i < nCellsX; i++ ){
838     for( j=0; j < nCellsY; j++ ){
839     for( k=0; k < nCellsZ; k++ ){
840    
841     myORTHO->getLatticePoints(&posX, &posY, &posZ, i, j, k);
842     for(l=0; l<4; l++){
843     waterSites[which].pos[0] = posX[l];
844     waterSites[which].pos[1] = posY[l];
845     waterSites[which].pos[2] = posZ[l];
846 mmeineke 825 getRandomRot( waterSites[which].rot );
847 mmeineke 821 which++;
848     }
849     }
850     }
851     }
852    
853 mmeineke 825 // calc the system sizes
854 mmeineke 821
855     nAtoms = 0;
856     molIndex = 0;
857 mmeineke 825 if(molStart != NULL ) delete[] molStart;
858 mmeineke 821 molStart = new int[nLipids + nWaters];
859    
860     for(j=0; j<nLipids; j++){
861     molStart[molIndex] = nAtoms;
862     molIndex++;
863     nAtoms += lipidNatoms;
864     }
865    
866     for(j=0; j<nWaters; j++){
867     molStart[molIndex] = nAtoms;
868     molIndex++;
869     nAtoms += waterNatoms;
870     }
871    
872 mmeineke 825 testInfo->n_atoms = nAtoms;
873     theConfig = testInfo->getConfiguration();
874     theConfig->destroyArrays();
875     theConfig->createArrays( nAtoms );
876     testInfo->atoms = new Atom*[nAtoms];
877     atoms = testInfo->atoms;
878    
879     molIndex = 0;
880     for(i=0; i<nLipids; i++ ){
881     lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
882     molStart[molIndex], theConfig );
883     molIndex++;
884     }
885    
886     for(i=0; i<nWaters; i++){
887    
888     getRandomRot( waterSites[i].rot );
889     waterLocate->placeMol( waterSites[i].pos, waterSites[i].rot, atoms,
890     molStart[molIndex], theConfig );
891     molIndex++;
892     }
893    
894     atoms[0]->getPos( myPos );
895     maxZ = myPos[2];
896     minZ = myPos[2];
897     for(i=0;i<nAtoms;i++){
898     atoms[i]->getPos( myPos );
899     minZ = (minZ > myPos[2]) ? myPos[2] : minZ;
900     maxZ = (maxZ < myPos[2]) ? myPos[2] : maxZ;
901     }
902     boxZ = (maxZ - (minZ - waterFudge / 2.0));
903    
904     // create the real Atom arrays
905    
906 mmeineke 874 delete[] (mainInfo->atoms);
907     theConfig = mainInfo->getConfiguration();
908 mmeineke 821 theConfig->createArrays( nAtoms );
909 mmeineke 874 mainInfo->atoms = new Atom*[nAtoms];
910     mainInfo->n_atoms = nAtoms;
911     atoms = mainInfo->atoms;
912 mmeineke 821
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
931 mmeineke 825 for(j=0;j<nLipids;j++){
932    
933     lipidSites[j].pos[0] -= centerX;
934     lipidSites[j].pos[1] -= centerY;
935     lipidSites[j].pos[2] -= centerZ;
936    
937 mmeineke 874 mainInfo->wrapVector( lipidSites[j].pos );
938 mmeineke 825 }
939 mmeineke 821
940 mmeineke 825 for(j=0;j<nWaters;j++){
941    
942     waterSites[j].pos[0] -= centerX;
943     waterSites[j].pos[1] -= centerY;
944     waterSites[j].pos[2] -= centerZ;
945    
946 mmeineke 874 mainInfo->wrapVector( waterSites[j].pos );
947 mmeineke 825 }
948 mmeineke 821
949     // initialize lipid positions
950    
951     molIndex = 0;
952     for(i=0; i<nLipids; i++ ){
953     lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
954     molStart[molIndex], theConfig );
955     molIndex++;
956     }
957    
958     // initialize the water positions
959    
960     for(i=0; i<nWaters; i++){
961 mmeineke 825
962 mmeineke 821 getRandomRot( waterSites[i].rot );
963     waterLocate->placeMol( waterSites[i].pos, waterSites[i].rot, atoms,
964     molStart[molIndex], theConfig );
965     molIndex++;
966     }
967    
968     // set up the writer and write out
969    
970 mmeineke 874 writer = new DumpWriter( mainInfo );
971 mmeineke 821 writer->writeFinal( 0.0 );
972    
973 mmeineke 851 std::cout << "\n"
974     << "----------------------------------------\n"
975     << "\n"
976     << " final nLipids = " << nLipids << "\n"
977     << " final nWaters = " << nWaters << "\n"
978     << "\n";
979    
980 mmeineke 821 return 1;
981     }
982    
983    
984     /***************************************************************************
985     * prints out the usage for the command line arguments, then exits.
986     ***************************************************************************/
987    
988     void usage(){
989     (void)fprintf(stdout,
990     "\n"
991     "The proper usage is: %s [options] <input_file>\n"
992     "\n"
993     "Options:\n"
994     "\n"
995     " short:\n"
996     " ------\n"
997     " -o <name> The output prefix\n"
998     " -l <lipidName> The name of the lipid molecule specified in the BASS file.\n"
999     " -w <waterName> The name of the water molecule specified in the BASS file.\n"
1000     " -s <double> The leaf spaceing of the bilayer.\n"
1001     " -a <double> The hexagonal lattice constant, a, for the bilayer leaf.\n"
1002     " -b <double> The hexagonal lattice constant, b, for the bilayer leaf.\n"
1003     " -h <double> Use to set a and b for a normal hex lattice with spacing <double>\n"
1004    
1005     "\n"
1006     " long:\n"
1007     " -----\n"
1008    
1009     " --version displays the version number\n"
1010     " --help displays this help message.\n"
1011     "\n"
1012     "\n",
1013     programName);
1014     }