ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/bilayerSys.cpp
Revision: 537
Committed: Fri May 16 21:37:56 2003 UTC (21 years, 11 months ago) by mmeineke
File size: 16641 byte(s)
Log Message:
still working on the bilayer code

File Contents

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