示例#1
0
        /// <summary>
        /// Integrates the shear force along intersection of element with defined plane.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="plane">The plane.</param>
        /// <returns>Integrated force</returns>
        public static Force IntegrateNormalForce(this TriangleFlatShell element, Plane plane, LoadCombination cmb)
        {
            //step 1: does intersect?
            //step 2: get a tensor (no matter where, this is constant stress)
            //step 3: find rotation amount for tensors
            //step 4: rotate tensors
            //step 5: integrate forces

            if (!DoesIntersects(element, plane))
                return Force.Zero;

            var intersection = GetIntersection(element, plane);

            //step 2
            var tensor = element.GetInternalForce(0, 0, cmb);

            //step 3
            var t = element.GetTransformationMatrix().Transpose(); //transpose of t
            var nLocal = (Vector)(t * plane.Normal.ToMatrix()).ToPoint();//project of N to local element coord system
            var theta = Math.Atan2(nLocal.Y, nLocal.X) - Math.PI / 2;

            //step 4
            var rotatedTensor = MembraneStressTensor.Rotate(tensor.MembraneTensor, theta);

            // shear direction
            var shearLocalDirection = new Vector(Math.Cos(theta), Math.Sin(theta), 0);//direction of shear force in local element coord system, which is vector I rotated by amount theta
            var shearGlobalDirection = (Vector)(t.Transpose() * shearLocalDirection.ToMatrix()).ToPoint();

            var fShearAmount = rotatedTensor.Txy * element.Thickness * intersection.Length;//shear force

            var shearForce = fShearAmount * shearGlobalDirection.GetUnit();

            return new Force(shearForce, Vector.Zero);
        }
示例#2
0
        private static double GetError(MembraneStressTensor test, MembraneStressTensor accurate)
        {
            var v1 = new Vector(test.Sx, test.Sy, test.Txy);
            var v2 = new Vector(accurate.Sx, accurate.Sy, accurate.Txy);

            return(GetError(v1, v2));
        }
示例#3
0
        /// <summary>
        /// Rotates the define local stress tensor into direction of plane.
        /// </summary>
        /// <param name="shell">The shell.</param>
        /// <param name="localStressTensor">The local stress tensor.</param>
        /// <param name="targetPlane">The target plane.</param>
        /// <returns>
        /// Rotated tensor
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public static MembraneStressTensor RotateTensor(this TriangleFlatShell shell, MembraneStressTensor localStressTensor, Plane targetPlane)
        {
            var t = shell.GetTransformationMatrix().Transpose();

            var plane = targetPlane;

            var nLocal = (Vector)(t * plane.Normal.ToMatrix()).ToPoint();//project of N to local element coord system

            var theta = Math.Atan2(nLocal.Y, nLocal.X) - Math.PI / 2;

            var buf = MembraneStressTensor.Rotate(localStressTensor, theta);

            return buf;
        }
示例#4
0
        public GeneralStressTensor GetLocalStressAt(Element targetElement, Displacement[] localDisplacements, params double[] isoCoords)
        {
            //Note: membrane internal force is constant

            //step 1 : get transformation matrix
            //step 2 : convert globals points to locals
            //step 3 : convert global displacements to locals
            //step 4 : calculate B matrix and D matrix
            //step 5 : M=D*B*U
            //Note : Steps changed...

            //var trans = this.GetTransformationMatrix();

            //var lp = GetLocalPoints();

            //var g2l = new Func<Vector, Vector>(glob => (trans.Transpose() * glob.ToMatrix()).ToVector());
            //var l2g = new Func<Vector, Vector>(local => (trans*local.ToMatrix()).ToPoint());


            //var d1g = this.nodes[0].GetNodalDisplacement(combination);
            //var d2g = this.nodes[1].GetNodalDisplacement(combination);
            //var d3g = this.nodes[2].GetNodalDisplacement(combination);

            //step 3
            var d1l = localDisplacements[0]; // new Displacement(g2l(d1g.Displacements), g2l(d1g.Rotations));
            var d2l = localDisplacements[1]; //new Displacement(g2l(d2g.Displacements), g2l(d2g.Rotations));
            var d3l = localDisplacements[2]; //new Displacement(g2l(d3g.Displacements), g2l(d3g.Rotations));

            var u =
                new Matrix(new[]
                           { d1l.DX, d1l.DY, d2l.DX, d2l.DY, /**/ d3l.DX, d3l.DY });

            var d = this.GetDMatrixAt(targetElement, isoCoords);

            var b = this.GetBMatrixAt(targetElement, isoCoords);


            var sCst = d * b * u;

            var buf = new MembraneStressTensor();

            buf.Sx  = sCst[0, 0];
            buf.Sy  = sCst[1, 0];
            buf.Txy = sCst[2, 0];

            return(new GeneralStressTensor(buf));
        }
示例#5
0
        public static void Test6_2()
        {
            Console.WriteLine("Example 13: I Beam With Flat Shell, BFE vs ABAQUS");

            var magic = 0;

            //example #13 p175

            #region creating model

            var model = new Model();

            var l = UnitConverter.In2M(40);
            var w = UnitConverter.In2M(10);
            var h = UnitConverter.In2M(5);
            var t = UnitConverter.In2M(0.25);

            var e  = UnitConverter.Ksi2Pas(10000); //10'000 ksi
            var no = 0.3;

            var n = 9;

            var xSpan = l / (n - 1);

            var nodes = new Node[n][];

            for (var i = 0; i < n; i++)
            {
                var x = i * xSpan;

                nodes[i] = new Node[7];

                nodes[i][0] = new Node(x, 0, 0);
                nodes[i][1] = new Node(x, w / 2, 0);
                nodes[i][2] = new Node(x, w, 0);

                nodes[i][3] = new Node(x, w / 2, h / 2);

                nodes[i][4] = new Node(x, 0, h);
                nodes[i][5] = new Node(x, w / 2, h);
                nodes[i][6] = new Node(x, w, h);

                model.Nodes.AddRange(nodes[i]);
            }

            var pairs = new int[6][];

            pairs[0] = new int[] { 0, 1 };
            pairs[1] = new int[] { 1, 2 };
            pairs[2] = new int[] { 1, 3 };
            pairs[3] = new int[] { 3, 5 };
            pairs[4] = new int[] { 4, 5 };
            pairs[5] = new int[] { 5, 6 };

            for (var i = 0; i < n - 1; i++)
            {
                for (int j = 0; j < 6; j++)
                {
                    var n11 = nodes[i][pairs[j][0]];
                    var n12 = nodes[i][pairs[j][1]];

                    var n21 = nodes[i + 1][pairs[j][0]];
                    var n22 = nodes[i + 1][pairs[j][1]];

                    {
                        var elm1 = new TriangleFlatShell()
                        {
                            Thickness = t, PoissonRatio = no, ElasticModulus = e
                        };

                        elm1.Nodes[0] = n11;
                        elm1.Nodes[1] = n12;
                        elm1.Nodes[2] = n21;

                        model.Elements.Add(elm1);

                        var elm2 = new TriangleFlatShell()
                        {
                            Thickness = t, PoissonRatio = no, ElasticModulus = e
                        };

                        elm2.Nodes[0] = n21;
                        elm2.Nodes[1] = n22;
                        elm2.Nodes[2] = n12;

                        model.Elements.Add(elm2);
                    }
                }
            }

            //loading
            nodes.Last()[0].Loads.Add(new NodalLoad(new Force(0, UnitConverter.Kip2N(1.6), 0, 0, 0, 0)));
            nodes.Last()[6].Loads.Add(new NodalLoad(new Force(0, -UnitConverter.Kip2N(1.6), 0, 0, 0, 0)));

            nodes[0].ToList().ForEach(i => i.Constraints = Constraint.Fixed);

            #endregion

            model.Trace.Listeners.Add(new BriefFiniteElementNet.ConsoleTraceListener());
            new ModelWarningChecker().CheckModel(model);


            //ModelVisualizerControl.VisualizeInNewWindow(model);

            model.Solve();



            var A = nodes.Last()[2];
            var B = nodes.Last()[4];
            var C = nodes.First()[1];
            var D = nodes.First()[0];
            var E = nodes.Last()[6];

            /*
             * for (int i = 0; i < nodes.Last().Length; i++)
             * {
             *  nodes.Last()[i].Label = i.ToString();
             * }
             */

            /**/
            A.Label = "A";
            B.Label = "B";
            C.Label = "C";
            D.Label = "D";
            E.Label = "E";
            /**/


            for (int i = 0; i < model.Elements.Count; i++)
            {
                model.Elements[i].Label = i.ToString();
            }

            var da = 1 / 0.0254 * A.GetNodalDisplacement().Displacements; // [inch]
            var db = 1 / 0.0254 * B.GetNodalDisplacement().Displacements; // [inch]

            var abaqusDa = new Vector(-15.4207E-03, 88.2587E-03, 150.910E-03);
            var abaqusDb = new Vector(-15.3246E-03, -88.2629E-03, -148.940E-03);

            Console.WriteLine("Err at A against ABAQUS (displacement): {0:0.000}%", GetError(da, abaqusDa));
            Console.WriteLine("Err at B against ABAQUS (displacement): {0:0.000}%", GetError(db, abaqusDb));

            {
                var abaqusElms = new int[] { 96, 89, 57, 41 };

                var bfeElms = new[] { 0, 37, 40, 42 }.Select(i => model.Elements[i]).Cast <TriangleFlatShell>().ToArray();

                var bfeTensors =
                    bfeElms.Select(i => i.GetInternalForce(0, 0, LoadCombination.DefaultLoadCombination).MembraneTensor).ToArray();

                var abaqusTensors = new MembraneStressTensor[]
                {
                    new MembraneStressTensor() //elm 96
                    {
                        Sx  = Avg(7.36164, 6.88581, 7.48463 /**/, 8.14348, 8.61931, 8.02049 /**/),
                        Sy  = Avg(2.16196, 2.01921, 2.05925 /**/, 2.48958, 2.63233, 2.59229 /**/),
                        Txy = Avg(2.27915, 2.33284, 2.49939 /**/, 2.01766, 1.96396, 1.79742 /**/)
                    },

                    new MembraneStressTensor() //elm 89
                    {
                        Sx  = Avg(-230.883E-03, -268.773E-03, -226.600E-03, -157.940E-03, -120.050E-03, -162.222E-03),
                        Sy  = Avg(-646.591E-03, -591.701E-03, -523.641E-03, -278.264E-03, -333.154E-03, -401.214E-03),
                        Txy = -Avg(676.247E-03, 663.707E-03, 701.730E-03, -1.09379, -1.08125, -1.11928)
                    },

                    new MembraneStressTensor()
                    {
                        Sx  = Avg(-398.693E-03, -205.937E-03, -124.743E-03, 280.574E-03, 87.8183E-03, 6.62372E-03),
                        Sy  = Avg(-634.569E-03, -402.618E-03, -100.092E-03, 612.059E-03, 380.109E-03, 77.5826E-03),
                        Txy = Avg(838.081E-03, 925.471E-03, 871.566E-03, -881.344E-03, -968.735E-03, -914.829E-03)
                    },

                    new MembraneStressTensor()
                    {
                        Sx  = Avg(-18.7201E-03, 127.473E-03, 288.131E-03, 4.04619E-03, -142.147E-03, -302.805E-03),
                        Sy  = Avg(11.1952E-03, 174.315E-03, 540.586E-03, -37.4831E-03, -200.603E-03, -566.874E-03),
                        Txy = Avg(842.951E-03, 956.823E-03, 865.886E-03, -882.801E-03, -996.674E-03, -905.736E-03)
                    },
                };

                var globTensor = new Func <TriangleFlatShell, MembraneStressTensor>(elm =>
                {
                    var tns = elm.GetInternalForce(0, 0, LoadCombination.DefaultLoadCombination);

                    var rt = elm.RotateTensor(tns.MembraneTensor, Plane.XZPlane);

                    return(rt);
                });


                for (int i = 0; i < bfeTensors.Length; i++)
                {
                    var bfeTensor = bfeTensors[i];

                    bfeTensor = globTensor(bfeElms[i]);

                    bfeTensor = MembraneStressTensor.Multiply(bfeTensor, -UnitConverter.Pas2Psi(1) / 1000);

                    var abaqusTensor = abaqusTensors[i];

                    Console.WriteLine("Err against ABAQUS (AVG stress tensor) @ elm {1}: {0:0.000}%",
                                      GetError(bfeTensor, abaqusTensor), abaqusElms[i]);
                }
            }
        }
示例#6
0
        public static void Test6()
        {
            Console.WriteLine("Example 13: I Beam With Flat Shell, BFE vs SAP2000");

            var magic = 0;

            //example #13 p175

            #region creating model

            var model = new Model();

            var l = UnitConverter.In2M(40);
            var w = UnitConverter.In2M(10);
            var h = UnitConverter.In2M(5);
            var t = UnitConverter.In2M(0.25);

            var e  = UnitConverter.Ksi2Pas(10000); //10'000 ksi
            var no = 0.3;

            var n = 9;

            var xSpan = l / (n - 1);

            var nodes = new Node[n][];

            for (var i = 0; i < n; i++)
            {
                var x = i * xSpan;

                nodes[i] = new Node[7];

                nodes[i][0] = new Node(x, 0, 0);
                nodes[i][1] = new Node(x, w / 2, 0);
                nodes[i][2] = new Node(x, w, 0);

                nodes[i][3] = new Node(x, w / 2, h / 2);

                nodes[i][4] = new Node(x, 0, h);
                nodes[i][5] = new Node(x, w / 2, h);
                nodes[i][6] = new Node(x, w, h);

                model.Nodes.AddRange(nodes[i]);
            }

            var pairs = new int[6][];

            pairs[0] = new int[] { 0, 1 };
            pairs[1] = new int[] { 1, 2 };
            pairs[2] = new int[] { 1, 3 };
            pairs[3] = new int[] { 3, 5 };
            pairs[4] = new int[] { 4, 5 };
            pairs[5] = new int[] { 5, 6 };

            for (var i = 0; i < n - 1; i++)
            {
                for (int j = 0; j < 6; j++)
                {
                    var n11 = nodes[i][pairs[j][0]];
                    var n12 = nodes[i][pairs[j][1]];

                    var n21 = nodes[i + 1][pairs[j][0]];
                    var n22 = nodes[i + 1][pairs[j][1]];

                    {
                        var elm1 = new TriangleFlatShell()
                        {
                            Thickness = t, PoissonRatio = no, ElasticModulus = e
                        };

                        elm1.Nodes[0] = n11;
                        elm1.Nodes[1] = n12;
                        elm1.Nodes[2] = n21;

                        model.Elements.Add(elm1);

                        var elm2 = new TriangleFlatShell()
                        {
                            Thickness = t, PoissonRatio = no, ElasticModulus = e
                        };

                        elm2.Nodes[0] = n21;
                        elm2.Nodes[1] = n22;
                        elm2.Nodes[2] = n12;

                        model.Elements.Add(elm2);
                    }
                }
            }

            //loading
            nodes.Last()[0].Loads.Add(new NodalLoad(new Force(0, UnitConverter.Kip2N(1.6), 0, 0, 0, 0)));
            nodes.Last()[6].Loads.Add(new NodalLoad(new Force(0, -UnitConverter.Kip2N(1.6), 0, 0, 0, 0)));

            nodes[0].ToList().ForEach(i => i.Constraints = Constraint.Fixed);

            #endregion

            model.Trace.Listeners.Add(new BriefFiniteElementNet.ConsoleTraceListener());
            new ModelWarningChecker().CheckModel(model);


            //ModelVisualizerControl.VisualizeInNewWindow(model);

            model.Solve();

            var A = nodes.Last()[2];
            var B = nodes.Last()[4];
            var C = nodes.First()[1];
            var D = nodes.First()[0];
            var E = nodes.Last()[6];

            /*
             * for (int i = 0; i < nodes.Last().Length; i++)
             * {
             *  nodes.Last()[i].Label = i.ToString();
             * }
             */

            /**/
            A.Label = "A";
            B.Label = "B";
            C.Label = "C";
            D.Label = "D";
            E.Label = "E";
            /**/

            var da = 1 / 0.0254 * A.GetNodalDisplacement().Displacements; // [inch]
            var db = 1 / 0.0254 * B.GetNodalDisplacement().Displacements; // [inch]

            var sap2000Da = new Vector(-0.014921, 0.085471, 0.146070);    //tbl 7.14
            var sap2000Db = new Vector(-0.014834, -0.085475, -0.144533);  //tbl 7.14

            Console.WriteLine("Err at A against Sap2000 (displacement): {0:0.0}%", GetError(da, sap2000Da));
            Console.WriteLine("Err at B against Sap2000 (displacement): {0:0.0}%", GetError(db, sap2000Db));

            {
                //stresses
                var cElms = model.Elements.Cast <TriangleFlatShell>().Where(i => i.Nodes.Contains(C)).ToArray();
                var DElms = model.Elements.Cast <TriangleFlatShell>().Where(i => i.Nodes.Contains(D)).ToArray();
                var EElms = model.Elements.Cast <TriangleFlatShell>().Where(i => i.Nodes.Contains(E)).ToArray();

                var globTensor = new Func <TriangleFlatShell, MembraneStressTensor>(elm =>
                {
                    var tns = elm.GetInternalForce(0, 0, LoadCombination.DefaultLoadCombination);

                    var rt = elm.RotateTensor(tns.MembraneTensor, Plane.YZPlane);

                    return(rt);
                });

                var cSy =
                    cElms.Select(i => globTensor(i))
                    .Select(i => MembraneStressTensor.Multiply(i, UnitConverter.Pas2Psi(1) / 1000))
                    .Max(i => Math.Abs(i.Sy));

                var dSx =
                    DElms.Select(i => globTensor(i))
                    .Select(i => MembraneStressTensor.Multiply(i, UnitConverter.Pas2Psi(1) / 1000))
                    .Max(i => Math.Abs(i.Sx));

                var eTxy =
                    EElms.Select(i => globTensor(i))
                    .Select(i => MembraneStressTensor.Multiply(i, UnitConverter.Pas2Psi(1) / 1000))
                    .Max(i => Math.Abs(i.Txy));



                Console.WriteLine("S11 at C against Sap2000 (stress tensor): {0:0.0}%", GetError(cSy, 5.441));
                Console.WriteLine("S22 at D against Sap2000 (stress tensor): {0:0.0}%", GetError(dSx, 2.009));
                Console.WriteLine("S21 at E against Sap2000 (stress tensor): {0:0.0}%", GetError(eTxy, 1.450));
            }
        }
示例#7
0
        public static void Test3()
        {
            //example #2 p118

            Console.WriteLine("Example 2: CST element Test");


            #region creating model

            var model = new Model();

            var l = 48 * 0.0254; //in [m]
            var b = 12 * 0.0254; //
            var t = 1 * 0.0254;

            var e  = 206842772603; //30000 ksi
            var no = 0.25;         //Poisson ratio

            var n = 9;
            var m = 3;


            var span = l / (n - 1);

            var nodes = new Node[n][];

            for (var i = 0; i < n; i++)
            {
                nodes[i] = new Node[m];

                for (var j = 0; j < m; j++)
                {
                    model.Nodes.Add(nodes[i][j] = new Node(i * span, j * span, 0));

                    if (i == 0)
                    {
                        nodes[i][j].Constraints = Constraint.Fixed;
                    }

                    var newCns = new Constraint(
                        DofConstraint.Released, DofConstraint.Released, DofConstraint.Fixed,
                        DofConstraint.Fixed, DofConstraint.Fixed, DofConstraint.Fixed);

                    nodes[i][j].Constraints = nodes[i][j].Constraints & newCns;
                }
            }

            var tp = MembraneFormulation.PlaneStress;


            for (var i = 0; i < n - 1; i++)
            {
                for (var j = 0; j < m - 1; j++)
                {
                    var elm1 = new TriangleFlatShell()
                    {
                        ElasticModulus          = e,
                        PoissonRatio            = no,
                        Thickness               = t,
                        Behavior                = FlatShellBehaviour.Membrane,
                        MembraneFormulationType = tp
                    };

                    elm1.Nodes[2] = nodes[i][j + 1];
                    elm1.Nodes[1] = nodes[i + 1][j + 1];
                    elm1.Nodes[0] = nodes[i + 1][j];

                    model.Elements.Add(elm1);


                    var elm2 = new TriangleFlatShell()
                    {
                        ElasticModulus          = e,
                        PoissonRatio            = no,
                        Thickness               = t,
                        Behavior                = FlatShellBehaviour.Membrane,
                        MembraneFormulationType = tp
                    };

                    elm2.Nodes[2] = nodes[i][j];
                    elm2.Nodes[1] = nodes[i][j + 1];
                    elm2.Nodes[0] = nodes[i + 1][j];

                    model.Elements.Add(elm2);
                }
            }

            var pt = 177928.864; //40 kips

            nodes.Last()[0].Loads.Add(new NodalLoad(new Force(0, pt / 6, 0, 0, 00, 0)));
            nodes.Last()[1].Loads.Add(new NodalLoad(new Force(0, 4 * pt / 6, 0, 0, 00, 0)));
            nodes.Last()[2].Loads.Add(new NodalLoad(new Force(0, pt / 6, 0, 0, 00, 0)));

            #endregion

            model.Trace.Listeners.Add(new BriefFiniteElementNet.ConsoleTraceListener());
            new ModelWarningChecker().CheckModel(model);

            model.Solve();

            var d8  = 1 / 0.0254 * nodes[4].Last().GetNodalDisplacement().Displacements;
            var d10 = 1 / 0.0254 * nodes.Last().Last().GetNodalDisplacement().Displacements;



            var sap2000D8  = new Vector(-0.025605, 0.062971, 0);
            var sap2000D10 = new Vector(-0.034271, 0.194456, 0);


            Console.WriteLine("Err at A against Sap2000 (displacement): {0:0.0}%", GetError(d8, sap2000D8));
            Console.WriteLine("Err at B against Sap2000 (displacement): {0:0.0}%", GetError(d10, sap2000D10));

            {                                           //write internal forces
                var targetNode = nodes.First().First(); //stress at support node

                var targetElement = model.Elements.FirstOrDefault(i => i.Nodes.Contains(targetNode));

                var localS = (targetElement as TriangleFlatShell).GetInternalForce(0, 0,
                                                                                   LoadCombination.DefaultLoadCombination); //tensor in local coordinate system

                var globalS = (targetElement as TriangleFlatShell).RotateTensor(localS.MembraneTensor, Plane.XZPlane);      //tensor in global coordinate system

                var s6        = MembraneStressTensor.Multiply(globalS, UnitConverter.Pas2Psi(1) / 1000);
                var sap2000S6 = new MembraneStressTensor()
                {
                    Sx = -41.493, Sy = -10.37, Txy = 11.84
                };

                Console.WriteLine("Err at node 6 against Sap2000 (stress): {0:0.0}%", GetError(s6, sap2000S6));
            }
        }
示例#8
0
        /// <summary>
        /// Gets the stress due to the membrane action. Needs to be combined with bending stress!!!
        /// </summary>
        /// <param name="targetElement">Element under consideration</param>
        /// <param name="combination">A load combination</param>
        /// <returns>The stress in the element due to the membrane action. Needs to be combined with the stress due to bending!</returns>
        public MembraneStressTensor GetMembraneInternalStress(Element targetElement, LoadCombination combination)
        {
            //code moved to GetLocalInternalStressAt()

            //Note: membrane internal force is constant

            //step 1 : get transformation matrix
            //step 2 : convert globals points to locals
            //step 3 : convert global displacements to locals
            //step 4 : calculate B matrix and D matrix
            //step 5 : M=D*B*U

            var lds = new Displacement[targetElement.Nodes.Length];
            var tr  = targetElement.GetTransformationManager();

            for (var i = 0; i < targetElement.Nodes.Length; i++)
            {
                var globalD = targetElement.Nodes[i].GetNodalDisplacement(combination);
                var local   = tr.TransformGlobalToLocal(globalD);
                lds[i] = local;
            }
            //step 3
            var d1l = lds[0];
            var d2l = lds[1];
            var d3l = lds[2];

            var uCst = targetElement.MatrixPool.Allocate(6, 1);

            uCst.FillColumn(1, d1l.DX, d1l.DY, d2l.DX, d2l.DY, /**/ d3l.DX, d3l.DY);

            //cst -> constant over entire element -> provide random values for local
            var dbCst = this.GetDMatrixAt(targetElement, new double[] { 0, 0 });

            var bCst = this.GetBMatrixAt(targetElement, new double[] { 0, 0 });

            var sCst = dbCst * bCst * uCst;

            var buf = new MembraneStressTensor();

            buf.Sx  = sCst[0, 0];
            buf.Sy  = sCst[1, 0];
            buf.Txy = sCst[2, 0];

            return(buf);
        }

        #endregion
        public GeneralStressTensor GetLoadStressAt(Element targetElement, ElementalLoad load, double[] isoLocation)
        {
            throw new NotImplementedException();
        }

        #region strain
        /// <summary>
        /// Determine the strain in the element for a given load case
        /// </summary>
        /// <param name="targetElement">Element under consideration</param>
        /// <param name="loadCase">Loadcase for strain determination</param>
        /// <param name="isoCoords">The location - doesn't matter since it is constant in the CST element</param>
        /// <returns></returns>
        public StrainTensor GetMembraneInternalStrain(Element targetElement, LoadCase loadCase, params double[] isoCoords)
        {
            //Note: membrane internal force is constant

            //step 1 : get transformation matrix
            //step 2 : convert globals points to locals
            //step 3 : convert global displacements to locals
            //step 4 : calculate B matrix
            //step 5 : e=B*U
            //Note : Steps changed...
            var lds = new Displacement[targetElement.Nodes.Length];
            var tr  = targetElement.GetTransformationManager();

            for (var i = 0; i < targetElement.Nodes.Length; i++)
            {
                var globalD = targetElement.Nodes[i].GetNodalDisplacement(loadCase);
                var local   = tr.TransformGlobalToLocal(globalD);
                lds[i] = local;
            }

            // var locals = tr.TransformGlobalToLocal(globalDisplacements);

            var b = GetBMatrixAt(targetElement, isoCoords);

            var u1l = lds[0];
            var u2l = lds[1];
            var u3l = lds[2];

            var uCst =
                targetElement.MatrixPool.Allocate(new[]
                                                  { u1l.DX, u1l.DY, /**/ u2l.DX, u2l.DY, /**/ u3l.DX, u3l.DY });

            var ECst = b * uCst;

            var buf = new StrainTensor();

            buf.S11 = ECst[0, 0];
            buf.S22 = ECst[1, 0];
            buf.S12 = ECst[2, 0];

            return(buf);
        }

        public GeneralStressTensor GetLocalInternalStressAt(Element targetElement, Displacement[] localDisplacements, params double[] isoCoords)
        {
            //Note: membrane internal force is constant

            //step 1 : get transformation matrix
            //step 2 : convert globals points to locals
            //step 3 : convert global displacements to locals
            //step 4 : calculate B matrix and D matrix
            //step 5 : M=D*B*U


            var lds = localDisplacements;
            //step 3
            var d1l = lds[0];
            var d2l = lds[1];
            var d3l = lds[2];

            var uCst =
                targetElement.MatrixPool.Allocate(new[]
                                                  { d1l.DX, d1l.DY, d2l.DX, d2l.DY, /**/ d3l.DX, d3l.DY });

            //cst -> constant over entire element -> provide random values for local
            var dbCst = this.GetDMatrixAt(targetElement, new double[] { 0, 0 });

            var bCst = this.GetBMatrixAt(targetElement, new double[] { 0, 0 });

            var sCst = dbCst * bCst * uCst;

            var buf = new MembraneStressTensor();

            buf.Sx  = sCst[0, 0];
            buf.Sy  = sCst[1, 0];
            buf.Txy = sCst[2, 0];

            return(new GeneralStressTensor(buf));
        }
示例#9
0
        public static Tuple<Force,Point> GetTotalForce(this TriangleFlatShell element, Plane plane, int n)
        {
            //step 1: find intersection points
            //step 2: find tensors at intersection points
            //step 3: find rotation amount for tensors
            //step 4: rotate tensors
            //step 5: integrate forces

            //step 1
            var globalPoints = GetIntersectionPoints(element, plane, n);

            if (!globalPoints.Any())
                return new Tuple<Force, Point>();

            var t = element.GetTransformationMatrix().Transpose(); //transpose of t
            var locals = globalPoints.Select(i => (t * i.ToMatrix()).ToPoint()).ToArray();

            //step 2
            var tensors = GeTensorsAtIntersection(element, plane, n);
            var memTensors = tensors.Select(i => i.MembraneTensor).ToList();
            var bendTensors = tensors.Select(i => i.BendingTensor).ToList();

            //step 3
            var nLocal = (Vector)(t * plane.Normal.ToMatrix()).ToPoint();//project of N to local element coord system

            var theta = Math.Atan2(nLocal.Y, nLocal.X) - Math.PI/2;

            //step 4
            var rTensors = tensors.Select(i => MembraneStressTensor.Rotate(i.MembraneTensor, theta)).ToList();

            var avg = rTensors.Aggregate((i, j) => i + j);

            avg = MembraneStressTensor.Multiply(avg, 1.0 / tensors.Length);

            var length = (globalPoints.First() - globalPoints.Last()).Length;

            var fShearAmount = avg.Txy * element.Thickness * length;//shear force
            var fCompAmount = avg.Sy * element.Thickness * length;//compressive force

            // shear dirction
            var shearLocalDirection = new Vector(Math.Cos(theta), Math.Sin(theta), 0);//direction of shear force in local element coord system, which is vector I rotated by amount theta
            var shearGlobalDirection = (Vector) (t.Transpose()*shearLocalDirection.ToMatrix()).ToPoint();

            //compressive direction
            var compLocalDirection = new Vector(-Math.Sin(theta), Math.Cos(theta), 0);//direction of shear force in local element coord system, which is vector I rotated by amount theta
            var compGlobalDirection = (Vector)(t.Transpose() * compLocalDirection.ToMatrix()).ToPoint();


            var shearForce = fShearAmount*shearGlobalDirection.GetUnit();
            var compForce = fCompAmount*compGlobalDirection.GetUnit();

            var totForce = shearForce + compForce;

            var bufFrc = new Force(totForce, Vector.Zero);
            var loc = globalPoints.Aggregate((i, j) => (Point)((Vector)i + (Vector)j));

            loc.X /= globalPoints.Length;
            loc.Y /= globalPoints.Length;
            loc.Z /= globalPoints.Length;

            return new Tuple<Force, Point>(bufFrc, loc);
            //return bufFrc;
        }