public static ResultFEM Solve(Matrix <double> K, Matrix <double> f, int[] bc, double[] bcVal) { // Create dof array: int ndof = f.RowCount; // Initialize displacement vector Matrix u = new DenseMatrix(ndof, 1); int[] dof = new int[ndof]; for (int i = 0; i < ndof; i++) { dof[i] = i; } // Create the free dofs: int[] fdof = dof.Except(bc).ToArray(); int nfdof = fdof.Length; // Number of free dofs. int nbdof = ndof - nfdof; //Constrained dofs // Create the permutation array which puts the constrained dofs last: int[] permute = bc.Union(fdof).ToArray(); Permutation perm = new Permutation(permute); Permutation invPerm = perm.Inverse(); Matrix <double> KPermuted = DenseMatrix.OfMatrix(K); KPermuted.PermuteRows(invPerm); KPermuted.PermuteColumns(invPerm); // Split K::: Matrix <double> Kff = KPermuted.SubMatrix(nbdof, nfdof, nbdof, nfdof); System.Console.WriteLine(Kff); //Down right corner of matrix Matrix <double> Kfp = KPermuted.SubMatrix(nbdof, nfdof, 0, nbdof); //Down left corner of matrix // Split F::: Matrix <double> fPermuted = DenseMatrix.OfMatrix(f); fPermuted.PermuteRows(invPerm); Matrix <double> ff = fPermuted.SubMatrix(nbdof, nfdof, 0, 1); // Split displacements::: for (int i = 0; i < nbdof; i++) { u[i, 0] = bcVal[i]; } Matrix <double> up = u.SubMatrix(0, nbdof, 0, 1); // Must set up to constrained values in bc. // Solve for the unknown displacements::: Matrix <double> s = Kff.Solve(ff.Subtract(Kfp.Multiply(up))); u.SetSubMatrix(nbdof, 0, s); // Set displacements back. System.Console.WriteLine(u); // Permute back u u.PermuteRows(perm); System.Console.WriteLine("U after permut"); System.Console.WriteLine(K); System.Console.WriteLine(u); System.Console.WriteLine(f); // Get reaction forces: Matrix <double> Q = K.Multiply(u).Subtract(f); ResultFEM result = new ResultFEM(u, Q); return(result); }
public static ResultFEM Solve(Matrix<double> K, Matrix<double> f, int[] bc) { // Create dof array: int ndof = f.RowCount; // Initialize displacement vector Matrix u = new DenseMatrix(ndof, 1); int[] dof = new int[ndof]; for (int i = 0; i < ndof; i++) { dof[i] = i; } // Create the free dofs: int[] fdof = dof.Except(bc).ToArray(); int nfdof = fdof.Length; // Number of free dofs. int nbdof = ndof - nfdof; //Constrained dofs // Create the permutation array which puts the constrained dofs last: int[] permute = bc.Union(fdof).ToArray(); Permutation perm = new Permutation(permute); Permutation invPerm = perm.Inverse(); Matrix<double> KPermuted = DenseMatrix.OfMatrix(K); KPermuted.PermuteRows(invPerm); KPermuted.PermuteColumns(invPerm); // Split K::: Matrix<double> Kff = KPermuted.SubMatrix(nbdof, nfdof, nbdof, nfdof); System.Console.WriteLine(Kff); //Down right corner of matrix Matrix<double> Kfp = KPermuted.SubMatrix(nbdof, nfdof, 0, nbdof); //Down left corner of matrix // Split F::: Matrix<double> fPermuted = DenseMatrix.OfMatrix(f); fPermuted.PermuteRows(invPerm); Matrix<double> ff = fPermuted.SubMatrix(nbdof, nfdof, 0, 1); Matrix<double> up = u.SubMatrix(0, nbdof, 0, 1); // Must set up to constrained values in bc. // Solve for the unknown displacements::: Matrix<double> s = Kff.Solve(ff.Subtract(Kfp.Multiply(up))); u.SetSubMatrix(nbdof, 0, s); // Set displacements back. System.Console.WriteLine(u); // Permute back u u.PermuteRows(perm); System.Console.WriteLine("U after permut"); System.Console.WriteLine(K); System.Console.WriteLine(u); System.Console.WriteLine(f); // Get reaction forces: Matrix<double> Q = K.Multiply(u).Subtract(f); ResultFEM result = new ResultFEM(u, Q); return result; }