Exemplo n.º 1
0
        public static void ValidateSingleInclinedFrame()
        {
            var model = new Model();
            var ndes  = new Node[] { new Node(0, 0, 0), new Node(2, 3, 5) };

            var h = 0.1;
            var w = 0.05;

            var a  = h * w;
            var iy = h * h * h * w / 12;
            var iz = w * w * w * h / 12;
            var j  = iy + iz;

            var sec = new Sections.UniformParametric1DSection(a, iy, iz, j);
            var mat = UniformIsotropicMaterial.CreateFromYoungPoisson(1, 0.25);

            var elm = new BarElement(ndes[0], ndes[1])
            {
                Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame
            };

            //var elm2 = new BarElement(ndes[1], ndes[2]) { Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame };

            model.Elements.Add(elm);
            model.Nodes.Add(ndes);

            ndes[0].Constraints = Constraints.Fixed;

            ndes[1].Loads.Add(new NodalLoad(new Force(0, 1, 0, 0, 0, 0)));

            model.Solve_MPC();

            var res = OpenseesValidator.OpenseesValidate(model, LoadCase.DefaultLoadCase, false);
        }
Exemplo n.º 2
0
        public static void ValidateOneSpanUniformLoad()
        {
            var model = new Model();

            var ndes = new Node[] {
                new Node(0, 0, 0),
                new Node(1, 0, 0),
                //new Node(2, 0, 0)
            };

            var h = 0.1;
            var w = 0.05;

            var a  = h * w;
            var iy = h * h * h * w / 12;
            var iz = w * w * w * h / 12;
            var j  = iy + iz;
            var e  = 210e9;

            var sec = new Sections.UniformParametric1DSection(a, iy, iz, j);
            var mat = UniformIsotropicMaterial.CreateFromYoungPoisson(e, 0.25);

            BarElement e1;

            model.Elements.Add(e1 = new BarElement(ndes[0], ndes[1])
            {
                Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame
            });
            //model.Elements.Add(new BarElement(ndes[1], ndes[2]) { Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame });

            e1.StartReleaseCondition =
                //e1.EndReleaseCondition =
                Constraints.MovementFixed;

            var ld = new Loads.UniformLoad(LoadCase.DefaultLoadCase, Vector.K, 1000, CoordinationSystem.Global);

            var eqload = e1.GetGlobalEquivalentNodalLoads(ld);


            model.Nodes.Add(ndes);

            ndes[0].Constraints = ndes[2].Constraints = Constraints.Fixed;
            //ndes[1].Constraints = ndes[2].Constraints = Constraints.Fixed;

            //for (var i = 0; i < model.Elements.Count; i++)
            //    (model.Elements[i] as BarElement).Loads.Add();

            //ndes[1].Loads.Add(new NodalLoad(new Force(0, 1, 0, 0, 0, 0)));



            model.Solve_MPC();

            var res  = OpenseesValidator.OpenseesValidate(model, LoadCase.DefaultLoadCase, false);
            var disp = res[0];

            var idx = disp.Columns["Absolute Error"].Ordinal;

            var max = disp.Rows.Cast <DataRow>().Select(i => (double)i[idx]).Max();
        }
Exemplo n.º 3
0
        public static void ValidateConsoleUniformLoad()
        {
            var model = new Model();

            var ndes = new Node[] {
                new Node(0, 0, 0),
                new Node(5, 2, 3)
            };

            var h = 0.1;
            var w = 0.05;

            var a  = h * w;
            var iy = h * h * h * w / 12;
            var iz = w * w * w * h / 12;
            var j  = iy + iz;
            var e  = 210e9;

            var sec = new Sections.UniformParametric1DSection(a, iy, iz, j);
            var mat = UniformIsotropicMaterial.CreateFromYoungPoisson(e, 0.25);

            model.Elements.Add(new BarElement(ndes[0], ndes[1])
            {
                Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame
            });

            model.Nodes.Add(ndes);

            ndes[0].Constraints = Constraints.Fixed;

            (model.Elements[0] as BarElement).Loads.Add(new Loads.UniformLoad(LoadCase.DefaultLoadCase, Vector.K, 1000, CoordinationSystem.Local));

            model.Solve_MPC();

            var res = OpenseesValidator.OpenseesValidate(model, LoadCase.DefaultLoadCase, false);

            var disp = res[0];

            var idx = disp.Columns["Absolute Error"].Ordinal;

            var max = disp.Rows.Cast <DataRow>().Select(i => (double)i[idx]).Max();
        }
Exemplo n.º 4
0
        public static ValidationResult Validation_1()
        {
            var nx = 2;
            var ny = 2;
            var nz = 2;

            #region model definition
            var grd = StructureGenerator.Generate3DBarElementGrid(nx, ny, nz);

            //StructureGenerator.SetRandomiseConstraints(grd);
            StructureGenerator.SetRandomiseSections(grd);

            StructureGenerator.AddRandomiseNodalLoads(grd, LoadCase.DefaultLoadCase);//random nodal loads
            //StructureGenerator.AddRandomiseBeamUniformLoads(grd, LoadCase.DefaultLoadCase);//random elemental loads
            StructureGenerator.AddRandomDisplacements(grd, 0.1);
            #endregion

            grd.Solve_MPC();

            #region solve & compare
            var res = OpenseesValidator.OpenseesValidate(grd, LoadCase.DefaultLoadCase, false);


            var disp = res[0];
            var reac = res[1];

            var dispAbsErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var dispRelErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));

            var reacAbsErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var reacRelErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));


            var maxDispAbsError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispAbsErrIdx]);
            var maxDispRelError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispRelErrIdx]);


            var maxReacAbsError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacAbsErrIdx]);
            var maxReacRelError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacRelErrIdx]);


            var maxInternalDisplacementAbsErr = 0.0;
            var maxInternalForceResidual      = 0.0;

            foreach (var elm in grd.Elements)
            {
                var bar = elm as BarElement;

                if (bar == null)
                {
                    continue;
                }

                var tr = bar.GetTransformationManager();

                var L = (bar.StartNode.Location - bar.EndNode.Location).Length;

                var d1 = bar.GetInternalDisplacementAt(-1, LoadCase.DefaultLoadCase);
                var d2 = bar.GetInternalDisplacementAt(+1, LoadCase.DefaultLoadCase);

                var dn1 = tr.TransformGlobalToLocal(bar.StartNode.GetNodalDisplacement(LoadCase.DefaultLoadCase));
                var dn2 = tr.TransformGlobalToLocal(bar.EndNode.GetNodalDisplacement(LoadCase.DefaultLoadCase));

                var diff1 = dn1 - d1;
                var diff2 = dn2 - d2;

                var dd = Math.Max(diff1.Displacements.Length, diff2.Displacements.Length);
                var dr = Math.Max(diff1.Rotations.Length, diff2.Rotations.Length);

                maxInternalDisplacementAbsErr = Math.Max(maxInternalDisplacementAbsErr, dd);
                maxInternalDisplacementAbsErr = Math.Max(maxInternalDisplacementAbsErr, dr);
                //yet internal force

                var n = 10;

                var stf = bar.GetLocalStifnessMatrix();//.GetGlobalStifnessMatrix();

                var u1 = Displacement.ToVector(dn1);
                var u2 = Displacement.ToVector(dn2);

                var u = new Matrix(12, 1);

                u1.CopyTo(u.CoreArray, 0);
                u2.CopyTo(u.CoreArray, 6);

                var endFrc = stf * u;

                var stFc  = Force.FromVector(endFrc.CoreArray, 0);
                var endFc = Force.FromVector(endFrc.CoreArray, 6);

                for (var i = 0; i < n; i++)
                {
                    var xi = i / (n - 1.0) * 2.0 + -1;
                    var x  = bar.IsoCoordsToLocalCoords(xi)[0];

                    var fc = bar.GetInternalForceAt(xi);

                    var toBegin = fc.Move(new Vector(-x, 0, 0));
                    var toEnd   = fc.Move(new Vector(L - x, 0, 0));

                    var stResid  = stFc + toBegin;
                    var endResid = endFc - toEnd;

                    var errs = new double[]
                    {
                        stResid.Forces.Length,
                        stResid.Moments.Length,
                        endResid.Forces.Length,
                        endResid.Moments.Length
                    }.Max();

                    maxInternalForceResidual = Math.Max(maxInternalForceResidual, errs);
                }
            }
            #endregion


            var span = new HtmlTag("span");
            span.Add("p").Text("Validate 3D frame nodal displacement and reactions");
            span.Add("h3").Text("Validate with");
            span.Add("paragraph").Text("OpenSEES (the Open System for Earthquake Engineering Simulation) software (available via http://opensees.berkeley.edu/)");
            span.Add("h3").Text("Validate objective");


            span.Add("paragraph").Text("compare nodal displacement from BFE.net library and OpenSEES for a model consist of random 3d bars");

            span.Add("h3").Text("Model Definition");

            span.Add("paragraph").Text($"A {nx}x{ny}x{nz} grid, with {grd.Nodes.Count} nodes and {grd.Elements.Count} bar elements.").AddClosedTag("br");

            span.Add("paragraph").Text("Every node in the model have a random load on it, random displacement in original location.").AddClosedTag("br");
            span.Add("paragraph").Text("Every element in the model have a random uniform distributed load on it.").AddClosedTag("br");

            span.Add("h3").Text("Validation Result");

            #region nodal disp

            {//nodal displacements
                span.Add("h4").Text("Nodal Displacements");
                span.Add("paragraph")
                .Text(string.Format("Validation output for nodal displacements:"));


                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}<br/>-Max RELATIVE Error: {1:e3}", maxDispAbsError, maxDispRelError));

                var id = "tbl_" + Guid.NewGuid().ToString("N").Substring(0, 5);

                span.Add("button").Attr("type", "button").Text("Toggle Details").AddClasses("btn btn-primary")
                .Attr("onclick", $"$('#{id}').collapse('toggle');");

                var div = span.Add("div").AddClasses("panel-collapse", "collapse", "out").Id(id);

                var tbl = div.Add("table").AddClass("table table-striped table-inverse table-bordered table-hover");
                tbl.Id(id);

                var trH = tbl.Add("Thead").Add("tr");


                foreach (DataColumn column in disp.Columns)
                {
                    trH.Add("th").Attr("scope", "col").Text(column.ColumnName);
                }

                var tbody = tbl.Add("tbody");

                for (var i = 0; i < disp.Rows.Count; i++)
                {
                    var tr = tbody.Add("tr");

                    for (var j = 0; j < disp.Columns.Count; j++)
                    {
                        tr.Add("td").Text(disp.Rows[i][j].ToString());
                    }
                }
            }

            #endregion

            #region nodal reaction



            {//nodal reactions
                span.Add("h4").Text("Nodal Support Reactions");
                span.Add("paragraph")
                .Text(string.Format("Validation output for nodal support reactions:"));


                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}<br/>-Max RELATIVE Error: {1:e3}", maxReacAbsError, maxReacRelError));

                var id = "tbl_" + Guid.NewGuid().ToString("N").Substring(0, 5);

                span.Add("button").Attr("type", "button").Text("Toggle Details").AddClasses("btn btn-primary")
                .Attr("onclick", $"$('#{id}').collapse('toggle');");

                var div = span.Add("div").AddClasses("panel-collapse", "collapse", "out").Id(id);

                var tbl = div.Add("table").AddClass("table table-striped table-inverse table-bordered table-hover");
                tbl.Id(id);

                var trH = tbl.Add("Thead").Add("tr");


                foreach (DataColumn column in reac.Columns)
                {
                    trH.Add("th").Attr("scope", "col").Text(column.ColumnName);
                }

                var tbody = tbl.Add("tbody");

                for (var i = 0; i < reac.Rows.Count; i++)
                {
                    var tr = tbody.Add("tr");

                    for (var j = 0; j < reac.Columns.Count; j++)
                    {
                        tr.Add("td").Text(reac.Rows[i][j].ToString());
                    }
                }
            }

            #endregion

            #region internal displacement
            {//internal displacements
                span.Add("h4").Text("Internal Displacements");
                span.Add("paragraph")
                .Text(string.Format("Validation output for internal displacements (Displacement at each end node of bar elements should be equal to bar element's internal displacement of bar element at that node)"));

                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}", maxInternalDisplacementAbsErr));
            }
            #endregion

            #region internal force
            {//internal force
                span.Add("h4").Text("Internal Force");
                span.Add("paragraph")
                .Text(string.Format("Validation output for internal force (forces retrived by K.Δ formula should be in equiblirium with internal force of bar elements at any location within element):"));

                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}", maxInternalForceResidual));
            }
            #endregion

            var buf = new ValidationResult();
            buf.Span  = span;
            buf.Title = "3D Grid Validation";

            return(buf);
        }
Exemplo n.º 5
0
        public static void ValidateEndRelease()
        {
            var model = new Model();

            var ndes = new Node[] {
                new Node(0, 0, 0),
                new Node(3, 0, 0),
                new Node(6, 0, 0),
            };

            /**/
            var h = 0.1;
            var w = 0.05;

            var a  = h * w;
            var iy = h * h * h * w / 12;
            var iz = w * w * w * h / 12;
            var j  = iy + iz;
            var e  = 210e9;
            var nu = 0.3;

            var g = e / (2 * 1 + nu);
            /**/

            var sec = new Sections.UniformParametric1DSection(a, iy, iz, j);
            var mat = UniformIsotropicMaterial.CreateFromYoungShear(e, g);

            {
                var belm = new BarElement(ndes[0], ndes[1])
                {
                    Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame
                };

                belm.StartReleaseCondition =
                    Constraints.FixedDX & Constraints.FixedDY & Constraints.FixedDZ &
                    Constraints.FixedRX;

                model.Elements.Add(belm);
            }
            {
                var belm = new BarElement(ndes[1], ndes[2])
                {
                    Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame
                };

                belm.EndReleaseCondition =
                    Constraints.FixedDX & Constraints.FixedDY & Constraints.FixedDZ &
                    Constraints.FixedRX;

                model.Elements.Add(belm);
            }


            model.Nodes.Add(ndes);

            ndes[0].Constraints = ndes[2].Constraints = Constraints.Fixed;

            //ndes[1].Constraints =
            //    Constraints.FixedDX & Constraints.FixedRX
            //& Constraints.FixedDY & Constraints.FixedRZ//find beam.z dofs

            ;
            //(model.Elements[0] as BarElement).Loads.Add(new Loads.UniformLoad(LoadCase.DefaultLoadCase, Vector.K, 1000, CoordinationSystem.Local));

            ndes[1].Loads.Add(new NodalLoad(new Force(Vector.K, Vector.Zero)));
            //ndes[1].Loads.Add(new NodalLoad(new Force(Vector.J * 2, Vector.Zero)));

            model.Solve_MPC();


            var d = model.Nodes[1].GetNodalDisplacement();


            var t = (model.Elements[0] as BarElement).GetInternalForceAt(1);


            var res = OpenseesValidator.OpenseesValidate(model, LoadCase.DefaultLoadCase, false);

            var disp = res[0];

            var idx = disp.Columns["Absolute Error"].Ordinal;

            var max = disp.Rows.Cast <DataRow>().Select(i => (double)i[idx]).Max();
        }
        public static void ValidateConsoleUniformLoad()
        {
            var model = new Model();

            var ndes = new Node[] {
                new Node(0, 0, 0),
                new Node(3, 0, 0)
            };

            /**/
            var h = 0.1;
            var w = 0.05;

            var a  = h * w;
            var iy = h * h * h * w / 12;
            var iz = w * w * w * h / 12;
            var j  = iy + iz;
            var e  = 210e9;
            var nu = 0.3;

            var g = e / (2 * 1 + nu);
            /**/

            var sec = new Sections.UniformParametric1DSection(a, iy, iz, j);
            var mat = UniformIsotropicMaterial.CreateFromYoungShear(e, g);

            BarElement        belm;
            FrameElement2Node frmelm;

            belm = new BarElement(ndes[0], ndes[1])
            {
                Material = mat, Section = sec, Behavior = BarElementBehaviours.FullFrame
            };
            frmelm = new FrameElement2Node(ndes[0], ndes[1])
            {
                Iz = sec.Iz, Iy = sec.Iy, A = sec.A, J = sec.J, E = e, G = g
            };

            var bk   = belm.GetGlobalStifnessMatrix();
            var fk   = frmelm.GetGlobalStifnessMatrix();
            var diff = bk - fk;

            model.Elements.Add(belm);

            model.Nodes.Add(ndes);

            ndes[0].Constraints = Constraints.Fixed;

            //ndes[1].Constraints =
            //    Constraints.FixedDX & Constraints.FixedRX
            //& Constraints.FixedDY & Constraints.FixedRZ//find beam.z dofs

            ;
            var ul = new Loads.UniformLoad(LoadCase.DefaultLoadCase, Vector.K, 1000, CoordinationSystem.Global);

            (model.Elements[0] as BarElement).Loads.Add(ul);


            var eqv = (model.Elements[0] as BarElement).GetGlobalEquivalentNodalLoads(ul);

            //ndes[1].Loads.Add(new NodalLoad(new Force(Vector.K, Vector.Zero)));
            //ndes[1].Loads.Add(new NodalLoad(new Force(Vector.J*2, Vector.Zero)));

            model.Solve_MPC();


            var d = model.Nodes[1].GetNodalDisplacement();

            var t = (model.Elements[0] as BarElement).GetInternalForceAt(-1);


            var res = OpenseesValidator.OpenseesValidate(model, LoadCase.DefaultLoadCase, false);

            var disp = res[0];

            var idx = disp.Columns["Absolute Error"].Ordinal;

            var max = disp.Rows.Cast <DataRow>().Select(i => (double)i[idx]).Max();
        }
Exemplo n.º 7
0
        public static ValidationResult Validation_1()
        {
            var nx = 5;
            var ny = 5;
            var nz = 5;

            #region model definition
            var grd = StructureGenerator.Generate3DTriangleElementGrid(nx, ny, nz);

            StructureGenerator.SetRandomiseSections(grd);
            StructureGenerator.SetRandomiseMaterial(grd);

            StructureGenerator.AddRandomiseNodalLoads(grd, LoadCase.DefaultLoadCase);//random nodal loads
            //StructureGenerator.AddRandomiseBeamUniformLoads(grd, LoadCase.DefaultLoadCase);//random elemental loads
            StructureGenerator.AddRandomDisplacements(grd, 0.3);
            #endregion



            StructureGenerator.AddRandomiseNodalLoads(grd, LoadCase.DefaultLoadCase);//random nodal loads

            grd.Solve_MPC();


            var res = OpenseesValidator.OpenseesValidate(grd, LoadCase.DefaultLoadCase, false);

            var disp = res[0];
            var reac = res[1];

            var dispAbsErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var dispRelErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));

            var reacAbsErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var reacRelErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));


            var maxDispAbsError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispAbsErrIdx]);
            var maxDispRelError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispRelErrIdx]);


            var maxReacAbsError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacAbsErrIdx]);
            var maxReacRelError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacRelErrIdx]);


            //var buf = new ValidationResult();

            var span = new HtmlTag("span");
            span.Add("p").Text("Validate a 3D rame");
            span.Add("h3").Text("Validate with");
            span.Add("paragraph").Text("OpenSEES (the Open System for Earthquake Engineering Simulation) software (available via http://opensees.berkeley.edu/)");
            span.Add("h3").Text("Validate objective");
            span.Add("paragraph").Text("compare nodal displacement from BFE.net library and OpenSEES for a model consist of 3d bar elements with random material and section for each one, that forms a grid"
                                       + " with a randomized nodal loading and narrow erratic on location of joint of grid elements.");

            span.Add("h3").Text("Model Definition");

            span.Add("paragraph")
            .Text($"A {nx}x{ny}x{nz} grid, with {grd.Nodes.Count} nodes and {grd.Elements.Count} bar elements." +
                  " Every node in the model have a random load on it.");

            span.Add("h3").Text("Validation Result");

            span.Add("paragraph")
            .Text(string.Format("Validation output for nodal displacements:"));


            span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}<br/>-Max RELATIVE Error: {1:e3}", maxDispAbsError, maxDispRelError));



            //span.Add("").Text(string.Format("Max ABSOLUTE Error: {0:e3}", maxAbsError));


            var id = "tbl_" + Guid.NewGuid().ToString("N").Substring(0, 5);

            span.Add("button").Attr("type", "button").Text("Toggle Details").AddClasses("btn btn-primary")
            .Attr("onclick", $"$('#{id}').collapse('toggle');");

            var div = span.Add("div").AddClasses("panel-collapse", "collapse", "out").Id(id);

            var tbl = div.Add("table").AddClass("table table-striped table-inverse table-bordered table-hover");
            tbl.Id(id);

            var trH = tbl.Add("Thead").Add("tr");


            foreach (DataColumn column in disp.Columns)
            {
                trH.Add("th").Attr("scope", "col").Text(column.ColumnName);
            }

            var tbody = tbl.Add("tbody");

            for (var i = 0; i < disp.Rows.Count; i++)
            {
                var tr = tbody.Add("tr");

                for (var j = 0; j < disp.Columns.Count; j++)
                {
                    tr.Add("td").Text(disp.Rows[i][j].ToString());
                }
            }

            var buf = new ValidationResult();
            buf.Span  = span;
            buf.Title = "3D Grid Validation";

            return(buf);
        }
        public static ValidationResult Validation_2()
        {
            var nx = 2;
            var ny = 1;
            var nz = 2;

            #region model definition
            var grd = StructureGenerator.Generate3DTriangleElementGrid(nx, ny, nz);

            //StructureGenerator.SetRandomiseSections(grd);
            //StructureGenerator.SetRandomiseMaterial(grd);

            //StructureGenerator.AddRandomiseNodalLoads(grd, LoadCase.DefaultLoadCase);//random nodal loads
            //StructureGenerator.AddRandomiseBeamUniformLoads(grd, LoadCase.DefaultLoadCase);//random elemental loads
            //StructureGenerator.AddRandomDisplacements(grd, 0.3);

            var zMax = grd.Nodes.Max(i => i.Location.Z);

            foreach (var node in grd.Nodes)
            {
                if (node.Location.Z > 0.99 * zMax)
                {
                    node.Loads.Add(new NodalLoad(new Force(new Vector(000, 0000, 10000), Vector.Zero)));
                }
            }

            #endregion



            //StructureGenerator.AddRandomiseNodalLoads(grd, LoadCase.DefaultLoadCase);//random nodal loads

            grd.Solve_MPC();


            var res = OpenseesValidator.OpenseesValidate(grd, LoadCase.DefaultLoadCase, false);

            var disp = res[0];
            var reac = res[1];

            var dispAbsErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var dispRelErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));

            var reacAbsErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var reacRelErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));


            var maxDispAbsError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispAbsErrIdx]);
            var maxDispRelError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispRelErrIdx]);


            var maxReacAbsError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacAbsErrIdx]);
            var maxReacRelError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacRelErrIdx]);


            //var buf = new ValidationResult();

            var span = new HtmlTag("span");
            span.Add("p").Text("Validate a flat vertical sheet");
            span.Add("h3").Text("Validate with");
            span.Add("paragraph").Text("OpenSEES (the Open System for Earthquake Engineering Simulation) software (available via http://opensees.berkeley.edu/)");
            span.Add("h3").Text("Validate objective");
            span.Add("paragraph").Text("compare nodal displacement from BFE.net library and OpenSEES for a model consist of 3d triangle elements with same material and section for all, that forms a straight square plate"
                                       + " with a loads on top nodes");

            span.Add("h3").Text("Model Definition");

            span.Add("paragraph")
            .Text(string.Format("A {0}x{1}x{2} grid, with {3} nodes and {4} bar elements.", nx, 1, nz, grd.Nodes.Count, grd.Elements.Count));

            span.Add("h3").Text("Validation Result");

            span.Add("paragraph")
            .Text(string.Format("Validation output for nodal displacements:"));


            span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}<br/>-Max RELATIVE Error: {1:e3}", maxDispAbsError, maxDispRelError));



            //span.Add("").Text(string.Format("Max ABSOLUTE Error: {0:e3}", maxAbsError));


            var id = "tbl_" + Guid.NewGuid().ToString("N").Substring(0, 5);

            span.Add("button").Attr("type", "button").Text("Toggle Details").AddClasses("btn btn-primary")
            .Attr("onclick", string.Format("$('#{0}').collapse('toggle');", id));

            var div = span.Add("div").AddClasses("panel-collapse", "collapse", "out").Id(id);

            var tbl = div.Add("table").AddClass("table table-striped table-inverse table-bordered table-hover");
            tbl.Id(id);

            var trH = tbl.Add("Thead").Add("tr");


            foreach (DataColumn column in disp.Columns)
            {
                trH.Add("th").Attr("scope", "col").Text(column.ColumnName);
            }

            var tbody = tbl.Add("tbody");

            for (var i = 0; i < disp.Rows.Count; i++)
            {
                var tr = tbody.Add("tr");

                for (var j = 0; j < disp.Columns.Count; j++)
                {
                    tr.Add("td").Text(disp.Rows[i][j].ToString());
                }
            }

            var buf = new ValidationResult();
            buf.Span  = span;
            buf.Title = "3D Grid Validation";

            return(buf);
        }
        public static ValidationResult Validation_1()
        {
            var nx = 3;
            var ny = 3;
            var nz = 3;

            #region model definition
            var grd = StructureGenerator.Generate3DTet4Grid(nx, ny, nz);

            //StructureGenerator.SetRandomiseConstraints(grd);
            StructureGenerator.SetRandomiseSections(grd);

            StructureGenerator.AddRandomiseNodalLoads(grd, LoadCase.DefaultLoadCase);//random nodal loads
            //StructureGenerator.AddRandomiseBeamUniformLoads(grd, LoadCase.DefaultLoadCase);//random elemental loads
            StructureGenerator.AddRandomDisplacements(grd, 0.1);
            #endregion

            grd.Solve_MPC();

            #region solve & compare
            var res = OpenseesValidator.OpenseesValidate(grd, LoadCase.DefaultLoadCase, false);


            var disp = res[0];
            var reac = res[1];

            var dispAbsErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var dispRelErrIdx = disp.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));

            var reacAbsErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("absolute"));
            var reacRelErrIdx = reac.Columns.Cast <DataColumn>().ToList().FindIndex(i => i.ColumnName.ToLower().Contains("relative"));


            var maxDispAbsError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispAbsErrIdx]);
            var maxDispRelError = disp.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[dispRelErrIdx]);


            var maxReacAbsError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacAbsErrIdx]);
            var maxReacRelError = reac.Rows.Cast <DataRow>().Max(ii => (double)ii.ItemArray[reacRelErrIdx]);


            var maxInternalDisplacementAbsErr = 0.0;
            var maxInternalForceResidual      = 0.0;


            #endregion


            var span = new HtmlTag("span");
            span.Add("p").Text("Validate 3D frame nodal displacement and reactions");
            span.Add("h3").Text("Validate with");
            span.Add("paragraph").Text("OpenSEES (the Open System for Earthquake Engineering Simulation) software (available via http://opensees.berkeley.edu/)");
            span.Add("h3").Text("Validate objective");


            span.Add("paragraph").Text("compare nodal displacement from BFE.net library and OpenSEES for a model consist of random 3d bars");

            span.Add("h3").Text("Model Definition");

            {
            }
            span.Add("paragraph").Text(string.Format("A {0}x{1}x{2} grid, with {3} nodes and {4} bar elements.", nx, ny, nz, grd.Nodes.Count, grd.Elements.Count)).AddClosedTag("br");

            span.Add("paragraph").Text("Every node in the model have a random load on it, random displacement in original location.").AddClosedTag("br");
            span.Add("paragraph").Text("Every element in the model have a random uniform distributed load on it.").AddClosedTag("br");

            span.Add("h3").Text("Validation Result");

            #region nodal disp

            {//nodal displacements
                span.Add("h4").Text("Nodal Displacements");
                span.Add("paragraph")
                .Text(string.Format("Validation output for nodal displacements:"));


                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}<br/>-Max RELATIVE Error: {1:e3}", maxDispAbsError, maxDispRelError));

                var id = "tbl_" + Guid.NewGuid().ToString("N").Substring(0, 5);

                span.Add("button").Attr("type", "button").Text("Toggle Details").AddClasses("btn btn-primary")
                .Attr("onclick", string.Format("$('#{0}').collapse('toggle');", id));

                var div = span.Add("div").AddClasses("panel-collapse", "collapse", "out").Id(id);

                var tbl = div.Add("table").AddClass("table table-striped table-inverse table-bordered table-hover");
                tbl.Id(id);

                var trH = tbl.Add("Thead").Add("tr");


                foreach (DataColumn column in disp.Columns)
                {
                    trH.Add("th").Attr("scope", "col").Text(column.ColumnName);
                }

                var tbody = tbl.Add("tbody");

                for (var i = 0; i < disp.Rows.Count; i++)
                {
                    var tr = tbody.Add("tr");

                    for (var j = 0; j < disp.Columns.Count; j++)
                    {
                        tr.Add("td").Text(disp.Rows[i][j].ToString());
                    }
                }
            }

            #endregion

            #region nodal reaction



            {//nodal reactions
                span.Add("h4").Text("Nodal Support Reactions");
                span.Add("paragraph")
                .Text(string.Format("Validation output for nodal support reactions:"));


                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}<br/>-Max RELATIVE Error: {1:e3}", maxReacAbsError, maxReacRelError));

                var id = "tbl_" + Guid.NewGuid().ToString("N").Substring(0, 5);

                span.Add("button").Attr("type", "button").Text("Toggle Details").AddClasses("btn btn-primary")
                .Attr("onclick", string.Format("$('#{0}').collapse('toggle');", id));

                var div = span.Add("div").AddClasses("panel-collapse", "collapse", "out").Id(id);

                var tbl = div.Add("table").AddClass("table table-striped table-inverse table-bordered table-hover");
                tbl.Id(id);

                var trH = tbl.Add("Thead").Add("tr");


                foreach (DataColumn column in reac.Columns)
                {
                    trH.Add("th").Attr("scope", "col").Text(column.ColumnName);
                }

                var tbody = tbl.Add("tbody");

                for (var i = 0; i < reac.Rows.Count; i++)
                {
                    var tr = tbody.Add("tr");

                    for (var j = 0; j < reac.Columns.Count; j++)
                    {
                        tr.Add("td").Text(reac.Rows[i][j].ToString());
                    }
                }
            }

            #endregion

            #region internal displacement
            {//internal displacements
                span.Add("h4").Text("Internal Displacements");
                span.Add("paragraph")
                .Text(string.Format("Validation output for internal displacements (Displacement at each end node of bar elements should be equal to bar element's internal displacement of bar element at that node)"));

                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}", maxInternalDisplacementAbsErr));
            }
            #endregion

            #region internal force
            {//internal force
                span.Add("h4").Text("Internal Force");
                span.Add("paragraph")
                .Text(string.Format("Validation output for internal force (forces retrived by K.Δ formula should be in equiblirium with internal force of bar elements at any location within element):"));

                span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}", maxInternalForceResidual));
            }
            #endregion

            var buf = new ValidationResult();
            buf.Span  = span;
            buf.Title = "3D Grid Validation";

            return(buf);
        }