private IList <Vector> FEAnalysisHalfMbbBeam(Matrix x) { int numAllDofs = 2 * (nelx + 1) * (nely + 1); var K = DokSymmetric.CreateEmpty(numAllDofs); var F = Vector.CreateZero(numAllDofs); var U = Vector.CreateZero(numAllDofs); Matrix Ke = ElementStiffness(); int numElementDofs = Ke.NumRows; int[] elementDofsLocal = Enumerable.Range(0, numElementDofs).ToArray(); // Global stiffness matrix assembly for (int ely = 1; ely <= nely; ++ely) { for (int elx = 1; elx <= nelx; ++elx) { int[] elementDofsGlobal = GetElementDofs(elx, ely); double density = Math.Pow(x[ely - 1, elx - 1], penal); K.AddSubmatrixSymmetric(density * Ke, elementDofsLocal, elementDofsGlobal); } } // Define loads and supports for half MBB beam F[1] = -1.0; var fixedDofs = new HashSet <int>(); //TODO: Use LINQ to simplify this for (int i = 0; i < 2 * (nely + 1); i += 2) { fixedDofs.Add(i); } fixedDofs.Add(numAllDofs - 1); int[] freeDofs = Enumerable.Range(0, numAllDofs).Except(fixedDofs).ToArray(); // Solve linear system DokSymmetric Kf = K.GetSubmatrix(freeDofs); Vector Ff = F.GetSubvector(freeDofs); Vector Uf = CholeskyCSparseNet.Factorize(Kf.BuildSymmetricCscMatrix(true)).SolveLinearSystem(Ff); for (int i = 0; i < freeDofs.Length; ++i) { U[freeDofs[i]] = Uf[i]; } //U.CopyNonContiguouslyFrom(freeDofs, Uf, Enumerable.Range(0, freeDofs.Length).ToArray()); // alternative way, but probably slower. //foreach (int i in fixedDofs) U[i] = 0.0; // They are 0 by default return(new Vector[] { U }); }
public void UpdateModelAndAnalyze(IVectorView youngModuli) { this.youngModuli = youngModuli; // Global stiffness matrix assembly int numAllDofs = 2 * (numElementsX + 1) * (numElementsY + 1); var K = DokSymmetric.CreateEmpty(numAllDofs); for (int e = 0; e < NumElements; ++e) { int[] elementDofsGlobal = GetElementDofs(e); K.AddSubmatrixSymmetric(unitStiffness.Scale(youngModuli[e]), elementDofsLocal, elementDofsGlobal); } // Apply boundary conditions (int[] freeDofs, Vector[] Fs) = ApplyBoundaryConditions(); int numLoadCases = Fs.Length; globalDisplacements = new Vector[numLoadCases]; // Solve linear system DokSymmetric Kf = K.GetSubmatrix(freeDofs); var factor = CholeskyCSparseNet.Factorize(Kf.BuildSymmetricCscMatrix(true)); for (int c = 0; c < numLoadCases; ++c) { Vector Ff = Fs[c].GetSubvector(freeDofs); Vector Uf = factor.SolveLinearSystem(Ff); var U = Vector.CreateZero(numAllDofs); for (int i = 0; i < freeDofs.Length; ++i) { U[freeDofs[i]] = Uf[i]; } globalDisplacements[c] = U; //U.CopyNonContiguouslyFrom(freeDofs, Uf, Enumerable.Range(0, freeDofs.Length).ToArray()); // alternative way, but probably slower. } }