using FeMM.Common.Models;
using FeMM.Grasshopper.DataTypes.FeMM;
using FeMM.Grasshopper.Helpers;
using Grasshopper.Kernel;
using Maffeis.Checkers.Concrete.Attributes;
using Maffeis.Checkers.Concrete.Checkers;
using Maffeis.Checkers.Concrete.Results;
using Maffeis.Checkers.Concrete.SectionSolvers;
using Maffeis.Model.Materials;
using Maffeis.Model.Results;
using Maffeis.Model.Sections.Concrete;
using Maffeis.Model.Sections.Rebar;
using Maffeis.Model.Standards;
using Rhino.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
namespace FeMM.Grasshopper.Components.Checks
{
public class MixedSectionTensionCheckComponent : GH_Component
{
protected Dictionary<int, string> _standardOptions = new()
{
{ 0, "EC2" },
{ 1, "AASHTO" },
{ 2, "NTC2018" },
{ 3, "SBC 306-CR-18" }
};
/// <summary>
/// Initializes a new instance of the MixedSectionBeamComponent class.
/// </summary>
public MixedSectionTensionCheckComponent()
: base("Composite Section Tension Check", "CSTC", "Check the composite section with input forces", CategoryNameConstants.CATEGORY_CHECKS, CategoryNameConstants.SUBCATEGORY_STEELCHECKS)
{
}
/// <summary>
/// Registers all the input parameters for this component.
/// </summary>
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddGenericParameter("Beam Section", "BS", "Section to check", GH_ParamAccess.item);
pManager.AddGenericParameter("Concrete Material", "CM", "Concrete Material", GH_ParamAccess.item);
pManager.AddGenericParameter("Rebar Material", "RM", "Rebar Material", GH_ParamAccess.item);
pManager.AddGenericParameter("Steel Material", "SM", "Steel Material", GH_ParamAccess.item);
pManager.AddNumberParameter("Homogenized factor ", "N", "The homogenized factor", GH_ParamAccess.item, 15);
pManager.AddGenericParameter("Loads", "L", "The loads to check", GH_ParamAccess.list);
}
/// <summary>
/// Registers all the output parameters for this component.
/// </summary>
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddTextParameter("Header", "H", "The result string header", GH_ParamAccess.item);
pManager.AddTextParameter("Summary Results", "R", "The result string to save in .cvs", GH_ParamAccess.list);
pManager.AddPointParameter("Steel section points", "SSP", "The boundary points of the steel section", GH_ParamAccess.list);
pManager.AddTextParameter("Steel section value", "SSV", "The stress value associated to boundary points of the steel section", GH_ParamAccess.list);
pManager.AddPointParameter("Concrete section points", "CSP", "The boundary points of the concrete section", GH_ParamAccess.list);
pManager.AddTextParameter("Concrete section value", "CSV", "The stress value associated to boundary points of the concrete section", GH_ParamAccess.list);
pManager.AddPointParameter("Rebar points", "RP", "The points of the concrete section rebars", GH_ParamAccess.list);
pManager.AddTextParameter("Rebar value", "RV", "The stress value associated to points of the concrete section rebars", GH_ParamAccess.list);
pManager.AddLineParameter("Neutral axis", "NA", "The neutral axis of the forces", GH_ParamAccess.list);
}
/// <summary>
/// This is the method that actually does the work.
/// </summary>
/// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
protected override void SolveInstance(IGH_DataAccess DA)
{
GH_MixedSection section = null;
GH_Material concrete = null;
GH_Material rebarMat = null;
GH_Material steel = null;
var beamForceResultModel = new List<BeamForceResultModel>();
double homogenizedFactor = 0;
int count = 0;
if (!DA.GetData(count++, ref section))
return;
if (!DA.GetData(count++, ref concrete))
return;
if (!DA.GetData(count++, ref rebarMat))
return;
if (!DA.GetData(count++, ref steel))
return;
if (!DA.GetData(count++, ref homogenizedFactor))
return;
if (!DA.GetDataList(count++, beamForceResultModel))
return;
double bfw = section.SteelSection.B1; // bottom flange width
double tfw = section.SteelSection.B2; // top flange width
double h = section.SteelSection.D; // heigth
double bft = section.SteelSection.T1; // Bottom flange thickness
double tft = section.SteelSection.T2; // Top flange thickness
double wt = section.SteelSection.T3; // Web thickness
double hh = section.ConcreteSection.D; // heigth
double b = section.ConcreteSection.B; // base
double verticalOffset = section.VerticalOffset;
MaterialModel concreteModel = concrete.Value;
MaterialModel steelModel = steel.Value;
MaterialModel rebarModel = rebarMat.Value;
double rebarsAreaTot = section.ReinforcementArea;
double rebarsCover = section.ReinforcementCover;
int numberRebars = 4;
double rebarArea = rebarsAreaTot / numberRebars;
double rebarDiameter = Math.Sqrt(rebarArea * 4 / Math.PI);
var sectionH = new Maffeis.Model.Sections.SectionH(h, wt, tfw, tft, bfw, bft, section.Name);
var concreteMaterialACI318 = new ConcreteMaterialACI318(concreteModel.Name, concreteModel.SpecificCompressiveStrength,
ConcreteMaterial.CompressionStressStrainDiagrams.ParabolaRectangle);
var steelMaterialACI318 = new SteelMaterialACI318(steelModel.Name, steelModel.Modulus, steelModel.MinimumYieldStress, steelModel.MinimumTensileStress,
0.1, SteelMaterial.StressStrainCurveType.ElasticPerfectPlastic, SteelMaterial.SteelTypes.Structural);
var rebarMaterial = new SteelMaterialACI318(rebarModel.Name, rebarModel.Modulus, rebarModel.MinimumTensileStress, rebarModel.ExpectedTensileStress,
0.1, SteelMaterial.StressStrainCurveType.ElasticPerfectPlastic, SteelMaterial.SteelTypes.Rebar);
//var fakeRebar = new RebarSectionCircular("", 1.0, rebarMaterial);
var rebar = new RebarSectionCircular("", rebarDiameter, rebarMaterial);
var reinforcedConcreteSection = new ReinforcedConcreteSection(b, hh, concreteMaterialACI318, rebar, b / numberRebars, rebarsCover, null, 1000,
sectionH, steelMaterialACI318, 0, 0, section.Name);
var vect = reinforcedConcreteSection.SteelSections[0].Traslation;
reinforcedConcreteSection.SteelSections[0].Traslation = new Maffeis.Geometry.Vector2d(vect.X, vect.Y - verticalOffset);
var standardACI318P14 = new StandardACI318p14();
var standardAISC360P16 = new StandardAISC360p16();
double phi = ReinforcedConcreteSection.CalculateHomogenizedFactorPhi(homogenizedFactor, steelMaterialACI318, concreteMaterialACI318);
var coordinateSystem = GetLocalCoordinateSystem(reinforcedConcreteSection, phi);
var options = new SectionCheckerACI318.SectionOptionsStandardACI318(coordinateSystem,
SectionSolver.FailureAnalysisTypes.ConstantN, SectionSolver.FailureDomainTypes.Plastic, SectionSolver.StressAnalysisTypes.Linear, phi, 0, false, 64);
var resultBeamForces = new ResultBeamForces[beamForceResultModel.Count];
for (int i = 0; i < beamForceResultModel.Count; i++)
{
var force = beamForceResultModel[i];
resultBeamForces[i] = new ResultBeamForces(force.AxialForce, force.ShearForce.X, force.ShearForce.Y, force.Torque, force.BendingMoment.X, -force.BendingMoment.Y, coordinateSystem, i, force.LoadCase.Name);
}
var sectionCheckerAttribute = new SectionCheckerAttribute(reinforcedConcreteSection, resultBeamForces, null);
var sectionCheckerACI318 = new SectionCheckerACI318(sectionCheckerAttribute, options, standardACI318P14, false, false, -1, standardAISC360P16);
StressAnalysisResult[] results = sectionCheckerACI318.GetTensionAnalysisResult();
string[] outCsv = new string[results.Length];
string[] outConcreteTension = new string[results.Length];
string[] outSteelTension = new string[results.Length];
string[] outRebarTension = new string[results.Length];
Line[] lines = new Line[results.Length];
Point3d[] outConcretePoint = null;
Point3d[] outSteelPoint = null;
Point3d[] outRebarPoint = null;
int cifreSignificativeForze = 2;
int cifreSignificativeStress = 2;
int cifreSignificativeStresss = 6;
int cifreSignificativeStrain = 6;
int cifreSignificativePlane = 2;
for (int i = 0; i < results.Length; i++)
{
StressAnalysisResult result = results[i];
string csv = $"{section.Name};{result.Force.Id};{result.Force.Name};" +
$"{Math.Round(beamForceResultModel[i].Station, cifreSignificativeForze)};" +
$"{Math.Round(result.Force.N / 1000, cifreSignificativeForze)};" +
$"{Math.Round(result.Force.M1 / 1000000, cifreSignificativeForze)};" +
$"{Math.Round(result.Force.M2 / 1000000, cifreSignificativeForze)};";
Maffeis.Checker.Results.ResultType.StrainPlaneResult strainPlaneResult = result.CalculateStrainPlaneResult(true, phi);
csv += $"{Math.Round(strainPlaneResult.SigmaCMin, cifreSignificativeStress)};" +
$"{Math.Round(strainPlaneResult.SigmaCMax, cifreSignificativeStress)};";
csv += $"{Math.Round(strainPlaneResult.SigmaSMin, cifreSignificativeStress)};" +
$"{Math.Round(strainPlaneResult.SigmaSMax, cifreSignificativeStress)};";
csv += "0;0;";
csv += $"{Math.Round(strainPlaneResult.SigmaSSMin, cifreSignificativeStress)};" +
$"{Math.Round(strainPlaneResult.SigmaSSMax, cifreSignificativeStress)};";
csv += $"{Math.Round(strainPlaneResult.EpsilonCMin, cifreSignificativeStrain)};" +
$"{Math.Round(strainPlaneResult.EpsilonCMax, cifreSignificativeStrain)};";
csv += $"{Math.Round(strainPlaneResult.EpsilonSMin, cifreSignificativeStrain)};" +
$"{Math.Round(strainPlaneResult.EpsilonSMax, cifreSignificativeStrain)};";
csv += "0;0;";
csv += $"{Math.Round(strainPlaneResult.EpsilonSSMin, cifreSignificativeStrain)};" +
$"{Math.Round(strainPlaneResult.EpsilonSSMax, cifreSignificativeStrain)};";
csv += $"{Math.Round(strainPlaneResult.NetHeight, cifreSignificativePlane)};" +
$"{Math.Round(strainPlaneResult.NeutralAxisDistance, cifreSignificativePlane)};" +
$"{Math.Round(strainPlaneResult.NeutralAxisAngle, cifreSignificativePlane)}";
outCsv[i] = csv;
(Maffeis.Geometry.Point2d point, double tension)[] concreteTens = result.GetConcreteVerticesTension(phi);
string[] bufferConcrete = [.. concreteTens.Select(k => Math.Round(k.tension, cifreSignificativeStresss).ToString() + ";")];
outConcreteTension[i] = string.Concat(bufferConcrete);
outConcretePoint ??= [.. concreteTens.Select(k => new Point3d(k.point.X, k.point.Y, 0))];
(Maffeis.Geometry.Point2d point, double tension)[] steelTens = result.GetStructuralSteelVerticesTension(phi);
string[] bufferSteel = [.. steelTens.Select(k => Math.Round(k.tension, cifreSignificativeStresss).ToString() + ";")];
outSteelTension[i] = string.Concat(bufferSteel);
outSteelPoint ??= [.. steelTens.Select(k => new Point3d(k.point.X, k.point.Y, 0))];
(ReinforcedConcreteRebar rebar, double tension)[] rebarTens = result.GetRebarsTension(phi, 0);
string[] bufferRebar = [.. rebarTens.Select(k => Math.Round(k.tension, cifreSignificativeStresss).ToString() + ";")];
outRebarTension[i] = string.Concat(bufferRebar);
outRebarPoint ??= [.. rebarTens.Select(k => new Point3d(k.rebar.Position.X, k.rebar.Position.Y, 0))];
//Maffeis.Geometry.Line2d neutralAxis = result.StrainPlane.GetNeutralAxis();
//neutralAxis?.Move(result.StrainPlane.ReferencePoint.X, result.StrainPlane.ReferencePoint.Y);
//Maffeis.Geometry.BoundingBox2d concreteBB = reinforcedConcreteSection.Shape.Fill2d.GetBoundingBox();
//Maffeis.Geometry.BoundingBox2d steelBB = reinforcedConcreteSection.SteelSections[0].Section.Shape.Fill2d.GetBoundingBox();
//Maffeis.Geometry.Point2d[] steelFill = reinforcedConcreteSection.SteelSections[0].Section.Shape.Fill2d.Points;
//Maffeis.Geometry.Point2d[] steelFillGlobal = steelFill.Select(k => reinforcedConcreteSection.SteelSections[0].PositionToGlobal(k)).ToArray();
//for (int k = 0; k < steelFillGlobal.Count(); k++)
// concreteBB.Update(steelFillGlobal);
//concreteBB.Scale(1.1);
//var point1 = new Maffeis.Geometry.Point2d(concreteBB.Min.X, concreteBB.Min.Y);
//var point2 = new Maffeis.Geometry.Point2d(concreteBB.Max.X, concreteBB.Min.Y);
//var point3 = new Maffeis.Geometry.Point2d(concreteBB.Max.X, concreteBB.Max.Y);
//var point4 = new Maffeis.Geometry.Point2d(concreteBB.Min.X, concreteBB.Max.Y);
//var line1 = new Maffeis.Geometry.Line2d(point1, point2);
//var line2 = new Maffeis.Geometry.Line2d(point2, point3);
//var line3 = new Maffeis.Geometry.Line2d(point3, point4);
//var line4 = new Maffeis.Geometry.Line2d(point4, point1);
//var polygon = new Maffeis.Geometry.Polygon2d(new Maffeis.Geometry.Point2d[] { point1, point2, point3, point4 });
//bool int1 = neutralAxis.GetIntersectionWithInfiniteLine(line1, out var intersection1);
//bool int2 = neutralAxis.GetIntersectionWithInfiniteLine(line2, out var intersection2);
//bool int3 = neutralAxis.GetIntersectionWithInfiniteLine(line3, out var intersection3);
//bool int4 = neutralAxis.GetIntersectionWithInfiniteLine(line4, out var intersection4);
//var ppp = new List<Maffeis.Geometry.Point2d>();
//if (int1 && line1.IsPointOnLine(intersection1, 1))
// ppp.Add(intersection1);
//if (int2 && line2.IsPointOnLine(intersection2, 1))
// ppp.Add(intersection2);
//if (int3 && line3.IsPointOnLine(intersection3, 1))
// ppp.Add(intersection3);
//if (int4 && line4.IsPointOnLine(intersection4, 1))
// ppp.Add(intersection4);
//if (ppp.Count == 2)
//{
// var outLine = new Maffeis.Geometry.Line2d(ppp[0], ppp[1]);
// var startPt = new Point3d(ppp[0].X, ppp[0].Y, 0);
// var endPt = new Point3d(ppp[1].X, ppp[1].Y, 0);
// lines[i] = new Line(startPt, endPt);
// //var p1 = new Point3d(neutralAxis.Start.X, neutralAxis.Start.Y, 0);
// //var p2 = new Point3d(neutralAxis.End.X, neutralAxis.End.Y, 0);
// //lines[i] = new Line(p1, p2);
//}
//else
//{
// lines[i] = new Line();
//}
}
DA.SetDataList(1, outCsv);
DA.SetDataList(2, outSteelPoint);
DA.SetDataList(3, outSteelTension);
DA.SetDataList(4, outConcretePoint);
DA.SetDataList(5, outConcreteTension);
DA.SetDataList(6, outRebarPoint);
DA.SetDataList(7, outRebarTension);
DA.SetDataList(8, lines);
string header = "Beam Id;Force Id;Force Combo;Force station;N [kN];Mx [kNm];My [kNm];" +
"σc min [Mpa];σc max [Mpa];σs min [Mpa];σs max [Mpa];σsp min [Mpa];σsp max [Mpa];σss min [Mpa];σss max [Mpa];" +
"εc min;εc max;εs min;εs max;εsp min;εsp max;εss min;εss max;" +
"d [mm];x [mm];θ [°]";
DA.SetData(0, header);
}
protected static Maffeis.Geometry.CoordinateSystem GetLocalCoordinateSystem(IConcreteSection section, double phi)
{
return new Maffeis.Geometry.CoordinateSystem(section.GetHomogenizedCentroid(phi, out double _, out double _), new Maffeis.Geometry.Vector3d(-1, 0, 0), new Maffeis.Geometry.Vector3d(0, -1, 0));
}
/// <summary>
/// Provides an Icon for the component.
/// </summary>
protected override System.Drawing.Bitmap Icon => Properties.Resources.MixedSectionBeamIcon;
/// <summary>
/// Gets the unique ID for this component. Do not change this ID after release.
/// </summary>
public override Guid ComponentGuid => new("f4d2a021-7d8b-4db2-9fa8-ad08ded165d5");
}
}