public static void Check(Model model, LoadCase cse) { var n = model.Nodes.Count; var ft = new Vector(); var fs = new Vector[n]; var mt = new Vector(); model.Solve(); model.LastResult.AddAnalysisResultIfNotExists(cse); var css = model.LastResult.ConcentratedForces[cse]; //concentrated s var ess = model.LastResult.ElementForces[cse]; //elements for (var i = 0; i < n; i++) { var loc = model.Nodes[i].Location; var cs = Force.FromVector(css, 6 * i); var es = Force.FromVector(ess, 6 * i); var ss = model.Nodes[i].GetSupportReaction(cse); var fi = (cs + es + ss).Move(-(Vector)loc); fs[i] = fi.Forces; ft += fi.Forces; mt += fi.Moments; } Console.WriteLine("Total Force: {0}", ft); Console.WriteLine("Total Moment: {0}", mt); }
/// <summary> /// Gets the internal force at <see cref="x" /> position. /// </summary> /// <param name="x">The position (from start point).</param> /// <param name="cmb">The <see cref="LoadCombination" />.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> /// <remarks> /// Will calculate the internal forces of member regarding the <see cref="cmb" /> <see cref="LoadCombination" /> /// </remarks> public override Force GetInternalForceAt(double x, LoadCombination cmb) { var gStartDisp = StartNode.GetNodalDisplacement(cmb); var gEndDisp = EndNode.GetNodalDisplacement(cmb); var lStartDisp = new Displacement( TransformGlobalToLocal(gStartDisp.Displacements), TransformGlobalToLocal(gStartDisp.Rotations)); var lEndDisp = new Displacement( TransformGlobalToLocal(gEndDisp.Displacements), TransformGlobalToLocal(gEndDisp.Rotations)); var displVector = new double[] { lStartDisp.DX, lStartDisp.DY, lStartDisp.DZ, lStartDisp.RX, lStartDisp.RY, lStartDisp.RZ, lEndDisp.DX, lEndDisp.DY, lEndDisp.DZ, lEndDisp.RX, lEndDisp.RY, lEndDisp.RZ }; var lStartForces = GetLocalStiffnessMatrix().Multiply(displVector); var startForce = Force.FromVector(lStartForces, 0); var forceAtX = -startForce.Move(new Vector(x, 0, 0)); foreach (var ld in loads) { if (!cmb.ContainsKey(ld.Case)) { continue; } var frc = ((Load1D)ld).GetInternalForceAt(this, x); forceAtX += cmb[ld.Case] * frc; } return(forceAtX); }
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); }
public static ValidationResult Validation_2() { var nx = 5; var ny = 5; var nz = 5; 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); grd.Solve_MPC(); 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); } } var span = new HtmlTag("span"); span.Add("p").Text("Validate a 3D frame internal force and internal displacement"); span.Add("h3").Text("Validate objective"); span.Add("paragraph").Text("validate internal force and internal displacement of bar elements. ") .AddClosedTag("br"); span.Add("paragraph").Text("Internal displacement in each element at each end node should be equal to that node's displacement.").AddClosedTag("br"); span.Add("paragraph").Text("End forces and mid force should be in equiblirium with each other.").AddClosedTag("br"); 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("h3").Text("Validation Result"); {//internal displacements span.Add("h4").Text("Internal Displacements"); span.Add("paragraph") .Text(string.Format("Validation output for internal displacements:")); span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}", maxInternalDisplacementAbsErr)); } {//internal force span.Add("h4").Text("Internal Force"); span.Add("paragraph") .Text(string.Format("Validation output for internal force (force residuals):")); span.Add("p").AddClass("bg-info").AppendHtml(string.Format("-Max ABSOLUTE Error: {0:e3}", maxInternalForceResidual)); } var buf = new ValidationResult(); buf.Span = span; buf.Title = "Internal force & displacement validation"; return(buf); }