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

Comparing trunk/OOPSE/utils/sysbuilder/bilayerSys.cpp (file contents):
Revision 816 by tim, Mon Sep 15 16:52:02 2003 UTC vs.
Revision 817 by gezelter, Fri Oct 24 17:36:18 2003 UTC

# Line 33 | Line 33 | int buildRandomBilayer( void );
33                 double boxX, double boxY, double boxZ );
34  
35   int buildRandomBilayer( void );
36 + int buildLatticeBilayer( int isHexLattice,
37 +                         double hexSpacing,
38 +                         double aLat,
39 +                         double bLat,
40 +                         int targetNlipid,
41 +                         double targetWaterLipidRatio,
42 +                         double leafSpacing);
43  
44   void getRandomRot( double rot[3][3] );
45 + void getEulerRot( double theta, double phi, double psi, double rot[3][3] );
46 + void getUnitRot( double unit[3], double rot[3][3] );
47  
48   int buildBilayer( int isRandom ){
49    
# Line 42 | Line 51 | int buildBilayer( int isRandom ){
51      return buildRandomBilayer();
52    }
53    else{
54 <    sprintf( painCave.errMsg,
55 <             "Cannot currently create a non-random bilayer.\n" );
56 <    painCave.isFatal = 1;
57 <    simError();
49 <    return 0;
54 >
55 >    
56 >
57 >    return buildLatticeBilayer();
58    }
59   }
60  
# Line 571 | Line 579 | int buildRandomBilayer( void ){
579    //     if( molSeq != NULL ) delete[] molSeq;
580    //     if( simnfo != NULL ) delete simnfo;
581    //     if( writer != NULL ) delete writer;
582 +
583 +  return 1;
584 + }
585 +
586 + int buildLatticeBilayer(int isHexLattice,
587 +                        double hexSpacing,
588 +                        double aLat,
589 +                        double bLat,
590 +                        int targetNlipid,
591 +                        double targetWaterLipidRatio,
592 +                        double leafSpacing){
593 +
594 +  typedef struct{
595 +    double rot[3][3];
596 +    double pos[3];
597 +  } coord;
598 +
599 +  const double waterRho = 0.0334; // number density per cubic angstrom
600 +  const double waterVol = 4.0 / waterRho; // volume occupied by 4 waters
601 +  
602 +  double waterCell[3];
603 +
604 +  double *posX, *posY, *posZ;
605 +  double pos[3], posA[3], posB[3];
606 +
607 +  const double waterFudge = 5.0;
608 +
609 +  int i,j,k,l;
610 +  int nAtoms, atomIndex, molIndex, molID;
611 +  int* molSeq;
612 +  int* molMap;
613 +  int* molStart;
614 +  int testTot, done;
615 +  int nCells, nCellsX, nCellsY, nCellsZ;
616 +  int nx, ny;
617 +  double boxX, boxY, boxZ;
618 +  double unitVector[3];
619 +  int which;
620 +  int targetWaters;
621 +  
622 +  
623 +
624 +  coord testSite;
625 +
626 +  Atom** atoms;
627 +  SimInfo* simnfo;
628 +  SimState* theConfig;
629 +  DumpWriter* writer;
630 +
631 +  MoleculeStamp* lipidStamp;
632 +  MoleculeStamp* waterStamp;  
633 +  MoLocator *lipidLocate;
634 +  MoLocator *waterLocate;
635 +  int foundLipid, foundWater;
636 +  int nLipids, lipidNatoms, nWaters, waterNatoms;
637 +  
638 +  srand48( RAND_SEED );
639 +
640 +  // create the simInfo objects
641 +
642 +  simnfo = new SimInfo;
643 +
644 +  // set the the lipidStamp
645 +
646 +  foundLipid = 0;
647 +  foundWater = 0;
648 +  for(i=0; i<bsInfo.nComponents; i++){
649 +    if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.lipidName ) ){
650 +          
651 +      foundLipid = 1;
652 +      lipidStamp = bsInfo.compStamps[i];
653 +      nLipids = bsInfo.componentsNmol[i];
654 +      lipidNatoms = lipidStamp->getNAtoms();
655 +    }
656 +    if( !strcmp( bsInfo.compStamps[i]->getID(), bsInfo.waterName ) ){
657 +          
658 +      foundWater = 1;
659 +          
660 +      waterStamp = bsInfo.compStamps[i];
661 +      nWaters = bsInfo.componentsNmol[i];
662 +      waterNatoms = waterStamp->getNAtoms();
663 +    }
664 +  }
665 +  if( !foundLipid ){
666 +    sprintf(painCave.errMsg,
667 +            "Could not find lipid \"%s\" in the bass file.\n",
668 +            bsInfo.lipidName );
669 +    painCave.isFatal = 1;
670 +    simError();
671 +  }
672 +  if( !foundWater ){
673 +    sprintf(painCave.errMsg,
674 +            "Could not find solvent \"%s\" in the bass file.\n",
675 +            bsInfo.waterName );
676 +    painCave.isFatal = 1;
677 +    simError();
678 +  }
679 +  
680 +  //create the Molocator arrays
681 +  
682 +  lipidLocate = new MoLocator( lipidStamp );
683 +  waterLocate = new MoLocator( waterStamp );
684 +
685 +
686 +  // set up the bilayer leaves
687 +  
688 +  if (isHexLattice) {
689 +    aLat = sqrt(3.0)*hexSpacing;
690 +    bLat = hexSpacing;
691 +  }
692 +
693 +  nCells = (int) sqrt( (double)targetNlipid * bLat / (4.0 * aLat) );
694 +
695 +  nx = nCells;
696 +  ny = (int) ((double)nCells  * aLat / bLat);
697 +
698 +  boxX = nx * aLat;
699 +  boxY = ny * bLat;  
700 +
701 +  nLipids = 4 * nx * ny;
702 +  coord* lipidSites = new coord[nLipids];
703 +
704 +  unitVector[0] = 0.0;
705 +  unitVector[1] = 0.0;
706 +
707 +  which = 0;
708 +
709 +  for (i = 0; i < nx; i++) {
710 +    for (j = 0; j < ny; j++ ) {
711 +      for (k = 0; k < 2; k++) {
712 +        
713 +        lipidSites[which].pos[0] = (double)i * aLat;
714 +        lipidSites[which].pos[1] = (double)j * bLat;
715 +        lipidSites[which].pos[2] = ((double)k - 0.5) * (leafSpacing / 2.0);
716 +        
717 +        unitVector[2] = 2.0 * (double)k  - 1.0;
718 +        
719 +        getUnitRot( unitVector, lipidSites[which].rot );
720 +
721 +        which++;
722  
723 +        lipidSites[which].pos[0] = aLat * ((double)i + 0.5);
724 +        lipidSites[which].pos[1] = bLat * ((double)j + 0.5);
725 +        lipidSites[which].pos[2] = ((double)k - 0.5) * (leafSpacing / 2.0);
726 +        
727 +        unitVector[2] = 2.0 * (double)k  - 1.0;
728 +        
729 +        getUnitRot( unitVector, lipidSites[which].rot );
730 +        
731 +        which++;
732 +      }
733 +    }
734 +  }
735 +
736 +  targetWaters = targetWaterLipidRatio * nLipids;
737 +
738 +  // guess the size of the water box
739 +  
740 +  
741 +
742 +  nCellsX = (int)ceil(boxX / pow(waterVol, ( 1.0 / 3.0 )) );
743 +  nCellsY = (int)ceil(boxY / pow(waterVol, ( 1.0 / 3.0 )) );
744 +
745 +  done = 0;
746 +  nCellsZ = 0;
747 +  while( !done ){
748 +        
749 +    nCellsZ++;
750 +    testTot = 4 * nCellsX * nCellsY * nCellsZ;
751 +        
752 +    if( testTot >= targetWaters ) done = 1;
753 +  }
754 +  
755 +  nWaters = nCellsX * nCellsY * nCellsZ * 4;
756 +  
757 +  coord* waterSites = new coord[nWaters];
758 +
759 +  waterCell[0] = boxX / nCellsX;
760 +  waterCell[1] = boxY / nCellsY;
761 +  waterCell[2] = 4.0 / (waterRho * waterCell[0] * waterCell[1]);
762 +
763 +  Lattice *myORTHO;
764 +  myORTHO = new Lattice( ORTHORHOMBIC_LATTICE_TYPE, waterCell);
765 +  myORTHO->setStartZ( leafSpacing / 2.0 + waterFudge);
766 +
767 +  boxZ = waterCell[2] * nCellsZ;
768 +        
769 +  // create an fcc lattice in the water box.
770 +  
771 +  which = 0;
772 +  for( i=0; i < nCellsX; i++ ){
773 +    for( j=0; j < nCellsY; j++ ){
774 +      for( k=0; k < nCellsZ; k++ ){
775 +
776 +        myORTHO->getLatticePoints(&posX, &posY, &posZ, i, j, k);
777 +        for(l=0; l<4; l++){
778 +          waterSites[which].pos[0] = posX[l];
779 +          waterSites[which].pos[1] = posY[l];
780 +          waterSites[which].pos[2] = posZ[l];
781 +          which++;
782 +        }
783 +      }
784 +    }
785 +  }  
786 +
787 +  // create the real Atom arrays
788 +  
789 +  nAtoms = 0;
790 +  molIndex = 0;
791 +  molStart = new int[nLipids + nWaters];  
792 +  
793 +  for(j=0; j<nLipids; j++){
794 +    molStart[molIndex] = nAtoms;
795 +    molIndex++;
796 +    nAtoms += lipidNatoms;
797 +  }
798 +
799 +  for(j=0; j<nWaters; j++){
800 +    molStart[molIndex] = nAtoms;
801 +    molIndex++;
802 +    nAtoms += waterNatoms;
803 +  }
804 +  
805 +  theConfig = simnfo->getConfiguration();
806 +  theConfig->createArrays( nAtoms );
807 +  simnfo->atoms = new Atom*[nAtoms];
808 +  atoms = simnfo->atoms;
809 +
810 +  // initialize lipid positions
811 +
812 +  molIndex = 0;
813 +  for(i=0; i<nLipids; i++ ){
814 +    lipidLocate->placeMol( lipidSites[i].pos, lipidSites[i].rot, atoms,
815 +                           molStart[molIndex], theConfig );
816 +    molIndex++;
817 +  }
818 +
819 +  // initialize the water positions
820 +
821 +  for(i=0; i<nWaters; i++){
822 +    
823 +    getRandomRot( waterSites[i].rot );
824 +    waterLocate->placeMol( waterSites[i].pos, waterSites[i].rot, atoms,
825 +                           molStart[molIndex], theConfig );
826 +    molIndex++;
827 +  }
828 +
829 +  // set up the SimInfo object
830 +  
831 +  double Hmat[3][3];
832 +
833 +  Hmat[0][0] = boxX;
834 +  Hmat[0][1] = 0.0;
835 +  Hmat[0][2] = 0.0;
836 +
837 +  Hmat[1][0] = 0.0;
838 +  Hmat[1][1] = boxY;
839 +  Hmat[1][2] = 0.0;
840 +
841 +  Hmat[2][0] = 0.0;
842 +  Hmat[2][1] = 0.0;
843 +  Hmat[2][2] = boxZ;
844 +  
845 +
846 +  bsInfo.boxX = boxX;
847 +  bsInfo.boxY = boxY;
848 +  bsInfo.boxZ = boxZ;
849 +  
850 +  simnfo->setBoxM( Hmat );
851 +
852 +  sprintf( simnfo->sampleName, "%s.dump", bsInfo.outPrefix );
853 +  sprintf( simnfo->finalName, "%s.init", bsInfo.outPrefix );
854 +
855 +  // set up the writer and write out
856 +  
857 +  writer = new DumpWriter( simnfo );
858 +  writer->writeFinal( 0.0 );
859 +
860    return 1;
861   }
862  
863 +
864   void getRandomRot( double rot[3][3] ){
865  
866    double theta, phi, psi;
# Line 588 | Line 874 | void getRandomRot( double rot[3][3] ){
874  
875    theta = acos( cosTheta );
876  
877 +  getEulerRot( theta, phi, psi, rot );
878 + }
879 +
880 +
881 + void getEulerRot( double theta, double phi, double psi, double rot[3][3] ){
882 +
883    rot[0][0] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
884    rot[0][1] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
885    rot[0][2] = sin(theta) * sin(psi);
# Line 600 | Line 892 | void getRandomRot( double rot[3][3] ){
892    rot[2][1] = -cos(phi) * sin(theta);
893    rot[2][2] = cos(theta);  
894   }
895 +
896 +
897 + void getUnitRot( double u[3], double rot[3][3] ){
898 +
899 +  double theta, phi, psi;
900 +
901 +  theta = acos(u[2]);
902 +  phi = atan(u[1] / u[0]);
903 +  psi = 0.0;
904 +
905 +  getEulerRot( theta, phi, psi, rot );
906 + }
907                          
908  
909  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines