public void TestTranspose(int rows, int columns) { var sparseData = Tests.Double.MatrixHelper.LoadSparse(rows, columns); var sparseA = sparseData.A; var AT = sparseA.Transpose(); var coo = new CoordinateStorage <double>(rows, columns, sparseA.NonZerosCount); foreach (var a in sparseA.EnumerateIndexed()) { coo.At(a.Item1, a.Item2, a.Item3); } var cooT = coo.Transpose(true); var sparseB = SparseMatrix.OfIndexed(cooT); Assert.IsTrue(AT.Equals(sparseB)); cooT = coo.Transpose(false); var sparseC = SparseMatrix.OfIndexed(cooT); Assert.IsTrue(AT.Equals(sparseC)); Assert.IsTrue(ReferenceEquals(coo.RowIndices, cooT.ColumnIndices)); Assert.IsTrue(ReferenceEquals(coo.ColumnIndices, cooT.RowIndices)); Assert.IsTrue(ReferenceEquals(coo.Values, cooT.Values)); }
static void testRref2() { var crd = new CoordinateStorage <double>(3, 8, 1); crd.At(0, 2, 1); crd.At(0, 3, 1); crd.At(0, 4, 3); crd.At(0, 6, 2); crd.At(0, 7, 3); crd.At(1, 2, 2); crd.At(1, 3, 6); crd.At(1, 4, 1); crd.At(1, 6, 5); crd.At(1, 7, 1); crd.At(2, 2, 3); crd.At(2, 3, 7); crd.At(2, 4, 4); crd.At(2, 6, 7); crd.At(2, 7, 4); var rref = new CsparsenetQrDisplacementPermutationCalculator(); var a = crd.ToCCs(); var t = rref.CalculateDisplacementPermutation(a).Item1.ToDenseMatrix(); }
//========================= // methods //========================= private void InitializeFEM() { globalF = new double[totalDOFcount]; int localKsize = 81; globalK = new CoordinateStorage <double>(totalDOFcount, totalDOFcount, localKsize * Codend.TriangleList.Count); }
private List <List <int> > GetDistinctRigidElements(Model model, LoadCase loadCase) { for (int i = 0; i < model.Nodes.Count; i++) { model.Nodes[i].Index = i; } var n = model.Nodes.Count; var crd = new CoordinateStorage <double>(n, n, 1); foreach (var elm in model.RigidElements) { if (IsAppliableRigidElement(elm, loadCase)) { for (var i = 0; i < elm.Nodes.Count; i++) { crd.At(elm.Nodes[i].Index, elm.Nodes[i].Index, 1.0); } for (var i = 0; i < elm.Nodes.Count - 1; i++) { crd.At(elm.Nodes[i].Index, elm.Nodes[i + 1].Index, 1.0); crd.At(elm.Nodes[i + 1].Index, elm.Nodes[i].Index, 1.0); } } } var graph = Converter.ToCompressedColumnStorage(crd); var buf = CalcUtil.EnumerateGraphParts(graph); return(buf); }
public void TestOfIndexed_Coo_InPlace() { // rows > columns var coo = new CoordinateStorage <double>(10, 5, 3); coo.At(0, 0, 1.0); coo.At(1, 1, 1.0); coo.At(4, 4, 1.0); var A = SparseMatrix.OfIndexed(coo, true); Assert.AreEqual(3, A.NonZerosCount); // rows < columns coo = new CoordinateStorage <double>(5, 10, 3); coo.At(4, 4, 1.0); coo.At(1, 1, 1.0); coo.At(0, 0, 1.0); coo.At(4, 4, -1.0); // Results in one explicit zero entry. A = SparseMatrix.OfIndexed(coo, true); Assert.AreEqual(3, A.NonZerosCount); A.DropZeros(); Assert.AreEqual(2, A.NonZerosCount); }
/// <summary> /// Create a random symmetric sparse matrix. /// </summary> /// <param name="size">The size of the matrix.</param> /// <param name="density">The density (between 0.0 and 1.0).</param> /// <param name="random">The random source.</param> /// <returns>Random sparse matrix.</returns> public static SparseMatrix RandomSymmetric(int size, double density, Random random) { // Number of non-zeros per row. int nz = (int)Math.Max(size * size * density, 1d); var C = new CoordinateStorage <double>(size, size, nz); int m = (nz - size) / 2; for (int k = 0; k < m; k++) { int i = (int)Math.Min(random.NextDouble() * size, size - 1); int j = (int)Math.Min(random.NextDouble() * size, size - 1); double value = random.NextDouble(); C.At(i, j, value); C.At(j, i, value); } // Fill diagonal. for (int i = 0; i < size; i++) { C.At(i, i, random.NextDouble()); } return((SparseMatrix)C.ToSparseMatrix()); }
/// <summary> /// Create a random sparse matrix. /// </summary> /// <param name="rows">The number of rows.</param> /// <param name="columns">The number of columns.</param> /// <param name="density">The density (between 0.0 and 1.0).</param> /// <param name="band">The bandwidth of the matrix.</param> /// <param name="random">The random source.</param> /// <returns>Random sparse matrix.</returns> public static SparseMatrix Random(int rows, int columns, double density, int band, Random random) { var C = new CoordinateStorage <Complex>(rows, columns); // Number of non-zeros per row. int nz = (int)Math.Max(columns * density, 1d); for (int i = 0; i < rows; i++) { for (int j = 0; j < nz; j++) { int k = Math.Min(columns - 1, (int)(random.NextDouble() * columns)); // TODO: implement bandwidth /* * int k = (int)(2 * (random.NextDouble() - 0.5) * band); * * k = Math.Min(columns - 1, Math.Max(0, i - k)); */ C.At(i, k, new Complex(random.NextDouble(), random.NextDouble())); } } return((SparseMatrix)C.ToSparseMatrix()); }
public void TestKeep(int rows, int columns) { var sparseData = Tests.Double.MatrixHelper.LoadSparse(rows, columns); var sparseA = sparseData.A; var coo = new CoordinateStorage <double>(rows, columns, sparseA.NonZerosCount); foreach (var a in sparseA.EnumerateIndexed()) { coo.At(a.Item1, a.Item2, a.Item3); } // Only keep the first column. coo.Keep((i, j, a) => j < 1); var sparseB = SparseMatrix.OfIndexed(coo); foreach (var a in sparseB.EnumerateIndexed()) { int column = a.Item2; Assert.IsTrue(column < 1); } }
public void TestMatrixParallelMultiply() { var data = ResourceLoader.Get <double>("general-40x40.mat"); var acs = new CoordinateStorage <double>(40, 800, 40 * 800); var bcs = new CoordinateStorage <double>(800, 40, 800 * 40); // This just exceeds min_total_ops in ParallelMultiply foreach (var item in data.EnumerateIndexed()) { int i = item.Item1; int j = item.Item2; for (var k = 0; k < 20; k++) { acs.At(i, j + 40 * k, item.Item3); bcs.At(i + 40 * k, j, item.Item3); } } var A = CompressedColumnStorage <double> .OfIndexed(acs); var B = CompressedColumnStorage <double> .OfIndexed(bcs); var sResult = A.Multiply(B); var pResult = A.ParallelMultiply(B); CollectionAssert.AreEqual(sResult.Values, pResult.Values); }
private static void QrTest() { var coord = new CoordinateStorage <double>(7, 7, 1); coord.At(0, 2, 1); coord.At(0, 3, 1); coord.At(0, 4, 3); coord.At(0, 6, 2); coord.At(1, 2, 2); coord.At(1, 3, 6); coord.At(1, 4, 1); coord.At(1, 6, 5); coord.At(2, 2, 3); coord.At(2, 3, 7); coord.At(2, 4, 4); coord.At(2, 6, 7); var ccs = coord.ToCCs(); var qr = SparseQR.Create(ccs, ColumnOrdering.Natural); //var r = GetFactorR(qr, "R").ToDenseMatrix(); //var q = GetFactorR(qr, "Q").ToDenseMatrix(); //var t = (q * r.Transpose()); }
private CoordinateStorage <Complex> ReadMatrixComplex(StreamReader reader, NumberFormatInfo nfi) { var storage = new CoordinateStorage <Complex>(rowCount, columnCount, nonZerosCount); int i, j, count = 0; double valRe, valIm; string line; string[] vals; while (GetNextLine(reader, out line)) { vals = line.Split(seperator, StringSplitOptions.RemoveEmptyEntries); if (vals.Length != 4) { throw new FormatException(); // TODO: Exception text } i = int.Parse(vals[0]) - offset; j = int.Parse(vals[1]) - offset; valRe = double.Parse(vals[2], nfi); valIm = double.Parse(vals[3], nfi); storage.At(i, j, new Complex(valRe, valIm)); count++; } return(storage); }
private static void TstMtx() { var crd = new CoordinateStorage <double>(5, 5, 1); crd.At(0, 0, 1); crd.At(0, 1, -1); crd.At(0, 3, -3); crd.At(1, 0, -2); crd.At(1, 1, 5); crd.At(2, 2, 4); crd.At(2, 3, 6); crd.At(2, 4, 4); crd.At(3, 0, -4); crd.At(3, 2, 2); crd.At(3, 3, 7); crd.At(4, 1, 8); crd.At(4, 4, -5); var sp = crd.ToCCs().Transpose(); var dns = sp.ToDenseMatrix(); }
public void TestOfIndexed_Empty() { var coord = new CoordinateStorage <double>(0, 0, 0); var sparseA = new SparseMatrix(0, 0, 0); var sparseB = SparseMatrix.OfIndexed(coord); Assert.IsTrue(sparseA.Equals(sparseB)); }
/// <summary> /// Create a random Hermitian sparse matrix. /// </summary> /// <param name="size">The size of the matrix.</param> /// <param name="density">The density (between 0.0 and 1.0).</param> /// <param name="definite">If true, the matrix will be positive semi-definite.</param> /// <param name="random">The random source.</param> /// <returns>Random sparse matrix.</returns> public static SparseMatrix RandomHermitian(int size, double density, bool definite, Random random) { // Total number of non-zeros. int nz = (int)Math.Max(size * size * density, 1d); var C = new CoordinateStorage <Complex>(size, size, nz); int m = nz / 2; var norm = new double[size]; for (int k = 0; k < m; k++) { int i = (int)Math.Min(random.NextDouble() * size, size - 1); int j = (int)Math.Min(random.NextDouble() * size, size - 1); if (i == j) { // Skip diagonal. continue; } // Fill only lower part. if (i < j) { int temp = i; i = j; j = temp; } var value = new Complex(random.NextDouble(), random.NextDouble()); norm[i] += Complex.Abs(value); norm[j] += Complex.Abs(value); C.At(i, j, value); } // Fill diagonal. for (int i = 0; i < size; i++) { double value = random.NextDouble(); if (definite) { // Make the matrix diagonally dominant. value = (value + 1.0) * (norm[i] + 1.0); } C.At(i, i, value); } var A = SparseMatrix.OfIndexed(C); return((SparseMatrix)A.Add(A.Transpose())); }
/// <summary> /// Get the 1D Laplacian matrix (with Dirichlet boundary conditions). /// </summary> /// <param name="nx">Grid size.</param> /// <param name="eigenvalues">Vector to store eigenvalues (optional).</param> /// <returns>Laplacian sparse matrix.</returns> public static SparseMatrix Laplacian(int nx, DenseVector eigenvalues = null) { if (nx == 1) { // Handle special case n = 1. var A = new SparseMatrix(nx, nx); A.At(0, 0, 2.0); return(A); } var C = new CoordinateStorage <Complex>(nx, nx); for (int i = 0; i < nx; i++) { C.At(i, i, 2.0); if (i == 0) { C.At(i, i + 1, -1.0); } else if (i == (nx - 1)) { C.At(i, i - 1, -1.0); } else { C.At(i, i - 1, -1.0); C.At(i, i + 1, -1.0); } } if (eigenvalues != null) { // Compute eigenvalues. int count = Math.Min(nx, eigenvalues.Count); var eigs = new double[nx]; for (int i = 0; i < count; i++) { eigs[i] = 4 * Math.Pow(Math.Sin((i + 1) * Math.PI / (2 * (nx + 1))), 2); } Array.Sort(eigs); for (int i = 0; i < count; ++i) { eigenvalues.At(i, eigs[i]); } } return((SparseMatrix)C.ToSparseMatrix()); }
/// <summary> /// Get the 1D Laplacian matrix (with Dirichlet boundary conditions). /// </summary> /// <param name="nx">Grid size.</param> /// <param name="eigenvalues">Vector to store eigenvalues (optional).</param> /// <returns>Laplacian sparse matrix.</returns> public static CompressedColumnStorage <Complex> Laplacian(int nx, double[] eigenvalues = null) { if (nx == 1) { // Handle special case n = 1. var A = new CoordinateStorage <Complex>(nx, nx, 1); A.At(0, 0, 2.0); return(SparseMatrix.OfIndexed(A)); } var C = new CoordinateStorage <Complex>(nx, nx, 3 * nx); for (int i = 0; i < nx; i++) { C.At(i, i, 2.0); if (i == 0) { C.At(i, i + 1, -1.0); } else if (i == (nx - 1)) { C.At(i, i - 1, -1.0); } else { C.At(i, i - 1, -1.0); C.At(i, i + 1, -1.0); } } if (eigenvalues != null) { // Compute eigenvalues. int count = Math.Min(nx, eigenvalues.Length); var eigs = new double[nx]; for (int i = 0; i < count; i++) { eigs[i] = 4 * Math.Pow(Math.Sin((i + 1) * Math.PI / (2 * (nx + 1))), 2); } Array.Sort(eigs); for (int i = 0; i < count; ++i) { eigenvalues[i] = eigs[i]; } } return(SparseMatrix.OfIndexed(C)); }
/// <summary> /// Convert a row major array to coordinate storage. /// </summary> /// <param name="enumerable">Enumerates the entries of a matrix.</param> /// <param name="rowCount">Number of rows.</param> /// <param name="columnCount">Number of columns.</param> /// <returns>Coordinate storage.</returns> public static CoordinateStorage <T> FromEnumerable <T>(IEnumerable <Tuple <int, int, T> > enumerable, int rowCount, int columnCount) where T : struct, IEquatable <T>, IFormattable { var storage = new CoordinateStorage <T>(rowCount, columnCount, Math.Max(rowCount, columnCount)); foreach (var item in enumerable) { storage.At(item.Item1, item.Item2, item.Item3); } return(storage); }
public static CompressedColumnStorage <double> CreateDiagonalInverse(int dim, double[] diagonal) { var identityMatrix = new CoordinateStorage <double>(dim, dim, dim); for (int i = 0; i < dim; i++) { identityMatrix.At(i, i, 1.0 / diagonal[i]); } var compidentityMatrix = CSparse.Converter.ToCompressedColumnStorage(identityMatrix); return(compidentityMatrix); }
void PrecomputeDistanceMatrix2D(int W, int H, bool show = true) { int N = area_cnt; //////////////////////////////////////////////////////////// // step III-1. build matrix A for distance computation // [CAUTION] this is NEGATED matrix to use Cholesky decomp. //////////////////////////////////////////////////////////// var C_dist = new CoordinateStorage <double>(N, N, 5 * N); // banded matrix without exception for (int matid_this = 0; matid_this < N; matid_this++) { List <int> matid_neighbor; if (!MatrixNeighbors.TryGetValue(matid_this, out matid_neighbor)) { continue; } double A_diag = -1e-6; // small value to use Cholesky decomposition Action <int> CheckNeighbor = (id) => { int matid_next = matid_neighbor[id]; if (matid_next != -1) { A_diag += -1.0; C_dist.At(matid_this, matid_next, -1.0); } }; CheckNeighbor(0); CheckNeighbor(1); CheckNeighbor(2); CheckNeighbor(3); C_dist.At(matid_this, matid_this, -A_diag); } var A_dist = Converter.ToCompressedColumnStorage(C_dist) as SparseMatrix; //////////////////////////////////////////////////////////// // step III-2. build matrix A for heat diffusion //////////////////////////////////////////////////////////// #if USE_3RDPARTY solver_dist = new SuperLU(A_dist); var options = solver_dist.Options; options.SymmetricMode = true; solver_dist.Factorize(); #else solver_dist = SparseCholesky.Create(A_dist, ColumnOrdering.MinimumDegreeAtPlusA); #endif }
public static CompressedColumnStorage <double> ConvertSparsityJacobian(AlgebraicSystem problem) { var sparseJacobian = new CoordinateStorage <double>(problem.NumberOfEquations, problem.NumberOfVariables, problem.Jacobian.Count); foreach (var entry in problem.Jacobian) { sparseJacobian.At(entry.EquationIndex, entry.VariableIndex, 1); } var compJacobian = CSparse.Converter.ToCompressedColumnStorage(sparseJacobian); return(compJacobian); }
/// <summary> /// Inserts the permutation matrix of linking the <see cref="master"/> and <see cref="slave"/> nodes to each other. /// </summary> /// <param name="pij">The pij.</param> /// <param name="master">The master node index.</param> /// <param name="slave">The slave node index.</param> /// <param name="pt">The global permutation assembly.</param> public void InsertPij(Matrix pij, int master, int slave, CoordinateStorage <double> pt) { var row0 = slave * 6; var col0 = master * 6; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { pt.At(row0 + i, col0 + j, pij[i, j]); } } }
void PrecomputeHeatMatrix2D(double dt) { int N = area_cnt; //////////////////////////////////////////////////////////// // step I-1. build matrix A for heat diffusion //////////////////////////////////////////////////////////// var C_heat = new CoordinateStorage <double>(N, N, 5 * N); // banded matrix without exception for (int matid_this = 0; matid_this < N; matid_this++) { List <int> matid_neighbor; if (!MatrixNeighbors.TryGetValue(matid_this, out matid_neighbor)) { continue; } if (matid_neighbor[0] != -1) { C_heat.At(matid_this, matid_neighbor[0], -1.0 * dt); } if (matid_neighbor[1] != -1) { C_heat.At(matid_this, matid_neighbor[1], -1.0 * dt); } if (matid_neighbor[2] != -1) { C_heat.At(matid_this, matid_neighbor[2], -1.0 * dt); } if (matid_neighbor[3] != -1) { C_heat.At(matid_this, matid_neighbor[3], -1.0 * dt); } C_heat.At(matid_this, matid_this, 1.0 + 4.0 * dt); } var A_heat = Converter.ToCompressedColumnStorage(C_heat) as SparseMatrix; //////////////////////////////////////////////////////////// // step I-2. build matrix A for heat diffusion //////////////////////////////////////////////////////////// #if USE_3RDPARTY solver_heat = new SuperLU(A_heat); var options = solver_heat.Options; options.SymmetricMode = true; solver_heat.Factorize(); #else solver_heat = SparseCholesky.Create(A_heat, ColumnOrdering.MinimumDegreeAtPlusA); #endif }
// This is for constructing the lhs and rhs of system matrix // This will construct a HINES matrix (symmetric), it should be tridiagonal with some off // diagonal entries corresponding to a branch location in the neuron graph public static List <CoordinateStorage <double> > makeSparseStencils(NeuronCell myCell, double h, double k, double diffConst) { List <CoordinateStorage <double> > stencils = new List <CoordinateStorage <double> >(); var rhs = new CoordinateStorage <double>(myCell.vertCount, myCell.vertCount, myCell.vertCount * myCell.vertCount); var lhs = new CoordinateStorage <double>(myCell.vertCount, myCell.vertCount, myCell.vertCount * myCell.vertCount); // for keeping track of the neighbors of a node int nghbrCount; int nghbrInd; // need cfl coefficient double cfl = diffConst * k / h; double vRad;//= 1; // need to use radius data attached to geometry, TODO: move inside the loop and access for each node for (int p = 0; p < myCell.vertCount; p++) { nghbrCount = myCell.nodeData[p].neighborIDs.Count; vRad = myCell.nodeData[p].nodeRadius; if (vRad >= 1) { vRad = 0.1 * vRad; } vRad = 0.5 * vRad; // set main diagonal entries rhs.At(p, p, 1 - ((double)nghbrCount + h * h) * vRad * cfl / (2 * h)); lhs.At(p, p, 1 + ((double)nghbrCount + h * h) * vRad * cfl / (2 * h)); // this inner loop is for setting the off diagonal entries which correspond // to the neighbors of each node in the branch structure for (int q = 0; q < nghbrCount; q++) { nghbrInd = myCell.nodeData[p].neighborIDs[q]; // should I be using the neighbor radii here or same as main node? //vRad = myCell.nodeData[myCell.nodeData[p].neighborIDs[q]].nodeRadius; // for off diagonal entries rhs.At(p, nghbrInd, vRad * cfl / (2 * h)); //rhs.At(nghbrInd, p, vRad * cfl / (2 * h)); // for off diagonal entries lhs.At(p, nghbrInd, -vRad * cfl / (2 * h)); //lhs.At(nghbrInd, p, -vRad * cfl / (2 * h)); } } stencils.Add(rhs); stencils.Add(lhs); return(stencils); }
public SparseMatrix ToCcs() { var crd = new CoordinateStorage <double>(this.RowCount, this.ColumnCount, this.Equations.Sum(i => i.Size) + 1); for (var i = 0; i < this.Equations.Length; i++) { foreach (var tuple in this.Equations[i].EnumerateIndexed()) { crd.At(i, tuple.Item1, tuple.Item2); } } return(crd.ToCCs()); }
/// <summary> /// Convert a coordinate storage to compressed sparse row (CSR) format. /// </summary> /// <param name="storage">Coordinate storage.</param> /// <param name="cleanup">Remove and sum duplicate entries.</param> /// <returns>Compressed sparse row storage.</returns> public static SparseMatrix ToSparseMatrix(CoordinateStorage <Complex> coo, bool cleanup = true) { int nrows = coo.RowCount; int ncols = coo.ColumnCount; var rowind = coo.RowIndices; var colind = coo.ColumnIndices; var values = coo.Values; int p, k, nz = coo.NonZerosCount; var counts = new int[nrows]; for (k = 0; k < nz; k++) { // Determine row-lengths. counts[rowind[k]]++; } var result = new SparseMatrix(nrows, ncols); var storage = result.Storage as SparseCompressedRowMatrixStorage <Complex>; var ap = storage.RowPointers; // Get row pointers (starting position of each row). int valueCount = Helper.CumulativeSum(ap, counts, nrows); var ai = new int[valueCount]; var ax = new Complex[valueCount]; // Fill in output matrix. for (k = 0; k < nz; k++) { p = counts[rowind[k]]++; ai[p] = colind[k]; ax[p] = values[k]; } Helper.SortIndices(nrows, ax, ap, ai); if (cleanup) { Cleanup(ncols, nrows, ap, ref ai, ref ax); } storage.ColumnIndices = ai; storage.Values = ax; return(result); }
/// <summary> /// Convert a coordinate storage to compressed sparse column (CSC) format. /// </summary> /// <param name="storage">Coordinate storage.</param> /// <param name="cleanup">Remove and sum duplicate entries.</param> /// <returns>Compressed sparse column storage.</returns> public static CompressedColumnStorage <T> ToCompressedColumnStorage <T>(CoordinateStorage <T> storage, bool cleanup = true) where T : struct, IEquatable <T>, IFormattable { int nrows = storage.RowCount; int ncols = storage.ColumnCount; var values = storage.Values; var rowind = storage.RowIndices; var colind = storage.ColumnIndices; int p, k, nz = storage.NonZerosCount; var columnPointers = new int[ncols + 1]; var columnCounts = new int[ncols]; for (k = 0; k < nz; k++) { // Count columns columnCounts[colind[k]]++; } // Get row pointers int valueCount = Helper.CumulativeSum(columnPointers, columnCounts, ncols); var result = CompressedColumnStorage <T> .Create(nrows, ncols); var rowIndices = new int[valueCount]; var storageValues = new T[valueCount]; for (k = 0; k < nz; k++) { p = columnCounts[colind[k]]++; rowIndices[p] = rowind[k]; storageValues[p] = values[k]; } result.RowIndices = rowIndices; result.ColumnPointers = columnPointers; result.Values = storageValues; result.SortIndices(); if (cleanup) { result.Cleanup(); } return(result); }
/// <summary> /// Convert a row major array to coordinate storage. /// </summary> /// <param name="array">Row major array storage.</param> /// <param name="rowCount">Number of rows.</param> /// <param name="columnCount">Number of columns.</param> /// <returns>Coordinate storage.</returns> public static CoordinateStorage <T> FromRowMajorArray <T>(T[] array, int rowCount, int columnCount) where T : struct, IEquatable <T>, IFormattable { var storage = new CoordinateStorage <T>(rowCount, columnCount, Math.Max(rowCount, columnCount)); for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { storage.At(i, j, array[i * columnCount + j]); } } return(storage); }
/// <summary> /// Generates the permutation for delta for specified model in specified loadCase. /// Note that delta permutation = P_delta in reduction process /// </summary> /// <param name="target">The target.</param> /// <param name="loadCase">The load case.</param> /// <returns>delta permutation</returns> public static CCS GenerateP_Delta(Model target, LoadCase loadCase) { throw new NotImplementedException(); target.ReIndexNodes(); var buf = new CoordinateStorage <double>(target.Nodes.Count * 6, target.Nodes.Count * 6, 1); #region rigid elements foreach (var elm in target.RigidElements) { var centralNode = elm.Nodes[0]; var masterIdx = centralNode.Index; for (var i = 1; i < elm.Nodes.Count; i++) { var slaveIdx = elm.Nodes[i].Index; var d = centralNode.Location - elm.Nodes[i].Location; //buf[0, 4] = -(buf[1, 3] = d.Z); //buf[2, 3] = -(buf[0, 5] = d.Y); //buf[1, 5] = -(buf[2, 4] = d.X); buf.At(6 * slaveIdx + 0, 6 * masterIdx + 0, 1); buf.At(6 * slaveIdx + 1, 6 * masterIdx + 1, 1); buf.At(6 * slaveIdx + 2, 6 * masterIdx + 2, 1); buf.At(6 * slaveIdx + 1, 6 * masterIdx + 3, d.Z); buf.At(6 * slaveIdx + 0, 6 * masterIdx + 4, -d.Z); buf.At(6 * slaveIdx + 0, 6 * masterIdx + 5, d.Y); buf.At(6 * slaveIdx + 2, 6 * masterIdx + 3, -d.Y); // buf.At(6 * slaveIdx + 2, 6 * masterIdx + 4, d.X); // buf.At(6 * slaveIdx + 1, 6 * masterIdx + 5, -d.X); } //add to buf } #endregion throw new NotImplementedException(); return(buf.ToCCs()); }
/// <summary> /// Assembles the stiffness matrix of defined model and return it back. /// </summary> /// <returns>Assembled stiffness matrix</returns> public static CCS AssembleFullStiffnessMatrix(Model model) { model.ReIndexNodes(); var elements = model.Elements; var maxNodePerElement = model.Elements.Any() ? model.Elements.Select(i => i.Nodes.Length).Max() : 1; var rElmMap = new int[maxNodePerElement * 6]; var c = model.Nodes.Count * 6; var kt = new CoordinateStorage <double>(c, c, c); foreach (var elm in elements) { var c2 = elm.Nodes.Length; for (var i = 0; i < c2; i++) { rElmMap[6 * i + 0] = elm.Nodes[i].Index * 6 + 0; rElmMap[6 * i + 1] = elm.Nodes[i].Index * 6 + 1; rElmMap[6 * i + 2] = elm.Nodes[i].Index * 6 + 2; rElmMap[6 * i + 3] = elm.Nodes[i].Index * 6 + 3; rElmMap[6 * i + 4] = elm.Nodes[i].Index * 6 + 4; rElmMap[6 * i + 5] = elm.Nodes[i].Index * 6 + 5; } var mtx = elm.GetGlobalStifnessMatrix(); var d = c2 * 6; for (var i = 0; i < d; i++) { for (var j = 0; j < d; j++) { kt.At(rElmMap[i], rElmMap[j], mtx[i, j]); } } mtx.ReturnToPool(); } var stiffness = (CCS)Converter.ToCompressedColumnStorage(kt, true); return(stiffness); }
/// <summary> /// Convert a jagged array to compressed sparse column (CSC) format. /// </summary> /// <param name="array">Jagged array storage.</param> /// <returns>Compressed sparse column storage.</returns> public static CompressedColumnStorage <T> ToCompressedColumnStorage <T>(T[][] array) where T : struct, IEquatable <T>, IFormattable { int nrows = array.Length; int ncols = array[0].Length; var storage = new CoordinateStorage <T>(nrows, ncols, nrows); for (int i = 0; i < nrows; i++) { for (int j = 0; j < ncols; j++) { storage.At(i, j, array[i][j]); } } return(ToCompressedColumnStorage <T>(storage, false)); }