ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/bilayerSys.cpp
Revision: 538
Committed: Sat May 17 16:57:08 2003 UTC (21 years, 11 months ago) by mmeineke
File size: 17040 byte(s)
Log Message:
all seems to be working

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