public Matrix CalcLocalStiffnessMatrix(Element targetElement)
        {
            var intg = new GaussianIntegrator();

            intg.GammaPointCount = 2;
            intg.XiPointCount    = 2;
            intg.EtaPointCount   = 2;

            intg.A2 = 1;
            intg.A1 = -1;

            intg.F2 = (gama => + 1);
            intg.F1 = (gama => - 1);

            intg.G2 = (eta, gama) => + 1;
            intg.G1 = (eta, gama) => - 1;

            intg.H = new FunctionMatrixFunction((xi, eta, gamma) =>
            {
                var b = this.GetBMatrixAt(targetElement, new double[] { xi, eta, gamma });
                var d = this.GetDMatrixAt(targetElement, new double[] { xi, eta, gamma });
                var j = this.GetJMatrixAt(targetElement, new double[] { xi, eta, gamma });

                var buf = targetElement.MatrixPool.Allocate(b.ColumnCount, b.ColumnCount);

                CalcUtil.Bt_D_B(b, d, buf);

                //var detj = Math.Abs(j.Determinant());

                //buf.MultiplyByConstant(detj);

                return(buf);
            });

            var res = intg.Integrate();

            return(res);
        }
예제 #2
0
        /// <inheritdoc/>
        public IEnumerable <Tuple <DoF, double> > GetLoadInternalForceAt(Element targetElement, ElementalLoad load,
                                                                         double[] isoLocation)
        {
            var n = targetElement.Nodes.Length;

            var buff = new List <Tuple <DoF, double> >();

            var tr = targetElement.GetTransformationManager();

            var br = targetElement as BarElement;

            var endForces = GetLocalEquivalentNodalLoads(targetElement, load);

            for (var i = 0; i < n; i++)
            {
                endForces[i] = -endForces[i];//(2,1) section
            }
            #region 2,1 (due to inverse of equivalent nodal loads)

            Force ends;//internal force in x=0 due to inverse of equivalent nodal loads will store in this variable,

            {
                var xi_s = new double[br.Nodes.Length]; //xi loc of each force
                var x_s  = new double[br.Nodes.Length]; //x loc of each force

                for (var i = 0; i < xi_s.Length; i++)
                {
                    var x_i  = targetElement.Nodes[i].Location - targetElement.Nodes[0].Location;
                    var xi_i = br.LocalCoordsToIsoCoords(x_i.Length)[0];

                    xi_s[i] = xi_i;
                    x_s[i]  = x_i.X;
                }

                ends = new Force();//sum of moved end forces to destination

                for (var i = 0; i < n; i++)
                {
                    if (xi_s[i] < isoLocation[0])
                    {
                        var frc_i = endForces[i];// new Force();

                        ends += frc_i.Move(new Point(x_s[i], 0, 0), Point.Origins);
                    }
                }
            }

            #endregion

            var to = Iso2Local(targetElement, isoLocation)[0];


            #region uniform & trapezoid, uses integration method

            if (load is UniformLoad || load is PartialNonUniformLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0, xi1;
                int    degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0    = -1;
                    xi1    = 1;
                    degree = 0;
                }
                else if (load is PartialNonUniformLoad)
                {
                    var uld = (load as PartialNonUniformLoad);

                    magnitude = (xi => uld.GetMagnitudeAt(targetElement, new IsoPoint(xi)));
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0 = uld.StartLocation.Xi;
                    xi1 = uld.EndLocation.Xi;

                    degree = uld.SeverityFunction.Coefficients.Length;
                }
                else
                {
                    throw new NotImplementedException();
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = 0;                      // GetNMaxOrder(targetElement).Max();

                    var gpt = (nOrd + degree) / 2 + 3; //gauss point count

                    Matrix integral;

                    double i0 = 0, i1 = 0;//span for integration

                    var xi_t = isoLocation[0];

                    #region span of integration
                    {
                        if (xi_t < xi0)
                        {
                            i0 = i1 = xi0;
                        }

                        if (xi_t > xi1)
                        {
                            i0 = xi0;
                            i1 = xi1;
                        }

                        if (xi_t < xi1 && xi_t > xi0)
                        {
                            i0 = xi0;
                            i1 = xi_t;
                        }
                    }
                    #endregion

                    #region integration
                    {
                        if (i1 == i0)
                        {
                            integral = new Matrix(2, 1);
                        }
                        else
                        {
                            var x0 = br.IsoCoordsToLocalCoords(i0)[0];
                            var x1 = br.IsoCoordsToLocalCoords(i1)[0];

                            var intgV = GaussianIntegrator.CreateFor1DProblem(xx =>
                            {
                                //var xi = Local2Iso(targetElement, x)[0];
                                //var j = GetJMatrixAt(targetElement, xi);

                                var xi = br.LocalCoordsToIsoCoords(xx)[0];

                                var q__ = magnitude(xi);
                                var q_  = localDir * q__;

                                double df, dm;

                                if (this._direction == BeamDirection.Y)
                                {
                                    df = q_.Z;
                                    dm = -q_.Z * xx;
                                }
                                else
                                {
                                    df = q_.Y;
                                    dm = q_.Y * xx;
                                }

                                var buf_ = new Matrix(new double[] { df, dm });

                                return(buf_);
                            }, x0, x1, gpt);

                            integral = intgV.Integrate();
                        }
                    }
                    #endregion


                    var v_i = integral[0, 0];
                    var m_i = integral[1, 0];

                    var frc = new Force();

                    var x = Iso2Local(targetElement, isoLocation)[0];

                    var f = new Force();


                    if (this._direction == BeamDirection.Y)
                    {
                        f.Fz = v_i;
                        f.My = m_i;//negative is taken into account earlier
                    }
                    else
                    {
                        f.Fy = v_i;
                        f.Mz = m_i;
                    }



                    //f = f.Move(new Point(0, 0, 0), new Point(x, 0, 0));
                    //frc = frc + ends;
                    //var movedEnds = ends.Move(new Point(0, 0, 0), new Point(x, 0, 0));

                    if (br.StartReleaseCondition.DY == DofConstraint.Released)
                    {
                        f.Fy = 0;
                    }

                    if (br.StartReleaseCondition.DZ == DofConstraint.Released)
                    {
                        f.Fz = 0;
                    }

                    if (br.StartReleaseCondition.RY == DofConstraint.Released)
                    {
                        f.My = 0;
                    }

                    if (br.StartReleaseCondition.RZ == DofConstraint.Released)
                    {
                        f.Mz = 0;
                    }



                    var f2 = f + ends;

                    f2 = f2.Move(new Point(0, 0, 0), new Point(x, 0, 0));

                    f2 *= -1;

                    if (_direction == BeamDirection.Y)
                    {
                        buff.Add(Tuple.Create(DoF.Ry, f2.My));
                        buff.Add(Tuple.Create(DoF.Dz, f2.Fz));
                    }
                    else
                    {
                        buff.Add(Tuple.Create(DoF.Rz, f2.Mz));
                        buff.Add(Tuple.Create(DoF.Dy, f2.Fy));
                    }


                    return(buff);
                }
            }



            #endregion

            #region concentrated

            if (load is ConcentratedLoad)
            {
                var cns = load as ConcentratedLoad;

                var xi      = isoLocation[0];
                var targetX = br.IsoCoordsToLocalCoords(xi)[0];

                var frc = Force.Zero;

                if (cns.ForceIsoLocation.Xi < xi)
                {
                    frc = cns.Force;
                }

                if (cns.CoordinationSystem == CoordinationSystem.Global)
                {
                    frc = tr.TransformGlobalToLocal(frc);
                }

                var frcX = br.IsoCoordsToLocalCoords(cns.ForceIsoLocation.Xi)[0];

                frc = frc.Move(new Point(frcX, 0, 0), new Point(0, 0, 0));
                frc = frc.Move(new Point(0, 0, 0), new Point(targetX, 0, 0));

                var movedEnds = ends.Move(new Point(0, 0, 0), new Point(targetX, 0, 0));

                var f2 = frc + movedEnds;
                f2 *= -1;


                if (_direction == BeamDirection.Y)
                {
                    buff.Add(Tuple.Create(DoF.Ry, f2.My));
                    buff.Add(Tuple.Create(DoF.Dz, f2.Fz));
                }
                else
                {
                    buff.Add(Tuple.Create(DoF.Rz, f2.Mz));
                    buff.Add(Tuple.Create(DoF.Dy, f2.Fy));
                }

                return(buff);
            }

            #endregion

            throw new NotImplementedException();
        }
예제 #3
0
        public Force[] GetLocalEquivalentNodalLoads(Element targetElement, ElementalLoad load)
        {
            var bar = targetElement as BarElement;
            var n   = bar.Nodes.Length;


            //https://www.quora.com/How-should-I-perform-element-forces-or-distributed-forces-to-node-forces-translation-in-the-beam-element

            var tr = targetElement.GetTransformationManager();

            #region uniform

            if (load is UniformLoad || load is PartialNonUniformLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0, xi1;
                int    degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0    = -1;
                    xi1    = 1;
                    degree = 0;
                }
                else if (load is PartialNonUniformLoad)
                {
                    var uld = (load as PartialNonUniformLoad);

                    magnitude = (xi => uld.GetMagnitudeAt(targetElement, new IsoPoint(xi)));
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0 = uld.StartLocation.Xi;
                    xi1 = uld.EndLocation.Xi;

                    degree = uld.SeverityFunction.Coefficients.Length;
                }
                else
                {
                    throw new NotImplementedException();
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = GetNMaxOrder(targetElement).Max();

                    var gpt = (nOrd + degree) / 2 + 1;//gauss point count

                    var intg = GaussianIntegrator.CreateFor1DProblem(xi =>
                    {
                        var shp = GetNMatrixAt(targetElement, xi, 0, 0);

                        /*
                         * if (_direction == BeamDirection.Y)
                         * {
                         *  for (var i = 0; i < shp.ColumnCount; i++)
                         *  {
                         *      if (i % 2 == 1)
                         *          shp.MultiplyColumnByConstant(i, -1);
                         *  }
                         * }*/

                        var q__ = magnitude(xi);
                        var j   = GetJMatrixAt(targetElement, xi, 0, 0);
                        shp.MultiplyByConstant(j.Determinant());

                        var q_ = localDir * q__;

                        if (this._direction == BeamDirection.Y)
                        {
                            shp.MultiplyByConstant(q_.Z);
                        }
                        else
                        {
                            shp.MultiplyByConstant(q_.Y);
                        }

                        return(shp);
                    }, xi0, xi1, gpt);

                    var res = intg.Integrate();

                    var localForces = new Force[2];

                    if (this._direction == BeamDirection.Y)
                    {
                        var fz0 = res[0, 0];
                        var my0 = res[0, 1];
                        var fz1 = res[0, 2];
                        var my1 = res[0, 3];

                        localForces[0] = new Force(0, 0, fz0, 0, my0, 0);
                        localForces[1] = new Force(0, 0, fz1, 0, my1, 0);
                    }
                    else
                    {
                        var fy0 = res[0, 0];
                        var mz0 = res[0, 1];
                        var fy1 = res[0, 2];
                        var mz1 = res[0, 3];

                        localForces[0] = new Force(0, fy0, 0, 0, 0, mz0);
                        localForces[1] = new Force(0, fy1, 0, 0, 0, mz1);
                    }

                    return(localForces);
                }
            }

            #endregion

            #region ConcentratedLoad

            if (load is ConcentratedLoad)
            {
                var cl = load as ConcentratedLoad;

                var localforce = cl.Force;

                if (cl.CoordinationSystem == CoordinationSystem.Global)
                {
                    localforce = tr.TransformGlobalToLocal(localforce);
                }

                var buf = new Force[n];

                var ns = GetNMatrixAt(targetElement, cl.ForceIsoLocation.Xi);

                /*
                 * if (_direction == BeamDirection.Y)
                 *  for (var i = 0; i < ns.ColumnCount; i++)
                 *      if (i % 2 == 1)
                 *          ns.MultiplyColumnByConstant(i, -1);
                 */


                var j = GetJMatrixAt(targetElement, cl.ForceIsoLocation.Xi);

                var detJ = j.Determinant();

                ns.MultiplyRowByConstant(1, 1 / detJ);
                ns.MultiplyRowByConstant(2, 1 / (detJ * detJ));
                ns.MultiplyRowByConstant(3, 1 / (detJ * detJ * detJ));


                for (var i = 0; i < n; i++)
                {
                    var node = bar.Nodes[i];

                    var fi = new Force();

                    var ni = ns[0, 2 * i];
                    var mi = ns[0, 2 * i + 1];

                    var nip = ns[1, 2 * i];
                    var mip = ns[1, 2 * i + 1];

                    if (this._direction == BeamDirection.Z)
                    {
                        fi.Fy += localforce.Fy * ni;  //concentrated force
                        fi.Mz += localforce.Fy * mi;  //concentrated force

                        fi.Fy += localforce.Mz * nip; //concentrated moment
                        fi.Mz += localforce.Mz * mip; //concentrated moment
                    }
                    else
                    {
                        fi.Fz += localforce.Fz * ni;   //concentrated force
                        fi.My += localforce.Fz * mi;   //concentrated force

                        fi.Fz += localforce.My * nip;  //concentrated moment
                        fi.My += localforce.My * -mip; //concentrated moment
                    }

                    buf[i] = fi;
                }

                return(buf);
            }



            #endregion



            throw new NotImplementedException();
        }
예제 #4
0
        public Force[] GetLocalEquivalentNodalLoads(Element targetElement, ElementalLoad load)
        {
            var tr = targetElement.GetTransformationManager();

            #region uniform

            if (load is BriefFiniteElementNet.Loads.UniformLoad)
            {
                var ul = load as BriefFiniteElementNet.Loads.UniformLoad;

                var localDir = ul.Direction.GetUnit();

                if (ul.CoordinationSystem == CoordinationSystem.Global)
                {
                    localDir = tr.TransformGlobalToLocal(localDir);
                }

                var ux = localDir.X * ul.Magnitude;
                var uy = localDir.Y * ul.Magnitude;
                var uz = localDir.Z * ul.Magnitude;

                var intg = new GaussianIntegrator();

                intg.A1 = -1;
                intg.A2 = 1;

                intg.F1 = gama => - 1;
                intg.F2 = gama => 1;

                intg.G1 = (eta, gama) => 0;
                intg.G2 = (eta, gama) => 1;

                intg.GammaPointCount = 1;
                intg.XiPointCount    = intg.EtaPointCount = 2;

                intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
                {
                    var shp = GetNMatrixAt(targetElement, xi, eta, 0);
                    var j   = GetJMatrixAt(targetElement, xi, eta, 0);
                    shp.MultiplyByConstant(j.Determinant());
                    shp.MultiplyByConstant(uz);

                    return(shp);
                }
                                                    );


                var res = intg.Integrate();

                var localForces = new Force[4];

                for (var i = 0; i < 4; i++)
                {
                    localForces[i] = new Force(0, 0, res[i, 0], 0, 0, 0);
                }

                throw new NotImplementedException();
                var globalForces = localForces.Select(i => tr.TransformLocalToGlobal(i)).ToArray();

                return(globalForces);
            }

            #endregion

            #region non uniform
            if (load is BriefFiniteElementNet.Loads.PartialNonUniformLoad)  // TODO
            {
                //TODO
                throw new NotImplementedException();

                var ul = load as BriefFiniteElementNet.Loads.PartialNonUniformLoad;

                var localDir = ul.Direction.GetUnit();

                if (ul.CoordinationSystem == CoordinationSystem.Global)
                {
                    localDir = tr.TransformGlobalToLocal(localDir);
                }

                /*
                 * var interpolator = new Func<double, double, double>((xi,eta)=>
                 * {
                 *  var shp = GetNMatrixAt(targetElement, xi, eta, 0).Transpose();
                 *  var frc = new Matrix(4, 1);
                 *  //frc.FillColumn(0, ul.NodalMagnitudes);
                 *  var mult = shp * frc;
                 *
                 *  return mult[0, 0];
                 * });
                 *
                 * var ux = new Func<double, double, double>((xi, eta) => localDir.X * interpolator(xi, eta));
                 * var uy = new Func<double, double, double>((xi, eta) => localDir.Y * interpolator(xi, eta));
                 * var uz = new Func<double, double, double>((xi, eta) => localDir.Z * interpolator(xi, eta));
                 */

                var st = ul.StartLocation;
                var en = ul.EndLocation;

                var intg = new GaussianIntegrator();

                intg.A1 = 0;
                intg.A2 = 1;

                intg.F1 = gama => st.Eta;
                intg.F2 = gama => en.Eta;

                intg.G1 = (eta, gama) => st.Xi;
                intg.G2 = (eta, gama) => en.Xi;

                var order = ul.SeverityFunction.Degree;

                intg.GammaPointCount = 1;
                intg.XiPointCount    = intg.EtaPointCount = 2;

                throw new Exception();

                intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
                {
                    var shp = GetNMatrixAt(targetElement, xi, eta, 0);
                    var j   = GetJMatrixAt(targetElement, xi, eta, 0);
                    shp.MultiplyByConstant(j.Determinant());

                    //var uzm = ul.SeverityFunction.Evaluate(xi, eta);

                    //shp.MultiplyByConstant(uzm);

                    return(shp);
                }
                                                    );

                var res = intg.Integrate();

                var localForces = new Force[4];

                for (var i = 0; i < 4; i++)
                {
                    localForces[i] = new Force(0, 0, res[i, 0], 0, 0, 0);
                }

                return(localForces);
            }

            #endregion

            throw new NotImplementedException();
        }
        public static Matrix CalcLocalKMatrix_Bar(IElementHelper helper, Element targetElement)
        {
            var elm = targetElement as BarElement;

            if (elm == null)
            {
                throw new Exception();
            }

            var nb = helper.GetBMaxOrder(targetElement);
            var nd = elm.Material.GetMaxFunctionOrder();
            var nt = elm.Section.GetMaxFunctionOrder();
            var nj = helper.GetDetJOrder(targetElement);


            var sum = new int[3];

            foreach (var i in new int[][] { nb, nd, nb, nt, nj })//B D B |J|
            {
                for (int j = 0; j < 3; j++)
                {
                    sum[j] += i[j];
                }
            }

            var nXi   = sum[0] / 2 + 1;
            var nEta  = sum[1] / 2 + 1;
            var nGama = sum[2] / 2 + 1;

            //nXi += 2;

            //var ng = (2*nb + nd + nj)/2 + 1;
            var intg = new GaussianIntegrator();

            intg.A1 = 0;
            intg.A2 = 1;

            intg.F1            = (gama => 0);
            intg.F2            = (gama => 1);
            intg.EtaPointCount = 1;

            intg.G1 = (eta, gamma) => - 1;
            intg.G2 = (eta, gamma) => + 1;

            intg.GammaPointCount = nGama;
            intg.XiPointCount    = nXi;
            intg.EtaPointCount   = nEta;

            /*
             * intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
             * {
             *  var b = helper.GetBMatrixAt(elm, xi);
             *  var d = helper.GetDMatrixAt(elm, xi);
             *  var j = helper.GetJMatrixAt(elm, xi);
             *
             *  var buf_ =
             *      //new Matrix(b.ColumnCount, b.ColumnCount);
             *      targetElement.CreateOrRentMatrixFromPool(b.ColumnCount, b.ColumnCount);
             *
             *  Matrix.TransposeMultiply(b, b, buf_);
             *
             *  //var buf_2 = b.Transpose() * d * b;
             *  buf_.MultiplyByConstant(d[0, 0] * Math.Abs(j.Determinant()));
             *
             *  b.ReturnToPool();
             *  d.ReturnToPool();
             *  j.ReturnToPool();
             *
             *  return buf_;
             * });*/

            intg.H = new MultiplierMatrixFunction(elm, helper);

            intg.MatrixPool = elm.MatrixPool;

            var res = intg.Integrate();

            return(res);
        }
        public static Matrix CalcLocalKMatrix_Triangle(IElementHelper helper, Element targetElement)
        {
            var qq = targetElement as TriangleElement;

            if (qq == null)
            {
                throw new Exception();
            }

            var trans = qq.GetLambdaMatrix().Transpose();

            var nb = helper.GetBMaxOrder(targetElement);
            var nd = qq.Material.GetMaxFunctionOrder();
            var nt = qq.Section.GetMaxFunctionOrder();
            var nj = helper.GetDetJOrder(targetElement);

            var sum = new int[3];

            foreach (var i in new int[][] { nb, nd, nb, nt, nj })
            {
                for (int j = 0; j < 3; j++)
                {
                    sum[j] += i[j];
                }
            }

            var nXi   = sum[0] / 2 + 1;
            var nEta  = sum[1] / 2 + 1;
            var nGama = sum[2] / 2 + 1;

            var intg = new GaussianIntegrator();

            intg.GammaPointCount = nGama;
            intg.XiPointCount    = nXi;
            intg.EtaPointCount   = nEta;

            intg.A2 = 1;
            intg.A1 = 0;

            intg.F2 = (gama => 1);
            intg.F1 = (gama => 0);

            intg.G2 = ((eta, gama) => 1 - eta);
            intg.G1 = ((eta, gama) => 0);

            intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
            {
                var b = helper.GetBMatrixAt(qq, xi, eta);
                var d = helper.GetDMatrixAt(qq, xi, eta);
                var j = helper.GetJMatrixAt(qq, xi, eta);

                var buf = new Matrix(b.ColumnCount, b.ColumnCount);

                CalcUtil.Bt_D_B(b, d, buf);

                buf.MultiplyByConstant((j.Determinant()));

                return(buf);
            });

            var res = intg.Integrate();

            return(res);
        }
        public static Matrix CalcLocalCMatrix_Bar(IElementHelper helper, Element targetElement)
        {
            var elm = targetElement as BarElement;

            if (elm == null)
            {
                throw new Exception();
            }

            var nn = helper.GetNMaxOrder(targetElement);
            var nd = elm.Material.GetMaxFunctionOrder();
            var nt = elm.Section.GetMaxFunctionOrder();
            var nj = helper.GetDetJOrder(targetElement);

            var sum = new int[3];

            foreach (var i in new int[][] { nn, nd, nt, nn, nj })
            {
                for (int j = 0; j < 3; j++)
                {
                    sum[j] += i[j];
                }
            }

            var nXi   = sum[0] / 2 + 1;
            var nEta  = sum[1] / 2 + 1;
            var nGama = sum[2] / 2 + 1;

            //var nRho = elm.Material.GetMaxFunctionOrder().Max() + elm.Section.GetMaxFunctionOrder();
            //var ng = (2 * nn + nRho + nj) / 2 + 1;

            var intg = new GaussianIntegrator();

            intg.GammaPointCount = nGama;
            intg.XiPointCount    = nXi;
            intg.EtaPointCount   = nEta;

            intg.A1 = 0;
            intg.A2 = 1;

            intg.F1            = (gama => 0);
            intg.F2            = (gama => 1);
            intg.EtaPointCount = 1;

            intg.G1 = (eta, gamma) => - 1;
            intg.G2 = (eta, gamma) => + 1;
            //intg.XiPointCount = ng;

            intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
            {
                var n  = helper.GetNMatrixAt(elm, xi);
                var mu = helper.GetMuMatrixAt(elm, xi);
                var j  = helper.GetJMatrixAt(elm, xi);

                var buf_ = n.Transpose() * mu * n;
                buf_.MultiplyByConstant(j.Determinant());

                return(buf_);
            });

            var res = intg.Integrate();

            return(res);
        }
        public static Matrix CalcLocalKMatrix_Quad(IElementHelper helper, Element targetElement)
        {
            var qq = targetElement as QuadrilaturalElement;

            if (qq == null)
            {
                throw new Exception();
            }

            var trans = qq.GetLambdaMatrix().Transpose();

            var nb = helper.GetBMaxOrder(targetElement);
            var nd = qq.Material.GetMaxFunctionOrder();
            var nt = qq.Section.GetMaxFunctionOrder();
            var nj = helper.GetDetJOrder(targetElement);

            var sum = new int[3];

            foreach (var i in new int[][] { nb, nd, nb, nt, nj })
            {
                for (int j = 0; j < 3; j++)
                {
                    sum[j] += i[j];
                }
            }

            var nXi   = sum[0] / 2 + 1;
            var nEta  = sum[1] / 2 + 1;
            var nGama = sum[2] / 2 + 1;

            var intg = new GaussianIntegrator();

            intg.GammaPointCount = nGama;
            intg.XiPointCount    = nXi;
            intg.EtaPointCount   = nEta;

            intg.A2 = 1;
            intg.A1 = 0;

            intg.F2 = (gama => + 1);
            intg.F1 = (gama => - 1);

            intg.G2 = (eta, gama) => + 1;
            intg.G1 = (eta, gama) => - 1;   // formula 4.53 (Development of Membrane, Plate and Flat Shell Elements in Java) --> see GaussianIntegrator.cs for correct variable assignment

            intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
            {
                var b    = helper.GetBMatrixAt(qq, xi, eta);
                var d    = helper.GetDMatrixAt(qq, xi, eta);
                var j    = helper.GetJMatrixAt(qq, xi, eta);
                var detj = Math.Abs(j.Determinant());

                var buf = new Matrix(b.ColumnCount, b.ColumnCount); // result matrix , TODO: use matrix pool

                CalcUtil.Bt_D_B(b, d, buf);                         // multiplicates three matrices

                buf.Scale(detj);

                return(buf);
            });


            var res = intg.Integrate();

            return(res);
        }
예제 #9
0
        /// <inheritdoc/>
        public IEnumerable <Tuple <DoF, double> > GetLoadInternalForceAt(Element targetElement, Load load,
                                                                         double[] isoLocation)
        {
            var buff = new List <Tuple <DoF, double> >();

            //var buf = new FlatShellStressTensor();

            var tr = targetElement.GetTransformationManager();

            var br = targetElement as BarElement;

            var endForces = GetLocalEquivalentNodalLoads(targetElement, load);

            var n = targetElement.Nodes.Length;

            for (var i = 0; i < n; i++)
            {
                endForces[i] = -endForces[i];
            }

            #region 2,1 (due to inverse of equivalent nodal loads)

            Force ends;//internal force in x=0 due to inverse of equivalent nodal loads will store in this variable,

            {
                var xi_s = new double[br.Nodes.Length]; //xi loc of each force
                var x_s  = new double[br.Nodes.Length]; //x loc of each force

                for (var i = 0; i < xi_s.Length; i++)
                {
                    var x_i  = targetElement.Nodes[i].Location - targetElement.Nodes[0].Location;
                    var xi_i = br.LocalCoordsToIsoCoords(x_i.Length)[0];

                    xi_s[i] = xi_i;
                    x_s[i]  = x_i.X;
                }

                ends = new Force();//sum of moved end forces to destination

                for (var i = 0; i < n; i++)
                {
                    if (xi_s[i] < isoLocation[0])
                    {
                        var frc_i = endForces[i];// new Force();
                        ends += frc_i.Move(new Point(x_s[i], 0, 0), Point.Origins);
                    }
                }
            }


            #endregion


            var to = Iso2Local(targetElement, isoLocation)[0];

            //var xi = isoLocation[0];

            #region uniform & trapezoid

            if (load is UniformLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0;
                int    degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0 = -1;
                    //xi1 = 1;
                    degree = 0;
                }
                else
                {
                    throw new NotImplementedException();

                    /*
                     * var tld = (load as NonUniformlLoad);
                     *
                     * magnitude = (xi => (load as NonUniformlLoad).GetMagnitudesAt(xi, 0, 0)[0]);
                     * localDir = tld.Direction;
                     *
                     * if (tld.CoordinationSystem == CoordinationSystem.Global)
                     *  localDir = tr.TransformGlobalToLocal(localDir);
                     *
                     * xi0 = tld.StartLocation[0];
                     * xi1 = tld.EndLocation[0];
                     * degree = 1;
                     */
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = 0;                      // GetNMaxOrder(targetElement).Max();

                    var gpt = (nOrd + degree) / 2 + 1; //gauss point count

                    Matrix integral;


                    if (isoLocation[0] < xi0)
                    {
                        integral = new Matrix(2, 1);
                    }
                    else
                    {
                        var intgV = GaussianIntegrator.CreateFor1DProblem(x =>
                        {
                            var xi  = Local2Iso(targetElement, x)[0];
                            var q__ = magnitude(xi);
                            var q_  = localDir * q__;

                            var df = q_.X;

                            var buf_ = new Matrix(new double[] { df });

                            return(buf_);
                        }, 0, to, gpt);

                        integral = intgV.Integrate();
                    }

                    var f_i = integral[0, 0];

                    var movedEnds = ends.Move(new Point(), new Point());//no need to move as it is truss without moments
                    var fMoved    = new Force(f_i, 00, 00, 0, 0, 0);

                    var ft = movedEnds + fMoved;

                    //ft *= -1;

                    buff.Add(Tuple.Create(DoF.Dx, ft.Fx));
                }

                return(buff);
            }

            #endregion

            #region concentrated

            if (load is ConcentratedLoad)
            {
                var cns = load as ConcentratedLoad;

                var xi      = isoLocation[0];
                var targetX = br.IsoCoordsToLocalCoords(xi)[0];

                var frc = Force.Zero;

                if (cns.ForceIsoLocation.Xi < xi)
                {
                    frc = cns.Force;
                }

                if (cns.CoordinationSystem == CoordinationSystem.Global)
                {
                    frc = tr.TransformGlobalToLocal(frc);
                }


                var frcX = br.IsoCoordsToLocalCoords(cns.ForceIsoLocation.Xi)[0];

                frc = frc.Move(new Point(frcX, 0, 0), new Point(0, 0, 0));
                frc = frc.Move(new Point(0, 0, 0), new Point(targetX, 0, 0));

                var movedEnds = ends.Move(new Point(0, 0, 0), new Point(targetX, 0, 0));

                var f2 = frc + movedEnds;
                //f2 *= -1;

                buff.Add(Tuple.Create(DoF.Dx, f2.Fx));

                return(buff);
            }

            #endregion


            throw new NotImplementedException();
        }
예제 #10
0
        public Force[] GetLocalEquivalentNodalLoads(Element targetElement, Load load)
        {
            //https://www.quora.com/How-should-I-perform-element-forces-or-distributed-forces-to-node-forces-translation-in-the-beam-element

            if (load is Loads.UniformLoad)
            {
                var ul = load as Loads.UniformLoad;

                var localDir = ul.Direction;

                if (ul.CoordinationSystem == CoordinationSystem.Global)
                {
                    var tr = targetElement.GetTransformationManager();
                    localDir = tr.TransformGlobalToLocal(ul.Direction);
                }

                var ux = localDir.X * ul.Magnitude;
                var uy = localDir.Y * ul.Magnitude;
                var uz = localDir.Z * ul.Magnitude;

                var intg = new GaussianIntegrator();
                intg.A1           = -1;
                intg.A2           = +1;
                intg.XiPointCount = 2;
                intg.H            = new FunctionMatrixFunction((xi, eta, gama) =>
                {
                    var mtx = new Matrix(4, 0);
                    var shp = GetNMatrixAt(targetElement, xi, eta, gama);

                    return(shp);
                });

                var res = intg.Integrate();

                var buf = new Force[2];

                var fy0 = res[0, 0];
                var mz0 = res[1, 0];
                var fy1 = res[2, 0];
                var mz1 = res[3, 0];

                buf[0] = new Force(0, fy0, 0, 0, 0, mz0);
                buf[1] = new Force(0, fy1, 0, 0, 0, mz1);

                return(buf);
            }


            if (load is Loads.ConcentratedLoad)
            {
                var ul = load as Loads.ConcentratedLoad;

                var localforce = ul.Force;

                if (ul.CoordinationSystem == CoordinationSystem.Global)
                {
                    var tr = targetElement.GetTransformationManager();
                    localforce = tr.TransformGlobalToLocal(ul.Force);
                }

                var shp = GetNMatrixAt(targetElement, ul.ForceIsoLocation);
                throw new NotImplementedException();
            }

            throw new NotImplementedException();
        }
        public Force[] GetLocalEquivalentNodalLoads(Element targetElement, ElementalLoad load)
        {
            var hex = targetElement as HexahedralElement;
            var n   = hex.Nodes.Length;


            var tr = targetElement.GetTransformationManager();

            #region uniform

            if (load is UniformLoad || load is PartialNonUniformLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0, xi1;
                double eta0, eta1;
                double lambda0, lambda1;

                int degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0 = -1;
                    xi1 = 1;

                    eta0 = -1;
                    eta1 = 1;

                    lambda0 = -1;
                    lambda1 = 1;

                    degree = 0;
                }
                else if (load is PartialNonUniformLoad)
                {
                    var uld = (load as PartialNonUniformLoad);

                    magnitude = (xi => uld.GetMagnitudeAt(targetElement, new IsoPoint(xi)));
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0 = uld.StartLocation.Xi;
                    xi1 = uld.EndLocation.Xi;

                    eta0 = uld.StartLocation.Eta;
                    eta1 = uld.EndLocation.Eta;

                    lambda0 = uld.StartLocation.Lambda;
                    lambda1 = uld.EndLocation.Lambda;

                    degree = uld.SeverityFunction.Degree[0];// Coefficients.Length;
                }
                else
                {
                    throw new NotImplementedException();
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = GetNMaxOrder(targetElement);

                    //var gpt = (nOrd + degree) / 2 + 1;//gauss point count

                    var intg = new GaussianIntegrator();

                    intg.A1 = lambda0;
                    intg.A2 = lambda1;

                    intg.F1 = gama => eta0;
                    intg.F2 = gama => eta1;

                    intg.G1 = (eta, gama) => xi0;
                    intg.G2 = (eta, gama) => xi1;

                    intg.XiPointCount    = (nOrd[0] + degree) / 2 + 1;
                    intg.EtaPointCount   = (nOrd[1] + degree) / 2 + 1;
                    intg.GammaPointCount = (nOrd[2] + degree) / 2 + 1;

                    intg.MatrixPool = hex.MatrixPool;

                    intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
                    {
                        var shp = GetNMatrixAt(targetElement, xi, eta, gama);

                        var shp2 = hex.MatrixPool.Allocate(3, shp.ColumnCount);

                        shp2.AssembleInside(shp, 0, 0);
                        shp2.AssembleInside(shp, 1, 0);
                        shp2.AssembleInside(shp, 2, 0);


                        var j = GetJMatrixAt(targetElement, xi, 0, 0);
                        shp.MultiplyByConstant(j.Determinant());

                        var q__ = magnitude(xi);

                        var q_ = localDir * q__;

                        shp2.MultiplyRowByConstant(0, q_.X);
                        shp2.MultiplyRowByConstant(1, q_.Y);
                        shp2.MultiplyRowByConstant(2, q_.Z);

                        return(shp2);
                    });


                    var res = intg.Integrate();

                    var localForces = new Force[2];

                    //res is 3x8 matrix, each columns has x,y and z components for force on each node
                    for (var i = 0; i < 8; i++)
                    {
                        var fx = res[0, i];
                        var fy = res[1, i];
                        var fz = res[2, i];

                        localForces[i] = new Force(fx, fy, fz, 0, 0, 0);
                    }

                    return(localForces);
                }
            }

            #endregion

            #region ConcentratedLoad

            if (load is ConcentratedLoad)
            {
                var cl = load as ConcentratedLoad;

                var localforce = cl.Force;

                if (cl.CoordinationSystem == CoordinationSystem.Global)
                {
                    localforce = tr.TransformGlobalToLocal(localforce);
                }

                var buf = new Force[n];

                var ns = GetNMatrixAt(targetElement, cl.ForceIsoLocation.Xi, cl.ForceIsoLocation.Eta, cl.ForceIsoLocation.Lambda);

                for (var i = 0; i < n; i++)
                {
                    buf[i] = localforce * ns[0, i];
                }

                return(buf);
            }

            #endregion


            throw new NotImplementedException();
        }
예제 #12
0
        public Force[] GetLocalEquivalentNodalLoads(Element targetElement, Load load)
        {
            //https://www.quora.com/How-should-I-perform-element-forces-or-distributed-forces-to-node-forces-translation-in-the-beam-element

            var tr = targetElement.GetTransformationManager();

            #region uniform & trapezoid

            if (load is UniformLoad || load is PartialTrapezoidalLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0, xi1;
                int    degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    xi0    = -1;
                    xi1    = 1;
                    degree = 0;
                }
                else
                {
                    var tld = (load as PartialTrapezoidalLoad);

                    magnitude = (xi => (load as PartialTrapezoidalLoad).GetMagnitudesAt(xi, 0, 0)[0]);
                    localDir  = tld.Direction;

                    if (tld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    xi0    = tld.StarIsoLocations[0];
                    xi1    = tld.EndIsoLocations[0];
                    degree = 1;
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = GetNMaxOrder(targetElement).Max();

                    var gpt = (nOrd + degree) / 2 + 1;//gauss point count

                    var intg = GaussianIntegrator.CreateFor1DProblem(xi =>
                    {
                        var shp = GetNMatrixAt(targetElement, xi, 0, 0);
                        var q__ = magnitude(xi);
                        var j   = GetJMatrixAt(targetElement, xi, 0, 0);
                        shp.MultiplyByConstant(j.Determinant());

                        var q_ = localDir * q__;

                        if (this._direction == BeamDirection.Y)
                        {
                            shp.MultiplyByConstant(q_.Z);
                        }
                        else
                        {
                            shp.MultiplyByConstant(q_.Y);
                        }

                        return(shp);
                    }, xi0, xi1, gpt);

                    var res = intg.Integrate();

                    var localForces = new Force[2];

                    if (this._direction == BeamDirection.Y)
                    {
                        var fz0 = res[0, 0];
                        var my0 = res[0, 1];
                        var fz1 = res[0, 2];
                        var my1 = res[0, 3];

                        localForces[0] = new Force(0, 0, fz0, 0, my0, 0);
                        localForces[1] = new Force(0, 0, fz1, 0, my1, 0);
                    }
                    else
                    {
                        var fy0 = res[0, 0];
                        var mz0 = res[0, 1];
                        var fy1 = res[0, 2];
                        var mz1 = res[0, 3];

                        localForces[0] = new Force(0, fy0, 0, 0, 0, mz0);
                        localForces[1] = new Force(0, fy1, 0, 0, 0, mz1);
                    }

                    return(localForces);
                }
            }



            #endregion



            throw new NotImplementedException();
        }
        public static Matrix CalcLocalKMatrix_Triangle(IElementHelper helper, Element targetElement)
        {
            var tri = targetElement as TriangleElement;

            if (tri == null)
            {
                throw new Exception();
            }

            var trans = tri.GetLambdaMatrix().Transpose();

            //var nb = helper.GetBMaxOrder(targetElement);
            //var nd = tri.Material.GetMaxFunctionOrder();
            //var nt = tri.Section.GetMaxFunctionOrder().Max();
            //var nj = helper.GetDetJOrder(targetElement);


            var nn = helper.GetNMaxOrder(targetElement);
            var nd = tri.Material.GetMaxFunctionOrder();
            var nt = tri.Section.GetMaxFunctionOrder();
            var nj = helper.GetDetJOrder(targetElement);

            var sum = new int[3];

            foreach (var i in new int[][] { nn, nd, nt, nn, nj })
            {
                for (int j = 0; j < 3; j++)
                {
                    sum[j] += i[j];
                }
            }

            var nXi   = sum[0] / 2 + 1;
            var nEta  = sum[1] / 2 + 1;
            var nGama = sum[2] / 2 + 1;



            //var ng = (nb + nd + nt + nj)/2 + 1;

            var intg = new GaussianIntegrator();

            intg.GammaPointCount = nGama;
            intg.XiPointCount    = nXi;
            intg.EtaPointCount   = nEta;

            intg.A2 = 1;
            intg.A1 = 0;

            intg.F2 = (gama => 1);
            intg.F1 = (gama => 0);

            intg.G2 = ((eta, gama) => 1 - eta);
            intg.G1 = ((eta, gama) => 0);

            //intg.GammaPointCount = 1;
            //intg.XiPointCount = intg.EtaPointCount = ng;

            intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
            {
                var b = helper.GetBMatrixAt(tri, xi, eta);
                var d = helper.GetDMatrixAt(tri, xi, eta);
                var j = helper.GetJMatrixAt(tri, xi, eta);
                var t = tri.Section.GetThicknessAt(xi, eta);

                var buf = MatrixPool.Allocate(9, 9);

                CalcUtil.Bt_D_B(b, d, buf);

                buf.MultiplyByConstant(t * j.Determinant());

                return(buf);
            });

            var res = intg.Integrate();

            return(res);
        }
예제 #14
0
        /// <inheritdoc/>
        public IEnumerable <Tuple <DoF, double> > GetLoadInternalForceAt(Element targetElement, Load load,
                                                                         double[] isoLocation)
        {
            var buf = new FlatShellStressTensor();

            var tr = targetElement.GetTransformationManager();

            var br = targetElement as BarElement;

            var endForces = GetLocalEquivalentNodalLoads(targetElement, load);


            var v0 =
                endForces[0].Fx;

            v0 = -v0;

            var to = Iso2Local(targetElement, isoLocation)[0];

            //var xi = isoLocation[0];

            #region uniform & trapezoid

            if (load is UniformLoad || load is PartialTrapezoidalLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0, xi1;
                int    degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    xi0    = -1;
                    xi1    = 1;
                    degree = 0;
                }
                else
                {
                    var tld = (load as PartialTrapezoidalLoad);

                    magnitude = (xi => (load as PartialTrapezoidalLoad).GetMagnitudesAt(xi, 0, 0)[0]);
                    localDir  = tld.Direction;

                    if (tld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    xi0    = tld.StarIsoLocations[0];
                    xi1    = tld.EndIsoLocations[0];
                    degree = 1;
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = 0;                      // GetNMaxOrder(targetElement).Max();

                    var gpt = (nOrd + degree) / 2 + 1; //gauss point count

                    Matrix integral;


                    if (isoLocation[0] < xi0)
                    {
                        integral = new Matrix(2, 1);
                    }
                    else
                    {
                        var intgV = GaussianIntegrator.CreateFor1DProblem(x =>
                        {
                            var xi  = Local2Iso(targetElement, x)[0];
                            var q__ = magnitude(xi);
                            var q_  = localDir * q__;

                            var df = q_.X;

                            var buf_ = new Matrix(new double[] { df });

                            return(buf_);
                        }, 0, to, gpt);

                        integral = intgV.Integrate();
                    }

                    var f_i = integral[0, 0];

                    var memb = buf.MembraneTensor;
                    var bnd  = buf.BendingTensor;

                    var v = memb.S11 = -(f_i + v0);

                    buf.MembraneTensor = memb;
                    buf.BendingTensor  = bnd;

                    //return buf;
                }
            }



            #endregion

            throw new NotImplementedException();
        }
예제 #15
0
        public Force[] GetLocalEquivalentNodalLoads(Element targetElement, Load load)
        {
            var tr = targetElement.GetTransformationManager();

            #region uniform & trapezoid

            if (load is UniformLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0, xi1;
                int    degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    localDir = localDir.GetUnit();

                    xi0    = -1;
                    xi1    = 1;
                    degree = 0;
                }
                else
                {
                    throw new NotImplementedException();

                    /*
                     * var tld = (load as NonUniformlLoad);
                     *
                     * magnitude = (xi => (load as NonUniformlLoad).GetMagnitudesAt(xi, 0, 0)[0]);
                     * localDir = tld.Direction;
                     *
                     * if (tld.CoordinationSystem == CoordinationSystem.Global)
                     *  localDir = tr.TransformGlobalToLocal(localDir);
                     *
                     * xi0 = tld.StartLocation[0];
                     * xi1 = tld.EndLocation[0];
                     * degree = 1;*/
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = GetNMaxOrder(targetElement).Max();

                    var gpt = (nOrd + degree) / 2 + 1;//gauss point count

                    var intg = GaussianIntegrator.CreateFor1DProblem(xi =>
                    {
                        var shp = GetNMatrixAt(targetElement, xi, 0, 0);
                        var q__ = magnitude(xi);
                        var j   = GetJMatrixAt(targetElement, xi, 0, 0);
                        shp.MultiplyByConstant(j.Determinant());

                        var q_ = localDir * q__;

                        shp.MultiplyByConstant(q_.X);

                        return(shp);
                    }, xi0, xi1, gpt);

                    var res = intg.Integrate();

                    var localForces = new Force[2];

                    var fx0 = res[0, 0];
                    var fx1 = res[0, 1];

                    localForces[0] = new Force(fx0, 0, 0, 0, 0, 0);
                    localForces[1] = new Force(fx1, 0, 0, 0, 0, 0);

                    return(localForces);
                }
            }



            #endregion

            if (load is ConcentratedLoad)
            {
                var cns = load as ConcentratedLoad;

                var shapes = this.GetNMatrixAt(targetElement, cns.ForceIsoLocation.Xi);

                var localForce = cns.Force;

                if (cns.CoordinationSystem == CoordinationSystem.Global)
                {
                    localForce = tr.TransformGlobalToLocal(localForce);
                }


                shapes.MultiplyByConstant(localForce.Fx);

                var fxs = shapes.ExtractRow(0);

                var n = targetElement.Nodes.Length;

                var buf = new Force[n];

                for (var i = 0; i < n; i++)
                {
                    buf[i] = new Force(fxs[0, i], 0, 0, 0, 0, 0);
                }

                return(buf);
            }

            throw new NotImplementedException();
        }
예제 #16
0
        public Force[] GetLocalEquivalentNodalLoads(Element targetElement, Load load)
        {
            var tr = targetElement.GetTransformationManager();

            #region uniform & trapezoid

            if (load is UniformLoad || load is PartialTrapezoidalLoad)
            {
                Func <double, double> magnitude;
                Vector localDir;

                double xi0, xi1;
                int    degree;//polynomial degree of magnitude function

                #region inits
                if (load is UniformLoad)
                {
                    var uld = (load as UniformLoad);

                    magnitude = (xi => uld.Magnitude);
                    localDir  = uld.Direction;

                    if (uld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    xi0    = -1;
                    xi1    = 1;
                    degree = 0;
                }
                else
                {
                    var tld = (load as PartialTrapezoidalLoad);

                    magnitude = (xi => (load as PartialTrapezoidalLoad).GetMagnitudesAt(xi, 0, 0)[0]);
                    localDir  = tld.Direction;

                    if (tld.CoordinationSystem == CoordinationSystem.Global)
                    {
                        localDir = tr.TransformGlobalToLocal(localDir);
                    }

                    xi0    = tld.StarIsoLocations[0];
                    xi1    = tld.EndIsoLocations[0];
                    degree = 1;
                }

                localDir = localDir.GetUnit();
                #endregion

                {
                    var nOrd = GetNMaxOrder(targetElement).Max();

                    var gpt = (nOrd + degree) / 2 + 1;//gauss point count

                    var intg = GaussianIntegrator.CreateFor1DProblem(xi =>
                    {
                        var shp = GetNMatrixAt(targetElement, xi, 0, 0);
                        var q__ = magnitude(xi);
                        var j   = GetJMatrixAt(targetElement, xi, 0, 0);
                        shp.MultiplyByConstant(j.Determinant());

                        var q_ = localDir * q__;

                        shp.MultiplyByConstant(q_.X);

                        return(shp);
                    }, xi0, xi1, gpt);

                    var res = intg.Integrate();

                    var localForces = new Force[2];

                    var fx0 = res[0, 0];
                    var fx1 = res[0, 1];

                    localForces[0] = new Force(fx0, 0, 0, 0, 0, 0);
                    localForces[1] = new Force(fx1, 0, 0, 0, 0, 0);

                    return(localForces);
                }
            }



            #endregion

            throw new NotImplementedException();


            #region uniform

            if (load is Loads.UniformLoad)
            {
                var ul = load as Loads.UniformLoad;

                var localDir = ul.Direction.GetUnit();

                if (ul.CoordinationSystem == CoordinationSystem.Global)
                {
                    localDir = tr.TransformGlobalToLocal(localDir);
                }

                var ux = localDir.X * ul.Magnitude;
                var uy = localDir.Y * ul.Magnitude;
                var uz = localDir.Z * ul.Magnitude;

                var intg = GaussianIntegrator.CreateFor1DProblem(xi =>
                {
                    var shp = GetNMatrixAt(targetElement, xi, 0, 0);
                    var j   = GetJMatrixAt(targetElement, xi, 0, 0);
                    shp.MultiplyByConstant(j.Determinant());
                    shp.MultiplyByConstant(ux);

                    return(shp);
                }, -1, 1, 2);

                var res = intg.Integrate();

                var localForces = new Force[2];

                {
                    var fx0 = res[0, 0];
                    var fx1 = res[0, 1];

                    localForces[0] = new Force(fx0, 0, 0, 0, 0, 0);
                    localForces[1] = new Force(fx1, 0, 0, 0, 0, 0);
                }

                var globalForces = localForces.Select(i => tr.TransformLocalToGlobal(i)).ToArray();
                return(globalForces);
            }

            #endregion

            #region trapezoid

            if (load is PartialTrapezoidalLoad)
            {
                var trLoad = load as PartialTrapezoidalLoad;

                var localDir = trLoad.Direction;

                var startOffset = trLoad.StarIsoLocations[0];
                var endOffset   = trLoad.EndIsoLocations[0];
                var startMag    = trLoad.StartMagnitudes[0];
                var endMag      = trLoad.EndMagnitudes[0];


                if (trLoad.CoordinationSystem == CoordinationSystem.Global)
                {
                    localDir = tr.TransformGlobalToLocal(localDir);
                }


                var xi0 = -1 + startOffset;
                var xi1 = 1 - endOffset;

                var intg = GaussianIntegrator.CreateFor1DProblem(xi =>
                {
                    var shp = GetNMatrixAt(targetElement, xi, 0, 0);
                    var q__ = trLoad.GetMagnitudesAt(xi)[0];
                    var j   = GetJMatrixAt(targetElement, xi, 0, 0);
                    shp.MultiplyByConstant(j.Determinant());

                    var q_ = trLoad.Direction.GetUnit() * q__;

                    shp.MultiplyByConstant(q_.X);

                    return(shp);
                }, xi0, xi1, 3);

                var res = intg.Integrate();

                var localForces = new Force[2];

                {
                    var fx0 = res[0, 0];
                    var fx1 = res[0, 1];

                    localForces[0] = new Force(fx0, 0, 0, 0, 0, 0);
                    localForces[1] = new Force(fx1, 0, 0, 0, 0, 0);
                }

                var globalForces = localForces.Select(i => tr.TransformLocalToGlobal(i)).ToArray();

                return(globalForces);
            }

            #endregion
        }
        public static Matrix CalcLocalKMatrix_Tetrahedron(IElementHelper helper, Element targetElement)
        {
            var qq = targetElement as TetrahedronElement;

            if (qq == null)
            {
                throw new Exception();
            }

            var trans = qq.GetLambdaMatrix().Transpose();

            var nb = helper.GetBMaxOrder(targetElement);
            var nd = qq.Material.GetMaxFunctionOrder();
            var nj = helper.GetDetJOrder(targetElement);

            var sum = new int[3];

            foreach (var i in new int[][] { nb, nd, nb, nj })
            {
                for (int j = 0; j < 3; j++)
                {
                    sum[j] += i[j];
                }
            }

            var nXi   = sum[0] / 2 + 1;
            var nEta  = sum[1] / 2 + 1;
            var nGama = sum[2] / 2 + 1;

            var intg = new GaussianIntegrator();

            intg.GammaPointCount = nGama;
            intg.XiPointCount    = nXi;
            intg.EtaPointCount   = nEta;

            intg.A2 = 1;
            intg.A1 = 0;

            intg.F2 = (gama => 1 - gama);
            intg.F1 = (gama => 0);

            intg.G2 = ((eta, gama) => 1 - eta - gama);
            intg.G1 = ((eta, gama) => 0);

            intg.H = new FunctionMatrixFunction((xi, eta, gama) =>
            {
                var b = helper.GetBMatrixAt(qq, xi, eta);
                var d = helper.GetDMatrixAt(qq, xi, eta);
                var j = helper.GetJMatrixAt(qq, xi, eta);

                var buf = new Matrix(b.ColumnCount, b.ColumnCount);

                CalcUtil.Bt_D_B(b, d, buf);

                var detj = Math.Abs(j.Determinant());

                buf.Scale(detj); // is this correct? this is pretty close to formula 4.53 for DKQ-ELements (4.31 is without detj)

                return(buf);
            });

            var res = intg.Integrate();

            return(res);
        }