ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysbuilder/bilayerSys.cpp
Revision: 724
Committed: Tue Aug 26 20:13:17 2003 UTC (21 years ago) by mmeineke
File size: 13513 byte(s)
Log Message:
added define statemewnt to Statwriter and Dumpwriter to handle files larger than 2 gb.

commented out some print statements in Zconstraint

hard coding some system init into bilayer.sys

File Contents

# Content
1
2 #include <iostream>
3 #include <vector>
4 #include <algorithm>
5
6 #include <cstdlib>
7 #include <cstring>
8 #include <cmath>
9
10
11 #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 #include "latticeBuilder.hpp"
20
21 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 void buildMap( double &x, double &y, double &z,
33 double boxX, double boxY, double boxZ );
34
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
63 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 Lattice myFCC( FCC_LATTICE_TYPE, waterCell );
68 double *posX, *posY, *posZ;
69 double pos[3], posA[3], posB[3];
70
71 const double water_padding = 6.0;
72 const double lipid_spaceing = 8.0;
73
74
75 int i,j,k, l, m;
76 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 SimState* theConfig;
91 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
116 foundLipid = 1;
117 lipidStamp = bsInfo.compStamps[i];
118 nLipids = bsInfo.componentsNmol[i];
119 }
120 if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.waterName ) ){
121
122 foundWater = 1;
123
124 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 sprintf(painCave.errMsg,
137 "Could not find solvent \"%s\" in the bass file.\n",
138 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 nAtoms = lipidNatoms;
153
154 simnfo[0].n_atoms = nAtoms;
155 simnfo[0].atoms=new Atom*[nAtoms];
156
157 theConfig = simnfo[0].getConfiguration();
158 theConfig->createArrays( simnfo[0].n_atoms );
159
160 atoms=simnfo[0].atoms;
161
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
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 }
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 lipidLocate->placeMol( testSite.pos, testSite.rot, atoms, 0, theConfig );
215
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
227 atoms[j]->getPos( pos );
228
229 dx = waterX[i] - pos[0];
230 dy = waterY[i] - pos[1];
231 dz = waterZ[i] - pos[2];
232
233 buildMap( dx, dy, dz, testBox, testBox, testBox );
234
235 dx2 = dx * dx;
236 dy2 = dy * dy;
237 dz2 = dz * dz;
238
239 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 int nCellsX, nCellsY, nCellsZ;
254
255 const double boxTargetX = 20;
256 const double boxTargetY = 20;
257
258 nCellsX = (int)ceil(boxTargetX / waterCell);
259 nCellsY = (int)ceil(boxTargetY / waterCell);
260
261 int testTot;
262 int done = 0;
263 nCellsZ = 0;
264 while( !done ){
265
266 nCellsZ++;
267 testTot = 4 * nCellsX * nCellsY * nCellsZ;
268
269 if( testTot >= targetWaters ) done = 1;
270 }
271
272 // create the new water box to the new specifications
273
274 int newWaters = nCellsX * nCellsY * nCellsZ * 4;
275
276 delete[] waterX;
277 delete[] waterY;
278 delete[] waterZ;
279
280 coord* waterSites = new coord[newWaters];
281
282 double box_x = waterCell * nCellsX;
283 double box_y = waterCell * nCellsY;
284 double box_z = waterCell * nCellsZ;
285
286
287
288 // create an fcc lattice in the water box.
289
290 ndx = 0;
291 for( i=0; i < nCellsX; i++ ){
292 for( j=0; j < nCellsY; j++ ){
293 for( k=0; k < nCellsZ; k++ ){
294
295 myFCC.getLatticePoints(&posX, &posY, &posZ, i, j, k);
296 for(l=0; l<4; l++){
297 waterSites[ndx].pos[0] = posX[l];
298 waterSites[ndx].pos[1] = posY[l];
299 waterSites[ndx].pos[2] = posZ[l];
300 ndx++;
301 }
302 }
303 }
304 }
305
306 coord* lipidSites = new coord[nLipids];
307
308 // start a 3D RSA for the for the lipid placements
309
310
311 int reject;
312 int testDX, acceptedDX;
313
314 nAtoms = nLipids * lipidNatoms;
315
316 simnfo[1].n_atoms = nAtoms;
317 simnfo[1].atoms=new Atom*[nAtoms];
318
319 theConfig = simnfo[1].getConfiguration();
320 theConfig->createArrays( simnfo[1].n_atoms );
321
322 atoms=simnfo[1].atoms;
323
324 rCutSqr = lipid_spaceing * lipid_spaceing;
325
326 for(i=0; i<nLipids; i++ ){
327 done = 0;
328 while( !done ){
329
330 lipidSites[i].pos[0] = drand48() * box_x;
331 lipidSites[i].pos[1] = drand48() * box_y;
332 lipidSites[i].pos[2] = drand48() * box_z;
333
334 getRandomRot( lipidSites[i].rot );
335
336 ndx = i * lipidNatoms;
337
338 lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
339 ndx, theConfig );
340
341 reject = 0;
342 for( j=0; !reject && j<i; j++){
343 for(k=0; !reject && k<lipidNatoms; k++){
344
345 acceptedDX = j*lipidNatoms + k;
346 for(l=0; !reject && l<lipidNatoms; l++){
347
348 testDX = ndx + l;
349
350 atoms[testDX]->getPos( posA );
351 atoms[acceptedDX]->getPos( posB );
352
353 dx = posA[0] - posB[0];
354 dy = posA[1] - posB[1];
355 dz = posA[2] - posB[2];
356
357 buildMap( dx, dy, dz, box_x, box_y, box_z );
358
359 dx2 = dx * dx;
360 dy2 = dy * dy;
361 dz2 = dz * dz;
362
363 dSqr = dx2 + dy2 + dz2;
364 if( dSqr < rCutSqr ) reject = 1;
365 }
366 }
367 }
368
369 if( reject ){
370
371 for(j=0; j< lipidNatoms; j++) delete atoms[ndx+j];
372 }
373 else{
374 done = 1;
375 std::cout << (i+1) << " has been accepted\n";
376 }
377 }
378 }
379
380
381 // zSort of the lipid positions
382
383
384 vector< pair<int,double> >zSortArray;
385 for(i=0;i<nLipids;i++)
386 zSortArray.push_back( make_pair(i, lipidSites[i].pos[2]) );
387
388 sort(zSortArray.begin(),zSortArray.end(),SortCond());
389
390 ofstream outFile( "./zipper.bass", ios::app);
391
392 for(i=0; i<nLipids; i++){
393 outFile << "zConstraint[" << i << "]{\n"
394 << " molIndex = " << zSortArray[i].first << ";\n"
395 << " zPos = ";
396
397 if(i<32) outFile << "60.0;\n";
398 else outFile << "100.0;\n";
399
400 outFile << " kRatio = 0.5;\n"
401 << "}\n";
402 }
403
404 outFile.close();
405
406
407 // cut out the waters that overlap with the lipids.
408
409
410 delete[] isActive;
411 isActive = new int[newWaters];
412 for(i=0; i<newWaters; i++) isActive[i] = 1;
413 int n_active = newWaters;
414 rCutSqr = water_padding * water_padding;
415
416 for(i=0; ( (i<newWaters) && isActive[i] ); i++){
417 for(j=0; ( (j<nAtoms) && isActive[i] ); j++){
418
419 atoms[j]->getPos( pos );
420
421 dx = waterSites[i].pos[0] - pos[0];
422 dy = waterSites[i].pos[1] - pos[1];
423 dz = waterSites[i].pos[2] - pos[2];
424
425 buildMap( dx, dy, dz, box_x, box_y, box_z );
426
427 dx2 = dx * dx;
428 dy2 = dy * dy;
429 dz2 = dz * dz;
430
431 dSqr = dx2 + dy2 + dz2;
432 if( dSqr < rCutSqr ){
433 isActive[i] = 0;
434 n_active--;
435
436
437 }
438 }
439 }
440
441
442
443
444 if( n_active < nWaters ){
445
446 sprintf( painCave.errMsg,
447 "Too many waters were removed, edit code and try again.\n" );
448
449 painCave.isFatal = 1;
450 simError();
451 }
452
453 int quickKill;
454 while( n_active > nWaters ){
455
456 quickKill = (int)(drand48()*newWaters);
457
458 if( isActive[quickKill] ){
459 isActive[quickKill] = 0;
460 n_active--;
461
462 }
463 }
464
465 if( n_active != nWaters ){
466
467 sprintf( painCave.errMsg,
468 "QuickKill didn't work right. n_active = %d, and nWaters = %d\n",
469 n_active, nWaters );
470 painCave.isFatal = 1;
471 simError();
472 }
473
474 // clean up our messes before building the final system.
475
476 simnfo[0].getConfiguration()->destroyArrays();
477 simnfo[1].getConfiguration()->destroyArrays();
478
479 // create the real Atom arrays
480
481 nAtoms = 0;
482 molIndex = 0;
483 molStart = new int[nLipids + nWaters];
484
485 for(j=0; j<nLipids; j++){
486 molStart[molIndex] = nAtoms;
487 molIndex++;
488 nAtoms += lipidNatoms;
489 }
490
491 for(j=0; j<nWaters; j++){
492 molStart[molIndex] = nAtoms;
493 molIndex++;
494 nAtoms += waterNatoms;
495 }
496
497 theConfig = simnfo[2].getConfiguration();
498 theConfig->createArrays( nAtoms );
499 simnfo[2].atoms = new Atom*[nAtoms];
500 atoms = simnfo[2].atoms;
501 simnfo[2].n_atoms = nAtoms;
502
503 // initialize lipid positions
504
505 molIndex = 0;
506 for(i=0; i<nLipids; i++ ){
507 lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
508 molStart[molIndex], theConfig );
509 molIndex++;
510 }
511
512 // initialize the water positions
513
514 for(i=0; i<newWaters; i++){
515
516 if( isActive[i] ){
517
518 getRandomRot( waterSites[i].rot );
519 waterLocate->placeMol( waterSites[i].pos, waterSites[i].rot, atoms,
520 molStart[molIndex], theConfig );
521 molIndex++;
522 }
523 }
524
525 // set up the SimInfo object
526
527 double Hmat[3][3];
528
529 Hmat[0][0] = box_x;
530 Hmat[0][1] = 0.0;
531 Hmat[0][2] = 0.0;
532
533 Hmat[1][0] = 0.0;
534 Hmat[1][1] = box_y;
535 Hmat[1][2] = 0.0;
536
537 Hmat[2][0] = 0.0;
538 Hmat[2][1] = 0.0;
539 Hmat[2][2] = box_z;
540
541
542 bsInfo.boxX = box_x;
543 bsInfo.boxY = box_y;
544 bsInfo.boxZ = box_z;
545
546 simnfo[2].setBoxM( Hmat );
547
548 sprintf( simnfo[2].sampleName, "%s.dump", bsInfo.outPrefix );
549 sprintf( simnfo[2].finalName, "%s.init", bsInfo.outPrefix );
550
551 // set up the writer and write out
552
553 writer = new DumpWriter( &simnfo[2] );
554 writer->writeFinal( 0.0 );
555
556 // clean up the memory
557
558 // if( molMap != NULL ) delete[] molMap;
559 // if( cardDeck != NULL ) delete[] cardDeck;
560 // if( locate != NULL ){
561 // for(i=0; i<bsInfo.nComponents; i++){
562 // delete locate[i];
563 // }
564 // delete[] locate;
565 // }
566 // if( atoms != NULL ){
567 // for(i=0; i<nAtoms; i++){
568 // delete atoms[i];
569 // }
570 // Atom::destroyArrays();
571 // delete[] atoms;
572 // }
573 // if( molSeq != NULL ) delete[] molSeq;
574 // if( simnfo != NULL ) delete simnfo;
575 // if( writer != NULL ) delete writer;
576
577 return 1;
578 }
579
580 void getRandomRot( double rot[3][3] ){
581
582 double theta, phi, psi;
583 double cosTheta;
584
585 // select random phi, psi, and cosTheta
586
587 phi = 2.0 * M_PI * drand48();
588 psi = 2.0 * M_PI * drand48();
589 cosTheta = (2.0 * drand48()) - 1.0; // sample cos -1 to 1
590
591 theta = acos( cosTheta );
592
593 rot[0][0] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
594 rot[0][1] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
595 rot[0][2] = sin(theta) * sin(psi);
596
597 rot[1][0] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
598 rot[1][1] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
599 rot[1][2] = sin(theta) * cos(psi);
600
601 rot[2][0] = sin(phi) * sin(theta);
602 rot[2][1] = -cos(phi) * sin(theta);
603 rot[2][2] = cos(theta);
604 }
605
606
607
608 void buildMap( double &x, double &y, double &z,
609 double boxX, double boxY, double boxZ ){
610
611 if(x < 0) x -= boxX * (double)( (int)( (x / boxX) - 0.5 ) );
612 else x -= boxX * (double)( (int)( (x / boxX ) + 0.5));
613
614 if(y < 0) y -= boxY * (double)( (int)( (y / boxY) - 0.5 ) );
615 else y -= boxY * (double)( (int)( (y / boxY ) + 0.5));
616
617 if(z < 0) z -= boxZ * (double)( (int)( (z / boxZ) - 0.5 ) );
618 else z -= boxZ * (double)( (int)( (z / boxZ ) + 0.5));
619 }