ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysbuilder/bilayerSys.cpp
Revision: 763
Committed: Mon Sep 15 16:52:02 2003 UTC (20 years, 10 months ago) by tim
File size: 13521 byte(s)
Log Message:
add conserved quantity to statWriter
fix bug of vector wrapping at NPTi

File Contents

# User Rev Content
1 mmeineke 707
2 chuckv 678 #include <iostream>
3 mmeineke 707 #include <vector>
4     #include <algorithm>
5 chuckv 678
6     #include <cstdlib>
7     #include <cstring>
8     #include <cmath>
9    
10 mmeineke 707
11 chuckv 678 #include "simError.h"
12     #include "SimInfo.hpp"
13     #include "ReadWrite.hpp"
14    
15     #include "MoLocator.hpp"
16     #include "sysBuild.hpp"
17     #include "bilayerSys.hpp"
18    
19 chuckv 700 #include "latticeBuilder.hpp"
20 chuckv 678
21 mmeineke 707 class SortCond{
22    
23     public:
24     bool operator()(const pair<int, double>& p1, const pair<int, double>& p2){
25     return p1.second < p2.second;
26     }
27    
28    
29     };
30    
31    
32 chuckv 678 void buildMap( double &x, double &y, double &z,
33 chuckv 700 double boxX, double boxY, double boxZ );
34 chuckv 678
35     int buildRandomBilayer( void );
36    
37     void getRandomRot( double rot[3][3] );
38    
39     int buildBilayer( int isRandom ){
40    
41     if( isRandom ){
42     return buildRandomBilayer();
43     }
44     else{
45     sprintf( painCave.errMsg,
46     "Cannot currently create a non-random bilayer.\n" );
47     painCave.isFatal = 1;
48     simError();
49     return 0;
50     }
51     }
52    
53    
54     int buildRandomBilayer( void ){
55    
56     typedef struct{
57     double rot[3][3];
58     double pos[3];
59     } coord;
60    
61    
62 chuckv 700
63 chuckv 678 const double waterRho = 0.0334; // number density per cubic angstrom
64     const double waterVol = 4.0 / waterRho; // volume occupied by 4 waters
65     const double waterCell = 4.929; // fcc unit cell length
66    
67 chuckv 700 Lattice myFCC( FCC_LATTICE_TYPE, waterCell );
68     double *posX, *posY, *posZ;
69     double pos[3], posA[3], posB[3];
70    
71 chuckv 678 const double water_padding = 6.0;
72     const double lipid_spaceing = 8.0;
73    
74    
75 chuckv 700 int i,j,k, l, m;
76 chuckv 678 int nAtoms, atomIndex, molIndex, molID;
77     int* molSeq;
78     int* molMap;
79     int* molStart;
80     int* cardDeck;
81     int deckSize;
82     int rSite, rCard;
83     double cell;
84     int nCells, nSites, siteIndex;
85    
86     coord testSite;
87    
88     Atom** atoms;
89     SimInfo* simnfo;
90 chuckv 700 SimState* theConfig;
91 chuckv 678 DumpWriter* writer;
92    
93     MoleculeStamp* lipidStamp;
94     MoleculeStamp* waterStamp;
95     MoLocator *lipidLocate;
96     MoLocator *waterLocate;
97     int foundLipid, foundWater;
98     int nLipids, lipidNatoms, nWaters, waterNatoms;
99     double testBox, maxLength;
100    
101     srand48( RAND_SEED );
102    
103    
104     // create the simInfo objects
105    
106     simnfo = new SimInfo[3];
107    
108    
109     // set the the lipidStamp
110    
111     foundLipid = 0;
112     foundWater = 0;
113     for(i=0; i<bsInfo.nComponents; i++){
114     if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.lipidName ) ){
115 chuckv 700
116 chuckv 678 foundLipid = 1;
117     lipidStamp = bsInfo.compStamps[i];
118     nLipids = bsInfo.componentsNmol[i];
119     }
120     if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.waterName ) ){
121 chuckv 700
122 chuckv 678 foundWater = 1;
123 chuckv 700
124 chuckv 678 waterStamp = bsInfo.compStamps[i];
125     nWaters = bsInfo.componentsNmol[i];
126     }
127     }
128     if( !foundLipid ){
129     sprintf(painCave.errMsg,
130     "Could not find lipid \"%s\" in the bass file.\n",
131     bsInfo.lipidName );
132     painCave.isFatal = 1;
133     simError();
134     }
135     if( !foundWater ){
136 chuckv 700 sprintf(painCave.errMsg,
137     "Could not find solvent \"%s\" in the bass file.\n",
138 chuckv 678 bsInfo.waterName );
139     painCave.isFatal = 1;
140     simError();
141     }
142    
143     //create the temp Molocator and atom Arrays
144    
145     lipidLocate = new MoLocator( lipidStamp );
146     lipidNatoms = lipidStamp->getNAtoms();
147     maxLength = lipidLocate->getMaxLength();
148    
149     waterLocate = new MoLocator( waterStamp );
150     waterNatoms = waterStamp->getNAtoms();
151    
152 chuckv 700 nAtoms = lipidNatoms;
153 chuckv 678
154 chuckv 700 simnfo[0].n_atoms = nAtoms;
155     simnfo[0].atoms=new Atom*[nAtoms];
156 chuckv 678
157 chuckv 700 theConfig = simnfo[0].getConfiguration();
158     theConfig->createArrays( simnfo[0].n_atoms );
159 chuckv 678
160 chuckv 700 atoms=simnfo[0].atoms;
161 chuckv 678
162    
163     // create the test box for initial water displacement
164    
165     testBox = maxLength + waterCell * 4.0; // pad with 4 cells
166     nCells = (int)( testBox / waterCell + 1.0 );
167     int testWaters = 4 * nCells * nCells * nCells;
168    
169     double* waterX = new double[testWaters];
170     double* waterY = new double[testWaters];
171     double* waterZ = new double[testWaters];
172    
173     double x0 = 0.0 - ( testBox * 0.5 );
174     double y0 = 0.0 - ( testBox * 0.5 );
175     double z0 = 0.0 - ( testBox * 0.5 );
176    
177    
178     // create an fcc lattice in the water box.
179    
180     int ndx = 0;
181     for( i=0; i < nCells; i++ ){
182     for( j=0; j < nCells; j++ ){
183     for( k=0; k < nCells; k++ ){
184 chuckv 700
185     myFCC.getLatticePoints(&posX, &posY, &posZ, i, j, k);
186     for(l=0; l<4; l++){
187     waterX[ndx]=posX[l];
188     waterY[ndx]=posY[l];
189     waterZ[ndx]=posZ[l];
190     ndx++;
191     }
192 chuckv 678 }
193     }
194     }
195    
196     // calculate the number of water's displaced by our lipid.
197    
198     testSite.rot[0][0] = 1.0;
199     testSite.rot[0][1] = 0.0;
200     testSite.rot[0][2] = 0.0;
201    
202     testSite.rot[1][0] = 0.0;
203     testSite.rot[1][1] = 1.0;
204     testSite.rot[1][2] = 0.0;
205    
206     testSite.rot[2][0] = 0.0;
207     testSite.rot[2][1] = 0.0;
208     testSite.rot[2][2] = 1.0;
209    
210     testSite.pos[0] = 0.0;
211     testSite.pos[1] = 0.0;
212     testSite.pos[2] = 0.0;
213    
214 chuckv 700 lipidLocate->placeMol( testSite.pos, testSite.rot, atoms, 0, theConfig );
215 chuckv 678
216     int *isActive = new int[testWaters];
217     for(i=0; i<testWaters; i++) isActive[i] = 1;
218    
219     int n_deleted = 0;
220     double dx, dy, dz;
221     double dx2, dy2, dz2, dSqr;
222     double rCutSqr = water_padding * water_padding;
223    
224     for(i=0; ( (i<testWaters) && isActive[i] ); i++){
225     for(j=0; ( (j<lipidNatoms) && isActive[i] ); j++){
226 chuckv 700
227     atoms[j]->getPos( pos );
228 chuckv 678
229 chuckv 700 dx = waterX[i] - pos[0];
230     dy = waterY[i] - pos[1];
231     dz = waterZ[i] - pos[2];
232 chuckv 678
233     buildMap( dx, dy, dz, testBox, testBox, testBox );
234    
235     dx2 = dx * dx;
236     dy2 = dy * dy;
237     dz2 = dz * dz;
238 chuckv 700
239 chuckv 678 dSqr = dx2 + dy2 + dz2;
240     if( dSqr < rCutSqr ){
241     isActive[i] = 0;
242     n_deleted++;
243     }
244     }
245     }
246    
247     int targetWaters = nWaters + n_deleted * nLipids;
248    
249     targetWaters = (int) ( targetWaters * 1.2 );
250    
251     // find the best box size for the sim
252    
253 mmeineke 707 int nCellsX, nCellsY, nCellsZ;
254    
255 tim 763 const double boxTargetX = 66.22752;
256     const double boxTargetY = 60.53088;
257 mmeineke 707
258     nCellsX = (int)ceil(boxTargetX / waterCell);
259     nCellsY = (int)ceil(boxTargetY / waterCell);
260    
261 chuckv 678 int testTot;
262     int done = 0;
263 mmeineke 707 nCellsZ = 0;
264 chuckv 678 while( !done ){
265 chuckv 700
266 mmeineke 707 nCellsZ++;
267     testTot = 4 * nCellsX * nCellsY * nCellsZ;
268 chuckv 700
269 chuckv 678 if( testTot >= targetWaters ) done = 1;
270     }
271    
272     // create the new water box to the new specifications
273    
274 mmeineke 707 int newWaters = nCellsX * nCellsY * nCellsZ * 4;
275 chuckv 678
276     delete[] waterX;
277     delete[] waterY;
278     delete[] waterZ;
279    
280     coord* waterSites = new coord[newWaters];
281    
282 mmeineke 707 double box_x = waterCell * nCellsX;
283     double box_y = waterCell * nCellsY;
284     double box_z = waterCell * nCellsZ;
285 chuckv 700
286 chuckv 678 // create an fcc lattice in the water box.
287    
288     ndx = 0;
289 mmeineke 707 for( i=0; i < nCellsX; i++ ){
290     for( j=0; j < nCellsY; j++ ){
291     for( k=0; k < nCellsZ; k++ ){
292 chuckv 700
293     myFCC.getLatticePoints(&posX, &posY, &posZ, i, j, k);
294     for(l=0; l<4; l++){
295     waterSites[ndx].pos[0] = posX[l];
296     waterSites[ndx].pos[1] = posY[l];
297     waterSites[ndx].pos[2] = posZ[l];
298     ndx++;
299     }
300 chuckv 678 }
301     }
302     }
303    
304     coord* lipidSites = new coord[nLipids];
305    
306     // start a 3D RSA for the for the lipid placements
307    
308    
309     int reject;
310     int testDX, acceptedDX;
311    
312 chuckv 700 nAtoms = nLipids * lipidNatoms;
313    
314     simnfo[1].n_atoms = nAtoms;
315     simnfo[1].atoms=new Atom*[nAtoms];
316    
317     theConfig = simnfo[1].getConfiguration();
318     theConfig->createArrays( simnfo[1].n_atoms );
319    
320     atoms=simnfo[1].atoms;
321    
322 chuckv 678 rCutSqr = lipid_spaceing * lipid_spaceing;
323    
324     for(i=0; i<nLipids; i++ ){
325     done = 0;
326     while( !done ){
327 chuckv 700
328 chuckv 678 lipidSites[i].pos[0] = drand48() * box_x;
329     lipidSites[i].pos[1] = drand48() * box_y;
330     lipidSites[i].pos[2] = drand48() * box_z;
331 chuckv 700
332 chuckv 678 getRandomRot( lipidSites[i].rot );
333 chuckv 700
334 chuckv 678 ndx = i * lipidNatoms;
335    
336     lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
337 chuckv 700 ndx, theConfig );
338    
339 chuckv 678 reject = 0;
340     for( j=0; !reject && j<i; j++){
341     for(k=0; !reject && k<lipidNatoms; k++){
342    
343     acceptedDX = j*lipidNatoms + k;
344     for(l=0; !reject && l<lipidNatoms; l++){
345 chuckv 700
346 chuckv 678 testDX = ndx + l;
347    
348 chuckv 700 atoms[testDX]->getPos( posA );
349     atoms[acceptedDX]->getPos( posB );
350 chuckv 678
351 chuckv 700 dx = posA[0] - posB[0];
352     dy = posA[1] - posB[1];
353     dz = posA[2] - posB[2];
354    
355 chuckv 678 buildMap( dx, dy, dz, box_x, box_y, box_z );
356 chuckv 700
357 chuckv 678 dx2 = dx * dx;
358     dy2 = dy * dy;
359     dz2 = dz * dz;
360 chuckv 700
361 chuckv 678 dSqr = dx2 + dy2 + dz2;
362     if( dSqr < rCutSqr ) reject = 1;
363     }
364     }
365     }
366    
367     if( reject ){
368    
369     for(j=0; j< lipidNatoms; j++) delete atoms[ndx+j];
370     }
371     else{
372     done = 1;
373 chuckv 700 std::cout << (i+1) << " has been accepted\n";
374 chuckv 678 }
375     }
376     }
377    
378 mmeineke 707
379     // zSort of the lipid positions
380    
381    
382     vector< pair<int,double> >zSortArray;
383     for(i=0;i<nLipids;i++)
384     zSortArray.push_back( make_pair(i, lipidSites[i].pos[2]) );
385    
386     sort(zSortArray.begin(),zSortArray.end(),SortCond());
387    
388 mmeineke 724 ofstream outFile( "./zipper.bass", ios::app);
389 mmeineke 707
390     for(i=0; i<nLipids; i++){
391     outFile << "zConstraint[" << i << "]{\n"
392     << " molIndex = " << zSortArray[i].first << ";\n"
393     << " zPos = ";
394    
395     if(i<32) outFile << "60.0;\n";
396     else outFile << "100.0;\n";
397    
398     outFile << " kRatio = 0.5;\n"
399     << "}\n";
400     }
401    
402     outFile.close();
403    
404    
405 chuckv 678 // cut out the waters that overlap with the lipids.
406    
407 chuckv 700
408 chuckv 678 delete[] isActive;
409     isActive = new int[newWaters];
410     for(i=0; i<newWaters; i++) isActive[i] = 1;
411     int n_active = newWaters;
412     rCutSqr = water_padding * water_padding;
413    
414     for(i=0; ( (i<newWaters) && isActive[i] ); i++){
415     for(j=0; ( (j<nAtoms) && isActive[i] ); j++){
416    
417 chuckv 700 atoms[j]->getPos( pos );
418 chuckv 678
419 chuckv 700 dx = waterSites[i].pos[0] - pos[0];
420     dy = waterSites[i].pos[1] - pos[1];
421     dz = waterSites[i].pos[2] - pos[2];
422    
423 chuckv 678 buildMap( dx, dy, dz, box_x, box_y, box_z );
424    
425     dx2 = dx * dx;
426     dy2 = dy * dy;
427     dz2 = dz * dz;
428 chuckv 700
429 chuckv 678 dSqr = dx2 + dy2 + dz2;
430     if( dSqr < rCutSqr ){
431     isActive[i] = 0;
432     n_active--;
433 chuckv 700
434    
435 chuckv 678 }
436     }
437     }
438    
439 chuckv 700
440    
441    
442 chuckv 678 if( n_active < nWaters ){
443 chuckv 700
444 chuckv 678 sprintf( painCave.errMsg,
445     "Too many waters were removed, edit code and try again.\n" );
446 chuckv 700
447 chuckv 678 painCave.isFatal = 1;
448     simError();
449     }
450    
451     int quickKill;
452     while( n_active > nWaters ){
453    
454     quickKill = (int)(drand48()*newWaters);
455    
456     if( isActive[quickKill] ){
457     isActive[quickKill] = 0;
458     n_active--;
459 chuckv 700
460 chuckv 678 }
461     }
462    
463     if( n_active != nWaters ){
464 chuckv 700
465 chuckv 678 sprintf( painCave.errMsg,
466     "QuickKill didn't work right. n_active = %d, and nWaters = %d\n",
467     n_active, nWaters );
468     painCave.isFatal = 1;
469     simError();
470     }
471    
472     // clean up our messes before building the final system.
473    
474 chuckv 700 simnfo[0].getConfiguration()->destroyArrays();
475     simnfo[1].getConfiguration()->destroyArrays();
476 chuckv 678
477     // create the real Atom arrays
478    
479     nAtoms = 0;
480     molIndex = 0;
481     molStart = new int[nLipids + nWaters];
482    
483     for(j=0; j<nLipids; j++){
484     molStart[molIndex] = nAtoms;
485     molIndex++;
486     nAtoms += lipidNatoms;
487     }
488    
489     for(j=0; j<nWaters; j++){
490     molStart[molIndex] = nAtoms;
491     molIndex++;
492     nAtoms += waterNatoms;
493     }
494    
495 chuckv 700 theConfig = simnfo[2].getConfiguration();
496     theConfig->createArrays( nAtoms );
497     simnfo[2].atoms = new Atom*[nAtoms];
498     atoms = simnfo[2].atoms;
499     simnfo[2].n_atoms = nAtoms;
500 chuckv 678
501     // initialize lipid positions
502    
503     molIndex = 0;
504     for(i=0; i<nLipids; i++ ){
505     lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
506 chuckv 700 molStart[molIndex], theConfig );
507 chuckv 678 molIndex++;
508     }
509    
510     // initialize the water positions
511    
512     for(i=0; i<newWaters; i++){
513 chuckv 700
514 chuckv 678 if( isActive[i] ){
515 chuckv 700
516 chuckv 678 getRandomRot( waterSites[i].rot );
517     waterLocate->placeMol( waterSites[i].pos, waterSites[i].rot, atoms,
518 chuckv 700 molStart[molIndex], theConfig );
519 chuckv 678 molIndex++;
520     }
521     }
522    
523     // set up the SimInfo object
524    
525 chuckv 700 double Hmat[3][3];
526    
527     Hmat[0][0] = box_x;
528     Hmat[0][1] = 0.0;
529     Hmat[0][2] = 0.0;
530    
531     Hmat[1][0] = 0.0;
532     Hmat[1][1] = box_y;
533     Hmat[1][2] = 0.0;
534    
535     Hmat[2][0] = 0.0;
536     Hmat[2][1] = 0.0;
537     Hmat[2][2] = box_z;
538    
539    
540 chuckv 678 bsInfo.boxX = box_x;
541     bsInfo.boxY = box_y;
542     bsInfo.boxZ = box_z;
543    
544 chuckv 700 simnfo[2].setBoxM( Hmat );
545 chuckv 678
546 chuckv 700 sprintf( simnfo[2].sampleName, "%s.dump", bsInfo.outPrefix );
547     sprintf( simnfo[2].finalName, "%s.init", bsInfo.outPrefix );
548 chuckv 678
549     // set up the writer and write out
550    
551 chuckv 700 writer = new DumpWriter( &simnfo[2] );
552 chuckv 678 writer->writeFinal( 0.0 );
553    
554     // clean up the memory
555    
556 chuckv 700 // if( molMap != NULL ) delete[] molMap;
557     // if( cardDeck != NULL ) delete[] cardDeck;
558     // if( locate != NULL ){
559     // for(i=0; i<bsInfo.nComponents; i++){
560     // delete locate[i];
561     // }
562     // delete[] locate;
563     // }
564     // if( atoms != NULL ){
565     // for(i=0; i<nAtoms; i++){
566     // delete atoms[i];
567     // }
568     // Atom::destroyArrays();
569     // delete[] atoms;
570     // }
571     // if( molSeq != NULL ) delete[] molSeq;
572     // if( simnfo != NULL ) delete simnfo;
573     // if( writer != NULL ) delete writer;
574 chuckv 678
575     return 1;
576     }
577    
578     void getRandomRot( double rot[3][3] ){
579    
580     double theta, phi, psi;
581     double cosTheta;
582    
583     // select random phi, psi, and cosTheta
584    
585     phi = 2.0 * M_PI * drand48();
586     psi = 2.0 * M_PI * drand48();
587     cosTheta = (2.0 * drand48()) - 1.0; // sample cos -1 to 1
588    
589     theta = acos( cosTheta );
590    
591     rot[0][0] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
592     rot[0][1] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
593     rot[0][2] = sin(theta) * sin(psi);
594    
595     rot[1][0] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
596     rot[1][1] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
597     rot[1][2] = sin(theta) * cos(psi);
598    
599     rot[2][0] = sin(phi) * sin(theta);
600     rot[2][1] = -cos(phi) * sin(theta);
601     rot[2][2] = cos(theta);
602     }
603    
604    
605    
606     void buildMap( double &x, double &y, double &z,
607 chuckv 700 double boxX, double boxY, double boxZ ){
608 chuckv 678
609     if(x < 0) x -= boxX * (double)( (int)( (x / boxX) - 0.5 ) );
610     else x -= boxX * (double)( (int)( (x / boxX ) + 0.5));
611    
612     if(y < 0) y -= boxY * (double)( (int)( (y / boxY) - 0.5 ) );
613     else y -= boxY * (double)( (int)( (y / boxY ) + 0.5));
614    
615     if(z < 0) z -= boxZ * (double)( (int)( (z / boxZ) - 0.5 ) );
616     else z -= boxZ * (double)( (int)( (z / boxZ ) + 0.5));
617     }