ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/bilayerSys.cpp
Revision: 573
Committed: Thu Jul 3 19:41:26 2003 UTC (21 years, 10 months ago) by mmeineke
File size: 17194 byte(s)
Log Message:
 cleaned up the dependecy scripts in the makefiles

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 = 6.0;
52 const double lipid_spaceing = 8.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 targetWaters = (int) ( targetWaters * 1.2 );
228
229 // find the best box size for the sim
230
231 int testTot;
232 int done = 0;
233 ndx = 0;
234 while( !done ){
235
236 ndx++;
237 testTot = 4 * ndx * ndx * ndx;
238
239 if( testTot >= targetWaters ) done = 1;
240 }
241
242 nCells = ndx;
243
244
245 // create the new water box to the new specifications
246
247 int newWaters = nCells * nCells * nCells * 4;
248
249 delete[] waterX;
250 delete[] waterY;
251 delete[] waterZ;
252
253 coord* waterSites = new coord[newWaters];
254
255 double box_x = waterCell * nCells;
256 double box_y = waterCell * nCells;
257 double box_z = waterCell * nCells;
258
259 // create an fcc lattice in the water box.
260
261 ndx = 0;
262 for( i=0; i < nCells; i++ ){
263 for( j=0; j < nCells; j++ ){
264 for( k=0; k < nCells; k++ ){
265
266 waterSites[ndx].pos[0] = i * waterCell;
267 waterSites[ndx].pos[1] = j * waterCell;
268 waterSites[ndx].pos[2] = k * waterCell;
269 ndx++;
270
271 waterSites[ndx].pos[0] = i * waterCell + 0.5 * waterCell;
272 waterSites[ndx].pos[1] = j * waterCell + 0.5 * waterCell;
273 waterSites[ndx].pos[2] = k * waterCell;
274 ndx++;
275
276 waterSites[ndx].pos[0] = i * waterCell;
277 waterSites[ndx].pos[1] = j * waterCell + 0.5 * waterCell;
278 waterSites[ndx].pos[2] = k * waterCell + 0.5 * waterCell;
279 ndx++;
280
281 waterSites[ndx].pos[0] = i * waterCell + 0.5 * waterCell;
282 waterSites[ndx].pos[1] = j * waterCell;
283 waterSites[ndx].pos[2] = k * waterCell + 0.5 * waterCell;
284 ndx++;
285 }
286 }
287 }
288
289
290 // clear up memory from the test box
291
292 for(i=0; i<lipidNatoms; i++ ) delete atoms[i];
293
294 coord* lipidSites = new coord[nLipids];
295
296 // start a 3D RSA for the for the lipid placements
297
298
299 int reject;
300 int testDX, acceptedDX;
301
302 rCutSqr = lipid_spaceing * lipid_spaceing;
303
304 for(i=0; i<nLipids; i++ ){
305 done = 0;
306 while( !done ){
307
308 lipidSites[i].pos[0] = drand48() * box_x;
309 lipidSites[i].pos[1] = drand48() * box_y;
310 lipidSites[i].pos[2] = drand48() * box_z;
311
312 getRandomRot( lipidSites[i].rot );
313
314 ndx = i * lipidNatoms;
315
316 lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
317 ndx );
318
319 reject = 0;
320 for( j=0; !reject && j<i; j++){
321 for(k=0; !reject && k<lipidNatoms; k++){
322
323 acceptedDX = j*lipidNatoms + k;
324 for(l=0; !reject && l<lipidNatoms; l++){
325
326 testDX = ndx + l;
327
328 dx = atoms[testDX]->getX() - atoms[acceptedDX]->getX();
329 dy = atoms[testDX]->getY() - atoms[acceptedDX]->getY();
330 dz = atoms[testDX]->getZ() - atoms[acceptedDX]->getZ();
331
332 map( dx, dy, dz, box_x, box_y, box_z );
333
334 dx2 = dx * dx;
335 dy2 = dy * dy;
336 dz2 = dz * dz;
337
338 dSqr = dx2 + dy2 + dz2;
339 if( dSqr < rCutSqr ) reject = 1;
340 }
341 }
342 }
343
344 if( reject ){
345
346 for(j=0; j< lipidNatoms; j++) delete atoms[ndx+j];
347 }
348 else{
349 done = 1;
350 std::cout << i << " has been accepted\n";
351 }
352 }
353 }
354
355 // cut out the waters that overlap with the lipids.
356
357 delete[] isActive;
358 isActive = new int[newWaters];
359 for(i=0; i<newWaters; i++) isActive[i] = 1;
360 int n_active = newWaters;
361 rCutSqr = water_padding * water_padding;
362
363 for(i=0; ( (i<newWaters) && isActive[i] ); i++){
364 for(j=0; ( (j<nAtoms) && isActive[i] ); j++){
365
366 dx = waterSites[i].pos[0] - atoms[j]->getX();
367 dy = waterSites[i].pos[1] - atoms[j]->getY();
368 dz = waterSites[i].pos[2] - atoms[j]->getZ();
369
370 map( dx, dy, dz, box_x, box_y, box_z );
371
372 dx2 = dx * dx;
373 dy2 = dy * dy;
374 dz2 = dz * dz;
375
376 dSqr = dx2 + dy2 + dz2;
377 if( dSqr < rCutSqr ){
378 isActive[i] = 0;
379 n_active--;
380 }
381 }
382 }
383
384 if( n_active < nWaters ){
385
386 sprintf( painCave.errMsg,
387 "Too many waters were removed, edit code and try again.\n" );
388
389 painCave.isFatal = 1;
390 simError();
391 }
392
393 int quickKill;
394 while( n_active > nWaters ){
395
396 quickKill = (int)(drand48()*newWaters);
397
398 if( isActive[quickKill] ){
399 isActive[quickKill] = 0;
400 n_active--;
401 }
402 }
403
404 if( n_active != nWaters ){
405
406 sprintf( painCave.errMsg,
407 "QuickKill didn't work right. n_active = %d, and nWaters = %d\n",
408 n_active, nWaters );
409 painCave.isFatal = 1;
410 simError();
411 }
412
413 // clean up our messes before building the final system.
414
415 for(i=0; i<nAtoms; i++){
416
417 delete atoms[i];
418 }
419 Atom::destroyArrays();
420
421
422 // create the real Atom arrays
423
424 nAtoms = 0;
425 molIndex = 0;
426 molStart = new int[nLipids + nWaters];
427
428 for(j=0; j<nLipids; j++){
429 molStart[molIndex] = nAtoms;
430 molIndex++;
431 nAtoms += lipidNatoms;
432 }
433
434 for(j=0; j<nWaters; j++){
435 molStart[molIndex] = nAtoms;
436 molIndex++;
437 nAtoms += waterNatoms;
438 }
439
440
441 Atom::createArrays( nAtoms );
442 atoms = new Atom*[nAtoms];
443
444
445 // initialize lipid positions
446
447 molIndex = 0;
448 for(i=0; i<nLipids; i++ ){
449 lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
450 molStart[molIndex] );
451 molIndex++;
452 }
453
454 // initialize the water positions
455
456 for(i=0; i<newWaters; i++){
457
458 if( isActive[i] ){
459
460 getRandomRot( waterSites[i].rot );
461 waterLocate->placeMol( waterSites[i].pos, waterSites[i].rot, atoms,
462 molStart[molIndex] );
463 molIndex++;
464 }
465 }
466
467 // set up the SimInfo object
468
469 bsInfo.boxX = box_x;
470 bsInfo.boxY = box_y;
471 bsInfo.boxZ = box_z;
472
473 double boxVector[3];
474 simnfo = new SimInfo();
475 simnfo->n_atoms = nAtoms;
476 boxVector[0] = bsInfo.boxX;
477 boxVector[1] = bsInfo.boxY;
478 boxVector[2] = bsInfo.boxZ;
479 simnfo->setBox( boxVector );
480
481 sprintf( simnfo->sampleName, "%s.dump", bsInfo.outPrefix );
482 sprintf( simnfo->finalName, "%s.init", bsInfo.outPrefix );
483
484 simnfo->atoms = atoms;
485
486 // set up the writer and write out
487
488 writer = new DumpWriter( simnfo );
489 writer->writeFinal( 0.0 );
490
491 // clean up the memory
492
493 // if( molMap != NULL ) delete[] molMap;
494 // if( cardDeck != NULL ) delete[] cardDeck;
495 // if( locate != NULL ){
496 // for(i=0; i<bsInfo.nComponents; i++){
497 // delete locate[i];
498 // }
499 // delete[] locate;
500 // }
501 // if( atoms != NULL ){
502 // for(i=0; i<nAtoms; i++){
503 // delete atoms[i];
504 // }
505 // Atom::destroyArrays();
506 // delete[] atoms;
507 // }
508 // if( molSeq != NULL ) delete[] molSeq;
509 // if( simnfo != NULL ) delete simnfo;
510 // if( writer != NULL ) delete writer;
511
512 return 1;
513 }
514
515
516
517 int Old_buildRandomBilayer( void ){
518
519 int i,j,k;
520 int nAtoms, atomIndex, molIndex, molID;
521 int* molSeq;
522 int* molMap;
523 int* molStart;
524 int* cardDeck;
525 int deckSize;
526 int rSite, rCard;
527 double cell;
528 int nCells, nSites, siteIndex;
529 double rot[3][3];
530 double pos[3];
531
532 Atom** atoms;
533 SimInfo* simnfo;
534 DumpWriter* writer;
535 MoLocator** locate;
536
537 // initialize functions and variables
538
539 srand48( RAND_SEED );
540 molSeq = NULL;
541 molStart = NULL;
542 molMap = NULL;
543 cardDeck = NULL;
544 atoms = NULL;
545 locate = NULL;
546 simnfo = NULL;
547 writer = NULL;
548
549 // calculate the number of cells in the fcc box
550
551 nCells = 0;
552 nSites = 0;
553 while( nSites < bsInfo.totNmol ){
554 nCells++;
555 nSites = 4.0 * pow( (double)nCells, 3.0 );
556 }
557
558
559 // create the molMap and cardDeck arrays
560
561 molMap = new int[nSites];
562 cardDeck = new int[nSites];
563
564 for(i=0; i<nSites; i++){
565 molMap[i] = -1;
566 cardDeck[i] = i;
567 }
568
569 // randomly place the molecules on the sites
570
571 deckSize = nSites;
572 for(i=0; i<bsInfo.totNmol; i++){
573 rCard = (int)( deckSize * drand48() );
574 rSite = cardDeck[rCard];
575 molMap[rSite] = i;
576
577 // book keep the card deck;
578
579 deckSize--;
580 cardDeck[rCard] = cardDeck[deckSize];
581 }
582
583
584 // create the MoLocator and Atom arrays
585
586 nAtoms = 0;
587 molIndex = 0;
588 locate = new MoLocator*[bsInfo.nComponents];
589 molSeq = new int[bsInfo.totNmol];
590 molStart = new int[bsInfo.totNmol];
591 for(i=0; i<bsInfo.nComponents; i++){
592 locate[i] = new MoLocator( bsInfo.compStamps[i] );
593 for(j=0; j<bsInfo.componentsNmol[i]; j++){
594 molSeq[molIndex] = i;
595 molStart[molIndex] = nAtoms;
596 molIndex++;
597 nAtoms += bsInfo.compStamps[i]->getNAtoms();
598 }
599 }
600
601 Atom::createArrays( nAtoms );
602 atoms = new Atom*[nAtoms];
603
604
605 // place the molecules at each FCC site
606
607 cell = 5.0;
608 for(i=0; i<bsInfo.nComponents; i++){
609 if(cell < locate[i]->getMaxLength() ) cell = locate[i]->getMaxLength();
610 }
611 cell *= 1.2; // add a little buffer
612
613 cell *= M_SQRT2;
614
615 siteIndex = 0;
616 for(i=0; i<nCells; i++){
617 for(j=0; j<nCells; j++){
618 for(k=0; k<nCells; k++){
619
620 if( molMap[siteIndex] >= 0 ){
621 pos[0] = i * cell;
622 pos[1] = j * cell;
623 pos[2] = k * cell;
624
625 getRandomRot( rot );
626 molID = molSeq[molMap[siteIndex]];
627 atomIndex = molStart[ molMap[siteIndex] ];
628 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
629 }
630 siteIndex++;
631
632 if( molMap[siteIndex] >= 0 ){
633 pos[0] = i * cell + (0.5 * cell);
634 pos[1] = j * cell;
635 pos[2] = k * cell + (0.5 * cell);
636
637 getRandomRot( rot );
638 molID = molSeq[molMap[siteIndex]];
639 atomIndex = molStart[ molMap[siteIndex] ];
640 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
641 }
642 siteIndex++;
643
644 if( molMap[siteIndex] >= 0 ){
645 pos[0] = i * cell + (0.5 * cell);
646 pos[1] = j * cell + (0.5 * cell);
647 pos[2] = k * cell;
648
649 getRandomRot( rot );
650 molID = molSeq[molMap[siteIndex]];
651 atomIndex = molStart[ molMap[siteIndex] ];
652 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
653 }
654 siteIndex++;
655
656 if( molMap[siteIndex] >= 0 ){
657 pos[0] = i * cell;
658 pos[1] = j * cell + (0.5 * cell);
659 pos[2] = k * cell + (0.5 * cell);
660
661 getRandomRot( rot );
662 molID = molSeq[molMap[siteIndex]];
663 atomIndex = molStart[ molMap[siteIndex] ];
664 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
665 }
666 siteIndex++;
667 }
668 }
669 }
670
671 // set up the SimInfo object
672
673 bsInfo.boxX = nCells * cell;
674 bsInfo.boxY = nCells * cell;
675 bsInfo.boxZ = nCells * cell;
676
677 double boxVector[3];
678 simnfo = new SimInfo();
679 simnfo->n_atoms = nAtoms;
680 boxVector[0] = bsInfo.boxX;
681 boxVector[1] = bsInfo.boxY;
682 boxVector[2] = bsInfo.boxZ;
683 simnfo->setBox( boxVector );
684
685 sprintf( simnfo->sampleName, "%s.dump", bsInfo.outPrefix );
686 sprintf( simnfo->finalName, "%s.init", bsInfo.outPrefix );
687
688 simnfo->atoms = atoms;
689
690 // set up the writer and write out
691
692 writer = new DumpWriter( simnfo );
693 writer->writeFinal(0.0);
694
695 // clean up the memory
696
697 if( molMap != NULL ) delete[] molMap;
698 if( cardDeck != NULL ) delete[] cardDeck;
699 if( locate != NULL ){
700 for(i=0; i<bsInfo.nComponents; i++){
701 delete locate[i];
702 }
703 delete[] locate;
704 }
705 if( atoms != NULL ){
706 for(i=0; i<nAtoms; i++){
707 delete atoms[i];
708 }
709 Atom::destroyArrays();
710 delete[] atoms;
711 }
712 if( molSeq != NULL ) delete[] molSeq;
713 if( simnfo != NULL ) delete simnfo;
714 if( writer != NULL ) delete writer;
715
716 return 1;
717 }
718
719
720 void getRandomRot( double rot[3][3] ){
721
722 double theta, phi, psi;
723 double cosTheta;
724
725 // select random phi, psi, and cosTheta
726
727 phi = 2.0 * M_PI * drand48();
728 psi = 2.0 * M_PI * drand48();
729 cosTheta = (2.0 * drand48()) - 1.0; // sample cos -1 to 1
730
731 theta = acos( cosTheta );
732
733 rot[0][0] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
734 rot[0][1] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
735 rot[0][2] = sin(theta) * sin(psi);
736
737 rot[1][0] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
738 rot[1][1] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
739 rot[1][2] = sin(theta) * cos(psi);
740
741 rot[2][0] = sin(phi) * sin(theta);
742 rot[2][1] = -cos(phi) * sin(theta);
743 rot[2][2] = cos(theta);
744 }
745
746
747
748 void map( double &x, double &y, double &z,
749 double boxX, double boxY, double boxZ ){
750
751 if(x < 0) x -= boxX * (double)( (int)( (x / boxX) - 0.5 ) );
752 else x -= boxX * (double)( (int)( (x / boxX ) + 0.5));
753
754 if(y < 0) y -= boxY * (double)( (int)( (y / boxY) - 0.5 ) );
755 else y -= boxY * (double)( (int)( (y / boxY ) + 0.5));
756
757 if(z < 0) z -= boxZ * (double)( (int)( (z / boxZ) - 0.5 ) );
758 else z -= boxZ * (double)( (int)( (z / boxZ ) + 0.5));
759 }