/// <summary> /// Adds the analysis result. /// </summary> /// <param name="loadCase">The load case.</param> /// <remarks>if model is analyzed against specific load case, then displacements are available through <see cref="Displacements"/> property. /// If system is not analyses against a specific load case, then this method will analyses structure against <see cref="LoadCase"/>. /// While this method is using pre computed Cholesky Decomposition , its have a high performance in solving the system. /// </remarks> public void AddAnalysisResult_MPC(LoadCase loadCase) { var n = parent.Nodes.Count * 6; var dt = new double[n];//total delta ISolver solver; var sp = Stopwatch.StartNew(); var permCalculator = new CsparsenetQrDisplacementPermutationCalculator(); var perm = CalcUtil.GenerateP_Delta_Mpc(parent, loadCase, permCalculator); parent.Trace.Write(Common.TraceLevel.Info, "Calculating Displacement Permutation Matrix took {0} ms", sp.ElapsedMilliseconds); var np = perm.Item1.ColumnCount;//master count var rd = perm.Item2; var pd = perm.Item1; //var todo = pd.ToDenseMatrix(); sp.Restart(); var kt = MatrixAssemblerUtil.AssembleFullStiffnessMatrix(parent);//total stiffness matrix, same for all load cases parent.Trace.Write(Common.TraceLevel.Info, "Assemble Full Stiffness Matrix took {0} ms", sp.ElapsedMilliseconds); var ft = new double[n]; //{ var fe = elementForces[loadCase] = GetTotalElementsForceVector(loadCase); var fc = concentratedForces[loadCase] = GetTotalConcentratedForceVector(loadCase); ft.AddToSelf(fe); ft.AddToSelf(fc); //} if (perm.Item1.RowCount > 0 && perm.Item1.RowCount > 0) { var pf = pd.Transpose(); sp.Restart(); var kr = pf.Multiply(kt).Multiply(pd); var a1 = new double[n]; kt.Multiply(rd, a1); a1.AddToSelf(ft); var a2 = new double[np]; pf.Multiply(a1, a2); parent.Trace.Write(Common.TraceLevel.Info, "Applying boundary conditions took {0} ms", sp.ElapsedMilliseconds); var a3 = new double[np]; #region load/generate solver if (Solvers_New.ContainsKey(pd)) { solver = Solvers_New[pd]; } else { //var tt = kr.ToDenseMatrix(); solver = SolverFactory.CreateSolver((CCS)kr); Solvers_New[pd] = solver; } sp.Restart(); if (!solver.IsInitialized) { solver.Initialize(); } #endregion solver.Solve(a2, a3); parent.Trace.Write(Common.TraceLevel.Info, "Solving EQ system took {0} ms", sp.ElapsedMilliseconds); pd.Multiply(a3, dt); } dt.AddToSelf(rd, -1); ft.FillWith(0); kt.Multiply(dt, ft); var fx = supportReactions[loadCase] = (double[])ft.Clone(); ft.AddToSelf(fe, -1); ft.AddToSelf(fc, -1); _forces[loadCase] = ft; _displacements[loadCase] = dt; for (var i = 0; i < parent.Nodes.Count; i++) { #region constraint var virtConsts = new List <Constraint>(); var origConst = parent.Nodes[i].Constraints; virtConsts.Add(origConst); foreach (var element in parent.MpcElements) { if (!(element is VirtualConstraint)) { continue; } if (!element.AppliesForLoadCase(loadCase)) { continue; } if (!element.Nodes.Contains(parent.Nodes[i])) { continue; } virtConsts.Add((element as VirtualConstraint).Constraint); } var finalConst = new Constraint(); foreach (var cns in virtConsts) { if (cns.DX == DofConstraint.Fixed) { finalConst.DX = DofConstraint.Fixed; } if (cns.DY == DofConstraint.Fixed) { finalConst.DY = DofConstraint.Fixed; } if (cns.DZ == DofConstraint.Fixed) { finalConst.DZ = DofConstraint.Fixed; } if (cns.RX == DofConstraint.Fixed) { finalConst.RX = DofConstraint.Fixed; } if (cns.RY == DofConstraint.Fixed) { finalConst.RY = DofConstraint.Fixed; } if (cns.RZ == DofConstraint.Fixed) { finalConst.RZ = DofConstraint.Fixed; } } #endregion if (finalConst.DX == DofConstraint.Released) { fx[6 * i + 0] = 0; } if (finalConst.DY == DofConstraint.Released) { fx[6 * i + 1] = 0; } if (finalConst.DY == DofConstraint.Released) { fx[6 * i + 2] = 0; } if (finalConst.RX == DofConstraint.Released) { fx[6 * i + 3] = 0; } if (finalConst.RY == DofConstraint.Released) { fx[6 * i + 4] = 0; } if (finalConst.RZ == DofConstraint.Released) { fx[6 * i + 5] = 0; } } }
/// <summary> /// Adds the analysis result. /// </summary> /// <param name="loadCase">The load case.</param> /// <remarks>if model is analyzed against specific load case, then displacements are available through <see cref="Displacements"/> property. /// If system is not analyses against a specific load case, then this method will analyses structure against <see cref="LoadCase"/>. /// While this method is using pre computed Cholesky Decomposition , its have a high performance in solving the system. /// </remarks> public void AddAnalysisResult_MPC(LoadCase loadCase) { var n = parent.Nodes.Count * 6; var dt = new double[n];//total delta ISolver solver; var perm = CalcUtil.GenerateP_Delta_Mpc(parent, loadCase, new Mathh.GaussRrefFinder()); var np = perm.Item1.ColumnCount;//master count var rd = perm.Item2; var pd = perm.Item1; var kt = MatrixAssemblerUtil.AssembleFullStiffnessMatrix(parent); var ft = new double[n]; //{ var fe = elementForces[loadCase] = GetTotalElementsForceVector(loadCase); var fc = concentratedForces[loadCase] = GetTotalConcentratedForceVector(loadCase); ft.AddToSelf(fe); ft.AddToSelf(fc); //} if (perm.Item1.RowCount > 0 && perm.Item1.RowCount > 0) { var pf = pd.Transpose(); var kr = pf.Multiply(kt).Multiply(pd); var a1 = new double[n]; //a1.AddToSelf(rd); kt.Multiply(rd, a1); a1.AddToSelf(ft); var a2 = new double[np]; pf.Multiply(a1, a2); var a3 = new double[np]; #region load/generate solver if (Solvers_New.ContainsKey(pd)) { solver = Solvers_New[pd]; } else { solver = SolverFactory.CreateSolver((CCS)kr); Solvers_New[pd] = solver; } if (!solver.IsInitialized) { solver.Initialize(); } #endregion solver.Solve(a2, a3); pd.Multiply(a3, dt); } dt.AddToSelf(rd, -1); ft.FillWith(0); kt.Multiply(dt, ft); var fx = supportReactions[loadCase] = (double[])ft.Clone(); ft.AddToSelf(fe, -1); ft.AddToSelf(fc, -1); _forces[loadCase] = ft; _displacements[loadCase] = dt; //var forcesRegenerated= for (var i = 0; i < parent.Nodes.Count; i++) { #region constraint var virtConsts = new List <Constraint>(); var origConst = parent.Nodes[i].Constraints; virtConsts.Add(origConst); foreach (var element in parent.MpcElements) { if (!(element is VirtualConstraint)) { continue; } if (!element.AppliesForLoadCase(loadCase)) { continue; } if (!element.Nodes.Contains(parent.Nodes[i])) { continue; } virtConsts.Add((element as VirtualConstraint).Constraint); } var finalConst = new Constraint(); foreach (var cns in virtConsts) { if (cns.DX == DofConstraint.Fixed) { finalConst.DX = DofConstraint.Fixed; } if (cns.DY == DofConstraint.Fixed) { finalConst.DY = DofConstraint.Fixed; } if (cns.DZ == DofConstraint.Fixed) { finalConst.DZ = DofConstraint.Fixed; } if (cns.RX == DofConstraint.Fixed) { finalConst.RX = DofConstraint.Fixed; } if (cns.RY == DofConstraint.Fixed) { finalConst.RY = DofConstraint.Fixed; } if (cns.RZ == DofConstraint.Fixed) { finalConst.RZ = DofConstraint.Fixed; } } #endregion if (finalConst.DX == DofConstraint.Released) { fx[6 * i + 0] = 0; } if (finalConst.DY == DofConstraint.Released) { fx[6 * i + 1] = 0; } if (finalConst.DY == DofConstraint.Released) { fx[6 * i + 2] = 0; } if (finalConst.RX == DofConstraint.Released) { fx[6 * i + 3] = 0; } if (finalConst.RY == DofConstraint.Released) { fx[6 * i + 4] = 0; } if (finalConst.RZ == DofConstraint.Released) { fx[6 * i + 5] = 0; } } }
/// <summary> /// Adds the analysis result. /// </summary> /// <param name="loadCase">The load case.</param> /// <remarks>if model is analyzed against specific load case, then displacements are available through <see cref="Displacements"/> property. /// If system is not analyses against a specific load case, then this method will analyses structure against <see cref="LoadCase"/>. /// While this method is using pre computed Cholesky Decomposition , its have a high performance in solving the system. /// </remarks> public void AddAnalysisResult_MPC(LoadCase loadCase) { var n = parent.Nodes.Count * 6; var dt = new double[n];//total delta ISolver solver; var perm = CalcUtil.GenerateP_Delta_Mpc(parent, loadCase, new Mathh.GaussRrefFinder()); var np = perm.Item1.ColumnCount;//master count var rd = perm.Item2; var pd = perm.Item1; var kt = MatrixAssemblerUtil.AssembleFullStiffnessMatrix(parent); var ft = new double[n]; { var fe = elementForces[loadCase] = GetTotalElementsForceVector(loadCase); var fc = concentratedForces[loadCase] = GetTotalConcentratedForceVector(loadCase); ft.AddToSelf(fe); ft.AddToSelf(fc); } if (perm.Item1.RowCount > 0 && perm.Item1.RowCount > 0) { var pf = pd.Transpose(); var kr = pf.Multiply(kt).Multiply(pd); var a1 = new double[n]; //a1.AddToSelf(rd); kt.Multiply(rd, a1); a1.AddToSelf(ft); var a2 = new double[np]; pf.Multiply(a1, a2); var a3 = new double[np]; #region load/generate solver if (Solvers_New.ContainsKey(pd)) { solver = Solvers_New[pd]; } else { solver = SolverFactory.CreateSolver((CCS)kr); Solvers_New[pd] = solver; } if (!solver.IsInitialized) { solver.Initialize(); } #endregion solver.Solve(a2, a3); pd.Multiply(a3, dt); } dt.AddToSelf(rd, -1); kt.Multiply(dt, ft); _forces[loadCase] = ft; _displacements[loadCase] = dt; }