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 504 by mmeineke, Thu Apr 17 21:54:18 2003 UTC vs.
Revision 573 by mmeineke, Thu Jul 3 19:41:26 2003 UTC

# Line 13 | Line 13
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] );
# Line 32 | Line 36 | int buildBilayer( int isRandom ){
36   }
37  
38  
35
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;
# Line 127 | Line 608 | int buildRandomBilayer( void ){
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;
# Line 191 | Line 674 | int buildRandomBilayer( void ){
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 <  simnfo->box_x = bsInfo.boxX;
681 <  simnfo->box_y = bsInfo.boxY;
682 <  simnfo->box_z = bsInfo.boxZ;
683 <  
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  
# Line 205 | Line 690 | int buildRandomBilayer( void ){
690    // set up the writer and write out
691    
692    writer = new DumpWriter( simnfo );
693 <  writer->writeFinal();
693 >  writer->writeFinal(0.0);
694      
695    // clean up the memory
696    
# Line 258 | Line 743 | void getRandomRot( double rot[3][3] ){
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 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines