private void SetPlotInfo(SuperCell superCell, PlotStyle thisPlotStyle) { currentCell = superCell; plotStyle = thisPlotStyle; fieldLineStyle = FieldLineStyle.None; miscInfo = new MiscInfo(); displayList = new List<Vector3d>(); extents = new double[] { double.MaxValue, double.MinValue, double.MaxValue, double.MinValue, double.MaxValue, double.MinValue }; up = new Vector3d(0.0, 1.0, 0.0); right = new Vector3d(1.0, 0.0, 0.0); miscInfo.planeNormal = Calculator.Num2TK(Calculator.CrossProduct(superCell.latticeVectors.Column(0), superCell.latticeVectors.Column(1))); miscInfo.pointOnPlane = Calculator.Num2TK(superCell.centroids.Row(0)); rotationLocked = false; Vector3d oldTarget = target; if (!isRunning) { target = new Vector3d(0.0, 0.0, 0.0); theta = 0.0; phi = -Math.PI / 2; } switch (plotStyle) { case PlotStyle.Molecules: string[] distinctTypes = superCell.types.Distinct().ToArray(); miscInfo.colorOrder = new Color4[superCell.types.Length]; miscInfo.colorList = new List<Color4>(); for (int i = 0; i < superCell.types.Length; i++) { int index = 0; while (true) { if (superCell.types[i] == distinctTypes[index]) break; index++; } miscInfo.colorOrder[i] = molColors[index]; } for (int i = 0; i < superCell.mols.Count; i++) { Vector3d myCentroid = Calculator.Num2TK(superCell.mols[i].centroid); for (int j = 0; j < superCell.bonds.GetLength(0); j++) { miscInfo.colorList.Add(miscInfo.colorOrder[superCell.bonds[j, 0]-1]); Vector3d atom = Calculator.Num2TK(superCell.mols[i].atoms.Row(superCell.bonds[j, 0] - 1)) + myCentroid; extents = Calculator.UpdateExtents(extents, atom); target += atom; displayList.Add(atom); miscInfo.colorList.Add(miscInfo.colorOrder[superCell.bonds[j, 1]-1]); atom = Calculator.Num2TK(superCell.mols[i].atoms.Row(superCell.bonds[j, 1] - 1)) + myCentroid; extents = Calculator.UpdateExtents(extents, atom); target += atom; displayList.Add(atom); } } break; case PlotStyle.Centers: for (int i = 0; i < superCell.centroids.RowCount; i++) { Vector3d centroid = Calculator.Num2TK(superCell.centroids.Row(i)); extents = Calculator.UpdateExtents(extents, centroid); target += centroid; displayList.Add(centroid); } break; case PlotStyle.Directions: GrabDirections(superCell,false); break; case PlotStyle.Curl: GrabDirections(superCell,true); break; } target /= (double)displayList.Count; if (!isRunning) { gameWidth = (extents[1] - extents[0]) * 1.1; gameHeight = (extents[3] - extents[2]) * 1.1; gameDepth = extents[5] - extents[4]; depthClipPlane = Math.Max(Math.Max(gameWidth, gameDepth), gameDepth); eye = new Vector3d(target.X, target.Y, depthClipPlane * 2.0); } else { target = oldTarget; UpdateView(); } r = (eye - target).Length; }
public void Plot(SuperCell superCell, PlotStyle plotStyle) { Pause(); SetPlotInfo(superCell, plotStyle); UnPause(); if (!isRunning) { runGameThread = new Thread(PlotInit); runGameThread.Start(); isRunning = true; } }
public void PlotWithFieldLines(SuperCell superCell, PlotStyle plotStyle, FieldLineStyle fieldLines, double density) { Pause(); SetPlotInfo(superCell, plotStyle); this.fieldLineStyle = fieldLines; fieldLineList = new List<FieldLine>(); fieldLineList.Add(new FieldLine()); if (fieldLines == FieldLineStyle.Full) GrabAllFieldLines(); UnPause(); if (!isRunning) { runGameThread = new Thread(PlotInit); runGameThread.Start(); isRunning = true; } }
public void GrabDirections(SuperCell superCell, bool curls) { double multiplier; if (superCell.isParent) multiplier = 1; else multiplier = 10; if (plotStyle == PlotStyle.Directions) multiplier *= 10; for (int i = 0; i < superCell.centroids.RowCount; i++) { Vector3d centroid = Calculator.Num2TK(superCell.centroids.Row(i)); extents = Calculator.UpdateExtents(extents, centroid); Vector3d direction; if (curls) { if (superCell.isParent) { direction = Calculator.Num2TK(superCell.curls.Row(i)); } else { direction = Calculator.Num2TK(superCell.curls.Row(i) - superCell.parent.curls.Row(i)); } } else { if (superCell.isParent) { direction = Calculator.Num2TK(superCell.directions.Row(i)); } else { direction = Calculator.Num2TK(superCell.directions.Row(i) - superCell.parent.directions.Row(i)); } } target += 2 * centroid; displayList.Add(centroid - 0.5 * direction * multiplier); displayList.Add(centroid + 0.5 * direction * multiplier); } }
private void LoadParent() { if (parent != null) { DialogResult msgResult = MessageBox.Show("This will clear all current supercells. Are you sure?", "Load new parent", MessageBoxButtons.YesNo); if (msgResult == DialogResult.No) return; } openFileDialog.Multiselect = false; AtomsPerCellDialog dlg = new AtomsPerCellDialog(); DialogResult result = dlg.ShowDialog(); while (result == DialogResult.OK && !dlg.isNumber) { MessageBox.Show("That is not a number!"); result = dlg.ShowDialog(this); } if (result == DialogResult.OK) { result = openFileDialog.ShowDialog(); if (result == DialogResult.OK) { parent = SuperCell.ReadMol2_complex(openFileDialog.FileName, dlg.atomsPerCell); if (parent.isError) { Calculator.HandleErrors(parent); parent = null; } else { superList.Clear(); childListBox.Items.Clear(); baseStructureTextBox.Text = Path.GetFileNameWithoutExtension(parent.filePath); browseChildrenButton.Enabled = true; cloneButton.Enabled = true; removeSelectedButton.Enabled = true; plotParentButton.Enabled = true; childStructuresToolStripMenuItem.Enabled = true; } } } }
public static SuperCell ReadMol2_simple(String filePath, SuperCell parent) { StreamReader reader = File.OpenText(filePath); string line; bool startReading = false; SuperCell superCell = new SuperCell(parent); superCell.isError = false; superCell.errorType = SuperCellError.NoError; superCell.filePath = filePath; superCell.parent = parent; int atomsPerCell = superCell.order.Length; int molsPerCell = superCell.order.GetLength(0); int atomsPerMol = superCell.order.GetLength(1); int numMols = superCell.superCellSize[0] * superCell.superCellSize[1] * superCell.superCellSize[2]; int numCells = numMols * molsPerCell; double[,] atoms = new double[atomsPerMol, 3]; superCell.mols = new List<Molecule>(); while (true) { if (startReading) { for (int cell = 0; cell < numCells; cell++) { double[,] atomsBuffer = new double[atomsPerCell, 3]; for (int atom = 0; atom < atomsPerCell; atom++) { line = reader.ReadLine(); if (line == "@<TRIPOS>BOND") { superCell.isError = true; superCell.errorType = SuperCellError.Child_StructureMismatch; return superCell; } string[] items = line.Split(' '); 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)); } } break; } else { line = reader.ReadLine(); if (line == "@<TRIPOS>ATOM") startReading = true; } } superCell.centroids = DenseMatrix.Create(numMols, 3, 0); superCell.directions = DenseMatrix.Create(numMols, 3, 0); int count = 0; foreach (Molecule mol in superCell.mols) { superCell.centroids.SetRow(count, mol.centroid); superCell.directions.SetRow(count, mol.direction); count++; } superCell.CalculateDirectionDerivatives(); return superCell; }
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; }
public SuperCell(SuperCell parent) { isParent = false; superCellSize = parent.superCellSize; latticeVectors = parent.latticeVectors; latticeParams = parent.latticeParams; order = parent.order; types = parent.types; bonds = parent.bonds; bondTypes = parent.bondTypes; errorType = SuperCellError.NoError; }