public void InitialiseBends(bool suppress = false) { AngleConnection angle; Bend bend; AngleConnection[] connections = anglesDict.Values.ToArray(); int numBends = connections.Length; int[] bendAtomNums = new int[numBends * 3]; double[] bendAEqs = new double[numBends]; double[] bendKEqs = new double[numBends]; for (int i = 0; i < numBends; i++) { angle = connections[i]; bend = GetBendParameter(angle); if (bend == null) { if (!suppress) { throw new NoParameterException(typeof(Bend), angle.atom0, angle.atom1, angle.atom2); } continue; } bendAEqs[i] = Mathf.Deg2Rad * bend.req; bendKEqs[i] = bend.keq; bendAtomNums[i * 3] = angle.atom0.index; bendAtomNums[i * 3 + 1] = angle.atom1.index; bendAtomNums[i * 3 + 2] = angle.atom2.index; } Fortran.set_bends(ref numBends, bendAtomNums, bendAEqs, bendKEqs); }
public void Modulo() { Assert.AreEqual(2m, Fortran.Modulo(12m, 5m)); Assert.AreEqual(2d, Fortran.Modulo(12d, 5d)); Assert.AreEqual(2f, Fortran.Modulo(12f, 5f)); Assert.AreEqual(2, Fortran.Modulo(12, 5)); Assert.AreEqual(2L, Fortran.Modulo(12L, 5L)); Assert.AreEqual(3m, Fortran.Modulo(-12m, 5m)); Assert.AreEqual(3d, Fortran.Modulo(-12d, 5d)); Assert.AreEqual(3f, Fortran.Modulo(-12f, 5f)); Assert.AreEqual(3, Fortran.Modulo(-12, 5)); Assert.AreEqual(3L, Fortran.Modulo(-12L, 5L)); Assert.AreEqual(-3m, Fortran.Modulo(12m, -5m)); Assert.AreEqual(-3d, Fortran.Modulo(12d, -5d)); Assert.AreEqual(-3f, Fortran.Modulo(12f, -5f)); Assert.AreEqual(-3, Fortran.Modulo(12, -5)); Assert.AreEqual(-3L, Fortran.Modulo(12L, -5L)); Assert.AreEqual(-2m, Fortran.Modulo(-12m, -5m)); Assert.AreEqual(-2d, Fortran.Modulo(-12d, -5d)); Assert.AreEqual(-2f, Fortran.Modulo(-12f, -5f)); Assert.AreEqual(-2, Fortran.Modulo(-12, -5)); Assert.AreEqual(-2L, Fortran.Modulo(-12L, -5L)); }
public void InitialiseMasses() { int status = 0; Fortran.set_masses(atoms.masses, ref status); Fortran.CheckStatus(status); }
public void InitialiseStretches(bool suppress = false) { Connection connection; Stretch stretch; Connection[] connections = connectionsDict.Values.ToArray(); int numStretches = connections.Length; int[] stretchAtomNums = new int[numStretches * 2]; double[] stretchREqs = new double[numStretches]; double[] stretchKEqs = new double[numStretches]; for (int i = 0; i < numStretches; i++) { connection = connections[i]; stretch = GetStretchParameter(connection); if (stretch == null) { if (!suppress) { throw new NoParameterException(typeof(Stretch), connection.atom0, connection.atom1); } continue; } stretchREqs[i] = stretch.req; stretchKEqs[i] = stretch.keq; stretchAtomNums[i * 2] = connection.atom0.index; stretchAtomNums[i * 2 + 1] = connection.atom1.index; } Fortran.set_stretches(ref numStretches, stretchAtomNums, stretchREqs, stretchKEqs); }
/// <summary> /// Converts the specified angle, in degrees, to the nearest <see cref="Compass"/> /// direction.</summary> /// <param name="degrees"> /// The angle to convert, in degrees. This value is taken <see cref="Fortran.Modulo"/> 360 /// degrees, and may therefore be outside the interval [0, 360).</param> /// <returns> /// The <see cref="Compass"/> direction nearest to the specified <paramref name="degrees"/>. /// </returns> /// <remarks> /// The specified <paramref name="degrees"/> are measured in the same way as <see /// cref="Compass"/> directions, i.e. starting at zero for <see cref="Compass.North"/> and /// increasing clockwise.</remarks> public static Compass DegreesToCompass(double degrees) { degrees = Fortran.Modulo(degrees + 22.5, 360); int point = (int)(degrees / 45); return((Compass)(point * 45)); }
/// <summary> /// Gets the <see cref="Brush"/> within the specified <see cref="Array"/> whose index /// corresponds to the specified value.</summary> /// <param name="brushes"> /// An <see cref="Array"/> of <see cref="Brush"/> objects.</param> /// <param name="value"> /// An <see cref="Int32"/> value indicating a <paramref name="brushes"/> element.</param> /// <param name="min"> /// The lower limit for <paramref name="value"/>.</param> /// <param name="max"> /// The upper limit for <paramref name="value"/>.</param> /// <returns><para> /// The <paramref name="brushes"/> element that corresponds to the specified <paramref /// name="value"/>, given a possible range from <paramref name="min"/> to <paramref /// name="max"/>. /// </para><para>-or-</para><para> /// A null reference if <paramref name="max"/> is less than or equal to <paramref /// name="min"/>.</para></returns> /// <exception cref="ArgumentNullOrEmptyException"> /// <paramref name="brushes"/> is a null reference or an empty <see cref="Array"/>. /// </exception> /// <remarks><para> /// <b>GetBrush</b> converts the specified <paramref name="value"/>, ranging from <paramref /// name="min"/> to <paramref name="max"/>, to an index within the specified <paramref /// name="brushes"/>, ranging from zero to <see cref="Array.Length"/> minus one, and returns /// the <paramref name="brushes"/> element with that index. /// </para><para> /// <b>GetBrush</b> returns the first element if the specified <paramref name="value"/> is /// less than <paramref name="min"/>, and the last element if <paramref name="value"/> is /// greater than <paramref name="max"/>.</para></remarks> public static Brush GetBrush(Brush[] brushes, int value, int min, int max) { if (brushes == null || brushes.Length == 0) { ThrowHelper.ThrowArgumentNullOrEmptyException("brushes"); } // check for invalid range int range = max - min; if (range <= 0) { return(null); } int maxBrush = brushes.Length - 1; // handle edge cases and invalid indices if (value >= max) { return(brushes[maxBrush]); } if (value <= min) { return(brushes[0]); } double index = maxBrush * (double)(value - min) / (double)range; return(brushes[Fortran.NInt(index)]); }
public IEnumerator GetAmberEGH(bool suppressStretches = false, bool suppressBends = false, bool suppressTorsions = true, bool suppressNonBonding = false) { _busy++; rmsForces = 0f; int c; for (int atomNum = 0; atomNum < atoms.size; atomNum++) { for (c = 0; c < 3; c++) { positions[atomNum * 3 + c] = atoms[atomNum].p[c]; } } int numAtoms = size; forces = new double[numAtoms * 3]; Fortran.allocate_atom_arrays(ref numAtoms); int status = 0; double[] stretchesEnergy = new double[2]; double[] bendsEnergy = new double[2]; double[] torsionsEnergy = new double[2]; double[] vdwsEnergy = new double[2]; double[] coulombicEnergy = new double[2]; Fortran.e_amber(positions, forces, stretchesEnergy, bendsEnergy, torsionsEnergy, vdwsEnergy, coulombicEnergy, ref rmsForces, ref status ); Fortran.CheckStatus(status); //GetStretchesEGH(); //yield return null; //GetBendsEGH(); //yield return null; //GetTorsionEGH(); ///yield return null; //GetNonBondingEGH(); //yield return null; allStretchesEnergy = stretchesEnergy[0]; allBendsEnergy = bendsEnergy[0]; allTorsionsEnergy = torsionsEnergy[0]; allVdwsEnergy = vdwsEnergy[0]; allCoulombicEnergy = coulombicEnergy[0]; amberEnergy = allStretchesEnergy + allBendsEnergy + allTorsionsEnergy + allVdwsEnergy + allCoulombicEnergy; totalEnergy = amberEnergy + kineticEnergy; for (int atomNum = 0; atomNum < atoms.size; atomNum++) { for (c = 0; c < 3; c++) { atoms[atomNum].force[c] = (float)forces[3 * atomNum + c]; } } _busy--; yield return(null); }
/// <summary> /// Initializes a new instance of the <see cref="ChangeOverlay"/> class with the specified /// <see cref="OverlayImage"/>.</summary> /// <param name="editing"> /// <c>true</c> to edit the <see cref="EditorOptions.Overlay"/> defined by the current <see /// cref="EditorOptions"/>; <c>false</c> to edit the <see cref="AreaSection.Overlay"/> /// defined by the current <see cref="AreaSection"/>.</param> /// <exception cref="InvalidOperationException"> /// <paramref name="editing"/> is <c>true</c>, and <see cref="ApplicationInfo.IsEditor"/> is /// <c>false</c>.</exception> /// <remarks> /// The data of the specified <see cref="OverlayImage"/> may be changed in the dialog, as /// indicated by the value of the <see cref="DataChanged"/> property.</remarks> public ChangeOverlay(bool editing) { if (editing) { ApplicationInfo.CheckEditor(); this._overlay = ApplicationOptions.Instance.Editor.Overlay; } else { this._overlay = MasterSection.Instance.Areas.Overlay; } // copy original data for user cancellation this._originalOverlay = (OverlayImage)this._overlay.Clone(); this._editing = editing; InitializeComponent(); // set maximum ranges for image coordinates LeftUpDown.Minimum = Int32.MinValue; LeftUpDown.Maximum = Int32.MaxValue; TopUpDown.Minimum = Int32.MinValue; TopUpDown.Maximum = Int32.MaxValue; WidthUpDown.Minimum = 1; WidthUpDown.Maximum = Int32.MaxValue; HeightUpDown.Minimum = 1; HeightUpDown.Maximum = Int32.MaxValue; // show current map dimensions at 100% scale var mapBounds = MapViewManager.Instance.MapGrid.DisplayBounds; MapWidthInfo.Text = mapBounds.Width.ToString("N0", ApplicationInfo.Culture); MapHeightInfo.Text = mapBounds.Height.ToString("N0", ApplicationInfo.Culture); BorderWidthInfo.Text = MapView.MapBorder.X.ToString("N0", ApplicationInfo.Culture); BorderHeightInfo.Text = MapView.MapBorder.Y.ToString("N0", ApplicationInfo.Culture); // initialize size if at default values if (this._overlay.Bounds.Width == 1 && this._overlay.Bounds.Height == 1) { this._overlay.Bounds = new RectI( this._overlay.Bounds.Left, this._overlay.Bounds.Top, Fortran.NInt(mapBounds.Width), Fortran.NInt(mapBounds.Height)); } // show current overlay data ShowImagePath(); ShowImageSize(); AspectToggle.IsChecked = this._overlay.PreserveAspectRatio; LeftUpDown.Value = this._overlay.Bounds.Left; TopUpDown.Value = this._overlay.Bounds.Top; WidthUpDown.Value = this._overlay.Bounds.Width; HeightUpDown.Value = this._overlay.Bounds.Height; // construction completed this._initialized = true; }
/// <summary> /// Determines the index of the edge or vertex opposite to the edge or vertex with the /// specified index.</summary> /// <param name="index"> /// The zero-based index of an edge or vertex. This value is taken <see /// cref="Fortran.Modulo"/> the current <see cref="Connectivity"/>, and may therefore be /// negative or greater than the maximum index.</param> /// <returns> /// The zero-based index of the edge or vertex opposite to the specified <paramref /// name="index"/>. This value is always less than <see cref="Connectivity"/>.</returns> /// <exception cref="PropertyValueException"> /// <see cref="Connectivity"/> is not divisible by two. Opposing indices only exist if the /// total number of indices is even.</exception> /// <remarks> /// <b>OpposingIndex</b> should use the same index sequence as the <see /// cref="AngleToIndex"/> and <see cref="IndexToAngle"/> methods.</remarks> public int OpposingIndex(int index) { if (Connectivity % 2 != 0) { ThrowHelper.ThrowPropertyValueExceptionWithFormat( "Connectivity", Connectivity, Strings.PropertyNotDivisible, 2); } return(Fortran.Modulo(index + Connectivity / 2, Connectivity)); }
private void OnSave(object sender, RoutedEventArgs args) { args.Handled = true; // show preview and wait for input SaveGridDialog dialog = new SaveGridDialog() { Owner = this }; dialog.VisualHost.VisualChild = CreateVisual(new PointD()); if (dialog.ShowDialog() != true) { return; } // ask user for PNG file name string file = GetSaveFile(); if (String.IsNullOrEmpty(file)) { return; } // grow by (1,1) to ensure all lines are fully visible SizeD size = Grid.DisplayBounds.Size; int width = Fortran.Ceiling(size.Width + 1), height = Fortran.Ceiling(size.Height + 1); // render grid to standard ARGB bitmap RenderTargetBitmap bitmap = new RenderTargetBitmap( width, height, 96, 96, PixelFormats.Pbgra32); bitmap.Render(CreateVisual(new PointD())); bitmap.Freeze(); try { // encode bitmap as PNG file PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Interlace = PngInterlaceOption.Off; encoder.Frames.Add(BitmapFrame.Create(bitmap)); using (FileStream stream = new FileStream(file, FileMode.Create)) encoder.Save(stream); } catch (Exception e) { string message = String.Format( "An error occurred while attempting\n" + "to save the generated bitmap.\n\n{0}", e.Message); MessageBox.Show(this, message, "Save Grid Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// Converts the specified central angle to the index of the corresponding edge or vertex. /// </summary> /// <param name="angle"> /// The central angle to convert, in degrees. This value is taken <see /// cref="Fortran.Modulo"/> 360 degrees, and may therefore be outside the interval [0, 360). /// </param> /// <returns> /// The zero-based index of the edge or vertex at the specified <paramref name="angle"/>. /// </returns> /// <remarks><para> /// The specified <paramref name="angle"/> is measured from the center of the <see /// cref="RegularPolygon"/>, and increases clockwise from the right-hand side of the x-axis. /// </para><para> /// If <see cref="VertexNeighbors"/> is <c>false</c>, the returned index enumerates all /// edges in clockwise direction. Counting starts at the topmost edge if <see /// cref="HasTopIndex"/> is <c>true</c>, and with the edge to the right of the topmost /// vertex otherwise. /// </para><para> /// If <see cref="VertexNeighbors"/> is <c>true</c>, the returned index enumerates all edges /// and vertices in an alternating sequence. Counting starts with the topmost edge for <see /// cref="PolygonOrientation.OnEdge"/> orientation and with the topmost vertex otherwise, /// continuing clockwise. /// </para><para> /// Valid indices range from zero to <see cref="Connectivity"/> less one. The 360 degrees of /// a full rotation around the central point are evenly divided among this range so that /// each index corresponds to an equal arc. If <see cref="VertexNeighbors"/> is <c>true</c>, /// the arcs that are mapped to edge indices cover only the central half of each edge. The /// arcs covering the outer parts are mapped to vertex indices instead.</para></remarks> public int AngleToIndex(double angle) { double segment = 360.0 / Connectivity; if (HasTopIndex) { angle += segment / 2.0; } angle = Fortran.Modulo(angle + 90.0, 360.0); return((int)(angle / segment)); }
/// <summary> /// Converts the specified index of an edge or vertex to the corresponding central angle. /// </summary> /// <param name="index"> /// The zero-based index of an edge or vertex. This value is taken <see /// cref="Fortran.Modulo"/> the current <see cref="Connectivity"/>, and may therefore be /// negative or greater than the maximum index.</param> /// <returns> /// The central angle, in degrees, of the edge or vertex with the specified <paramref /// name="index"/>. This value is always in the interval [0, 360).</returns> /// <remarks><para> /// If <see cref="VertexNeighbors"/> is <c>false</c>, the specified <paramref name="index"/> /// enumerates all edges in clockwise direction. Counting starts at the topmost edge if <see /// cref="HasTopIndex"/> is <c>true</c>, and with the edge to the right of the topmost /// vertex otherwise. /// </para><para> /// If <see cref="VertexNeighbors"/> is <c>true</c>, the specified <paramref name="index"/> /// enumerates all edges and vertices in an alternating sequence. Counting starts with the /// topmost edge for <see cref="PolygonOrientation.OnEdge"/> orientation and with the /// topmost vertex otherwise, continuing clockwise. /// </para><para> /// The returned angle is measured from the center of the <see cref="RegularPolygon"/>, and /// increases clockwise from the right-hand side of the x-axis. /// </para><para> /// Valid indices range from zero to <see cref="Connectivity"/> less one. The angle /// associated with each index is the angle from the central point to a vertex or to the /// middle of an edge, respectively.</para></remarks> public double IndexToAngle(int index) { double segment = 360.0 / Connectivity; double angle = Fortran.Modulo(index, Connectivity) * segment; if (!HasTopIndex) { angle += segment / 2.0; } return(Fortran.Modulo(angle - 90.0, 360.0)); }
/// <summary> /// Normalizes the specified angle, in degrees, to the interval [0, 360) after rounding to /// the nearest <see cref="Int32"/> number.</summary> /// <param name="degrees"> /// The angle to normalize, in degrees.</param> /// <returns> /// The specified <paramref name="degrees"/> rounded to the nearest <see cref="Int32"/> /// number and normalized to the half-open interval [0, 360).</returns> /// <remarks> /// <b>NormalizeRoundedDegrees</b> uses <see cref="Fortran.NInt"/> to round the specified /// <paramref name="degrees"/> before normalization. The result is guaranteed to be an <see /// cref="Int32"/> value between 0 and 359.</remarks> public static int NormalizeRoundedDegrees(double degrees) { int angle = Fortran.NInt(degrees); angle %= 360; if (angle < 0) { angle += 360; } return(angle); }
/// <summary> /// Handles the <see cref="NumericUpDown.ValueChanged"/> event for the "Left", "Top", /// "Width", and "Height" <see cref="NumericUpDown"/> controls.</summary> /// <param name="sender"> /// The <see cref="NumericUpDown"/> control sending the event.</param> /// <param name="args"> /// An <see cref="EventArgs"/> object containing event data.</param> /// <remarks><para> /// <b>OnBoundsChanged</b> checks if the bounds specified by the "Coordinates" controls are /// actually different from the current <see cref="OverlayImage.Bounds"/> of the edited <see /// cref="OverlayImage"/>. (This may not be case for programmatic changes.) /// </para><para> /// If so, <b>OnBoundsChanged</b> updates the <see cref="OverlayImage"/> and the default /// <see cref="AreasTabContent.MapView"/> to reflect the new bounds, and sets the <see /// cref="DataChanged"/> flag. /// </para><para> /// If the "Preserve Original Aspect Ratio" option is enabled, <b>OnBoundsChanged</b> also /// adjusts the height of the <see cref="OverlayImage"/> if its width was changed, and vice /// versa, to preserve its original <see cref="OverlayImage.AspectRatio"/>.</para></remarks> private void OnBoundsChanged(object sender, EventArgs args) { if (this._ignoreEvents || !this._initialized) { return; } // retrieve bounds from numeric controls RectI bounds = new RectI( (int)LeftUpDown.Value, (int)TopUpDown.Value, (int)WidthUpDown.Value, (int)HeightUpDown.Value); // update overlay only if bounds have changed if (this._overlay.Bounds != bounds) { if (AspectToggle.IsChecked == true) { bool widthChanged = (sender == WidthUpDown.HostedControl); bool heightChanged = (sender == HeightUpDown.HostedControl); // adjust width or height to preserve aspect ratio if (widthChanged || heightChanged) { double ratio = this._overlay.AspectRatio; if (ratio > 0.0) { this._ignoreEvents = true; int width = bounds.Width, height = bounds.Height; if (widthChanged) { height = Fortran.NInt(width / ratio); HeightUpDown.Value = height; } else { Debug.Assert(heightChanged); width = Fortran.NInt(height * ratio); WidthUpDown.Value = width; } bounds = new RectI(bounds.Left, bounds.Top, width, height); this._ignoreEvents = false; } } } // broadcast data changes this._overlay.Bounds = bounds; AreasTabContent.MapView.ShowOverlay(this, this._editing); DataChanged = true; } }
private PointI GetBitmapPosition(MouseEventArgs args) { // get rounded position relative to bitmap Point cursor = args.GetPosition(BitmapImage); int x = Fortran.NInt(cursor.X), y = Fortran.NInt(cursor.Y); // check for valid position within bitmap if (x < 0 || y < 0 || x >= PaintBuffer.Size.Width || y >= PaintBuffer.Size.Height) { return(new PointI(-1, -1)); } return(new PointI(x, y)); }
/// <summary> /// Handles the <see cref="RangeBase.ValueChanged"/> event for the "Image" <see /// cref="ScrollBar"/>.</summary> /// <param name="sender"> /// The <see cref="Object"/> where the event handler is attached.</param> /// <param name="args"> /// A <see cref="RoutedPropertyChangedEventArgs{Double}"/> object containing event data. /// </param> /// <remarks> /// <b>OnFrameChanged</b> updates the "Image" group box with the selected image frame of the /// selected item in the "Entity Class" list view, if any.</remarks> private void OnFrameChanged(object sender, RoutedPropertyChangedEventArgs <Double> args) { // retrieve selected entity class, if any EntityClass entityClass = EntityList.SelectedItem as EntityClass; if (entityClass == null) { return; } // show selected image frame for entity class int frame = Fortran.NInt(FrameScrollBar.Value); ShowFrame(entityClass, frame); }
IEnumerator GetBestView(string atomsName) { Atoms atoms; if (atomsDictionary.TryGetValue(atomsName, out atoms)) { if (atoms == null) { Debug.LogErrorFormat("Could not focus on atoms ({0}) - object is null", atomsName); } else { int c; int size = atoms.size; double fov = activeCamera.fieldOfView * Mathf.Deg2Rad; double fill_amount = 0.9f; double min_distance = 10f; double[] positions = new double[size * 3]; double[] new_camera_position = new double[3]; for (int atomNum = 0; atomNum < atoms.size; atomNum++) { for (c = 0; c < 3; c++) { positions[atomNum * 3 + c] = atoms[atomNum].p[c]; } } Fortran.getBestCameraView(positions, ref size, new_camera_position, ref fov, ref fill_amount, ref min_distance); activeCamera.transform.position = new Vector3((float)new_camera_position[0], (float)new_camera_position[1], (float)new_camera_position[2]); } } else { Debug.LogErrorFormat("Atoms ({0}) are not in Atoms Dictionary", atomsName); } yield return(null); }
/// <summary> /// Ensures that the <see cref="PaintBuffer"/> covers the specified minimum size.</summary> /// <param name="required"> /// The new minimum size, in device-independent pixels, for the <see cref="PaintBuffer"/>. /// </param> /// <returns> /// <c>true</c> if the <see cref="PaintBuffer"/> must be cleared by the caller; otherwise, /// <c>false</c>.</returns> /// <remarks> /// To avoid frequent buffer reallocations, <b>EnsureBufferSize</b> grows the <see /// cref="PaintBuffer"/> to cover twice its current area or to the specified <paramref /// name="required"/> size, whichever is bigger. However, <b>EnsureBufferSize</b> will not /// grow the <see cref="PaintBuffer"/> beyond the device-independent size of the current /// virtual screen, unless the <paramref name="required"/> size is greater.</remarks> private bool EnsureBufferSize(SizeI required) { int width, height; SizeI estimate = required; if (PaintBuffer != null) { width = PaintBuffer.PixelWidth; height = PaintBuffer.PixelHeight; // quit if existing buffer is large enough if (width >= required.Width && height >= required.Height) { return(true); } // new estimate: double current buffer area estimate = new SizeD(width * 1.4, height * 1.4).Round(); } // default to virtual screen size SizeI screen = new SizeI( Fortran.Ceiling(SystemParameters.VirtualScreenWidth), Fortran.Ceiling(SystemParameters.VirtualScreenHeight)); SizeI minimum = new SizeI( Math.Min(screen.Width, estimate.Width), Math.Min(screen.Height, estimate.Height)); // choose maximum of screen size or required size width = Math.Max(minimum.Width, required.Width); height = Math.Max(minimum.Height, required.Height); // reallocate buffer with new size PaintBuffer = new WriteableBitmap(width, height, 96, 96, PixelFormats.Pbgra32, null); return(false); }
/// <summary> /// Creates a <see cref="PointI"/> from the specified polar coordinates.</summary> /// <param name="length"> /// The distance from the origin to the <see cref="PointI"/>.</param> /// <param name="angle"> /// The polar angle, in radians, of the <see cref="PointI"/>.</param> /// <returns> /// A <see cref="PointI"/> whose <see cref="Length"/> and <see cref="Angle"/> equal the /// specified <paramref name="length"/> and <paramref name="angle"/>.</returns> /// <remarks><para> /// <b>FromPolar</b> returns <see cref="Empty"/> if the specified <paramref name="length"/> /// equals zero, and inverts the signs of the <see cref="X"/> and <see cref="Y"/> /// coordinates if <paramref name="length"/> is less than zero. /// </para><para> /// The calculated <see cref="X"/> and <see cref="Y"/> coordinates are converted to the /// nearest <see cref="Int32"/> values using <see cref="Fortran.NInt"/> rounding. The /// resulting <see cref="Length"/> and <see cref="Angle"/> may differ accordingly from the /// specified <paramref name="length"/> and <paramref name="angle"/>.</para></remarks> public static PointI FromPolar(double length, double angle) { return(new PointI( Fortran.NInt(length * Math.Cos(angle)), Fortran.NInt(length * Math.Sin(angle)))); }
/// <summary> /// Converts the <see cref="LineD"/> to a <see cref="LineI"/> by rounding coordinates to the /// nearest <see cref="Int32"/> values.</summary> /// <returns> /// A <see cref="LineI"/> instance whose <see cref="LineI.Start"/> and <see /// cref="LineI.End"/> properties equal the corresponding properties of the <see /// cref="LineD"/>, rounded to the nearest <see cref="Int32"/> values.</returns> /// <remarks> /// The <see cref="Double"/> coordinates of the <see cref="LineD"/> are converted to <see /// cref="Int32"/> coordinates using <see cref="Fortran.NInt"/> rounding.</remarks> public LineI Round() { return(new LineI( Fortran.NInt(Start.X), Fortran.NInt(Start.Y), Fortran.NInt(End.X), Fortran.NInt(End.Y))); }
/// <summary> /// Draws the specified image frame to the specified <see cref="WriteableBitmap"/>. /// </summary> /// <param name="targetBitmap"> /// The <see cref="WriteableBitmap"/> for the drawing.</param> /// <param name="target"> /// The region within <paramref name="targetBitmap"/> on which the copied image frame is /// centered.</param> /// <param name="frameBitmap"> /// A <see cref="WriteableBitmap"/> containing exactly the image frame to copy.</param> /// <param name="scalingX"> /// An <see cref="ImageScaling"/> value indicating the horizontal scaling of the <paramref /// name="frameBitmap"/> to fit the specified <paramref name="target"/> region.</param> /// <param name="scalingY"> /// An <see cref="ImageScaling"/> value indicating the vertical scaling of the <paramref /// name="frameBitmap"/> fit the specified <paramref name="target"/> region.</param> /// <param name="offset"> /// An optional pixel offset that is added to the centered location within the <paramref /// name="target"/> region.</param> /// <param name="scalingVector"> /// An optional scaling vector whose negative components indicate the specified <paramref /// name="frameBitmap"/> should be mirrored along the corresponding axis. Specify zero or /// positive components for no mirroring.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="targetBitmap"/> or <paramref name="frameBitmap"/> is a null reference. /// </exception> /// <exception cref="InvalidEnumArgumentException"> /// <paramref name="scalingX"/> or <paramref name="scalingY"/> equals <see /// cref="ImageScaling.Stretch"/>.</exception> /// <remarks> /// <b>DrawFrameCore</b> is called by <see cref="DrawFrame"/> when drawing to a <see /// cref="WriteableBitmap"/> without <see cref="ImageScaling.Stretch"/> scaling.</remarks> private static void DrawFrameCore(WriteableBitmap targetBitmap, RectI target, WriteableBitmap frameBitmap, ImageScaling scalingX, ImageScaling scalingY, PointI offset, PointI scalingVector) { if (targetBitmap == null) { ThrowHelper.ThrowArgumentNullException("targetBitmap"); } if (frameBitmap == null) { ThrowHelper.ThrowArgumentNullException("frameBitmap"); } // compute coordinates of centered & offset frame SizeI source = new SizeI(frameBitmap.PixelWidth, frameBitmap.PixelHeight); int x = Fortran.NInt(target.X + offset.X + (target.Width - source.Width) / 2.0); int y = Fortran.NInt(target.Y + offset.Y + (target.Height - source.Height) / 2.0); int endX = x + source.Width, endY = y + source.Height; // adjust horizontal coordinates for desired scaling switch (scalingX) { case ImageScaling.Repeat: while (x > target.X) { x -= source.Width; } endX = target.Right; break; case ImageScaling.Stretch: ThrowHelper.ThrowInvalidEnumArgumentException( "scalingX", (int)scalingX, typeof(ImageScaling)); break; } // adjust vertical coordinates for desired scaling switch (scalingY) { case ImageScaling.Repeat: while (y > target.Y) { y -= source.Height; } endY = target.Bottom; break; case ImageScaling.Stretch: ThrowHelper.ThrowInvalidEnumArgumentException( "scalingY", (int)scalingY, typeof(ImageScaling)); break; } // check scaling vector for mirroring bool mirrorX = (scalingVector.X < 0); bool mirrorY = (scalingVector.Y < 0); // repeatedly copy frame to fill target bounds for (int dx = x; dx < endX; dx += source.Width) { for (int dy = y; dy < endY; dy += source.Height) { // adjust for obscured upper & left edges int sourceX = 0, sourceY = 0, targetX = 0, targetY = 0; if (dx < 0) { sourceX = -dx; } else { targetX = dx; } if (dy < 0) { sourceY = -dy; } else { targetY = dy; } // adjust for obscured lower & right edges int width = Math.Min(source.Width - sourceX, target.Right - targetX); int height = Math.Min(source.Height - sourceY, target.Bottom - targetY); if (width <= 0 || height <= 0) { continue; } // call mirroring overload only if necessary RectI bounds = new RectI(sourceX, sourceY, width, height); if (mirrorX || mirrorY) { targetBitmap.Read(targetX, targetY, frameBitmap, bounds, mirrorX, mirrorY); } else { targetBitmap.Read(targetX, targetY, frameBitmap, bounds); } } } }
/// <summary> /// Renders the visual content of the <see cref="MapViewRenderer"/>.</summary> /// <param name="context"> /// The <see cref="DrawingContext"/> for the rendering.</param> /// <remarks><para> /// <b>OnRender</b> calls the base class implementation of <see cref="UIElement.OnRender"/>, /// and then immediately returns if the associated <see cref="MapView"/> has not been fully /// initialized yet, or already been disposed of. /// </para><para> /// Otherwise, <b>OnRender</b> redraws the current <see cref="MapViewControl.Viewport"/>. /// The <see cref="Graphics.MapView.Extent"/> of the associated <see cref="MapView"/> /// outside the current <see cref="MapViewControl.Viewport"/> remains empty. /// </para></remarks> protected override void OnRender(DrawingContext context) { base.OnRender(context); if (MapView.Catalog == null || MapView.IsDisposed) { return; } // check if there is anything to render Rect viewRegion = Control.Viewport; if (viewRegion.Width == 0 || viewRegion.Height == 0) { return; } // distance from center point to upper-left corner double centerX = MapView.TileWidth / 2.0; double centerY = MapView.TileHeight / 2.0; // compute sites covered by viewport RectD region = viewRegion.ToRectD(); RectI intRegion = region.Circumscribe(); RectI siteRegion = MapView.ViewToSite(region); // resize & clear paint buffer bool mustClear = EnsureBufferSize(intRegion.Size); PaintBuffer.Lock(); if (mustClear) { PaintBuffer.Clear(); } // cache performance options this._bitmapGrid = ApplicationOptions.Instance.View.BitmapGrid; this._opaqueImages = ApplicationOptions.Instance.View.OpaqueImages; // draw entities of all sites within region for (int x = siteRegion.Left; x < siteRegion.Right; x++) { for (int y = siteRegion.Top; y < siteRegion.Bottom; y++) { Site site = MapView.WorldState.Sites[x, y]; // compute upper-left corner of bitmap tile PointD display = MapView.SiteToView(site.Location); PointI pixel = new PointI( Fortran.NInt(display.X - centerX), Fortran.NInt(display.Y - centerY)); // draw entities in current site DrawEntities(pixel, intRegion, site); } } // copy paint buffer to viewport PaintBuffer.Unlock(); context.DrawImage(PaintBuffer, new Rect(region.Left, region.Top, PaintBuffer.Width, PaintBuffer.Height)); // draw optional decoration on all sites DrawDecoration(context, siteRegion); }
/// <summary> /// Converts the <see cref="PointF"/> to a <see cref="PointI"/> by rounding coordinates to /// the nearest <see cref="Int32"/> values.</summary> /// <returns> /// A <see cref="PointI"/> instance whose <see cref="PointI.X"/> and <see cref="PointI.Y"/> /// properties equal the corresponding properties of the <see cref="PointF"/>, rounded to /// the nearest <see cref="Int32"/> values.</returns> /// <remarks> /// The <see cref="Single"/> coordinates of the <see cref="PointF"/> are converted to <see /// cref="Int32"/> coordinates using <see cref="Fortran.NInt"/> rounding.</remarks> public PointI Round() { return(new PointI(Fortran.NInt(X), Fortran.NInt(Y))); }
// Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Q)) { Fortran.deallocate_all(); main.ClearQueue(); #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #else Application.Quit(); #endif } //Handle key presses if (Input.GetKeyDown(KeyCode.Escape)) { if (activeAtoms) { activeAtoms.ClearSelection(); } } //Keep track of mouse position here screenMousePosition = Input.mousePosition; worldMousePosition = activeCamera.ScreenToWorldPoint(new Vector3(screenMousePosition.x, screenMousePosition.y, activeCamera.nearClipPlane)); leftClickDown = Input.GetAxis("Left Click"); rightClickDown = Input.GetAxis("Right Click"); //Handle 6-axis motion mouseX = Input.GetAxis("Mouse X"); mouseY = Input.GetAxis("Mouse Y"); rotation.x = leftClickDown * mouseY; rotation.y = leftClickDown * mouseX; rotation.z = rightClickDown * mouseX; activeCamera.transform.localPosition += Input.GetAxis("Pan") * activeCamera.transform.right + Input.GetAxis("Vertical") * activeCamera.transform.up + Input.GetAxis("Forward") * activeCamera.transform.forward; activeCamera.transform.Rotate(rotation); //Differentiate between click and drag clicked = false; if (leftClickDown == 0) { clicked = (oldLeftClickDown != 0 && !dragged); dragged = false; } else { if (!dragged) { dragged = (mouseX * mouseX + mouseY * mouseY > dragThreshold); } } oldLeftClickDown = leftClickDown; //Get hovered atom if (activeAtoms != null) { frameNum++; if (frameNum == framesUntilRefresh) { frameNum = 0; } else { ray = activeCamera.ScreenPointToRay(screenMousePosition); //MOVE ALL HOVER HALOES TO ATOMS RaycastHit[] hitInfos; hitInfos = Physics.RaycastAll(ray); numHits = hitInfos.Length; if (numHits > 0) { closestAtom = null; hitAtom = null; closestAngle = 90f; for (int i = 0; i < numHits; i++) { hitInfo = hitInfos [i]; mouseCollider = hitInfo.collider.gameObject.GetComponent <MouseCollider> (); if (mouseCollider == null) { continue; } hitAtom = mouseCollider.parent; if (hitAtom.parent != activeAtoms) { continue; } //Make sure the atom that's closest to the cursor is selected angle = Vector3.Angle(ray.direction, hitAtom.transform.position - activeCamera.transform.position); if (angle > closestAngle) { continue; } closestAtom = hitAtom; closestAtomIndex = hitAtom.index; closestAngle = angle; } if (closestAtom != null) { if (closestAtomIndex != activeAtoms.hoveredAtom) { activeAtoms.hoveredAtom = closestAtomIndex; } if (clicked) { activeAtoms.ToggleSelect(closestAtomIndex); } } } else { if (hitAtom != null) { activeAtoms.hoveredAtom = -1; } } } } //if (Physics.Raycast (ray, out hitInfo)) { // MouseCollider hoveredAtomCollider = hitInfo.collider.gameObject.GetComponent<MouseCollider> (); // // if (hoveredAtomCollider != null) { // hoveredAtomCollider.parent.parent.hoveredAtom = hoveredAtomCollider.parent.index; // } //} }
public IEnumerator AMBEROpt(int steps, int updateAfterSteps = 5) { _busy++; int status = 0; int c = 0; int numAtoms = size; positions = new double[numAtoms * 3]; for (int atomNum = 0; atomNum < numAtoms; atomNum++) { for (c = 0; c < 3; c++) { positions[3 * atomNum + c] = atoms[atomNum].p[c]; } } Fortran.allocate_atom_arrays(ref numAtoms); IEnumerator iEnumerator; iEnumerator = InitialiseParameters(); while (iEnumerator.MoveNext()) { } yield return(null); double[] stretchesEnergy = new double[2]; double[] bendsEnergy = new double[2]; double[] torsionsEnergy = new double[2]; double[] vdwsEnergy = new double[2]; double[] coulombicEnergy = new double[2]; string logPath = "/Users/tristanmackenzie/Unity/ONIOM/Assets/Plugins/out.log"; System.IO.File.Delete(logPath); double convergence_threshold = 0.00001; int precision = 3; int iprint = 0; int matrix_corrections = 17; int stepNum = 0; Vector3 vPosition = new Vector3(); while (stepNum < steps) { writeArray(positions, logPath); Fortran.lbfgs_optimise(positions, ref updateAfterSteps, stretchesEnergy, bendsEnergy, torsionsEnergy, vdwsEnergy, coulombicEnergy, ref convergence_threshold, ref precision, ref iprint, ref matrix_corrections, ref status ); writeArray(positions, logPath); Fortran.CheckStatus(status); allStretchesEnergy = stretchesEnergy[0]; allBendsEnergy = bendsEnergy[0]; allTorsionsEnergy = torsionsEnergy[0]; allVdwsEnergy = vdwsEnergy[0]; allCoulombicEnergy = coulombicEnergy[0]; amberEnergy = allStretchesEnergy + allBendsEnergy + allTorsionsEnergy + allVdwsEnergy + allCoulombicEnergy; totalEnergy = amberEnergy + kineticEnergy; stepNum += updateAfterSteps; for (int atomNum = 0; atomNum < numAtoms; atomNum++) { for (c = 0; c < 3; c++) { vPosition[c] = (float)positions[3 * atomNum + c]; } atoms[atomNum].transform.localPosition = vPosition; } yield return(null); } _busy--; yield return(null); }
public IEnumerator MDVerlet(int steps, int updateAfterSteps = 5) { _busy++; int status = 0; int c = 0; int numAtoms = size; positions = new double[numAtoms * 3]; for (int atomNum = 0; atomNum < numAtoms; atomNum++) { for (c = 0; c < 3; c++) { positions[3 * atomNum + c] = atoms[atomNum].p[c]; } } Fortran.allocate_atom_arrays(ref numAtoms); IEnumerator iEnumerator; iEnumerator = InitialiseParameters(); while (iEnumerator.MoveNext()) { } yield return(null); double[] stretchesEnergy = new double[2]; double[] bendsEnergy = new double[2]; double[] torsionsEnergy = new double[2]; double[] vdwsEnergy = new double[2]; double[] coulombicEnergy = new double[2]; double mdTimeStep = atoms.globalSettings.mdTimeStep; double mdDampingFactor = atoms.globalSettings.mdDampingFactor; string logPath = "/Users/tristanmackenzie/Unity/ONIOM/Assets/Plugins/out.log"; System.IO.File.Delete(logPath); //Run MD int stepNum = 0; Vector3 vPosition = new Vector3(); while (stepNum < steps) { writeArray(positions, logPath); Fortran.md_verlet(positions, ref updateAfterSteps, ref mdTimeStep, ref mdDampingFactor, stretchesEnergy, bendsEnergy, torsionsEnergy, vdwsEnergy, coulombicEnergy, ref kineticEnergy, ref rmsForces, ref status); writeArray(positions, logPath); Fortran.CheckStatus(status); allStretchesEnergy = stretchesEnergy[0]; allBendsEnergy = bendsEnergy[0]; allTorsionsEnergy = torsionsEnergy[0]; allVdwsEnergy = vdwsEnergy[0]; allCoulombicEnergy = coulombicEnergy[0]; amberEnergy = allStretchesEnergy + allBendsEnergy + allTorsionsEnergy + allVdwsEnergy + allCoulombicEnergy; totalEnergy = amberEnergy + kineticEnergy; stepNum += updateAfterSteps; for (int atomNum = 0; atomNum < numAtoms; atomNum++) { for (c = 0; c < 3; c++) { vPosition[c] = (float)positions[3 * atomNum + c]; } atoms[atomNum].transform.localPosition = vPosition; } yield return(null); } _busy--; yield return(null); }
/// <summary> /// Draws a set of line graphs connecting the specified point collections to the /// specified <see cref="DrawingContext"/>.</summary> /// <param name="context"> /// The <see cref="DrawingContext"/> for the rendering.</param> /// <param name="bounds"> /// The region within <paramref name="context"/>, in device-independent pixels, where to /// draw.</param> /// <param name="colors"> /// An <see cref="Array"/> containing the <see cref="Color"/> for each graph.</param> /// <param name="points"> /// An <see cref="Array"/> containing the <see cref="Point"/> collections that /// constitute each graph.</param> /// <param name="typeface"> /// The <see cref="Typeface"/> to use for axis labels.</param> /// <exception cref="ArgumentException"> /// <paramref name="colors"/> and <paramref name="points"/> contain a different number /// of elements.</exception> /// <exception cref="ArgumentNullException"> /// <paramref name="context"/>, <paramref name="colors"/>, <paramref name="points"/>, or /// <paramref name="typeface"/> is a null reference.</exception> /// <remarks> /// <b>DrawGraph</b> does nothing if the specified <paramref name="points"/> array is /// empty, or contains only empty <see cref="Point"/> collections.</remarks> private static void DrawGraph(DrawingContext context, Rect bounds, Color[] colors, Point[][] points, Typeface typeface) { if (context == null) { ThrowHelper.ThrowArgumentNullException("context"); } if (colors == null) { ThrowHelper.ThrowArgumentNullException("colors"); } if (points == null) { ThrowHelper.ThrowArgumentNullException("values"); } if (typeface == null) { ThrowHelper.ThrowArgumentNullException("typeface"); } if (colors.Length != points.Length) { ThrowHelper.ThrowArgumentExceptionWithFormat( "colors", Tektosyne.Strings.ArgumentConflict, "points"); } // check for empty drawing region if (bounds.Width <= 0 || bounds.Height <= 0) { return; } Point minimum = new Point(Double.MaxValue, Double.MaxValue); Point maximum = new Point(Double.MinValue, Double.MinValue); // determine minimum and maximum coordinates foreach (Point[] line in points) { if (line == null) { continue; } foreach (Point point in line) { if (minimum.X > point.X) { minimum.X = point.X; } if (maximum.X < point.X) { maximum.X = point.X; } if (minimum.Y > point.Y) { minimum.Y = point.Y; } if (maximum.Y < point.Y) { maximum.Y = point.Y; } } } // check for empty point collections if (minimum.X > maximum.X || minimum.Y > maximum.Y) { return; } // ensure non-empty ranges along both axes if (minimum.X == maximum.X) { ++maximum.X; } if (minimum.Y == maximum.Y) { --minimum.Y; ++maximum.Y; } // determine horizontal and vertical scale double scaleX = bounds.Width / (maximum.X - minimum.X); double scaleY = bounds.Height / (maximum.Y - minimum.Y); // determine horizontal and vertical origin Point origin = new Point( bounds.Left - scaleX * minimum.X, bounds.Top + scaleY * maximum.Y); // create required pens Pen blackPen = new Pen(Brushes.Black, 1.0); Pen lightPen = new Pen(Brushes.LightGray, 1.0); // draw black lines of origin context.DrawLine(blackPen, new Point(origin.X, bounds.Top), new Point(origin.X, bounds.Bottom)); context.DrawLine(blackPen, new Point(bounds.Left, origin.Y), new Point(bounds.Right, origin.Y)); // calculate optimal axis divisions Point division = new Point( GetAxisDivision(maximum.X - minimum.X), GetAxisDivision(maximum.Y - minimum.Y)); // draw vertical tick lines and labels for (double tick = (maximum.X / division.X) * division.X; tick >= minimum.X; tick -= division.X) { // draw division line double x = origin.X + tick * scaleX; context.DrawLine(lightPen, new Point(x, bounds.Top), new Point(x, bounds.Bottom)); // print label left of line string tickText = tick.ToString("N0", ApplicationInfo.Culture); var text = new FormattedText(tickText, ApplicationInfo.Culture, FlowDirection.LeftToRight, typeface, 10, Brushes.Black); context.DrawText(text, new Point(x - 12, bounds.Top + 2)); } // draw horizontal tick lines and labels for (double tick = (maximum.Y / division.Y) * division.Y; tick >= minimum.Y; tick -= division.Y) { // draw division line double y = origin.Y - Fortran.NInt(tick * scaleY); context.DrawLine(lightPen, new Point(bounds.Left, y), new Point(bounds.Right, y)); // print label below line string tickText = tick.ToString("N0", ApplicationInfo.Culture); var text = new FormattedText(tickText, ApplicationInfo.Culture, FlowDirection.LeftToRight, typeface, 10, Brushes.Black); context.DrawText(text, new Point(bounds.Left + 4, y + 2)); } // draw all point collections for (int i = 0; i < points.Length; i++) { Point[] line = points[i]; if (line == null) { continue; } // draw lines from one point to the next Pen pen = new Pen(new SolidColorBrush(colors[i]), 2.0); for (int j = 0; j < line.Length - 1; j++) { Point p0 = new Point(origin.X + line[j].X * scaleX, origin.Y - line[j].Y * scaleY); Point p1 = new Point(origin.X + line[j + 1].X * scaleX, origin.Y - line[j + 1].Y * scaleY); context.DrawLine(pen, p0, p1); } } }
public void InitialiseTorsions(bool suppress = true) { DihedralConnection dihedral; Torsion torsion; DihedralConnection[] dihedrals = dihedralsDict.Values.ToArray(); List <int> torsionAtomNumList = new List <int>(); List <double> torsionVList = new List <double>(); List <double> torsionGammaList = new List <double>(); List <double> torsionPathList = new List <double>(); int numTorsions = 0; double npaths; for (int i = 0; i < dihedrals.Length; i++) { dihedral = dihedrals[i]; torsion = GetTorsionParameter(dihedral); if (torsion == null) { if (!suppress) { throw new NoParameterException(typeof(Torsion), dihedral.atom0, dihedral.atom1, dihedral.atom2, dihedral.atom3); } continue; } torsionVList.Add(torsion.v0); torsionVList.Add(torsion.v1); torsionVList.Add(torsion.v2); torsionVList.Add(torsion.v3); torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma0); torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma1); torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma2); torsionGammaList.Add(Mathf.Deg2Rad * torsion.gamma3); if (torsion.npaths > 0.0) { npaths = torsion.npaths; } else { //Determine number of paths from connectivity npaths = (double) (neighbourCount[dihedral.atom1.index] - 1) * (neighbourCount[dihedral.atom2.index] - 1) ; if (npaths <= 0.0) { throw new System.Exception(string.Format( "Error defining torsion: Atom {0} has {1} neighbours. Atom {2} has {3} neighbours", dihedral.atom1.index, neighbourCount[dihedral.atom1.index], dihedral.atom2.index, neighbourCount[dihedral.atom2.index] ) ); } } torsionPathList.Add(npaths); torsionAtomNumList.Add(dihedral.atom0.index); torsionAtomNumList.Add(dihedral.atom1.index); torsionAtomNumList.Add(dihedral.atom2.index); torsionAtomNumList.Add(dihedral.atom3.index); numTorsions++; } Fortran.set_torsions( ref numTorsions, torsionAtomNumList.ToArray(), torsionVList.ToArray(), torsionGammaList.ToArray(), torsionPathList.ToArray() ); }
/// <summary> /// Converts the <see cref="SizeF"/> to a <see cref="SizeI"/> by rounding dimensions to the /// nearest <see cref="Int32"/> values.</summary> /// <returns> /// A <see cref="SizeI"/> instance whose <see cref="SizeI.Width"/> and <see /// cref="SizeI.Height"/> properties equal the corresponding properties of the <see /// cref="SizeF"/>, rounded to the nearest <see cref="Int32"/> values.</returns> /// <remarks> /// The <see cref="Single"/> dimensions of the <see cref="SizeF"/> are converted to <see /// cref="Int32"/> dimensions using <see cref="Fortran.NInt"/> rounding.</remarks> public SizeI Round() { return(new SizeI(Fortran.NInt(Width), Fortran.NInt(Height))); }
public void InitialiseNonBonding(bool suppress = false) { int a0; int a1; int bondDistance; double amberVCutoff = parameters.nonbonding.vCutoff == 0f ? atoms.globalSettings.maxNonBondingCutoff : parameters.nonbonding.vCutoff; double amberCCutoff = parameters.nonbonding.cCutoff == 0f ? atoms.globalSettings.maxNonBondingCutoff : parameters.nonbonding.cCutoff; float vScale; float cScale; float[] vScales = parameters.nonbonding.vScales; float[] cScales = parameters.nonbonding.cScales; Dictionary <string, VdW> vdwDict = new Dictionary <string, VdW>(); foreach (VdW vdw in parameters.vdws) { vdwDict.Add(vdw.t, vdw); } VdW vdw0; VdW vdw1; Atom atom0; Atom atom1; int numNonBonding = size * (size - 1) / 2; int nonBondingIndex = 0; double[] q0q1s = new double[numNonBonding]; double[] vdwREqs = new double[numNonBonding]; double[] vdwVs = new double[numNonBonding]; int[] nonBondingAtomNums = new int[numNonBonding * 2]; for (a0 = 0; a0 < size - 1; a0++) { atom0 = atoms[a0]; if (!vdwDict.TryGetValue(atom0.amberName, out vdw0)) { if (!suppress) { throw new NoParameterException(typeof(VdW), atom0); } for (a1 = a0 + 1; a1 < size; a1++) { nonBondingAtomNums[nonBondingIndex * 2] = a0; nonBondingAtomNums[nonBondingIndex * 2 + 1] = a1; nonBondingIndex++; } continue; } for (a1 = a0 + 1; a1 < size; a1++) { atom1 = atoms[a1]; bondDistance = distanceMatrix[a0, a1]; vScale = vScales[bondDistance]; cScale = cScales[bondDistance]; nonBondingAtomNums[nonBondingIndex * 2] = a0; nonBondingAtomNums[nonBondingIndex * 2 + 1] = a1; if (vScale != 0f) { if (vdwDict.TryGetValue(atom1.amberName, out vdw1)) { q0q1s[nonBondingIndex] = cScale * atom0.partialCharge * atom0.partialCharge; vdwREqs[nonBondingIndex] = (vdw0.r + vdw1.r) * 0.5f; vdwVs[nonBondingIndex] = Mathf.Sqrt(vdw0.v * vdw1.v) * vScale; } ; } else { } nonBondingIndex++; } } Fortran.set_non_bonding( ref numNonBonding, nonBondingAtomNums, vdwVs, vdwREqs, ref amberVCutoff, q0q1s, ref parameters.dielectricConstant, ref amberCCutoff ); }