예제 #1
0
        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;
        }
예제 #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 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;
        }