示例#1
0
        public static SuperCell ReadMol2_complex(string fileName, int atomsPerCell)
        {
            SuperCell superCell = new SuperCell();
            superCell.isError = false;
            superCell.isParent = true;
            superCell.errorType = SuperCellError.NoError;
            superCell.filePath = fileName;

            #region RawDataReader
            Queue<string> atomLines = new Queue<string>();
            List<string> bondLines = new List<string>();
            StreamReader reader = File.OpenText(fileName);
            string line;
            bool startReading = false;
            bool bondsPresent = false;
            bool latticePresent = false;

            while (true)
            {
                if (startReading)
                {
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line == "@<TRIPOS>BOND")
                        {
                            bondsPresent = true;
                            break;
                        }
                        else
                        {
                            atomLines.Enqueue(line);
                        }
                    }
                    break;
                }
                else
                {
                    line = reader.ReadLine();
                    if (line == "@<TRIPOS>ATOM") startReading = true;
                }
            }

            if (bondsPresent)
            {
                while ((line = reader.ReadLine()) != null)
                {
                    if (line == "@<TRIPOS>CRYSIN")
                    {
                        latticePresent = true;
                        break;
                    }
                    else
                    {
                        bondLines.Add(line);
                    }
                }
            }
            else
            {
                superCell.isError = true;
                superCell.errorType = SuperCellError.Base_NoBonds;
                return superCell;
            }

            string latticeLine;
            if (!latticePresent)
            {
                superCell.isError = true;
                superCell.errorType = SuperCellError.Base_NoLattice;
                return superCell;
            }
            else
            {
                latticeLine = reader.ReadLine();
            }
            #endregion

            #region OrderFinder
            Queue<int[]> bondsQueue = new Queue<int[]>();
            Queue<int> bondTypesQueue = new Queue<int>();
            int[] tempBond;
            int numBonds = 0;

            while (true)
            {
                string[] items = bondLines[bondsQueue.Count].Split(' ');
                tempBond = new int[2] { int.Parse(items[1]), int.Parse(items[2]) };
                if (tempBond[0] > atomsPerCell || tempBond[1] > atomsPerCell)
                {
                    break;
                }
                else
                {
                    bondsQueue.Enqueue(tempBond);
                    bondTypesQueue.Enqueue(int.Parse(items[3]));
                    numBonds++;
                }
            }

            Node headNode = new Node();
            Node thisAtom;
            superCell.bonds = new int[bondsQueue.Count, 2];
            superCell.bondTypes = new int[bondsQueue.Count];
            int count = 0;

            while (bondsQueue.Count > 0)
            {
                tempBond = bondsQueue.Dequeue();
                superCell.bonds[count, 0] = tempBond[0];
                superCell.bonds[count, 1] = tempBond[1];
                superCell.bondTypes[count] = bondTypesQueue.Dequeue();
                thisAtom = headNode.SearchChildren(tempBond[0]);
                if (thisAtom != null)
                {
                    Node otherAtom = headNode.SearchChildren(tempBond[1]);
                    if (otherAtom != null)
                    {
                        otherAtom.ChangeParent(thisAtom);
                    }
                    else
                    {
                        thisAtom.AddChild(new Node(tempBond[1]));
                    }
                }
                else
                {
                    Node otherAtom = headNode.SearchChildren(tempBond[1]);
                    if (otherAtom != null)
                    {
                        otherAtom.AddChild(new Node(tempBond[0]));
                    }
                    else
                    {
                        Node tempNode = new Node(tempBond[0]);
                        headNode.AddChild(tempNode);
                        tempNode.AddChild(new Node(tempBond[1]));
                    }
                }
                count++;
            }

            if (headNode.Children.Count > 0)
            {
                superCell.order = headNode.FindOrder();
            }
            else
            {
                superCell.isError = true;
                superCell.errorType = SuperCellError.Base_CouldntFindOrder;
                return superCell;
            }
            #endregion

            #region RawDataProcessor
            int numAtoms = atomLines.Count;
            int molsPerCell = superCell.order.GetLength(0);
            int atomsPerMol = superCell.order.GetLength(1);
            int numCells = numAtoms / atomsPerCell;
            int numMols = molsPerCell*numCells;

            superCell.types = new string[atomsPerCell];
            superCell.mols = new List<Molecule>();

            for (int cell = 0; cell < numCells; cell++)
            {
                double[,] atomsBuffer = new double[atomsPerCell, 3];
                for (int atom = 0; atom < atomsPerCell; atom++)
                {
                    string[] items = atomLines.Dequeue().Split(' ');
                    if (cell == 0)
                    {
                        if (items[5].Length > 2)
                        {
                            superCell.types[atom] = items[5].Remove(items[5].Length - 2);
                        }
                        else
                        {
                            superCell.types[atom] = items[5];
                        }
                    }

                    atomsBuffer[atom, 0] = double.Parse(items[2]);
                    atomsBuffer[atom, 1] = double.Parse(items[3]);
                    atomsBuffer[atom, 2] = double.Parse(items[4]);
                }

                for (int mol = 0; mol < molsPerCell; mol++)
                {
                    double[,] thisMol = new double[atomsPerMol, 3];
                    for (int atom = 0; atom < atomsPerMol; atom++)
                    {
                        thisMol[atom, 0] = atomsBuffer[superCell.order[mol, atom], 0];
                        thisMol[atom, 1] = atomsBuffer[superCell.order[mol, atom], 1];
                        thisMol[atom, 2] = atomsBuffer[superCell.order[mol, atom], 2];
                    }
                    superCell.mols.Add(new Molecule(thisMol, true));
                }

            }

            superCell.centroids = DenseMatrix.Create(numMols, 3, 0);
            superCell.directions = DenseMatrix.Create(numMols, 3, 0);
            count = 0;
            foreach (Molecule mol in superCell.mols)
            {
                superCell.centroids.SetRow(count, mol.centroid);
                superCell.directions.SetRow(count, mol.direction);
                count++;
            }

            #endregion

            #region LatticeFinder
            string[] latticeItems = latticeLine.Split(' ');
            double[,] incompleteLattice = new double[2, 3] { { double.Parse(latticeItems[0]), double.Parse(latticeItems[1]), double.Parse(latticeItems[2]) },
                                                             { double.Parse(latticeItems[3]), double.Parse(latticeItems[4]), double.Parse(latticeItems[5]) } };

            superCell.latticeParams = new double[2, 3] { { 0.0, 0.0, 0.0 }, { incompleteLattice[1, 0], incompleteLattice[1, 1], incompleteLattice[1, 2] } };
            superCell.superCellSize = new int[3] { 0, 0, 0 };
            superCell.latticeVectors = DenseMatrix.OfArray(new double[,] { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } });
            bool[] cellDone = new bool[3] { false, false, false };

            double tempA;
            double tempB;
            double tempC;

            int cellA=0;
            int cellB=0;
            int cellC=0;

            if (numMols > 1)
            {
                for (int i = 0; i < 3; i++)
                {
                    tempA = (superCell.mols[molsPerCell].centroid - superCell.mols[0].centroid).L2Norm();
                    double tempLatticeRatio = incompleteLattice[0, i] / tempA;
                    if (Math.Abs(tempLatticeRatio - Math.Round(tempLatticeRatio)) < 0.001)
                    {
                        cellA = (int)Math.Round(tempLatticeRatio);
                        superCell.superCellSize[i] = cellA;
                        superCell.latticeParams[0, i] = tempA;
                        cellDone[i] = true;
                        superCell.latticeVectors.SetColumn(i, superCell.mols[molsPerCell].centroid - superCell.mols[0].centroid);
                        break;
                    }

                }
            }
            else
            {
                superCell.isError = true;
                superCell.errorType = SuperCellError.Base_SingleMol;
                return superCell;
            }

            if (numMols > cellA)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (cellDone[i] == true) continue;
                    tempB = (superCell.mols[cellA*molsPerCell].centroid - superCell.mols[0].centroid).L2Norm();
                    double tempLatticeRatio = incompleteLattice[0, i] / tempB;
                    if (Math.Abs(tempLatticeRatio - Math.Round(tempLatticeRatio)) < 0.001)
                    {
                        cellB = (int)Math.Round(tempLatticeRatio);
                        superCell.superCellSize[i] = cellB;
                        superCell.latticeParams[0, i] = tempB;
                        cellDone[i] = true;
                        superCell.latticeVectors.SetColumn(i, superCell.mols[cellA*molsPerCell].centroid - superCell.mols[0].centroid);
                        break;
                    }
                }
            }
            else
            {
                superCell.isError = true;
                superCell.errorType = SuperCellError.Base_LineCell;
                return superCell;
            }

            if (numMols > cellA * cellB)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (cellDone[i] == true) continue;
                    tempC = (superCell.mols[cellA * cellB * molsPerCell].centroid - superCell.mols[0].centroid).L2Norm();
                    double tempLatticeRatio = incompleteLattice[0, i] / tempC;
                    if (Math.Abs(tempLatticeRatio - Math.Round(tempLatticeRatio)) < 0.001)
                    {
                        cellC = (int)Math.Round(tempLatticeRatio);
                        superCell.superCellSize[i] = cellC;
                        superCell.latticeParams[0, i] = tempC;
                        cellDone[i] = true;
                        superCell.latticeVectors.SetColumn(i, superCell.mols[cellA*cellB*molsPerCell].centroid - superCell.mols[0].centroid);
                        break;
                    }
                }
            }
            else
            {
                int cIndex = 3;
                for (int i = 0; i < 3; i++)
                {
                    if (cellDone[i] == false) cIndex = i;
                }
                superCell.superCellSize[cIndex] = 1;
                superCell.latticeParams[0,cIndex] = incompleteLattice[0, cIndex];
                superCell.latticeVectors.SetColumn(cIndex, FindCVect(superCell.latticeVectors.Column((cIndex + 1) % 3), superCell.latticeVectors.Column((cIndex + 2) % 3), superCell.latticeParams[1, (cIndex + 1) % 3], superCell.latticeParams[1, (cIndex + 2) % 3], superCell.latticeParams[0, cIndex]));
            }
            #endregion

            superCell.CalculateDirectionDerivatives();

            return superCell;
        }
示例#2
0
 public void ChangeParent(Node parent)
 {
     if (Parent.Parent != null)
     {
         Parent.ChangeParent(this);
     }
     Parent.Children.Remove(this);
     parent.AddChild(this);
 }
示例#3
0
 public Node(int mol, Node parent)
 {
     AtomNumber = mol;
     parent.AddChild(this);
     Children = new List<Node>();
 }
示例#4
0
 public void AddChild(Node child)
 {
     Children.Add(child);
     child.Parent = this;
 }
示例#5
0
 public Node(int mol)
 {
     this.AtomNumber = mol;
     Parent = null;
     Children = new List<Node>();
 }