ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/utils/bilayerSys.cpp
(Generate patch)

Comparing trunk/OOPSE/utils/bilayerSys.cpp (file contents):
Revision 498 by mmeineke, Mon Apr 14 21:22:54 2003 UTC vs.
Revision 538 by mmeineke, Sat May 17 16:57:08 2003 UTC

# Line 1 | Line 1
1 + #include <iostream>
2 +
3   #include <cstdlib>
4   #include <cstring>
5   #include <cmath>
6  
7   #include "simError.h"
6 #include "parse_me.h"
7 #include "MakeStamps.hpp"
8 #include "Globals.hpp"
8   #include "SimInfo.hpp"
9   #include "ReadWrite.hpp"
10  
11 <
11 > #include "MoLocator.hpp"
12   #include "sysBuild.hpp"
13   #include "bilayerSys.hpp"
14  
15  
17 // this routine is defined in BASS_interface.cpp
18 extern void set_interface_stamps( MakeStamps* ms, Globals* g );
16  
17 < void buildRandomBilayer( sysBuildInfo info );
17 > void map( double &x, double &y, double &z,
18 >          double boxX, double boxY, double boxZ );
19  
20 + int buildRandomBilayer( void );
21  
22 < void buildBilayer( sysBuildInfo info ){
22 > void getRandomRot( double rot[3][3] );
23 >
24 > int buildBilayer( int isRandom ){
25    
26 <  if( info.isRandom ){
27 <    buildRandomBilayer( info );
26 >  if( isRandom ){
27 >    return buildRandomBilayer();
28    }
29    else{
29
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 < void buildRandomBilayer( sysBuildInfo info ){
41 >  typedef struct{
42 >    double rot[3][3];
43 >    double pos[3];
44 >  } coord;
45  
46 <  MakeStamps* the_stamps;
47 <  Globals* the_globals;
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 <  bwMolLinked bwInfo;
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 <  // init the bwInfo
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 <  bwinfo.components = NULL;
117 >  //create the temp Molocator and atom Arrays
118    
119 <  bwInfo.havePressure = 0;
120 <  bwInfo.haveTauBarrostat = 0;
121 <  bwInfo.haveTauTemp = 0;
122 <  bwInfo.haveQmass = 0;
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 <  // create parser and read the Bas file
137 >  double* waterX = new double[testWaters];
138 >  double* waterY = new double[testWaters];
139 >  double* waterZ = new double[testWaters];
140    
141 <  simnfo = new SimInfo();
142 <  the_stamps = new MakeStamps();
143 <  the_globals = new Globals();
61 <  set_interface_stamps( the_stamps, the_globals );
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  
63  yacc_BASS( info.in_name );  
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 <  // set the easy ones first
68 <  bwInfo.targetTemp = the_globals->getTargetTemp();
69 <  bwInfo.dt = the_globals->getDt();
70 <  bwInfo.runTime = the_globals->getRunTime();
176 >  // calculate the number of water's displaced by our lipid.
177  
178 <  // get the ones we know are there, yet still may need some work.
179 <  bwInfo.nComponents = the_globals->getNComponents();
180 <  strcpy( bwInfo.forceField, the_globals->getForceField() );
178 >  testSite.rot[0][0] = 1.0;
179 >  testSite.rot[0][1] = 0.0;
180 >  testSite.rot[0][2] = 0.0;
181  
182 <  // get the ensemble:
183 <  strcpy( bwInfo.ensemble, the_globals->getEnsemble() );
184 <  if( !strcasecmp( bwInfo.ensemble, "NPT" ) ) {
185 <    
186 <    if (the_globals->haveTargetPressure()){
187 <      bwInfo.targetPressure = the_globals->getTargetPressure();
188 <      bwInfo.havePressure = 1;
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 <    else {
224 <      sprintf( painCave.errMsg,
225 <               "buildBilayer error: If you use the constant pressure\n"
87 <               "    ensemble, you must set targetPressure.\n"
88 <               "    This was found in the BASS file.\n");
89 <      painCave.isFatal = 1;
90 <      simError();
91 <    }
223 >  }
224 >  
225 >  int targetWaters = nWaters + n_deleted * nLipids;
226  
227 <    if (the_globals->haveTauThermostat()){
228 <      bwInfo.tauThermostat = the_globals->getTauThermostat();
229 <      bwInfo.haveTauThermostat = 1;;
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 <    else if (the_globals->haveQmass()){
98 <      bwinfo.Qmass = the_globals->getQmass();
99 <      bwInfo.haveQmass = 1;
100 <    }
101 <    else {
102 <      sprintf( painCave.errMsg,
103 <               "buildBilayer error: If you use one of the constant temperature\n"
104 <               "    ensembles, you must set either tauThermostat or qMass.\n"
105 <               "    Neither of these was found in the BASS file.\n");
106 <      painCave.isFatal = 1;
107 <      simError();
108 <    }
285 >  }  
286  
287 <    if (the_globals->haveTauBarostat()){
288 <      bwInfo.tauBarostat = the_globals->getTauBarostat();
289 <      bwInfo.haveTauBarostat = 1;
290 <    }                                    
291 <    else {
292 <      sprintf( painCave.errMsg,
293 <               "SimSetup error: If you use the constant pressure\n"
294 <               "    ensemble, you must set tauBarostat.\n"
295 <               "    This was found in the BASS file.\n");
296 <      painCave.isFatal = 1;
297 <      simError();
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 <  } else if ( !strcasecmp( ensemble, "NVT") ) {
365 <    the_extendedsystem = new ExtendedSystem( simnfo );
366 <    the_extendedsystem->setTargetTemp(the_globals->getTargetTemp());
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 <    if (the_globals->haveTauThermostat())
369 <      the_extendedsystem->setTauThermostat(the_globals->getTauThermostat());
370 <    else if (the_globals->haveQmass())
371 <      the_extendedsystem->setQmass(the_globals->getQmass());
372 <    else {
373 <      sprintf( painCave.errMsg,
374 <               "SimSetup error: If you use one of the constant temperature\n"
375 <               "    ensembles, you must set either tauThermostat or qMass.\n"
376 <               "    Neither of these was found in the BASS file.\n");
377 <      painCave.isFatal = 1;
378 <      simError();
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 <  } else if ( !strcasecmp( ensemble, "NVE") ) {
383 <  } else {
382 >  if( n_active < nWaters ){
383 >    
384      sprintf( painCave.errMsg,
385 <             "SimSetup Warning. Unrecognized Ensemble -> %s, "
386 <             "reverting to NVE for this simulation.\n",
387 <             ensemble );
146 <    painCave.isFatal = 0;
385 >             "Too many waters were removed, edit code and try again.\n" );
386 >    
387 >    painCave.isFatal = 1;
388      simError();
389 <    strcpy( ensemble, "NVE" );
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    }  
150  strcpy( simnfo->ensemble, ensemble );
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 <  delete stamps;
155 <  delete globals;
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 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines