public static CCS GetReducedFreeFreeStiffnessMatrix(this Model model, LoadCase lc) { var fullst = MatrixAssemblerUtil.AssembleFullStiffnessMatrix(model); var mgr = DofMappingManager.Create(model, lc); var dvd = CalcUtil.GetReducedZoneDividedMatrix(fullst, mgr); return(dvd.ReleasedReleasedPart); }
/// <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(LoadCase loadCase) { ISolver solver; var map = DofMappingManager.Create(parent, loadCase); var n = parent.Nodes.Count; //node count var m = map.M; //master node count var pu = PermutationGenerator.GetDisplacementPermute(parent, map); //permutation of U var pf = PermutationGenerator.GetForcePermute(parent, map); //permutation of F var fe = elementForces[loadCase] = GetTotalElementsForceVector(loadCase); var fc = concentratedForces[loadCase] = GetTotalConcentratedForceVector(loadCase); var ft = fe.Plus(fc); var fr = pf.Multiply(ft); var ffr = GetFreePartOfReducedVector(fr, map); var fsr = GetFixedPartOfReducedVector(fr, map); var kt = MatrixAssemblerUtil.AssembleFullStiffnessMatrix(parent); var kr = (CCS)((CCS)pf.Multiply(kt)).Multiply(pu); #region U_s,r var usr = new double[map.RMap3.Length]; { //should fill usr var ut_temp = GetTotalDispVector(loadCase, map); for (int i = 0; i < usr.Length; i++) { var t1 = map.RMap3[i]; var t2 = map.RMap1[t1]; usr[i] = ut_temp[t2]; } } #endregion var krd = CalcUtil.GetReducedZoneDividedMatrix(kr, map); AnalyseStiffnessMatrixForWarnings(krd, map, loadCase); {//TODO: remove var minAbsDiag = double.MaxValue; foreach (var tpl in krd.ReleasedReleasedPart.EnumerateIndexed2()) { if (tpl.Item1 == tpl.Item2) { minAbsDiag = Math.Min(minAbsDiag, Math.Abs(tpl.Item3)); } } if (krd.ReleasedReleasedPart.RowCount != 0) { //var kk = krd.ReleasedReleasedPart.ToDenseMatrix(); } } #region solver if (Solvers.ContainsKey(map.MasterMap)) { solver = Solvers[map.MasterMap]; } else { solver = //SolverGenerator(krd.ReleasedReleasedPart); SolverFactory.CreateSolver(krd.ReleasedReleasedPart); Solvers[map.MasterMap] = solver; } if (!solver.IsInitialized) { solver.Initialize(); } #endregion double[] ufr = new double[map.RMap2.Length]; string message; var input = ffr.Minus(krd.ReleasedFixedPart.Multiply(usr)); solver.Solve(input, ufr); //if (res2 != SolverResult.Success) // throw new BriefFiniteElementNetException(message); var fpsr = krd.FixedReleasedPart.Multiply(ufr).Plus(krd.FixedFixedPart.Multiply(usr)); var fsrt = fpsr.Minus(fsr);// no needed var fx = supportReactions[loadCase] = new double[6 * n]; #region forming ft for (var i = 0; i < map.Fixity.Length; i++) { if (map.Fixity[i] == DofConstraint.Fixed) { ft[i] = 0; } } for (var i = 0; i < fpsr.Length; i++) { var totDofNum = map.RMap1[map.RMap3[i]]; ft[totDofNum] = fx[totDofNum] = fpsr[i]; } #endregion #region forming ur var ur = new double[map.M * 6]; for (var i = 0; i < usr.Length; i++) { ur[map.RMap3[i]] = usr[i]; } for (var i = 0; i < ufr.Length; i++) { ur[map.RMap2[i]] = ufr[i]; } #endregion var ut = pu.Multiply(ur); _forces[loadCase] = ft; _displacements[loadCase] = ut; }
private void AddAnalysisResult2(LoadCase loadCase) { ISolver solver; var map = DofMappingManager.Create(parent, loadCase); var n = parent.Nodes.Count; //node count var m = map.M; //master node count var dispPermute = PermutationGenerator.GetDisplacementPermute(parent, map); var forcePermute = PermutationGenerator.GetForcePermute(parent, map); var ft = GetTotalForceVector(loadCase, map); var ut = GetTotalDispVector(loadCase, map); var kt = MatrixAssemblerUtil.AssembleFullStiffnessMatrix(parent); for (var i = 0; i < map.Fixity.Length; i++) { if (map.Fixity[i] == DofConstraint.Fixed) { ft[i] = 0; } else { ut[i] = 0; } } var kr = (CCS)((CCS)forcePermute.Multiply(kt)).Multiply(dispPermute); var fr = forcePermute.Multiply(ft); var ur = new double[fr.Length]; for (var i = 0; i < 6 * m; i++) { ur[i] = ut[map.RMap1[i]]; } var krd = CalcUtil.GetReducedZoneDividedMatrix(kr, map); AnalyseStiffnessMatrixForWarnings(krd, map, loadCase); var ff_r = GetFreePartOfReducedVector(fr, map); var us_r = GetFixedPartOfReducedVector(ur, map); if (Solvers.ContainsKey(map.MasterMap)) { solver = Solvers[map.MasterMap]; } else { solver = //SolverGenerator(krd.ReleasedReleasedPart); SolverFactory.CreateSolver(krd.ReleasedReleasedPart); Solvers[map.MasterMap] = solver; } if (!solver.IsInitialized) { solver.Initialize(); } #region ff - kfs * us //درسته، تغییرش نده گوس... var ff_r_negative = ff_r.Clone(); for (var i = 0; i < ff_r.Length; i++) { ff_r[i] = -ff_r[i]; } krd.ReleasedFixedPart.Multiply(us_r, ff_r); for (var i = 0; i < ff_r.Length; i++) { ff_r[i] = -ff_r[i]; } #endregion var urf = new double[map.RMap2.Length]; //string msg; //var res = solver.Solve(ff_r, urf); //if (res != SolverResult.Success) // throw new BriefFiniteElementNetException(msg); var frs = CalcUtil.Add(krd.FixedReleasedPart.Multiply(urf), krd.FixedFixedPart.Multiply(us_r)); for (var i = 0; i < urf.Length; i++) { ur[map.RMap2[i]] = urf[i]; } for (var i = 0; i < frs.Length; i++) { fr[map.RMap3[i]] = frs[i]; } for (var i = 0; i < map.RMap3.Length; i++) { var ind = i; var gi = map.RMap1[map.RMap3[ind]]; ft[gi] = frs[ind]; } var ut2 = dispPermute.Multiply(ur); for (int i = 0; i < 6 * n; i++) { if (map.Fixity[i] == DofConstraint.Fixed) { ut2[i] = ut[i]; } } _forces[loadCase] = ft; _displacements[loadCase] = ut2; }
/// <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); kt.Multiply(dt, ft); _forces[loadCase] = ft; _displacements[loadCase] = dt; }