private List <List <int> > GetDistinctRigidElements(Model model, LoadCase loadCase)
        {
            for (int i = 0; i < model.Nodes.Count; i++)
            {
                model.Nodes[i].Index = i;
            }

            var n = model.Nodes.Count;

            var crd = new CoordinateStorage <double>(n, n, 1);

            foreach (var elm in model.RigidElements)
            {
                if (IsAppliableRigidElement(elm, loadCase))
                {
                    for (var i = 0; i < elm.Nodes.Count; i++)
                    {
                        crd.At(elm.Nodes[i].Index, elm.Nodes[i].Index, 1.0);
                    }

                    for (var i = 0; i < elm.Nodes.Count - 1; i++)
                    {
                        crd.At(elm.Nodes[i].Index, elm.Nodes[i + 1].Index, 1.0);
                        crd.At(elm.Nodes[i + 1].Index, elm.Nodes[i].Index, 1.0);
                    }
                }
            }

            var graph = Converter.ToCompressedColumnStorage(crd);

            var buf = CalcUtil.EnumerateGraphParts(graph);

            return(buf);
        }
Пример #2
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);
        }
Пример #3
0
        public static double[] GetAngleWithAxises(Vector vec)
        {
            var buf = new List <double>();

            buf.Add(CalcUtil.RadToDeg(Math.Acos(vec.X / vec.Length)));
            buf.Add(CalcUtil.RadToDeg(Math.Acos(vec.Y / vec.Length)));
            buf.Add(CalcUtil.RadToDeg(Math.Acos(vec.Z / vec.Length)));


            return(buf.ToArray());
        }
Пример #4
0
        /// <summary>
        /// Solves the instance with specified <see cref="solverType" /> and assuming linear behavior (both geometric and material) and for default load case.
        /// </summary>
        /// <param name="solverType">The solver type.</param>
        public void Solve(BuiltInSolverType solverType)
        {
            var gen = new Func <CompressedColumnStorage, ISolver>(i =>
            {
                var sl = CalcUtil.CreateBuiltInSolver(solverType);
                sl.A   = i;
                return(sl);
            });

            Solve(gen);
        }
Пример #5
0
        public void Solve_MPC(params LoadCase[] cases)
        {
            var fact = CalcUtil.CreateBuiltInSolverFactory(BuiltInSolverType.CholeskyDecomposition);

            var cfg = new SolverConfiguration();

            cfg.SolverFactory = fact;

            cfg.LoadCases.AddRange(cases);

            Solve_MPC(cfg);
        }
Пример #6
0
        /// <summary>
        /// Solves the instance assuming linear behavior (both geometric and material) for specified cases.
        /// </summary>
        /// <param name="cases">The cases.</param>
        public void Solve(params LoadCase[] cases)
        {
            var cfg = new SolverConfiguration();

            cfg.SolverGenerator = i =>
            {
                var sl = CalcUtil.CreateBuiltInSolver(BuiltInSolverType.CholeskyDecomposition);
                sl.A = i;
                return(sl);
            };

            cfg.LoadCases = new List <LoadCase>(cases);

            Solve(cfg);
        }
Пример #7
0
        public void Solve_MPC()
        {
            var fact = CalcUtil.CreateBuiltInSolverFactory(BuiltInSolverType.CholeskyDecomposition);

            var cfg = new SolverConfiguration();

            cfg.SolverFactory = fact;

            cfg.LoadCases = new List <LoadCase>()
            {
                LoadCase.DefaultLoadCase
            };

            Solve_MPC(cfg);
        }
Пример #8
0
        public Force[] GetGlobalEquivalentNodalLoads(Element element)
        {
            if (element is FrameElement2Node)
            {
                var frElm = element as FrameElement2Node;

                var l = (frElm.EndNode.Location - frElm.StartNode.Location).Length;

                var w = GetLocalDistributedLoad(element as Element1D);

                var localEndForces = new Force[2];


                localEndForces[0] = new Force(w.X * l / 2, w.Y * l / 2, w.Z * l / 2, 0, -w.Z * l * l / 12.0, w.Y * l * l / 12.0);
                localEndForces[1] = new Force(w.X * l / 2, w.Y * l / 2, w.Z * l / 2, 0, w.Z * l * l / 12.0, -w.Y * l * l / 12.0);


                localEndForces = CalcUtil.ApplyReleaseMatrixToEndForces(frElm, localEndForces);//applying release matrix to end forces



                for (var i = 0; i < element.Nodes.Length; i++)
                {
                    var frc = localEndForces[i];

                    localEndForces[i] =
                        new Force(
                            frElm.TransformLocalToGlobal(frc.Forces),
                            frElm.TransformLocalToGlobal(frc.Moments));
                }

                return(localEndForces);
            }


            return(element.GetGlobalEquivalentNodalLoads(this));
        }
Пример #9
0
        private static List <List <int> > GetDistinctRigidElements(Model model, LoadCase loadCase)
        {
            for (int i = 0; i < model.Nodes.Count; i++)
            {
                model.Nodes[i].Index = i;
            }

            var n = model.Nodes.Count;

            var ecrd = new CoordinateStorage <double>(n, n, 1); //for storing existence of rigid elements
            var crd  = new CoordinateStorage <double>(n, n, 1); //for storing hinged connection of rigid elements

            for (int ii = 0; ii < model.RigidElements.Count; ii++)
            {
                var elm = model.RigidElements[ii];

                if (IsAppliableRigidElement(elm, loadCase))
                {
                    for (var i = 0; i < elm.Nodes.Count; i++)
                    {
                        ecrd.At(elm.Nodes[i].Index, elm.Nodes[i].Index, 1.0);
                    }

                    for (var i = 0; i < elm.Nodes.Count - 1; i++)
                    {
                        ecrd.At(elm.Nodes[i].Index, elm.Nodes[i + 1].Index, 1.0);
                        ecrd.At(elm.Nodes[i + 1].Index, elm.Nodes[i].Index, 1.0);
                    }
                }
            }

            var graph = Converter.ToCompressedColumnStorage(ecrd);

            var buf = CalcUtil.EnumerateGraphParts(graph);

            return(buf);
        }
        /// <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;
        }
Пример #11
0
 /// <summary>
 /// Solves the instance with specified <see cref="solverType" /> and assuming linear behavior (both geometric and material) and for default load case.
 /// </summary>
 /// <param name="solverType">The solver type.</param>
 public void Solve(BuiltInSolverType solverType)
 {
     Solve(CalcUtil.CreateBuiltInSolverFactory(solverType));
 }
        /// <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;
        }
Пример #15
0
        public override Force[] GetGlobalEquivalentNodalLoads(Element element)
        {
            if (element is FrameElement2Node)
            {
                var e = element as FrameElement2Node;

                var localForce = this.force;

                if (this.coordinationSystem == CoordinationSystem.Global)
                {
                    var tmp = e.TransformGlobalToLocal(localForce.Forces, localForce.Moments);

                    localForce.Forces  = tmp[0];
                    localForce.Moments = tmp[1];
                }

                var buf = new Force[2];

                buf[0] = new Force();

                var l = (e.EndNode.Location - e.StartNode.Location).Length;

                var a = distanseFromStartNode;
                var b = l - a;

                var mymy1 = localForce.My * b / (l * l) * (b - 2 * a);
                var mymy2 = localForce.My * a / (l * l) * (a - 2 * b);

                var myfz1 = 6 * localForce.My * a * b / (l * l * l);
                var myfz2 = -myfz1;


                var mzmz1 = localForce.Mz * b / (l * l) * (b - 2 * a);
                var mzmz2 = localForce.Mz * a / (l * l) * (a - 2 * b);

                var mzfy1 = -6 * localForce.Mz * a * b / (l * l * l);
                var mzfy2 = -mzfy1;


                var fzmy1 = -localForce.Fz * a * b * b / (l * l);
                var fzmy2 = localForce.Fz * a * a * b / (l * l);

                var fzfz1 = localForce.Fz * b * b / (l * l * l) * (3 * a + b);
                var fzfz2 = localForce.Fz * a * a / (l * l * l) * (3 * b + a);


                var fymz1 = localForce.Fy * a * b * b / (l * l);
                var fymz2 = -localForce.Fy * a * a * b / (l * l);

                var fyfy1 = localForce.Fy * b * b / (l * l * l) * (3 * a + b);
                var fyfy2 = localForce.Fy * a * a / (l * l * l) * (3 * b + a);


                var fxfx1 = localForce.Fx * b / l;
                var fxfx2 = localForce.Fx * a / l;

                var mxmx1 = localForce.Mx * b / l;
                var mxmx2 = localForce.Mx * a / l;

                var f1 = new Force(
                    fxfx1,
                    mzfy1 + fyfy1,
                    fzfz1 + myfz1,
                    mxmx1,
                    mymy1 + fzmy1,
                    mzmz1 + fymz1
                    );

                var f2 = new Force(
                    fxfx2,
                    mzfy2 + fyfy2,
                    fzfz2 + myfz2,
                    mxmx2,
                    mymy2 + fzmy2,
                    mzmz2 + fymz2
                    );

                var localEndForces = new Force[2];
                localEndForces[0] = f1;
                localEndForces[1] = f2;

                localEndForces = CalcUtil.ApplyReleaseMatrixToEndForces(e, localEndForces);//applying release matrix to end forces

                var vecs  = new Vector[] { localEndForces[0].Forces, localEndForces[0].Moments, localEndForces[1].Forces, localEndForces[1].Moments };
                var tvecs = e.TransformLocalToGlobal(vecs);

                buf[0] = new Force(tvecs[0], tvecs[1]);
                buf[1] = new Force(tvecs[2], tvecs[3]);

                return(buf);
            }

            throw new NotImplementedException();
        }
Пример #16
0
        public static DofMappingManager Create(Model model, LoadCase cse)
        {
            var n = model.Nodes.Count;
            var m = 0;

            for (var i = 0; i < n; i++)
            {
                model.Nodes[i].Index = i;
            }

            var masters = CalcUtil.GetMasterMapping(model, cse);

            for (var i = 0; i < n; i++)
            {
                if (masters[i] == i)
                {
                    m++;
                }
            }

            var cnt = 0;

            var fixity = new DofConstraint[6 * n];


            #region Map4 and rMap4

            var map4  = new int[n];
            var rMap4 = new int[m];

            map4.FillNegative();
            rMap4.FillNegative();

            for (var i = 0; i < n; i++)
            {
                if (masters[i] == i)
                {
                    map4[i]    = cnt;
                    rMap4[cnt] = i;
                    cnt++;
                }
            }

            #endregion

            #region Map1 and rMap1

            var map1  = new int[6 * n];
            var rMap1 = new int[6 * m];

            map1.FillNegative();
            rMap1.FillNegative();

            cnt = 0;

            for (var i = 0; i < m; i++)
            {
                var ir = i;
                var it = rMap4[i];

                for (var j = 0; j < 6; j++)
                {
                    map1[it * 6 + j]  = ir * 6 + j;
                    rMap1[ir * 6 + j] = it * 6 + j;
                }
            }

            #endregion

            #region map2,map3,rmap2,rmap3

            var mf = 0;//fixes
            var mr = 0;

            for (var i = 0; i < n; i++)
            {
                if (masters[i] != i)
                {
                    continue;
                }

                var ctx = model.Nodes[i].Constraints;
                var s   = ctx.Sum();
                mf += s;
            }

            mr = 6 * m - mf;

            var rMap2 = new int[mr];
            var rMap3 = new int[mf];
            var map2  = new int[6 * m];
            var map3  = new int[6 * m];

            rMap2.FillNegative();
            rMap3.FillNegative();
            map2.FillNegative();
            map3.FillNegative();


            var rcnt = 0;
            var fcnt = 0;

            for (var i = 0; i < m; i++)
            {
                var arr = model.Nodes[rMap4[i]].Constraints.ToArray();

                for (var j = 0; j < 6; j++)
                {
                    if (arr[j] == DofConstraint.Released)
                    {
                        map2[6 * i + j] = rcnt;
                        rMap2[rcnt]     = 6 * i + j;
                        rcnt++;
                    }
                    else
                    {
                        map3[6 * i + j] = fcnt;
                        rMap3[fcnt]     = 6 * i + j;
                        fcnt++;
                    }
                }
            }


            for (var i = 0; i < n; i++)
            {
                var ctx = model.Nodes[i].Constraints.ToArray();

                for (var j = 0; j < 6; j++)
                {
                    fixity[6 * i + j] = ctx[j];
                }
            }

            #endregion

            #region RMaster

            var rMaster = new int[n];
            rMaster.FillNegative();

            cnt = 0;

            for (var i = 0; i < masters.Length; i++)
            {
                if (masters[i] == i)
                {
                    rMaster[i] = cnt++;
                }
            }

            #endregion


            var buf = new DofMappingManager();

            buf.Map1  = map1;
            buf.RMap1 = rMap1;

            buf.Map2  = map2;
            buf.RMap2 = rMap2;

            buf.Map3  = map3;
            buf.RMap3 = rMap3;

            buf.Map4  = map4;
            buf.RMap4 = rMap4;

            buf.Fixity = fixity;

            buf.M = m;
            buf.N = n;

            buf.MasterMap  = masters;
            buf.RMasterMap = rMaster;

            return(buf);
        }
Пример #17
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;
                }
            }
        }