using FeMM.Common.Helpers;
using FeMM.Common.Models;
using FeMM.Grasshopper.DataTypes.FeMM;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using Maffeis.Utilities.Units;
using System;
using System.Collections.Generic;
namespace FeMM.Grasshopper.Components.Materials
{
public class MaterialCustomComponent : GH_Component
{
private List<int> _paramsIdx;
private List<string> _paramsName;
/// <summary>
/// Initializes a new instance of the MaterialCustomComponent class.
/// </summary>
public MaterialCustomComponent()
: base("Custom Material", "CM", "Custom material", Helpers.CategoryNameConstants.CATEGORY_FEMM, Helpers.CategoryNameConstants.SUBCATEGORY_MATERIALS)
{
}
/// <summary>
/// Registers all the input parameters for this component.
/// </summary>
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddTextParameter("Name", "N", "The name of the material", GH_ParamAccess.item);
// Kind param
pManager.AddIntegerParameter("Kind", "K", "The kind of the material", GH_ParamAccess.item);
Param_Integer param = (Param_Integer)pManager[1];
Array values = Enum.GetValues(typeof(MaterialModel.MaterialKind));
foreach (MaterialModel.MaterialKind val in values)
param.AddNamedValue(val.GetDescription(), (int)val);
pManager.AddIntegerParameter("Units", "U", "The measure units", GH_ParamAccess.item);
// Mesaure units param
Param_Integer type_param = (Param_Integer)pManager[2];
values = Enum.GetValues(typeof(ModelModel.ModelUnits));
foreach (ModelModel.ModelUnits val in values)
type_param.AddNamedValue(val.GetDescription(), (int)val);
// Material data params
_paramsIdx =
[
pManager.AddNumberParameter("Modulus", "E", "Modulus", GH_ParamAccess.item),
pManager.AddNumberParameter("Poisson Ratio", char.ConvertFromUtf32(0x3BD), "Poisson Ratio", GH_ParamAccess.item),
pManager.AddNumberParameter("Thermal Expansion", char.ConvertFromUtf32(0x3B1), "Thermal Expansion", GH_ParamAccess.item),
pManager.AddNumberParameter("Shear Modulus", "G", "Shear Modulus", GH_ParamAccess.item),
pManager.AddBooleanParameter("Use Poisson", char.ConvertFromUtf32(0x3BD) + "?", "Use Poisson", GH_ParamAccess.item),
pManager.AddNumberParameter("Density", char.ConvertFromUtf32(0x3C1), "Density", GH_ParamAccess.item),
pManager.AddNumberParameter("Yielding", "fk", "Yielding", GH_ParamAccess.item),
pManager.AddNumberParameter("Strength for Steel", "ftk", "Strength", GH_ParamAccess.item),
];
_paramsName = [];
foreach (int i in _paramsIdx)
{
pManager[i].Optional = true;
_paramsName.Add(pManager[i].Name);
}
}
/// <summary>
/// Registers all the output parameters for this component.
/// </summary>
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddGenericParameter("Material", "M", "The custom material", GH_ParamAccess.item);
}
/// <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)
{
string name = "";
int kind = 0;
int units = 0;
double modulus = 0, ni = 0, alpha = 0, g = 0, rho = 0, fk = 0, ftk = 0;
bool use_poisson = false;
if (!DA.GetData("Units", ref units))
return;
UpdateInputDescriptions((ModelModel.ModelUnits)units);
if (!DA.GetData("Kind", ref kind))
return;
Message = ((MaterialModel.MaterialKind)kind).ToString();
if (!DA.GetData("Name", ref name))
return;
if (!DA.GetData(_paramsIdx[0], ref modulus))
return;
if (!DA.GetData(_paramsIdx[1], ref ni))
return;
if (!DA.GetData(_paramsIdx[2], ref alpha))
return;
if (!DA.GetData(_paramsIdx[3], ref g))
return;
if (!DA.GetData(_paramsIdx[4], ref use_poisson))
return;
if (!DA.GetData(_paramsIdx[5], ref rho))
return;
if (!DA.GetData(_paramsIdx[6], ref fk))
return;
if (!DA.GetData(_paramsIdx[7], ref ftk))
return;
// Convert to Nmm
CommonModelHelper.GetUtilitiesConversionParams(
(ModelModel.ModelUnits)units,
out UnitsConvert.LengthUnits lengthUnits,
out UnitsConvert.ForceUnits forceUnits,
out UnitsConvert.MassUnits massUnits,
out UnitsConvert.PressureUnits pressureUnits,
out UnitsConvert.TemperatureUnits temperatureUnits);
modulus = UnitsConvert.ConvertToDefaultUnits(modulus, pressureUnits, 1);
g = UnitsConvert.ConvertToDefaultUnits(g, pressureUnits, 1);
rho = UnitsConvert.ConvertToDefaultUnits(rho, massUnits, 1, lengthUnits, -3);
fk = UnitsConvert.ConvertToDefaultUnits(fk, pressureUnits, 1);
ftk = UnitsConvert.ConvertToDefaultUnits(ftk, pressureUnits, 1);
var material = new MaterialModel
{
Kind = (MaterialModel.MaterialKind)kind,
Name = name,
Modulus = modulus,
PoissonRatio = ni,
ThermalExpansion = alpha,
ShearModulus = g,
UsePoisson = use_poisson,
Density = rho
};
switch (material.Kind)
{
case MaterialModel.MaterialKind.Aluminium:
//material.MinimumYieldStress = mys;
//material.MinimumTensileStress = mts;
//material.ExpectedYieldStress = eys;
//material.ExpectedTensileStress = ets;
break;
case MaterialModel.MaterialKind.Concrete:
case MaterialModel.MaterialKind.Precast:
material.SpecificCompressiveStrength = fk;
break;
case MaterialModel.MaterialKind.Steel:
material.MinimumYieldStress = fk;
material.MinimumTensileStress = ftk;
material.ExpectedYieldStress = 1.1 * fk;
material.ExpectedTensileStress = 1.1 * ftk;
break;
case MaterialModel.MaterialKind.Undefined:
break;
default:
throw new NotSupportedException();
}
DA.SetData(0, new GH_Material(material));
}
private void UpdateInputDescriptions(ModelModel.ModelUnits units)
{
switch (units)
{
//do not change the variables here. also default units in utilities are affected
case ModelModel.ModelUnits.kNm:
Params.Input[_paramsIdx[0]].NickName = _paramsName[0] + " (kPa)";
Params.Input[_paramsIdx[2]].NickName = _paramsName[2] + " (1/C)";
Params.Input[_paramsIdx[3]].NickName = _paramsName[3] + " (kPa)";
Params.Input[_paramsIdx[5]].NickName = _paramsName[5] + " (ton/m³)";
Params.Input[_paramsIdx[6]].NickName = _paramsName[6] + " (kPa)";
Params.Input[_paramsIdx[7]].NickName = _paramsName[7] + " (kPa)";
break;
case ModelModel.ModelUnits.SI:
Params.Input[_paramsIdx[0]].NickName = _paramsName[0] + " (Pa)";
Params.Input[_paramsIdx[2]].NickName = _paramsName[2] + " (1/C)";
Params.Input[_paramsIdx[3]].NickName = _paramsName[3] + " (Pa)";
Params.Input[_paramsIdx[5]].NickName = _paramsName[5] + " (kg/m³)";
Params.Input[_paramsIdx[6]].NickName = _paramsName[6] + " (Pa)";
Params.Input[_paramsIdx[7]].NickName = _paramsName[7] + " (Pa)";
break;
case ModelModel.ModelUnits.Nmm:
Params.Input[_paramsIdx[0]].NickName = _paramsName[0] + " (MPa)";
Params.Input[_paramsIdx[2]].NickName = _paramsName[2] + " (1/C)";
Params.Input[_paramsIdx[3]].NickName = _paramsName[3] + " (MPa)";
Params.Input[_paramsIdx[5]].NickName = _paramsName[5] + " (ton/mm³)";
Params.Input[_paramsIdx[6]].NickName = _paramsName[6] + " (MPa)";
Params.Input[_paramsIdx[7]].NickName = _paramsName[7] + " (MPa)";
break;
case ModelModel.ModelUnits.IPS:
Params.Input[_paramsIdx[0]].NickName = _paramsName[0] + " (psi)";
Params.Input[_paramsIdx[2]].NickName = _paramsName[2] + " (1/F)";
Params.Input[_paramsIdx[3]].NickName = _paramsName[3] + " (psi)";
Params.Input[_paramsIdx[5]].NickName = _paramsName[5] + " (lb/in³)";
Params.Input[_paramsIdx[6]].NickName = _paramsName[6] + " (psi)";
Params.Input[_paramsIdx[7]].NickName = _paramsName[7] + " (psi)";
break;
}
}
/// <summary>
/// Provides an Icon for the component.
/// </summary>
protected override System.Drawing.Bitmap Icon => Properties.Resources.MaterialCustomIcon;
/// <summary>
/// Gets the unique ID for this component. Do not change this ID after release.
/// </summary>
public override Guid ComponentGuid => new("262c4c26-81bf-4cfc-9ff9-28cb6db0c7bd");
}
}