/// <summary> /// Replaces all cell values of the receiver with the values of another matrix. /// Both matrices must have the same number of Slices, Rows and Columns. /// If both matrices share the same cells (as is the case if they are views derived from the same matrix) and intersect in an ambiguous way, then replaces <i>as if</i> using an intermediate auxiliary deep copy of <i>other</i>. /// </summary> /// <param name="source">the source matrix to copy from (may be identical to the receiver).</param> /// <returns><i>this</i> (for convenience only).</returns> /// <exception cref="ArgumentException">if <i>Slices() != source.Slices() || Rows() != source.Rows() || Columns() != source.Columns()</i></exception> public override DoubleMatrix3D Assign(DoubleMatrix3D source) { // overriden for performance only if (!(source is DenseDoubleMatrix3D)) { return(base.Assign(source)); } DenseDoubleMatrix3D other = (DenseDoubleMatrix3D)source; if (other == this) { return(this); } CheckShape(other); if (HaveSharedCells(other)) { DoubleMatrix3D c = other.Copy(); if (!(c is DenseDoubleMatrix3D)) { // should not happen return(base.Assign(source)); } other = (DenseDoubleMatrix3D)c; } if (!this.IsView && !other.IsView) { // quickest Array.Copy(other.Elements, 0, this.Elements, 0, this.Elements.Length); return(this); } return(base.Assign(other)); }
/// <summary> /// 27 point stencil operation. /// Applies a function to a moving <i>3 x 3 x 3</i> window. /// </summary> /// <param name="A">the matrix to operate on.</param> /// <param name="function">the function to be applied to each window.</param> /// <param name="maxIterations">the maximum number of times the stencil shall be applied to the matrixd; Should be a multiple of 2 because two iterations are always done in one atomic step.</param> /// <param name="hasConverged"> /// condition; will return before maxIterations are done when <i>hasConverged.apply(A)==true</i>. /// Set this parameter to <i>null</i> to indicate that no convergence checks shall be made. /// </param> /// <param name="convergenceIterations"> /// the number of iterations to pass between each convergence check. /// (Since a convergence may be expensive, you may want to do it only every 2,4 or 8 iterationsd) /// </param> /// <returns>the number of iterations actually executedd </returns> public static int Stencil27(DoubleMatrix3D A, Cern.Colt.Function.Double27Function function, int maxIterations, DoubleMatrix3DProcedure hasConverged, int convergenceIterations) { DoubleMatrix3D B = A.Copy(); if (convergenceIterations <= 1) { convergenceIterations = 2; } if (convergenceIterations % 2 != 0) { convergenceIterations++; // odd -> make it even } int i = 0; while (i < maxIterations) { // do two steps at a time for efficiency A.ZAssign27Neighbors(B, function); B.ZAssign27Neighbors(A, function); i = i + 2; if (i % convergenceIterations == 0 && hasConverged != null) { if (hasConverged(A)) { return(i); } } } return(i); }
/// <summary> /// Returns whether all cells of the given matrix <i>A</i> are equal to the given value. /// The result is <i>true</i> if and only if <i>A != null</i> and /// <i>! (System.Math.Abs(value - A[slice,row,col]) > Tolerance)</i> holds for all coordinates. /// @param A the first matrix to compare. /// @param value the value to compare against. /// @return <i>true</i> if the matrix is equal to the value; /// <i>false</i> otherwise. /// </summary> public Boolean Equals(DoubleMatrix3D A, double value) { if (A == null) { return(false); } int rows = A.Rows; int columns = A.Columns; double epsilon = Tolerance; for (int slice = A.Slices; --slice >= 0;) { for (int row = rows; --row >= 0;) { for (int column = columns; --column >= 0;) { //if (!(A.getQuick(slice,row,column) == value)) return false; //if (System.Math.Abs(value - A.getQuick(slice,row,column)) > epsilon) return false; double x = A[slice, row, column]; double diff = System.Math.Abs(value - x); if ((Double.IsNaN(diff)) && ((Double.IsNaN(value) && Double.IsNaN(x)) || value == x)) { diff = 0; } if (!(diff <= epsilon)) { return(false); } } } } return(true); }
public static double GetPhiX(DoubleMatrix3D u, DoubleMatrix3D v, DoubleMatrix3D w, int i, int j, int k, NumericalParameters numPar) { double u_x = GetDX(u, i, j, k, numPar); double v_x = GetDX(v, i, j, k, numPar); double w_x = GetDX(w, i, j, k, numPar); double u_y = GetDY(u, i, j, k, numPar); double u_z = GetDZ(u, i, j, k, numPar); return(2 * u_x * u_x + v_x * v_x + w_x * w_x + v_x * u_y + w_x * u_z); }
public static double GetPhiZ(DoubleMatrix3D u, DoubleMatrix3D v, DoubleMatrix3D w, int i, int j, int k, NumericalParameters numPar) { double u_z = GetDZ(u, i, j, k, numPar); double v_z = GetDZ(v, i, j, k, numPar); double w_z = GetDZ(w, i, j, k, numPar); double w_x = GetDX(w, i, j, k, numPar); double w_y = GetDY(w, i, j, k, numPar); return(u_z * u_z + v_z * v_z + 2 * w_z * w_z + u_z * w_x + w_y * v_z); }
/// <summary> /// Returns <i>true</i> if both matrices share common cells. /// More formally, returns <i>true</i> if <i>other != null</i> and at least one of the following conditions is met /// <ul> /// <li>the receiver is a view of the other matrix /// <li>the other matrix is a view of the receiver /// <li><i>this == other</i> /// </ul> /// </summary> protected new Boolean HaveSharedCellsRaw(DoubleMatrix3D other) { if (other is SelectedDenseDoubleMatrix3D) { SelectedDenseDoubleMatrix3D otherMatrix = (SelectedDenseDoubleMatrix3D)other; return(this.Elements == otherMatrix.Elements); } else if (other is DenseDoubleMatrix3D) { DenseDoubleMatrix3D otherMatrix = (DenseDoubleMatrix3D)other; return(this.Elements == otherMatrix.Elements); } return(false); }
/// <summary> /// Returns a string <i>s</i> such that <i>Object[] m = s</i> is a legal C# statement. /// </summary> /// <param name="matrix">the matrix to format.</param> /// <returns></returns> public String ToSourceCode(DoubleMatrix3D matrix) { Formatter copy = (Formatter)this.Clone(); String b3 = Blanks(3); String b6 = Blanks(6); copy.SetPrintShape(false); copy.SetColumnSeparator(", "); copy.SetRowSeparator("},\n" + b6 + "{"); copy.SetSliceSeparator("}\n" + b3 + "},\n" + b3 + "{\n" + b6 + "{"); String lead = "{\n" + b3 + "{\n" + b6 + "{"; String trail = "}\n" + b3 + "}\n}"; return(lead + copy.ToString(matrix) + trail); }
private static double GetDX(DoubleMatrix3D data, int i, int j, int k, NumericalParameters numPar) { if (i == 0) { return((GetValue(data, i + 1, j, k) - GetValue(data, i, j, k)) / numPar.Dx); } else if (i == numPar.Nx - 1) { return((GetValue(data, i, j, k) - GetValue(data, i - 1, j, k)) / numPar.Dx); } else { return((GetValue(data, i + 1, j, k) - GetValue(data, i - 1, j, k)) / (2 * numPar.Dx)); } }
private static double GetDZ(DoubleMatrix3D data, int i, int j, int k, NumericalParameters numPar) { if (k == 0) { return((GetValue(data, i, j, k + 1) - GetValue(data, i, j, k)) / numPar.Dz); } else if (k == numPar.Nz - 1) { return((GetValue(data, i, j, k) - GetValue(data, i, j, k - 1)) / numPar.Dz); } else { return((GetValue(data, i, j, k + 1) - GetValue(data, i, j, k - 1)) / (2 * numPar.Dz)); } }
private static double GetDY(DoubleMatrix3D data, int i, int j, int k, NumericalParameters numPar) { if (j == 0) { return((GetValue(data, i, j + 1, k) - GetValue(data, i, j, k)) / numPar.Dy); } else if (j == numPar.Ny - 1) { return((GetValue(data, i, j, k) - GetValue(data, i, j - 1, k)) / numPar.Dy); } else { return((GetValue(data, i, j + 1, k) - GetValue(data, i, j - 1, k)) / (2 * numPar.Dy)); } }
/// <summary> /// Constructs a matrix with cells having descending values. /// For debugging purposes. /// </summary> /// <param name="slices"></param> /// <param name="rows"></param> /// <param name="columns"></param> /// <returns></returns> public DoubleMatrix3D Descending(int slices, int rows, int columns) { DoubleMatrix3D matrix = Make(slices, rows, columns); int v = 0; for (int slice = slices; --slice >= 0;) { for (int row = rows; --row >= 0;) { for (int column = columns; --column >= 0;) { matrix[slice, row, column] = v++; } } } return(matrix); }
/// <summary> /// Returns a string representation of the given matrix with axis as well as rows and columns labeled. /// Pass <i>null</i> to one or more parameters to indicate that the corresponding decoration element shall not appear in the string converted matrix. /// </summary> /// <param name="matrix">The matrix to format.</param> /// <param name="sliceNames">The headers of all slices (to be put above each slice).</param> /// <param name="rowNames">The headers of all rows (to be put to the left of the matrix).</param> /// <param name="columnNames">The headers of all columns (to be put to above the matrix).</param> /// <param name="sliceAxisName">The label of the z-axis (to be put above each slice).</param> /// <param name="rowAxisName">The label of the y-axis.</param> /// <param name="columnAxisName">The label of the x-axis.</param> /// <param name="title">The overall title of the matrix to be formatted.</param> /// <returns>the matrix converted to a string.</returns> private String XToTitleString(DoubleMatrix3D matrix, String[] sliceNames, String[] rowNames, String[] columnNames, String sliceAxisName, String rowAxisName, String columnAxisName, String title) { if (matrix.Size == 0) { return("Empty matrix"); } StringBuilder buf = new StringBuilder(); for (int i = 0; i < matrix.Slices; i++) { if (i != 0) { buf.Append(sliceSeparator); } buf.Append(ToTitleString(matrix.ViewSlice(i), rowNames, columnNames, rowAxisName, columnAxisName, title + "\n" + sliceAxisName + "=" + sliceNames[i])); } return(buf.ToString()); }
/// <summary> /// Returns a string representation of the given matrix. /// </summary> /// <param name="matrix">the matrix to convert.</param> /// <returns>A string representation of the given matrix.</returns> public String ToString(DoubleMatrix3D matrix) { var buf = new StringBuilder(); Boolean oldPrintShape = this.printShape; this.printShape = false; for (int slice = 0; slice < matrix.Slices; slice++) { if (slice != 0) { buf.Append(sliceSeparator); } buf.Append(ToString((AbstractMatrix2D)matrix.ViewSlice(slice))); } this.printShape = oldPrintShape; if (printShape) { buf.Insert(0, Shape(matrix) + "\n"); } return(buf.ToString()); }
public DoubleMatrix3D Sort(DoubleMatrix3D matrix, Cern.Colt.Matrix.DoubleAlgorithms.DoubleMatrix2DComparator c) { int[] sliceIndexes = new int[matrix.Slices]; // indexes to reorder instead of matrix itself for (int i = sliceIndexes.Length; --i >= 0;) { sliceIndexes[i] = i; } DoubleMatrix2D[] views = new DoubleMatrix2D[matrix.Slices]; // precompute views for speed for (int i = views.Length; --i >= 0;) { views[i] = matrix.ViewSlice(i); } IntComparator comp = new IntComparator((a, b) => { return(c(views[a], views[b])); }); RunSort(sliceIndexes, 0, sliceIndexes.Length, comp); // view the matrix according to the reordered slice indexes // take all rows and columns in the original order return(matrix.ViewSelection(sliceIndexes, null, null)); }
public DoubleMatrix3D Sort(DoubleMatrix3D matrix, int row, int column) { if (row < 0 || row >= matrix.Rows) { throw new IndexOutOfRangeException("row=" + row + ", matrix=" + Formatter.Shape(matrix)); } if (column < 0 || column >= matrix.Columns) { throw new IndexOutOfRangeException("column=" + column + ", matrix=" + Formatter.Shape(matrix)); } int[] sliceIndexes = new int[matrix.Slices]; // indexes to reorder instead of matrix itself for (int i = sliceIndexes.Length; --i >= 0;) { sliceIndexes[i] = i; } DoubleMatrix1D sliceView = matrix.ViewRow(row).ViewColumn(column); IntComparator comp = new IntComparator((a, b) => { double av = sliceView[a]; double bv = sliceView[b]; if (Double.IsNaN(av) || Double.IsNaN(bv)) { return(CompareNaN(av, bv)); // swap NaNs to the end } return(av < bv ? -1 : (av == bv ? 0 : 1)); } ); RunSort(sliceIndexes, 0, sliceIndexes.Length, comp); // view the matrix according to the reordered slice indexes // take all rows and columns in the original order return(matrix.ViewSelection(sliceIndexes, null, null)); }
/// <summary> /// 27 neighbor stencil transformation.For efficient finite difference operations. /// Applies a function to a moving<i>3 x 3 x 3</i> window. /// Does nothing if <i>Rows() < 3 || Columns() < 3 || Slices() < 3</i>. /// <pre> /// B[k, i, j] = function.apply( /// A[k - 1, i - 1, j - 1], A[k - 1, i - 1, j], A[k - 1, i - 1, j + 1], /// A[k - 1, i, j - 1], A[k - 1, i, j], A[k - 1, i, j + 1], /// A[k - 1, i + 1, j - 1], A[k - 1, i + 1, j], A[k - 1, i + 1, j + 1], /// /// A[k, i - 1, j - 1], A[k, i - 1, j], A[k, i - 1, j + 1], /// A[k, i, j - 1], A[k, i, j], A[k, i, j + 1], /// A[k, i + 1, j - 1], A[k, i + 1, j], A[k, i + 1, j + 1], /// /// A[k + 1, i - 1, j - 1], A[k + 1, i - 1, j], A[k + 1, i - 1, j + 1], /// A[k + 1, i, j - 1], A[k + 1, i, j], A[k + 1, i, j + 1], /// A[k + 1, i + 1, j - 1], A[k + 1, i + 1, j], A[k + 1, i + 1, j + 1] /// ) /// /// x x x - - x x x - - - - /// x o x - - x o x - - - - /// x x x - - x x x..d - x x x /// - - - - - - - - - x o x /// - - - - - - - - - x x x /// </pre> /// Make sure that cells of<i>this</i> and<i> B</i> do not overlap. /// In case of overlapping views, behaviour is unspecified. /// </pre> /// <p> /// <b>Example:</b> /// <pre> /// double alpha = 0.25; /// double beta = 0.75; /// /// cern.colt.function.Double27Function f = new cern.colt.function.Double27Function() { /// public double apply( /// double a000, double a001, double a002, /// double a010, double a011, double a012, /// double a020, double a021, double a022, /// /// double a100, double a101, double a102, /// double a110, double a111, double a112, /// double a120, double a121, double a122, /// /// double a200, double a201, double a202, /// double a210, double a211, double a212, /// double a220, double a221, double a222) { /// return beta* a111 + alpha* (a000 + ..d + a222); /// } /// }; /// A.zAssign27Neighbors(B, f); /// </pre> /// </summary> /// <param name="B">the matrix to hold the results.</param> /// <param name="function">the function to be applied to the 27 cells.</param> /// <returns></returns> /// <exception cref="NullReferenceException">if <i>function==null</i>.</exception> /// <exception cref="ArgumentException">if <i>Rows() != B.Rows() || Columns() != B.Columns() || Slices() != B.Slices() </i>.</exception> public override void ZAssign27Neighbors(DoubleMatrix3D B, Cern.Colt.Function.Double27Function function) { // overridden for performance only if (!(B is DenseDoubleMatrix3D)) { base.ZAssign27Neighbors(B, function); return; } if (function == null) { throw new NullReferenceException(Cern.LocalizedResources.Instance().Exception_FuncionMustNotBeNull); } CheckShape(B); int r = Rows - 1; int c = Columns - 1; if (Rows < 3 || Columns < 3 || Slices < 3) { return; // nothing to do } DenseDoubleMatrix3D BB = (DenseDoubleMatrix3D)B; int A_ss = SliceStride; int A_rs = RowStride; int B_rs = BB.RowStride; int A_cs = ColumnStride; int B_cs = BB.ColumnStride; double[] elems = this.Elements; double[] B_elems = BB.Elements; if (elems == null || B_elems == null) { throw new NullReferenceException(); } for (int k = 1; k < Slices - 1; k++) { int A_index = Index(k, 1, 1); int B_index = BB.Index(k, 1, 1); for (int i = 1; i < r; i++) { int A002 = A_index - A_ss - A_rs - A_cs; int A012 = A002 + A_rs; int A022 = A012 + A_rs; int A102 = A002 + A_ss; int A112 = A102 + A_rs; int A122 = A112 + A_rs; int A202 = A102 + A_ss; int A212 = A202 + A_rs; int A222 = A212 + A_rs; double a000, a001, a002; double a010, a011, a012; double a020, a021, a022; double a100, a101, a102; double a110, a111, a112; double a120, a121, a122; double a200, a201, a202; double a210, a211, a212; double a220, a221, a222; a000 = elems[A002]; A002 += A_cs; a001 = elems[A002]; a010 = elems[A012]; A012 += A_cs; a011 = elems[A012]; a020 = elems[A022]; A022 += A_cs; a021 = elems[A022]; a100 = elems[A102]; A102 += A_cs; a101 = elems[A102]; a110 = elems[A112]; A112 += A_cs; a111 = elems[A112]; a120 = elems[A122]; A122 += A_cs; a121 = elems[A122]; a200 = elems[A202]; A202 += A_cs; a201 = elems[A202]; a210 = elems[A212]; A212 += A_cs; a211 = elems[A212]; a220 = elems[A222]; A222 += A_cs; a221 = elems[A222]; int B11 = B_index; for (int j = 1; j < c; j++) { // in each step 18 cells can be remembered in registers - they don't need to be reread from slow memory // in each step 9 instead of 27 cells need to be read from memory. a002 = elems[A002 += A_cs]; a012 = elems[A012 += A_cs]; a022 = elems[A022 += A_cs]; a102 = elems[A102 += A_cs]; a112 = elems[A112 += A_cs]; a122 = elems[A122 += A_cs]; a202 = elems[A202 += A_cs]; a212 = elems[A212 += A_cs]; a222 = elems[A222 += A_cs]; B_elems[B11] = function( a000, a001, a002, a010, a011, a012, a020, a021, a022, a100, a101, a102, a110, a111, a112, a120, a121, a122, a200, a201, a202, a210, a211, a212, a220, a221, a222); B11 += B_cs; // move remembered cells a000 = a001; a001 = a002; a010 = a011; a011 = a012; a020 = a021; a021 = a022; a100 = a101; a101 = a102; a110 = a111; a111 = a112; a120 = a121; a121 = a122; a200 = a201; a201 = a202; a210 = a211; a211 = a212; a220 = a221; a221 = a222; } A_index += A_rs; B_index += B_rs; } } }
private void SolveColumnX(int i, int j, int startIndex, int endIndex, LayerData oldLayer, LayerData prevLayer, LayerData nextLayer, bool state) { DoubleMatrix3D u = new DoubleMatrix3D { FirstMatrix = oldLayer.U, SecondMatrix = prevLayer.U }; DoubleMatrix3D v = new DoubleMatrix3D { FirstMatrix = oldLayer.V, SecondMatrix = prevLayer.V }; DoubleMatrix3D w = new DoubleMatrix3D { FirstMatrix = oldLayer.W, SecondMatrix = prevLayer.W }; DoubleMatrix3D T = new DoubleMatrix3D { FirstMatrix = oldLayer.T, SecondMatrix = prevLayer.T }; int length = endIndex - startIndex; double[] downRow = new double[length]; double[] middleRow = new double[length]; double[] upperRow = new double[length]; double[] f = new double[length]; //Solving for U double h = 1.0 / (numPar.Re * numPar.Dx * numPar.Dx); for (int k = 1; k < length - 1; k++) { if (i == 0 || i == height - 1 || j == Az || j == Dz - 1) { downRow[k] = 0.0; middleRow[k] = 1.0; upperRow[k] = 0.0; f[k] = 0.0; } else { downRow[k] = Auxiliaries.GetValue(u, startIndex + k, i, j) / (2 * numPar.Dx) - h; middleRow[k] = 3.0 / numPar.Dt + 2.0 * h; upperRow[k] = -Auxiliaries.GetValue(u, startIndex + k, i, j) / (2.0 * numPar.Dx) - h; f[k] = 3.0 * prevLayer.U[startIndex + k, i, j] / numPar.Dt - (Auxiliaries.GetValue(T, startIndex + k + 1, i, j) - Auxiliaries.GetValue(T, startIndex + k - 1, i, j)) / (2.0 * numPar.Dx); } if (column) { if ((j == Bz || j == Cz - 1) && (k >= Bx && k <= Cx - 1)) { downRow[k] = 0.0; middleRow[k] = 1.0; upperRow[k] = 0.0; f[k] = 0.0; } } } if (startIndex == Ax && i != 0 && i != height - 1 && j != Az && j != Dz - 1) { f[0] = 1.0; } else { f[0] = 0.0; } upperRow[0] = 0.0; middleRow[0] = 1.0; downRow[0] = 0.0; if (!state) { f[length - 1] = 0.0; upperRow[length - 1] = 0.0; middleRow[length - 1] = 1.0; downRow[length - 1] = 0.0; } else { f[length - 1] = 2.0 * prevLayer.U[length - 2, i, j] - prevLayer.U[length - 3, i, j]; upperRow[length - 1] = 0.0; middleRow[length - 1] = 1.0; downRow[length - 1] = 0.0; } PurlinMatrix pmatrix = new PurlinMatrix(downRow, middleRow, upperRow); PurlinSolver pSolver = new PurlinSolver(pmatrix, f); double[] result = pSolver.Solve(); nextLayer.U.SetColumn(i, j, startIndex, Dimensions.Width, result); //if (state) // nextLayer.U[length - 1, i, j] = 2.0 * nextLayer.U[length - 2, i, j] - nextLayer.U[length - 3, i, j]; //Solving for V for (int k = 1; k < length - 1; k++) { if (i == 0 || i == height - 1 || j == Az || j == Dz - 1) { f[k] = 0.0; } else { f[k] = 3 * prevLayer.V[startIndex + k, i, j] / numPar.Dt; } if (column) { if ((j == Bz || j == Cz - 1) && (k >= Bx && k <= Cx - 1)) { f[k] = 0.0; } } } f[0] = 0.0; if (!state) { f[length - 1] = 0.0; } else { f[length - 1] = 2.0 * prevLayer.V[length - 2, i, j] - prevLayer.V[length - 3, i, j]; } pSolver = new PurlinSolver(pmatrix, f); result = pSolver.Solve(); nextLayer.V.SetColumn(i, j, startIndex, Dimensions.Width, result); //if (state) // nextLayer.V[length - 1, i, j] = 2.0 * nextLayer.V[length - 2, i, j] - nextLayer.V[length - 3, i, j]; //Solving for W for (int k = 1; k < length - 1; k++) { if (i == 0 || i == height - 1 || j == Az || j == Dz - 1) { f[k] = 0.0; } else { f[k] = 3 * prevLayer.W[startIndex + k, i, j] / numPar.Dt; } if (column) { if ((j == Bz || j == Cz - 1) && (k >= Bx && k <= Cx - 1)) { f[k] = 0.0; } } } f[0] = 0.0; if (state) { f[length - 1] = 0.0; } else { f[length - 1] = 2.0 * prevLayer.W[length - 2, i, j] - prevLayer.W[length - 3, i, j]; } pSolver = new PurlinSolver(pmatrix, f); result = pSolver.Solve(); nextLayer.W.SetColumn(i, j, startIndex, Dimensions.Width, result); //if (state) // nextLayer.W[length - 1, i, j] = 2.0 * nextLayer.W[length - 2, i, j] - nextLayer.W[length - 3, i, j]; //Solving for T h = 1.0 / (numPar.Re * numPar.Pr * numPar.Dx * numPar.Dx); for (int k = 1; k < length - 1; k++) { upperRow[k] = 0.0; middleRow[k] = 1.0; downRow[k] = 0.0; if (i == 0) { f[k] = prevLayer.T[k, i + 1, j]; } else if (i == height - 1) { f[k] = prevLayer.T[k, i - 1, j]; } else if (j == Az) { f[k] = oldLayer.T[k, i, j + 1]; } else if (j == Dz - 1) { f[k] = oldLayer.T[k, i, j - 1]; } else { downRow[k] = Auxiliaries.GetValue(u, startIndex + k, i, j) / (2 * numPar.Dx) - h; middleRow[k] = 3.0 / numPar.Dt + 2.0 * h; upperRow[k] = -Auxiliaries.GetValue(u, startIndex + k, i, j) / (2.0 * numPar.Dx) - h; f[k] = 3 * prevLayer.T[startIndex + k, i, j] / numPar.Dt + cp * Auxiliaries.GetPhiX(u, v, w, startIndex + k, i, j, numPar); } if (column) { if ((j == Bz) && (k >= Bx && k <= Cx - 1)) { f[k] = oldLayer.T[k, i, j - 1]; } else if ((j == Cz - 1) && (k >= Bx && k <= Cx - 1)) { f[k] = oldLayer.T[k, i, j + 1]; } } } if (startIndex == Ax && i != 0 && i != height - 1 && j != Az && j != Dz - 1) { f[0] = 1.0; upperRow[0] = 0.0; middleRow[0] = 1.0; downRow[0] = 0.0; } else { f[0] = 0.0; upperRow[0] = 1.0; middleRow[0] = -1.0; downRow[0] = 0.0; } if (!state) { upperRow[length - 1] = 0.0; middleRow[length - 1] = -1.0; downRow[length - 1] = 1.0; f[length - 1] = 0.0; } else { upperRow[length - 1] = 0.0; middleRow[length - 1] = 1.0; downRow[length - 1] = 0.0; f[length - 1] = 2.0 * prevLayer.T[length - 2, i, j] - prevLayer.T[length - 3, i, j]; } pmatrix = new PurlinMatrix(downRow, middleRow, upperRow); pSolver = new PurlinSolver(pmatrix, f); result = pSolver.Solve(); nextLayer.T.SetColumn(i, j, startIndex, Dimensions.Width, result); //if (state) // nextLayer.T[length - 1, i, j] = 2.0 * nextLayer.T[length - 2, i, j] - nextLayer.T[length - 3, i, j]; }
private void SolveColumnZ(int i, int j, int startIndex, int endIndex, LayerData oldLayer, LayerData prevLayer, LayerData nextLayer) { DoubleMatrix3D u = new DoubleMatrix3D { FirstMatrix = oldLayer.U, SecondMatrix = prevLayer.U }; DoubleMatrix3D v = new DoubleMatrix3D { FirstMatrix = oldLayer.V, SecondMatrix = prevLayer.V }; DoubleMatrix3D w = new DoubleMatrix3D { FirstMatrix = oldLayer.W, SecondMatrix = prevLayer.W }; DoubleMatrix3D T = new DoubleMatrix3D { FirstMatrix = oldLayer.T, SecondMatrix = prevLayer.T }; int length = endIndex - startIndex; double[] downRow = new double[length]; double[] middleRow = new double[length]; double[] upperRow = new double[length]; double[] f = new double[length]; //Solving for U double h = 1.0 / (numPar.Dz * numPar.Dz * numPar.Re); for (int k = 1; k < length - 1; k++) { downRow[k] = Auxiliaries.GetValue(w, i, j, startIndex + k) / (2.0 * numPar.Dz) - h; middleRow[k] = 3.0 / numPar.Dt + 2.0 * h; upperRow[k] = -Auxiliaries.GetValue(w, i, j, startIndex + k) / (2.0 * numPar.Dz) - h; f[k] = 3.0 * prevLayer.U[i, j, startIndex + k] / numPar.Dt; } upperRow[0] = 0.0; middleRow[0] = 1.0; downRow[0] = 0.0; f[0] = 0.0; upperRow[length - 1] = 0.0; middleRow[length - 1] = 1.0; downRow[length - 1] = 0.0; f[length - 1] = 0.0; PurlinMatrix pmatrix = new PurlinMatrix(downRow, middleRow, upperRow); PurlinSolver pSolver = new PurlinSolver(pmatrix, f); double[] result = pSolver.Solve(); nextLayer.U.SetColumn(i, j, startIndex, Dimensions.Thickness, result); //Solving for V for (int k = 1; k < length - 1; k++) { f[k] = 3.0 * prevLayer.V[i, j, startIndex + k] / numPar.Dt; } f[0] = 0.0; f[length - 1] = 0.0; pSolver = new PurlinSolver(pmatrix, f); result = pSolver.Solve(); nextLayer.V.SetColumn(i, j, startIndex, Dimensions.Thickness, result); //Solving for W for (int k = 1; k < length - 1; k++) { f[k] = 3.0 * prevLayer.W[i, j, startIndex + k] / numPar.Dt - (Auxiliaries.GetValue(T, i, j, startIndex + k + 1) - Auxiliaries.GetValue(T, i, j, startIndex + k - 1)) / (2.0 * numPar.Dz); } f[0] = 0.0; f[length - 1] = 0.0; pSolver = new PurlinSolver(pmatrix, f); result = pSolver.Solve(); nextLayer.W.SetColumn(i, j, startIndex, Dimensions.Thickness, result); //Solving for T h = 1.0 / (numPar.Dz * numPar.Dz * numPar.Re * numPar.Pr); for (int k = 1; k < length - 1; k++) { downRow[k] = Auxiliaries.GetValue(w, i, j, startIndex + k) / (2.0 * numPar.Dz) - h; middleRow[k] = 3.0 / numPar.Dt + 2.0 * h; upperRow[k] = -Auxiliaries.GetValue(w, i, j, startIndex + k) / (2.0 * numPar.Dz) - h; f[k] = 3.0 * prevLayer.T[i, j, startIndex + k] / numPar.Dt + cp * Auxiliaries.GetPhiZ(u, v, w, i, j, startIndex + k, numPar); } upperRow[0] = 1.0; middleRow[0] = -1.0; downRow[0] = 0.0; f[0] = 0.0; upperRow[length - 1] = 0.0; middleRow[length - 1] = -1.0; downRow[length - 1] = 1.0; f[length - 1] = 0; pSolver = new PurlinSolver(pmatrix, f); result = pSolver.Solve(); nextLayer.T.SetColumn(i, j, startIndex, Dimensions.Thickness, result); }
public static double GetValue(DoubleMatrix3D data, int i, int j, int k) { return((data.FirstMatrix[i, j, k] + data.SecondMatrix[i, j, k]) / 2.0); }