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 506 by mmeineke, Fri Apr 25 16:02:26 2003 UTC vs.
Revision 538 by mmeineke, Sat May 17 16:57:08 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 = 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 +  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 +  // 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 +  }  
286 +
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 +      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 +      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 +  if( n_active < nWaters ){
383 +    
384 +    sprintf( painCave.errMsg,
385 +             "Too many waters were removed, edit code and try again.\n" );
386 +    
387 +    painCave.isFatal = 1;
388 +    simError();
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 +  }  
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 +  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;
# Line 260 | Line 737 | void getRandomRot( double rot[3][3] ){
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