ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/bilayerSys.cpp
Revision: 543
Committed: Fri May 30 21:32:33 2003 UTC (21 years, 11 months ago) by mmeineke
File size: 17088 byte(s)
Log Message:
currently modifiying Symplectic to become the basic integrator.

bilayerSys.cpp altered for building tb3.

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 simnfo = new SimInfo();
474 simnfo->n_atoms = nAtoms;
475 simnfo->box_x = bsInfo.boxX;
476 simnfo->box_y = bsInfo.boxY;
477 simnfo->box_z = bsInfo.boxZ;
478
479 sprintf( simnfo->sampleName, "%s.dump", bsInfo.outPrefix );
480 sprintf( simnfo->finalName, "%s.init", bsInfo.outPrefix );
481
482 simnfo->atoms = atoms;
483
484 // set up the writer and write out
485
486 writer = new DumpWriter( simnfo );
487 writer->writeFinal();
488
489 // clean up the memory
490
491 // if( molMap != NULL ) delete[] molMap;
492 // if( cardDeck != NULL ) delete[] cardDeck;
493 // if( locate != NULL ){
494 // for(i=0; i<bsInfo.nComponents; i++){
495 // delete locate[i];
496 // }
497 // delete[] locate;
498 // }
499 // if( atoms != NULL ){
500 // for(i=0; i<nAtoms; i++){
501 // delete atoms[i];
502 // }
503 // Atom::destroyArrays();
504 // delete[] atoms;
505 // }
506 // if( molSeq != NULL ) delete[] molSeq;
507 // if( simnfo != NULL ) delete simnfo;
508 // if( writer != NULL ) delete writer;
509
510 return 1;
511 }
512
513
514
515 int Old_buildRandomBilayer( void ){
516
517 int i,j,k;
518 int nAtoms, atomIndex, molIndex, molID;
519 int* molSeq;
520 int* molMap;
521 int* molStart;
522 int* cardDeck;
523 int deckSize;
524 int rSite, rCard;
525 double cell;
526 int nCells, nSites, siteIndex;
527 double rot[3][3];
528 double pos[3];
529
530 Atom** atoms;
531 SimInfo* simnfo;
532 DumpWriter* writer;
533 MoLocator** locate;
534
535 // initialize functions and variables
536
537 srand48( RAND_SEED );
538 molSeq = NULL;
539 molStart = NULL;
540 molMap = NULL;
541 cardDeck = NULL;
542 atoms = NULL;
543 locate = NULL;
544 simnfo = NULL;
545 writer = NULL;
546
547 // calculate the number of cells in the fcc box
548
549 nCells = 0;
550 nSites = 0;
551 while( nSites < bsInfo.totNmol ){
552 nCells++;
553 nSites = 4.0 * pow( (double)nCells, 3.0 );
554 }
555
556
557 // create the molMap and cardDeck arrays
558
559 molMap = new int[nSites];
560 cardDeck = new int[nSites];
561
562 for(i=0; i<nSites; i++){
563 molMap[i] = -1;
564 cardDeck[i] = i;
565 }
566
567 // randomly place the molecules on the sites
568
569 deckSize = nSites;
570 for(i=0; i<bsInfo.totNmol; i++){
571 rCard = (int)( deckSize * drand48() );
572 rSite = cardDeck[rCard];
573 molMap[rSite] = i;
574
575 // book keep the card deck;
576
577 deckSize--;
578 cardDeck[rCard] = cardDeck[deckSize];
579 }
580
581
582 // create the MoLocator and Atom arrays
583
584 nAtoms = 0;
585 molIndex = 0;
586 locate = new MoLocator*[bsInfo.nComponents];
587 molSeq = new int[bsInfo.totNmol];
588 molStart = new int[bsInfo.totNmol];
589 for(i=0; i<bsInfo.nComponents; i++){
590 locate[i] = new MoLocator( bsInfo.compStamps[i] );
591 for(j=0; j<bsInfo.componentsNmol[i]; j++){
592 molSeq[molIndex] = i;
593 molStart[molIndex] = nAtoms;
594 molIndex++;
595 nAtoms += bsInfo.compStamps[i]->getNAtoms();
596 }
597 }
598
599 Atom::createArrays( nAtoms );
600 atoms = new Atom*[nAtoms];
601
602
603 // place the molecules at each FCC site
604
605 cell = 5.0;
606 for(i=0; i<bsInfo.nComponents; i++){
607 if(cell < locate[i]->getMaxLength() ) cell = locate[i]->getMaxLength();
608 }
609 cell *= 1.2; // add a little buffer
610
611 cell *= M_SQRT2;
612
613 siteIndex = 0;
614 for(i=0; i<nCells; i++){
615 for(j=0; j<nCells; j++){
616 for(k=0; k<nCells; k++){
617
618 if( molMap[siteIndex] >= 0 ){
619 pos[0] = i * cell;
620 pos[1] = j * cell;
621 pos[2] = k * cell;
622
623 getRandomRot( rot );
624 molID = molSeq[molMap[siteIndex]];
625 atomIndex = molStart[ molMap[siteIndex] ];
626 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
627 }
628 siteIndex++;
629
630 if( molMap[siteIndex] >= 0 ){
631 pos[0] = i * cell + (0.5 * cell);
632 pos[1] = j * cell;
633 pos[2] = k * cell + (0.5 * cell);
634
635 getRandomRot( rot );
636 molID = molSeq[molMap[siteIndex]];
637 atomIndex = molStart[ molMap[siteIndex] ];
638 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
639 }
640 siteIndex++;
641
642 if( molMap[siteIndex] >= 0 ){
643 pos[0] = i * cell + (0.5 * cell);
644 pos[1] = j * cell + (0.5 * cell);
645 pos[2] = k * cell;
646
647 getRandomRot( rot );
648 molID = molSeq[molMap[siteIndex]];
649 atomIndex = molStart[ molMap[siteIndex] ];
650 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
651 }
652 siteIndex++;
653
654 if( molMap[siteIndex] >= 0 ){
655 pos[0] = i * cell;
656 pos[1] = j * cell + (0.5 * cell);
657 pos[2] = k * cell + (0.5 * cell);
658
659 getRandomRot( rot );
660 molID = molSeq[molMap[siteIndex]];
661 atomIndex = molStart[ molMap[siteIndex] ];
662 locate[molID]->placeMol( pos, rot, atoms, atomIndex );
663 }
664 siteIndex++;
665 }
666 }
667 }
668
669 // set up the SimInfo object
670
671 bsInfo.boxX = nCells * cell;
672 bsInfo.boxY = nCells * cell;
673 bsInfo.boxZ = nCells * cell;
674
675 simnfo = new SimInfo();
676 simnfo->n_atoms = nAtoms;
677 simnfo->box_x = bsInfo.boxX;
678 simnfo->box_y = bsInfo.boxY;
679 simnfo->box_z = bsInfo.boxZ;
680
681 sprintf( simnfo->sampleName, "%s.dump", bsInfo.outPrefix );
682 sprintf( simnfo->finalName, "%s.init", bsInfo.outPrefix );
683
684 simnfo->atoms = atoms;
685
686 // set up the writer and write out
687
688 writer = new DumpWriter( simnfo );
689 writer->writeFinal();
690
691 // clean up the memory
692
693 if( molMap != NULL ) delete[] molMap;
694 if( cardDeck != NULL ) delete[] cardDeck;
695 if( locate != NULL ){
696 for(i=0; i<bsInfo.nComponents; i++){
697 delete locate[i];
698 }
699 delete[] locate;
700 }
701 if( atoms != NULL ){
702 for(i=0; i<nAtoms; i++){
703 delete atoms[i];
704 }
705 Atom::destroyArrays();
706 delete[] atoms;
707 }
708 if( molSeq != NULL ) delete[] molSeq;
709 if( simnfo != NULL ) delete simnfo;
710 if( writer != NULL ) delete writer;
711
712 return 1;
713 }
714
715
716 void getRandomRot( double rot[3][3] ){
717
718 double theta, phi, psi;
719 double cosTheta;
720
721 // select random phi, psi, and cosTheta
722
723 phi = 2.0 * M_PI * drand48();
724 psi = 2.0 * M_PI * drand48();
725 cosTheta = (2.0 * drand48()) - 1.0; // sample cos -1 to 1
726
727 theta = acos( cosTheta );
728
729 rot[0][0] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
730 rot[0][1] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
731 rot[0][2] = sin(theta) * sin(psi);
732
733 rot[1][0] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
734 rot[1][1] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
735 rot[1][2] = sin(theta) * cos(psi);
736
737 rot[2][0] = sin(phi) * sin(theta);
738 rot[2][1] = -cos(phi) * sin(theta);
739 rot[2][2] = cos(theta);
740 }
741
742
743
744 void map( double &x, double &y, double &z,
745 double boxX, double boxY, double boxZ ){
746
747 if(x < 0) x -= boxX * (double)( (int)( (x / boxX) - 0.5 ) );
748 else x -= boxX * (double)( (int)( (x / boxX ) + 0.5));
749
750 if(y < 0) y -= boxY * (double)( (int)( (y / boxY) - 0.5 ) );
751 else y -= boxY * (double)( (int)( (y / boxY ) + 0.5));
752
753 if(z < 0) z -= boxZ * (double)( (int)( (z / boxZ) - 0.5 ) );
754 else z -= boxZ * (double)( (int)( (z / boxZ ) + 0.5));
755 }