ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/sysbuilder/bilayerSys.cpp
Revision: 678
Committed: Mon Aug 11 22:12:31 2003 UTC (21 years, 8 months ago) by chuckv
File size: 17305 byte(s)
Log Message:
Arranged sysbuilder into a subdirectory. Fixed some of sysbuilder to work with new
atom allocation in libmdtools.

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