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, 3 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

# User Rev Content
1 mmeineke 504 #include <iostream>
2    
3 mmeineke 498 #include <cstdlib>
4     #include <cstring>
5     #include <cmath>
6    
7     #include "simError.h"
8     #include "SimInfo.hpp"
9     #include "ReadWrite.hpp"
10    
11 mmeineke 501 #include "MoLocator.hpp"
12 mmeineke 498 #include "sysBuild.hpp"
13     #include "bilayerSys.hpp"
14    
15    
16 mmeineke 536
17     void map( double &x, double &y, double &z,
18     double boxX, double boxY, double boxZ );
19    
20 mmeineke 501 int buildRandomBilayer( void );
21 mmeineke 498
22 mmeineke 501 void getRandomRot( double rot[3][3] );
23 mmeineke 498
24 mmeineke 501 int buildBilayer( int isRandom ){
25 mmeineke 498
26 mmeineke 501 if( isRandom ){
27     return buildRandomBilayer();
28 mmeineke 498 }
29     else{
30     sprintf( painCave.errMsg,
31     "Cannot currently create a non-random bilayer.\n" );
32     painCave.isFatal = 1;
33     simError();
34 mmeineke 501 return 0;
35 mmeineke 498 }
36     }
37    
38    
39 mmeineke 501 int buildRandomBilayer( void ){
40 mmeineke 498
41 mmeineke 536 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 mmeineke 538 const double waterVol = 4.0 / waterRho; // volume occupied by 4 waters
49 mmeineke 536 const double waterCell = 4.929; // fcc unit cell length
50    
51 mmeineke 543 const double water_padding = 6.0;
52     const double lipid_spaceing = 8.0;
53 mmeineke 536
54    
55 mmeineke 538 int i,j,k, l;
56 mmeineke 502 int nAtoms, atomIndex, molIndex, molID;
57 mmeineke 501 int* molSeq;
58     int* molMap;
59 mmeineke 504 int* molStart;
60 mmeineke 501 int* cardDeck;
61     int deckSize;
62     int rSite, rCard;
63     double cell;
64     int nCells, nSites, siteIndex;
65 mmeineke 536
66     coord testSite;
67    
68 mmeineke 538 Atom** atoms;
69     SimInfo* simnfo;
70     DumpWriter* writer;
71    
72 mmeineke 536 MoleculeStamp* lipidStamp;
73     MoleculeStamp* waterStamp;
74     MoLocator *lipidLocate;
75 mmeineke 538 MoLocator *waterLocate;
76 mmeineke 536 int foundLipid, foundWater;
77 mmeineke 538 int nLipids, lipidNatoms, nWaters, waterNatoms;
78 mmeineke 536 double testBox, maxLength;
79    
80     srand48( RAND_SEED );
81    
82    
83     // set the the lipidStamp
84    
85     foundLipid = 0;
86 mmeineke 538 foundWater = 0;
87 mmeineke 536 for(i=0; i<bsInfo.nComponents; i++){
88     if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.lipidName ) ){
89    
90 mmeineke 538 foundLipid = 1;
91 mmeineke 536 lipidStamp = bsInfo.compStamps[i];
92     nLipids = bsInfo.componentsNmol[i];
93     }
94     if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.waterName ) ){
95    
96     foundWater = 1;
97 mmeineke 538
98 mmeineke 536 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 mmeineke 537 "Could not find solvent \"%s\" in the bass file.\n",
112 mmeineke 536 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 mmeineke 538 waterNatoms = waterStamp->getNAtoms();
125 mmeineke 536
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 mmeineke 538 nCells = (int)( testBox / waterCell + 1.0 );
135 mmeineke 536 int testWaters = 4 * nCells * nCells * nCells;
136    
137     double* waterX = new double[testWaters];
138 mmeineke 538 double* waterY = new double[testWaters];
139     double* waterZ = new double[testWaters];
140 mmeineke 536
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 mmeineke 543 targetWaters = (int) ( targetWaters * 1.2 );
228    
229 mmeineke 536 // 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 mmeineke 537 coord* waterSites = new coord[newWaters];
254 mmeineke 536
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 mmeineke 537 waterSites[ndx].pos[0] = i * waterCell;
267     waterSites[ndx].pos[1] = j * waterCell;
268     waterSites[ndx].pos[2] = k * waterCell;
269 mmeineke 536 ndx++;
270    
271 mmeineke 537 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 mmeineke 536 ndx++;
275    
276 mmeineke 537 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 mmeineke 536 ndx++;
280    
281 mmeineke 537 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 mmeineke 536 ndx++;
285     }
286     }
287     }
288    
289    
290 mmeineke 537 // clear up memory from the test box
291 mmeineke 536
292 mmeineke 537 for(i=0; i<lipidNatoms; i++ ) delete atoms[i];
293 mmeineke 536
294 mmeineke 537 coord* lipidSites = new coord[nLipids];
295 mmeineke 536
296 mmeineke 537 // start a 3D RSA for the for the lipid placements
297    
298    
299     int reject;
300     int testDX, acceptedDX;
301 mmeineke 536
302 mmeineke 537 rCutSqr = lipid_spaceing * lipid_spaceing;
303 mmeineke 536
304 mmeineke 537 for(i=0; i<nLipids; i++ ){
305     done = 0;
306     while( !done ){
307    
308 mmeineke 538 lipidSites[i].pos[0] = drand48() * box_x;
309     lipidSites[i].pos[1] = drand48() * box_y;
310     lipidSites[i].pos[2] = drand48() * box_z;
311 mmeineke 537
312 mmeineke 538 getRandomRot( lipidSites[i].rot );
313 mmeineke 537
314     ndx = i * lipidNatoms;
315 mmeineke 536
316 mmeineke 538 lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
317     ndx );
318 mmeineke 537
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 mmeineke 536
328 mmeineke 537 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 mmeineke 536
344 mmeineke 537 if( reject ){
345 mmeineke 536
346 mmeineke 537 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 mmeineke 536
366 mmeineke 538 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 mmeineke 536
370 mmeineke 537 map( dx, dy, dz, box_x, box_y, box_z );
371 mmeineke 536
372 mmeineke 537 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 mmeineke 536
421 mmeineke 537
422     // create the real Atom arrays
423    
424 mmeineke 536 nAtoms = 0;
425     molIndex = 0;
426 mmeineke 537 molStart = new int[nLipids + nWaters];
427    
428     for(j=0; j<nLipids; j++){
429     molStart[molIndex] = nAtoms;
430     molIndex++;
431     nAtoms += lipidNatoms;
432 mmeineke 536 }
433 mmeineke 537
434 mmeineke 538 for(j=0; j<nWaters; j++){
435 mmeineke 537 molStart[molIndex] = nAtoms;
436     molIndex++;
437     nAtoms += waterNatoms;
438     }
439 mmeineke 536
440 mmeineke 537
441 mmeineke 536 Atom::createArrays( nAtoms );
442     atoms = new Atom*[nAtoms];
443    
444 mmeineke 537
445     // initialize lipid positions
446 mmeineke 536
447 mmeineke 538 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 mmeineke 536
454 mmeineke 538 // 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 mmeineke 537 // set up the SimInfo object
468 mmeineke 536
469 mmeineke 537 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 mmeineke 536
482 mmeineke 537 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 mmeineke 538 // 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 mmeineke 536
510 mmeineke 537 return 1;
511 mmeineke 536 }
512    
513 mmeineke 537
514 mmeineke 536
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 mmeineke 501 double rot[3][3];
528     double pos[3];
529    
530     Atom** atoms;
531 mmeineke 498 SimInfo* simnfo;
532 mmeineke 501 DumpWriter* writer;
533     MoLocator** locate;
534    
535     // initialize functions and variables
536 mmeineke 498
537 mmeineke 501 srand48( RAND_SEED );
538     molSeq = NULL;
539 mmeineke 504 molStart = NULL;
540 mmeineke 501 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 mmeineke 502 nSites = 4.0 * pow( (double)nCells, 3.0 );
554 mmeineke 501 }
555    
556    
557     // create the molMap and cardDeck arrays
558 mmeineke 498
559 mmeineke 501 molMap = new int[nSites];
560     cardDeck = new int[nSites];
561 mmeineke 498
562 mmeineke 501 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 mmeineke 498
569 mmeineke 501 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 mmeineke 498
581    
582 mmeineke 501 // 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 mmeineke 504 molStart = new int[bsInfo.totNmol];
589 mmeineke 501 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 mmeineke 504 molStart[molIndex] = nAtoms;
594 mmeineke 501 molIndex++;
595 mmeineke 502 nAtoms += bsInfo.compStamps[i]->getNAtoms();
596 mmeineke 501 }
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 mmeineke 506 cell *= 1.2; // add a little buffer
610    
611 mmeineke 502 cell *= M_SQRT2;
612 mmeineke 498
613 mmeineke 501 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 mmeineke 504 atomIndex = molStart[ molMap[siteIndex] ];
626     locate[molID]->placeMol( pos, rot, atoms, atomIndex );
627 mmeineke 501 }
628     siteIndex++;
629 mmeineke 498
630 mmeineke 501 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 mmeineke 504
635 mmeineke 501 getRandomRot( rot );
636     molID = molSeq[molMap[siteIndex]];
637 mmeineke 504 atomIndex = molStart[ molMap[siteIndex] ];
638     locate[molID]->placeMol( pos, rot, atoms, atomIndex );
639 mmeineke 501 }
640     siteIndex++;
641 mmeineke 498
642 mmeineke 501 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 mmeineke 504 atomIndex = molStart[ molMap[siteIndex] ];
650     locate[molID]->placeMol( pos, rot, atoms, atomIndex );
651 mmeineke 501 }
652     siteIndex++;
653 mmeineke 498
654 mmeineke 501 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 mmeineke 504
659 mmeineke 501 getRandomRot( rot );
660     molID = molSeq[molMap[siteIndex]];
661 mmeineke 504 atomIndex = molStart[ molMap[siteIndex] ];
662     locate[molID]->placeMol( pos, rot, atoms, atomIndex );
663 mmeineke 501 }
664     siteIndex++;
665     }
666     }
667     }
668 mmeineke 498
669 mmeineke 501 // 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 mmeineke 502 simnfo->n_atoms = nAtoms;
677     simnfo->box_x = bsInfo.boxX;
678     simnfo->box_y = bsInfo.boxY;
679     simnfo->box_z = bsInfo.boxZ;
680 mmeineke 501
681 mmeineke 504 sprintf( simnfo->sampleName, "%s.dump", bsInfo.outPrefix );
682 mmeineke 502 sprintf( simnfo->finalName, "%s.init", bsInfo.outPrefix );
683 mmeineke 504
684 mmeineke 502 simnfo->atoms = atoms;
685 mmeineke 501
686     // set up the writer and write out
687    
688 mmeineke 502 writer = new DumpWriter( simnfo );
689 mmeineke 501 writer->writeFinal();
690 mmeineke 498
691 mmeineke 501 // 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 mmeineke 498 }
699 mmeineke 501 delete[] locate;
700     }
701     if( atoms != NULL ){
702     for(i=0; i<nAtoms; i++){
703     delete atoms[i];
704 mmeineke 498 }
705 mmeineke 501 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 mmeineke 498
712 mmeineke 501 return 1;
713     }
714 mmeineke 498
715    
716 mmeineke 501 void getRandomRot( double rot[3][3] ){
717 mmeineke 498
718 mmeineke 501 double theta, phi, psi;
719     double cosTheta;
720 mmeineke 498
721 mmeineke 501 // select random phi, psi, and cosTheta
722 mmeineke 498
723 mmeineke 501 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 mmeineke 498
727 mmeineke 501 theta = acos( cosTheta );
728 mmeineke 498
729 mmeineke 501 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 mmeineke 502 rot[0][2] = sin(theta) * sin(psi);
732 mmeineke 501
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 mmeineke 498 }
741 mmeineke 501
742 mmeineke 536
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     }