public static CCS GetForcePermute(Model model, DofMappingManager mgr)
        {
            var buf = new PermutationGenerator();

            buf._target = model;
            buf.DofMap  = mgr;
            buf._m      = mgr.M;
            buf._n      = mgr.N;

            return(buf.GetForcePermutation());
        }
        /// <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;
        }