using FeMM.Common.Models;
using FeMM.Grasshopper.Components.Models.MeCheck2;
using FeMM.Grasshopper.Components.Parameters;
using FeMM.Grasshopper.DataTypes;
using FeMM.Grasshopper.DataTypes.FeMM;
using FeMM.Grasshopper.DataTypes.MeCheck2;
using FeMM.Grasshopper.Helpers;
using Grasshopper.Kernel;
using Maffeis.Geometry;
using Maffeis.Model.Materials;
using Maffeis.Model.Results;
using Maffeis.Model.Sections.Concrete;
using Maffeis.Model.Standards;
using Maffeis.Utilities.Maths;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.Versioning;
using System.Text;
namespace FeMM.Grasshopper.Components.MeCheck2
{
#if NETCOREAPP
[SupportedOSPlatform("windows")]
#endif
public class SuperElementSectionExtractorComponent : GH_Component
{
protected bool _run;
#region JSON_VARIABLES
StandardEN1992p11 _concreteStandard;
StandardEN1993p11 _structuralSteelStandard;
ConcreteMaterialEN1992 _concreteMaterialEN1992;
SteelMaterialEN1993 _steelMaterialEN1993;
SteelMaterialEN1992 _rebarMaterial;
private double _geometrySlabHeight;
private double _geometrySlabWidth;
private double _geometryTopFlangeThickness;
private double _geometryTopFlangeWidth;
private double _geometryNetWebHeight;
private double _geometryWebThickness;
private double _geometryBottomFlangeThickness;
private double _geometryBottomFlangeWidth;
private double _geometryRebarsTopDistanceLayer0;
private double _geometryRebarsTopDistanceLayer1;
private double _geometryRebarsAreaLayer0;
private double _geometryRebarsAreaLayer1;
private double _geometryConcreteOffest;
private bool _geometryTopFlangeLocalBuckling;
private bool _geometryWebLocalBuckling;
private bool _geometryBottomFlangeLocalBuckling;
private bool _epsilonBasedOnCurrentStress;
private double _homogenizationNInf;
private double _homogenizationN0;
private bool _useHomogenizationN;
private bool _considerConcrete;
private bool _considerRebar;
private (ResultBeamForces OnlySteel, ResultBeamForces NInfinite, ResultBeamForces NInstant) _selectedComboForces = (null, null, null);
private (double StrainInfiniteTime, double StrainIstantTime) _selectedStrains = (0, 0);
private (ResultBeamForces[] OnlySteel, ResultBeamForces[] NInfinite, ResultBeamForces[] NInstant) _forcesForOutput;
private (double[] StrainInfiniteTime, double[] StrainIstantTime) _strains;
private CompositeSectionStiffeners _sectionStiffeners;
// Units conversions
public static readonly double FROM_N_TO_KN = 0.001;
public static readonly double FROM_NM_TO_KNM = 0.000001;
#endregion
/// <summary>
/// Initializes a new instance of the ChecksComponent class.
/// </summary>
public SuperElementSectionExtractorComponent()
: base("Super Element Section Extractor", "SESE", "Extract the data of a Superelement section", CategoryNameConstants.CATEGORY_CHECKS, CategoryNameConstants.SUBCATEGORY_MECHECK2)
{
_run = false;
}
public override void CreateAttributes()
{
ComponentAttributes.ComponentOneButtonAttributes attr = new(this, "Run");
attr.ButtonPressed += () =>
{
_run = true;
ExpireSolution(true);
};
m_attributes = attr;
}
/// <summary>
/// Registers all the input parameters for this component.
/// </summary>
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddGenericParameter("FeMM Model", "FM", "The FeMM model", GH_ParamAccess.item);
pManager.AddGenericParameter("Super-Element Beam", "SE", "The Super-Element Beam", GH_ParamAccess.list);
pManager.AddNumberParameter("Section Distance", "SD", "Distance of the section to extract", GH_ParamAccess.item, 0.0);
pManager.AddTextParameter("Combination Name", "CN", "Name of the combination of which the force analysis will be selected", GH_ParamAccess.item);
pManager.AddBooleanParameter("Web Local Instability", "WLI", "If true, web is subjected to loacel instability", GH_ParamAccess.item, true);
pManager.AddBooleanParameter("Top Flange Local Instability", "TFLI", "If true, top flange is subjected to loacel instability", GH_ParamAccess.item, true);
pManager.AddBooleanParameter("Bottom Flange Local Instability", "BLI", "If true, bottom flange is subjected to loacel instability", GH_ParamAccess.item, true);
pManager.AddBooleanParameter("Effective Epsilon", "ε", "If true, consider the epsilon based on the real tensione distribuition on the part of the section. " +
"Otherwise, it consider the yelding tension over all the section (safety side, higher tension, lower class)", GH_ParamAccess.item, false);
pManager.AddTextParameter("Save Path", "P", "Local folder path at which the data will be saved", GH_ParamAccess.item);
pManager.AddBooleanParameter("Autorun", "A", "Execute the component authomatically on input data change", GH_ParamAccess.item, false);
int idx = pManager.AddParameter(new CompositeSectionStiffenersParameter());
pManager[idx].Optional = true;
}
/// <summary>
/// Registers all the output parameters for this component.
/// </summary>
protected override void RegisterOutputParams(GH_OutputParamManager pManager) { }
/// <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)
{
Message = "";
GH_Model model = new();
List<GH_CompositeBeam> beams = [];
double sectionDistance = 0.0;
string comboName = null;
bool webFlangeInstab = false;
bool topFlangeInstab = false;
bool bottomFlangeInstab = false;
bool effectiveEpsilon = false;
string savePath = null;
string folderPath = null;
string fileName = null;
bool autoRun = false;
int n = 0;
if (!DA.GetData(n++, ref model)) return;
if (!DA.GetDataList(n++, beams)) return;
if (!DA.GetData(n++, ref sectionDistance)) return;
if (!DA.GetData(n++, ref comboName)) return;
if (!DA.GetData(n++, ref webFlangeInstab)) return;
if (!DA.GetData(n++, ref topFlangeInstab)) return;
if (!DA.GetData(n++, ref bottomFlangeInstab)) return;
if (!DA.GetData(n++, ref effectiveEpsilon)) return;
if (!DA.GetData(n++, ref savePath)) return;
if (!DA.GetData(n++, ref autoRun)) return;
GH_CompositeSectionStiffeners goo = null;
DA.GetData(n++, ref goo);
_sectionStiffeners = goo?.Value;
if (model.Value == null)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Null model");
Message = "Error";
return;
}
List<SuperElementAttributeModel> superElementsBuffer = Common.Helpers.CommonModelHelper.GetSuperElements(model.Value);
if (superElementsBuffer == null || superElementsBuffer.Count == 0)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Super-Element in the model");
Message = "Error";
return;
}
if (beams == null || beams.Count == 0)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Beam passed");
Message = "Error";
return;
}
if (string.IsNullOrWhiteSpace(savePath))
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No save path selected");
Message = "Error";
return;
}
if (sectionDistance < 0)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The distance value must be greater than zero");
Message = "Error";
_run = false;
return;
}
if (_run || autoRun)
{
CompositeBeamModel beamModel = null;
double cumulativeDistance = 0;
foreach (var beam in beams)
{
cumulativeDistance += beam.Value.Length;
if (cumulativeDistance >= sectionDistance)
{
beamModel = beam.Value;
sectionDistance -= (cumulativeDistance - beam.Value.Length);
break;
}
}
if (beamModel == null)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The distance value exceeds the beam dimension");
Message = "Error";
_run = false;
return;
}
fileName = Path.GetFileNameWithoutExtension(savePath);
folderPath = Path.GetDirectoryName(savePath);
if (!Directory.Exists(folderPath))
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The selected folder doesn't exists");
Message = "Error";
_run = false;
return;
}
try
{
/* ---------- Data Extraction ---------- */
double start_bfw = beamModel.StartBeamProperty.SteelSection.B1; // bottom flange width
double start_tfw = beamModel.StartBeamProperty.SteelSection.B2; // top flange width
double start_h = beamModel.StartBeamProperty.SteelSection.D; // heigth
double start_bft = beamModel.StartBeamProperty.SteelSection.T1; // Bottom flange thickness
double start_tft = beamModel.StartBeamProperty.SteelSection.T2; // Top flange thickness
double start_wt = beamModel.StartBeamProperty.SteelSection.T3; // Web thickness
double start_hh = beamModel.StartBeamProperty.ConcreteSection.Height; // heigth
double start_b = beamModel.StartBeamProperty.ConcreteSection.Width; // base
double start_topRebarsAreaTot = beamModel.StartBeamProperty.ConcreteSection.TopRebarArea;
double start_topRebarsCover = beamModel.StartBeamProperty.ConcreteSection.TopCover;
double start_bottomRebarsAreaTot = beamModel.StartBeamProperty.ConcreteSection.BottomRebarArea;
double start_bottomRebarsCover = beamModel.StartBeamProperty.ConcreteSection.BottomCover;
double start_verticalOffset = beamModel.StartBeamProperty.VerticalOffset;
double start_NInst = beamModel.StartBeamProperty.NInstant;
double start_NInf = beamModel.StartBeamProperty.NInfinite;
bool start_considerConcrete = beamModel.StartBeamProperty.ConsiderConcrete;
bool start_considerRebar = beamModel.StartBeamProperty.ConsiderRebar;
MaterialModel start_concreteModel = beamModel.StartBeamProperty.ConcreteMaterial;
MaterialModel start_steelModel = beamModel.StartBeamProperty.SteelMaterial;
MaterialModel start_rebarModel = beamModel.StartBeamProperty.RebarMaterial;
double end_bfw = beamModel.EndBeamProperty.SteelSection.B1; // bottom flange width
double end_tfw = beamModel.EndBeamProperty.SteelSection.B2; // top flange width
double end_h = beamModel.EndBeamProperty.SteelSection.D; // heigth
double end_bft = beamModel.EndBeamProperty.SteelSection.T1; // Bottom flange thickness
double end_tft = beamModel.EndBeamProperty.SteelSection.T2; // Top flange thickness
double end_wt = beamModel.EndBeamProperty.SteelSection.T3; // Web thickness
double end_hh = beamModel.EndBeamProperty.ConcreteSection.Height; // heigth
double end_b = beamModel.EndBeamProperty.ConcreteSection.Width; // base
double end_topRebarsAreaTot = beamModel.EndBeamProperty.ConcreteSection.TopRebarArea;
double end_topRebarsCover = beamModel.EndBeamProperty.ConcreteSection.TopCover;
double end_bottomRebarsAreaTot = beamModel.EndBeamProperty.ConcreteSection.BottomRebarArea;
double end_bottomRebarsCover = beamModel.EndBeamProperty.ConcreteSection.BottomCover;
double end_verticalOffset = beamModel.EndBeamProperty.VerticalOffset;
double end_NInst = beamModel.EndBeamProperty.NInstant;
double end_NInf = beamModel.EndBeamProperty.NInfinite;
bool end_considerConcrete = beamModel.EndBeamProperty.ConsiderConcrete;
bool end_considerRebar = beamModel.EndBeamProperty.ConsiderRebar;
MaterialModel end_concreteModel = beamModel.EndBeamProperty.ConcreteMaterial;
MaterialModel end_steelModel = beamModel.EndBeamProperty.SteelMaterial;
MaterialModel end_rebarModel = beamModel.EndBeamProperty.RebarMaterial;
double homogenizedFactorInfinite = beamModel.StartBeamProperty.NInfinite;
double homogenizedFactorInstant = beamModel.StartBeamProperty.NInstant;
/* ---------- Section Data ---------- */
bool constantSection = false;
if (start_bfw == end_bfw && start_tfw == end_tfw && start_h == end_h && start_bft == end_bft && start_tft == end_tft && start_wt == end_wt)
{
if (start_hh == end_hh && start_b == end_b && start_topRebarsAreaTot == end_topRebarsAreaTot && start_topRebarsCover == end_topRebarsCover &&
start_verticalOffset == end_verticalOffset)
{
if (start_concreteModel == end_concreteModel && start_steelModel == end_steelModel && start_rebarModel == end_rebarModel)
constantSection = true;
}
}
// Standards
_concreteStandard = new StandardEN1992p11();
_structuralSteelStandard = new StandardEN1993p11();
// Geometry
_geometryTopFlangeLocalBuckling = topFlangeInstab;
_geometryWebLocalBuckling = webFlangeInstab;
_geometryBottomFlangeLocalBuckling = bottomFlangeInstab;
_epsilonBasedOnCurrentStress = effectiveEpsilon;
// Homogenization
_useHomogenizationN = true;
_homogenizationNInf = homogenizedFactorInfinite;
_homogenizationN0 = homogenizedFactorInstant;
// Options
_considerConcrete = start_considerConcrete;
_considerRebar = start_considerRebar;
if (constantSection)
{
// Geometry
_geometrySlabHeight = start_hh;
_geometrySlabWidth = start_b;
_geometryConcreteOffest = start_verticalOffset;
_geometryTopFlangeThickness = start_tft;
_geometryTopFlangeWidth = start_tfw;
_geometryWebThickness = start_wt;
_geometryNetWebHeight = start_h - (start_bft + start_tft);
_geometryBottomFlangeThickness = start_bft;
_geometryBottomFlangeWidth = start_bfw;
_geometryRebarsAreaLayer0 = start_bottomRebarsAreaTot;
_geometryRebarsAreaLayer1 = start_topRebarsAreaTot;
_geometryRebarsTopDistanceLayer0 = start_bottomRebarsCover;
_geometryRebarsTopDistanceLayer1 = start_topRebarsCover;
// Materials
_concreteMaterialEN1992 = new ConcreteMaterialEN1992(start_concreteModel.Name, start_concreteModel.SpecificCompressiveStrength, ConcreteMaterial.CompressionStressStrainDiagrams.ParabolaRectangle);
_steelMaterialEN1993 = new SteelMaterialEN1993(start_steelModel.Name, start_steelModel.Modulus, start_steelModel.MinimumYieldStress, start_steelModel.MinimumTensileStress, 0.1, SteelMaterial.StressStrainCurveType.ElasticPerfectPlastic, SteelMaterial.SteelTypes.Structural);
_rebarMaterial = new SteelMaterialEN1992(start_rebarModel.Name, start_rebarModel.Modulus, start_rebarModel.MinimumTensileStress, start_rebarModel.ExpectedTensileStress, 0.1, SteelMaterial.StressStrainCurveType.ElasticPerfectPlastic, SteelMaterial.SteelTypes.Rebar);
}
else
{
// Geometry
_geometrySlabHeight = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_hh, end_hh, sectionDistance);
var hInterpolated = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_h, end_h, sectionDistance);
_geometrySlabWidth = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_b, end_b, sectionDistance);
_geometryConcreteOffest = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_verticalOffset, start_verticalOffset, sectionDistance);
_geometryTopFlangeThickness = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_tft, end_tft, sectionDistance);
_geometryTopFlangeWidth = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_tfw, end_tfw, sectionDistance);
_geometryWebThickness = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_wt, end_wt, sectionDistance);
_geometryBottomFlangeThickness = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_bft, end_bft, sectionDistance);
_geometryNetWebHeight = hInterpolated - (_geometryBottomFlangeThickness + _geometryTopFlangeThickness);
_geometryBottomFlangeWidth = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_bfw, end_bfw, sectionDistance);
_geometryRebarsAreaLayer0 = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_bottomRebarsAreaTot, end_bottomRebarsAreaTot, sectionDistance);
_geometryRebarsAreaLayer1 = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_topRebarsAreaTot, end_topRebarsAreaTot, sectionDistance);
_geometryRebarsTopDistanceLayer0 = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_bottomRebarsCover, end_bottomRebarsCover, sectionDistance);
_geometryRebarsTopDistanceLayer1 = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_topRebarsCover, end_topRebarsCover, sectionDistance);
// Materials
double fck = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_concreteModel.SpecificCompressiveStrength, end_concreteModel.SpecificCompressiveStrength, sectionDistance);
_concreteMaterialEN1992 = new ConcreteMaterialEN1992(start_concreteModel.Name, fck, ConcreteMaterial.CompressionStressStrainDiagrams.ParabolaRectangle);
double mysS = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_steelModel.MinimumYieldStress, end_steelModel.MinimumYieldStress, sectionDistance);
double mtsS = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_steelModel.MinimumTensileStress, end_steelModel.MinimumTensileStress, sectionDistance);
double eS = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_steelModel.Modulus, end_steelModel.Modulus, sectionDistance);
_steelMaterialEN1993 = new SteelMaterialEN1993(start_steelModel.Name, eS, mysS, mtsS, 0.1, SteelMaterial.StressStrainCurveType.ElasticPerfectPlastic, SteelMaterial.SteelTypes.Structural);
double mysR = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_rebarModel.MinimumYieldStress, end_rebarModel.MinimumYieldStress, sectionDistance);
double mtsR = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_rebarModel.MinimumTensileStress, end_rebarModel.MinimumTensileStress, sectionDistance);
double eR = Interpolation.GetLinearInterpolation(0, beamModel.Length, start_rebarModel.Modulus, end_rebarModel.Modulus, sectionDistance);
_rebarMaterial = new SteelMaterialEN1992(start_rebarModel.Name, eR, mysR, mtsR, 0.1, SteelMaterial.StressStrainCurveType.ElasticPerfectPlastic, SteelMaterial.SteelTypes.Rebar);
}
/* ---------- Forces ---------- */
try
{
CoordinateSystem cs = new(Point3d.Origin, new Vector3d(-1, 0, 0), new Vector3d(0, -1, 0));
ResultBeamForces[] resultBeamForcesOnlySteelsForOutput = new ResultBeamForces[model.Value.Combinations.Count];
ResultBeamForces[] resultBeamForcesInfinitesForOutput = new ResultBeamForces[model.Value.Combinations.Count];
ResultBeamForces[] resultBeamForcesInstantsForOutput = new ResultBeamForces[model.Value.Combinations.Count];
double[] strainNIstantArray = new double[model.Value.Combinations.Count];
double[] strainNInfiniteArray = new double[model.Value.Combinations.Count];
for (int c = 0; c < model.Value.Combinations.Count; c++)
{
if (model.Value.Combinations[c] is LoadCaseCombinationModel combo)
{
ResultBeamForces resultBeamForcesOnlySteelForOutput = new(0, 0, 0, 0, 0, 0, cs, 1, combo.Name);
ResultBeamForces resultBeamForcesInfiniteForOutput = new(0, 0, 0, 0, 0, 0, cs, 1, combo.Name);
ResultBeamForces resultBeamForcesInstantForOutput = new(0, 0, 0, 0, 0, 0, cs, 1, combo.Name);
double strainNIstant = 0;
double strainNInfinite = 0;
/* ----- Get Strain Values ----- */
for (int ss = 0; ss < beamModel.Loads.Count; ss++)
{
if (beamModel.Loads[ss] is CompositeBeamSlabStrainModel compositeBeamSlabStrainModel)
{
if (compositeBeamSlabStrainModel != null)
{
foreach (KeyValuePair<CaseModel, double> kvp in combo.Values)
{
CaseModel loadCase = kvp.Key;
double coeff = kvp.Value;
{
if (compositeBeamSlabStrainModel.LoadCase.Name == loadCase.Name)
{
if (compositeBeamSlabStrainModel.LoadCase.Stages.Count > 0 && compositeBeamSlabStrainModel.LoadCase.Stages.FirstOrDefault().BridgePhase == LoadCaseModel.BridgeStage.BridgePhases.StrainInstant)
{
strainNIstant = compositeBeamSlabStrainModel.Value.Strain;
strainNIstant *= coeff;
}
else if (compositeBeamSlabStrainModel.LoadCase.Stages.Count > 0 && compositeBeamSlabStrainModel.LoadCase.Stages.FirstOrDefault().BridgePhase == LoadCaseModel.BridgeStage.BridgePhases.StrainInfinite)
{
strainNInfinite = compositeBeamSlabStrainModel.Value.Strain;
strainNInfinite *= coeff;
}
}
}
}
}
}
}
/* ----- Get AxialForce, Vx, Vy, Torque, Mx, My Values ----- */
foreach (KeyValuePair<CaseModel, double> kvp in combo.Values)
{
CaseModel loadCase = kvp.Key;
double coeff = kvp.Value;
List<BeamForceResultModel> beamForceResultModels = [];
for (int ll = 0; ll < beamModel.Results.Count; ll++)
{
if (beamModel.Results[ll] is BeamForceResultModel beamForceResultModel)
{
beamForceResultModels.Add(beamForceResultModel);
}
}
var fff = beamForceResultModels.Where(w => w.LoadCase.Name == loadCase.Name).OrderBy(ff => ff.Station).ToList();
if (fff != null && fff.Count > 0)
{
double[] dists = new double[fff.Count];
double[] axialForces = new double[fff.Count];
double[] vxs = new double[fff.Count];
double[] vys = new double[fff.Count];
double[] torques = new double[fff.Count];
double[] mxs = new double[fff.Count];
double[] mys = new double[fff.Count];
for (int i = 0; i < fff.Count; i++)
{
var ff = fff[i];
double dist = 0;
if (ff.NormalizedLength)
dist = ff.Station * beamModel.Length;
else
dist = ff.Station;
dists[i] = dist;
axialForces[i] = ff.AxialForce;
vxs[i] = ff.Vx;
vys[i] = ff.Vy;
torques[i] = ff.Torque;
mxs[i] = ff.Mx;
mys[i] = ff.My;
}
var axialForce = Interpolation.GetLinearInterpolation(dists, axialForces, sectionDistance);
var vx = Interpolation.GetLinearInterpolation(dists, vxs, sectionDistance);
var vy = Interpolation.GetLinearInterpolation(dists, vys, sectionDistance);
var torque = Interpolation.GetLinearInterpolation(dists, torques, sectionDistance);
var mx = Interpolation.GetLinearInterpolation(dists, mxs, sectionDistance);
var my = Interpolation.GetLinearInterpolation(dists, mys, sectionDistance);
ResultBeamForces fffForOutput = new(axialForce, vx, vy, torque, my, mx, cs);
fffForOutput *= coeff;
if (((LoadCaseModel)fff[0].LoadCase).Stages.FirstOrDefault().BridgePhase == LoadCaseModel.BridgeStage.BridgePhases.OnlySteel)
resultBeamForcesOnlySteelForOutput += fffForOutput;
if (((LoadCaseModel)fff[0].LoadCase).Stages.FirstOrDefault().BridgePhase == LoadCaseModel.BridgeStage.BridgePhases.NInfinite)
resultBeamForcesInfiniteForOutput += fffForOutput;
if (((LoadCaseModel)fff[0].LoadCase).Stages.FirstOrDefault().BridgePhase == LoadCaseModel.BridgeStage.BridgePhases.NInstant)
resultBeamForcesInstantForOutput += fffForOutput;
}
}
/* -------------------- */
resultBeamForcesOnlySteelsForOutput[c] = resultBeamForcesOnlySteelForOutput;
resultBeamForcesInfinitesForOutput[c] = resultBeamForcesInfiniteForOutput;
resultBeamForcesInstantsForOutput[c] = resultBeamForcesInstantForOutput;
strainNInfiniteArray[c] = strainNInfinite;
strainNIstantArray[c] = strainNIstant;
if (combo.Name == comboName)
{
_selectedComboForces = (resultBeamForcesOnlySteelForOutput, resultBeamForcesInfiniteForOutput, resultBeamForcesInstantForOutput);
_selectedStrains = (strainNInfinite, strainNIstant);
}
}
}
_forcesForOutput = (resultBeamForcesOnlySteelsForOutput, resultBeamForcesInfinitesForOutput, resultBeamForcesInstantsForOutput);
_strains = (strainNInfiniteArray, strainNIstantArray);
}
catch (Exception e)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Fail to get forces: {e.Message}");
Message = "Error";
_run = false;
return;
}
/* ---------- Data Export ---------- */
string filePath = $"{folderPath}\\{fileName}.bscj";
switch (ExportSection(filePath))
{
case -1:
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Unable to export beam section to file");
Message = "Error";
_run = false;
return;
case 1:
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"There is no combo named {comboName}");
break;
}
/* --------------------------------- */
Message = "Done";
}
catch (Exception e)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Generic error: {e.Message}");
Message = "Error";
_run = false;
return;
}
_run = false;
}
}
/// <summary>
/// Export section analysis data of the beam to archive.<br/>
/// Returns:<br/>
/// -1 -> An unhandled error occurred during the export process<br/>
/// 0 -> Data exported successfully<br/>
/// 1 -> Data exported, but the selected combo was not found<br/>
/// </summary>
/// <param name="filePath"></param>
/// <param name="beamModel"></param>
/// <returns></returns>
private int ExportSection(string filePath)
{
int res = 0;
try
{
var memStream = new MemoryStream();
var streamWriter = new StreamWriter(memStream, Encoding.UTF8);
var writer = new JsonTextWriter(streamWriter);
var serializer = new JsonSerializer
{
TypeNameHandling = TypeNameHandling.Auto
};
writer.WriteStartObject();
// Save file version
int fileVersionNumber = 8;
writer.WritePropertyName("Version");
writer.WriteValue(fileVersionNumber);
serializer.TypeNameHandling = TypeNameHandling.Objects; // to force "$type" for standard in json
// Save current concrete standard
writer.WritePropertyName("ConcreteStandard");
serializer.Serialize(writer, _concreteStandard);
// Save current structural steel standard
writer.WritePropertyName("StructuralSteelStandard");
serializer.Serialize(writer, _structuralSteelStandard);
// Save current concrete material
writer.WritePropertyName("ConcreteMaterial");
serializer.Serialize(writer, _concreteMaterialEN1992);
// Save current rebars material
writer.WritePropertyName("RebarSteelMaterial");
serializer.Serialize(writer, _rebarMaterial);
// Save current structural material
writer.WritePropertyName("StrucSteelMaterial");
serializer.Serialize(writer, _steelMaterialEN1993);
serializer.TypeNameHandling = TypeNameHandling.Auto;
// Geometry
WriteGeometry(writer);
// Homogenization
WriteHomogenization(writer);
// Selected Combo Forces
if (_selectedComboForces != (null, null, null))
WriteSelectedComboForces(writer);
else
res = 1;
// Options
WriteOptions(writer);
//Stiffeners
_sectionStiffeners?.Write(writer);
// Forces
writer.WritePropertyName("Forces");
writer.WriteStartArray();
for (int c = 0; c < _forcesForOutput.OnlySteel.Length; c++)
WriteComboForce(writer, _forcesForOutput.OnlySteel[c], _forcesForOutput.NInfinite[c], _forcesForOutput.NInstant[c], _strains.StrainInfiniteTime[c], _strains.StrainIstantTime[c]);
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
var memArray = memStream.ToArray();
var compressedMemArray = Compress(memArray);
File.WriteAllBytes(filePath, compressedMemArray);
}
catch
{
return -1;
}
return res;
}
private void WriteGeometry(JsonTextWriter writer)
{
writer.WritePropertyName("GeometrySlabHeight");
writer.WriteValue(_geometrySlabHeight);
writer.WritePropertyName("GeometrySlabWidth");
writer.WriteValue(_geometrySlabWidth);
writer.WritePropertyName("GeometryConcreteOffest");
writer.WriteValue(_geometryConcreteOffest);
writer.WritePropertyName("GeometryTopFlangeThickness");
writer.WriteValue(_geometryTopFlangeThickness);
writer.WritePropertyName("GeometryTopFlangeWidth");
writer.WriteValue(_geometryTopFlangeWidth);
writer.WritePropertyName("GeometryNetWebHeight");
writer.WriteValue(_geometryNetWebHeight);
writer.WritePropertyName("GeometryWebThickness");
writer.WriteValue(_geometryWebThickness);
writer.WritePropertyName("GeometryBottomFlangeThickness");
writer.WriteValue(_geometryBottomFlangeThickness);
writer.WritePropertyName("GeometryBottomFlangeWidth");
writer.WriteValue(_geometryBottomFlangeWidth);
writer.WritePropertyName("GeometryTopFlangeLocalBuckling");
writer.WriteValue(_geometryTopFlangeLocalBuckling);
writer.WritePropertyName("GeometryWebLocalBuckling");
writer.WriteValue(_geometryWebLocalBuckling);
writer.WritePropertyName("GeometryBottomFlangeLocalBuckling");
writer.WriteValue(_geometryBottomFlangeLocalBuckling);
writer.WritePropertyName("EpsilonBasedOnCurrentStress");
writer.WriteValue(_epsilonBasedOnCurrentStress);
writer.WritePropertyName("GeometryRebarsTopDistanceLayer0");
writer.WriteValue(_geometryRebarsTopDistanceLayer0);
writer.WritePropertyName("GeometryRebarsTopDistanceLayer1");
writer.WriteValue(_geometryRebarsTopDistanceLayer1);
writer.WritePropertyName("GeometryRebarsAreaLayer0");
writer.WriteValue(_geometryRebarsAreaLayer0);
writer.WritePropertyName("GeometryRebarsAreaLayer1");
writer.WriteValue(_geometryRebarsAreaLayer1);
}
private void WriteHomogenization(JsonTextWriter writer)
{
writer.WritePropertyName("HomogenizationNInf");
writer.WriteValue(_homogenizationNInf);
writer.WritePropertyName("HomogenizationN0");
writer.WriteValue(_homogenizationN0);
writer.WritePropertyName("UseHomogenizationN");
writer.WriteValue(_useHomogenizationN);
}
private void WriteSelectedComboForces(JsonTextWriter writer)
{
writer.WritePropertyName("OnlySteelForceN");
writer.WriteValue(_selectedComboForces.OnlySteel.N * FROM_N_TO_KN); // [N] -> [kN]
writer.WritePropertyName("OnlySteelForceVy");
writer.WriteValue(_selectedComboForces.OnlySteel.V2 * FROM_N_TO_KN); // [N] -> [kN]
writer.WritePropertyName("OnlySteelForceMx");
writer.WriteValue(_selectedComboForces.OnlySteel.M1 * FROM_NM_TO_KNM); // [N*mm] -> [kN*m]
writer.WritePropertyName("InfiniteTimeForceN");
writer.WriteValue(_selectedComboForces.NInfinite.N * FROM_N_TO_KN);
writer.WritePropertyName("InfiniteTimeForceVy");
writer.WriteValue(_selectedComboForces.NInfinite.V2 * FROM_N_TO_KN);
writer.WritePropertyName("InfiniteTimeForceMx");
writer.WriteValue(_selectedComboForces.NInfinite.M1 * FROM_NM_TO_KNM);
writer.WritePropertyName("InfiniteTimeForceE");
writer.WriteValue(_selectedStrains.StrainInfiniteTime);
writer.WritePropertyName("InstantTimeForceN");
writer.WriteValue(_selectedComboForces.NInstant.N * FROM_N_TO_KN);
writer.WritePropertyName("InstantTimeForceVy");
writer.WriteValue(_selectedComboForces.NInstant.V2 * FROM_N_TO_KN);
writer.WritePropertyName("InstantTimeForceMx");
writer.WriteValue(_selectedComboForces.NInstant.M1 * FROM_NM_TO_KNM);
writer.WritePropertyName("InstantTimeForceE");
writer.WriteValue(_selectedStrains.StrainIstantTime);
}
private void WriteOptions(JsonTextWriter writer)
{
writer.WritePropertyName("ConsiderConcrete");
writer.WriteValue(_considerConcrete);
writer.WritePropertyName("ConsiderRebars");
writer.WriteValue(_considerRebar);
}
private static void WriteComboForce(JsonTextWriter writer, ResultBeamForces onlySteel, ResultBeamForces nInfinite, ResultBeamForces nInstant, double strainInfiniteTime, double strainIstantTime)
{
writer.WriteStartObject();
writer.WritePropertyName("Name");
writer.WriteValue(onlySteel.Name);
writer.WritePropertyName("N0");
writer.WriteValue(onlySteel.N * FROM_N_TO_KN); // [N] -> [kN]
writer.WritePropertyName("Vy0");
writer.WriteValue(onlySteel.V2 * FROM_N_TO_KN); // [N] -> [kN]
writer.WritePropertyName("Mx0");
writer.WriteValue(onlySteel.M1 * FROM_NM_TO_KNM); // [N*mm] -> [kN*m]
writer.WritePropertyName("N1");
writer.WriteValue(nInfinite.N * FROM_N_TO_KN);
writer.WritePropertyName("Vy1");
writer.WriteValue(nInfinite.V2 * FROM_N_TO_KN);
writer.WritePropertyName("Mx1");
writer.WriteValue(nInfinite.M1 * FROM_NM_TO_KNM);
writer.WritePropertyName("N2");
writer.WriteValue(nInstant.N * FROM_N_TO_KN);
writer.WritePropertyName("Vy2");
writer.WriteValue(nInstant.V2 * FROM_N_TO_KN);
writer.WritePropertyName("Mx2");
writer.WriteValue(nInstant.M1 * FROM_NM_TO_KNM);
writer.WritePropertyName("StrainInfinite");
writer.WriteValue(strainInfiniteTime);
writer.WritePropertyName("StrainInstant");
writer.WriteValue(strainIstantTime);
writer.WriteEndObject();
}
private static byte[] Compress(byte[] data)
{
if (data is null || data.Length == 0)
{
throw new ArgumentException("Data to compress cannot be null or empty");
}
var compressedStream = new MemoryStream();
using (var gzipStream = new GZipStream(compressedStream, CompressionLevel.Optimal))
{
gzipStream.Write(data, 0, data.Length);
}
return compressedStream.ToArray();
}
public override GH_Exposure Exposure => GH_Exposure.tertiary;
/// <summary>
/// Provides an Icon for the component.
/// </summary>
protected override System.Drawing.Bitmap Icon => Properties.Resources.SuperElementCheckIcon;
/// <summary>
/// Gets the unique ID for this component. Do not change this ID after release.
/// </summary>
public override Guid ComponentGuid => new("18116f13-8dfd-4a4d-ac05-b6ccc8dc6bd9");
}
}