public void ModelMassSIUnits() { var k3d = new Toolkit(); var gamma = 1.0; // (kN/m3) var unit_material = new FemMaterial_Isotrop("unit", "unit", 1, 0.5, 0.5, gamma, 1.0, -1.0, FemMaterial.FlowHypothesis.mises, 1.0, null); var b = 100; // (cm) var t = 50; // (cm) var unit_crosec = k3d.CroSec.Box(b, b, b, t, t, t, 0, 0, unit_material); var elems = new List <BuilderBeam>() { k3d.Part.IndexToBeam(0, 1, "A", unit_crosec), }; var L = 1.0; // in m var points = new List <Point3> { new Point3(), new Point3(L, 0, 0) }; var model = k3d.Model.AssembleModel(elems, null, null, out var info, out var mass, out var cog, out var msg, out var runtimeWarning, new List <Joint>(), points); var ucf = UnitsConversionFactory.Conv(); mass = ucf.kg().toUnit(mass); Assert.AreEqual(mass, 100, 1e-10); }
private static List <CroSec> StbSecBeamRcToK3dCroSec(IEnumerable <StbSecBeam_RC> girders) { var k3dCroSecList = new List <CroSec>(); if (girders == null) { return(k3dCroSecList); } foreach (StbSecBeam_RC girder in girders) { double width, depth; FemMaterial_Isotrop material = Material.StbToRcFemMaterial(girder.strength_concrete); object[] figures = girder.StbSecFigureBeam_RC.Items; switch (figures[0]) { case StbSecBeam_RC_Straight straight: width = straight.width / 10d; depth = straight.depth / 10d; break; case StbSecBeam_RC_Taper _: StbSecBeam_RC_Taper[] tapers = { figures[0] as StbSecBeam_RC_Taper, figures[1] as StbSecBeam_RC_Taper }; width = tapers.First(figure => figure.pos == StbSecBeam_RC_TaperPos.START).width / 10d; depth = tapers.First(figure => figure.pos == StbSecBeam_RC_TaperPos.START).depth / 10d; break; case StbSecBeam_RC_Haunch _: StbSecBeam_RC_Haunch[] haunches; haunches = figures.Length == 2 ? new[] { figures[0] as StbSecBeam_RC_Haunch, figures[1] as StbSecBeam_RC_Haunch } : new[] { figures[0] as StbSecBeam_RC_Haunch, figures[1] as StbSecBeam_RC_Haunch, figures[2] as StbSecBeam_RC_Haunch }; width = haunches.First(figure => figure.pos == StbSecBeam_RC_HaunchPos.CENTER).width / 10d; depth = haunches.First(figure => figure.pos == StbSecBeam_RC_HaunchPos.CENTER).depth / 10d; break; default: throw new ArgumentException("Convert StbSecBeam_RC to karamba3d error"); } var name = $"BD-{width * 10}x{depth * 10}"; var k3dCroSec = new CroSec_Trapezoid("RcBeam", name, null, null, material, depth, width, width); k3dCroSec.AddElemId("Id" + girder.id); k3dCroSecList.Add(k3dCroSec); } return(k3dCroSecList); }
public void ModelMassImperialUnits() { // make temporary changes to the the ini-file and units-conversion INIReader.ClearSingleton(); UnitsConversionFactory.ClearSingleton(); var ini = INIReader.Instance(); ini.Values["UnitsSystem"] = "imperial"; ini.Values["gravity"] = "9.80665"; var k3d = new Toolkit(); var gamma = 1.0; // (kip/ft3) var unit_material = new FemMaterial_Isotrop("unit", "unit", 1, 0.5, 0.5, gamma, 1.0, -1.0, FemMaterial.FlowHypothesis.mises, 1.0, null); var b = 12; // (inch) var t = 6; // (inch) var unit_crosec = k3d.CroSec.Box(b, b, b, t, t, t, 0, 0, unit_material); var elems = new List <BuilderBeam>() { k3d.Part.IndexToBeam(0, 1, "A", unit_crosec), }; var L = 1.0; // in feet var points = new List <Point3> { new Point3(), new Point3(L, 0, 0) }; var model = k3d.Model.AssembleModel(elems, null, null, out var info, out var mass, out var cog, out var msg, out var runtimeWarning, new List <Joint>(), points); // clear temporary changes to the the ini-file and units-conversion INIReader.ClearSingleton(); UnitsConversionFactory.ClearSingleton(); ini = INIReader.Instance(); // switch back to SI units ini.Values["UnitsSystem"] = "SI"; Assert.AreEqual(mass, 1000, 1e-10); }
private static List <CroSec> StbSecColumnRcToK3dCroSec(IEnumerable <StbSecColumn_RC> columns) { var k3dCroSecList = new List <CroSec>(); if (columns == null) { return(k3dCroSecList); } foreach (StbSecColumn_RC column in columns) { string name; CroSec_Beam k3dCroSec; object figure = column.StbSecFigureColumn_RC.Item; FemMaterial_Isotrop material = Material.StbToRcFemMaterial(column.strength_concrete); switch (figure) { case StbSecColumn_RC_Rect rect: double widthX = rect.width_X / 10d; double widthY = rect.width_Y / 10d; name = $"CD-{widthX * 10}x{widthY * 10}"; k3dCroSec = new CroSec_Trapezoid("RcColRect", name, null, null, material, widthX, widthY, widthY); break; case StbSecColumn_RC_Circle circle: double d = circle.D / 10d; name = $"P-{d * 10}"; k3dCroSec = new CroSec_Circle("RcColCircle", name, null, null, material, d, d / 2); break; default: throw new ArgumentException("Convert StbSecColumn_RC to karamba3d error"); } k3dCroSec.AddElemId("Id" + column.id); k3dCroSecList.Add(k3dCroSec); } return(k3dCroSecList); }
public FEResults Analyze() { var license_path = Karamba.Licenses.License.licensePath(); var license = Karamba.Licenses.License.getLicense(); var has_expired = Karamba.Licenses.License.has_expired(); var license_type = Karamba.Licenses.License.licenseType(); var k3d = new Toolkit(); var logger = new MessageLogger(); // create beam elements var lines = new List <Line3>(); var colSecs = new List <CroSec>(); for (int i = 0; i < modelGeo.Beams.Count; i++) { Beam b = modelGeo.Beams[i]; double l = Math.Max(Points.Distance(b.Section[0], b.Section[1]), Points.Distance(b.Section[1], b.Section[2])); double w = Math.Min(Points.Distance(b.Section[0], b.Section[1]), Points.Distance(b.Section[1], b.Section[2])); Vector3 v = new Vector3((b.End.X - b.Start.X) / beamDisc, (b.End.Y - b.Start.Y) / beamDisc, (b.End.Z - b.Start.Z) / beamDisc); var nodeI = new Point3(b.Start.X, b.Start.Y, b.Start.Z); for (int beamInd = 0; beamInd < beamDisc; ++beamInd) { var nodeK = new Point3(nodeI.X + v.X, nodeI.Y + v.Y, nodeI.Z + v.Z); lines.Add(new Line3(nodeI, nodeK)); colSecs.Add(k3d.CroSec.Box(height: l, uf_thick: w, lf_width: w)); nodeI = nodeK; } } List <ShellMesh> shellMeshes = CreateMesh(); List <Mesh3> slabMeshes = shellMeshes.Where(sm => sm.Shell.type == ShellType.Slab).Select(s => s.Mesh).ToList(); List <Mesh3> wallMeshes = shellMeshes.Where(sm => sm.Shell.type == ShellType.Wall).Select(s => s.Mesh).ToList(); // materials FemMaterial C4050 = new FemMaterial_Isotrop("concrete", "C40/50", 35e6, 14.58e6, 14.58e6, 25, 40e3, 0, System.Drawing.Color.Blue); // cross-sections List <CroSec> slabSecs = slabMeshes.SelectMany(s => new List <CroSec> { k3d.CroSec.ShellConst(height: 0.250) }).ToList();; // be careful with units (most likely) in cm !! List <CroSec> wallSecs = wallMeshes.SelectMany(s => new List <CroSec> { k3d.CroSec.ShellConst(height: 0.300) }).ToList();; // be careful with units (most likely) in cm !! colSecs.ForEach(c => c.setMaterial(C4050)); slabSecs.ForEach(c => c.setMaterial(C4050)); wallSecs.ForEach(c => c.setMaterial(C4050)); // FE elements var slabElements = k3d.Part.MeshToShell(slabMeshes, new List <string>(), slabSecs, logger, out List <Point3> outSlabPoints); var wallElements = k3d.Part.MeshToShell(wallMeshes, new List <string>(), wallSecs, logger, out List <Point3> outWallPoints); var beamElements = k3d.Part.LineToBeam(lines, new List <string>(), colSecs, logger, out List <Point3> outColPoints); List <BuilderElement> elements = new List <BuilderElement>(slabElements); elements.AddRange(wallElements); elements.AddRange(beamElements); // ------ LOADS --------- List <Load> loads = new List <Load>(); // mesh loads on slabs List <Load> slabLoads = new List <Load>(); for (int i = 0; i < slabMeshes.Count; i++) { slabLoads.Add(k3d.Load.MeshLoad(new List <Vector3> { new Vector3(0, 0, -2.5) }, slabMeshes[i])); } //loads.AddRange(slabLoads); // gravity GravityLoad gravity = new GravityLoad(new Vector3(0, 0, -1), 0); loads.Add(gravity); // supports var colSupports = modelGeo.Beams.Where(b => b.Start.Z == 0) .Select(b => k3d.Support.Support(new Point3(b.Start.X, b.Start.Y, 0), k3d.Support.SupportFixedConditions)).ToList(); var wallSupports = wallMeshes.SelectMany(m => m.Vertices.Where(v => v.Z == 0) .Select(v => k3d.Support.Support(new Point3(v.X, v.Y, v.Z), k3d.Support.SupportFixedConditions))).ToList(); var supports = colSupports; supports.AddRange(wallSupports); // assemble the model var model = k3d.Model.AssembleModel(elements, supports, loads, out string info, out double mass, out Point3 cog, out string msg, out bool runtimeWarning); // calculate the model model = k3d.Algorithms.AnalyzeThI(model, out var maxDisp, out var outG, out var outComp, out var warning); Karamba.Results.NodalDisp.solve(model, 0, out var trans, out var rot); // OUTPUTS List <MWVector3D> pointDisps = new List <MWVector3D>(); List <MWPoint3D> points = new List <MWPoint3D>(); for (int i = 0; i < model.nodes.Count; i++) { var n0 = model.nodes[i].pos; var n1 = trans[i]; points.Add(new MWPoint3D(n0.X, n0.Y, n0.Z)); pointDisps.Add(new MWVector3D(n1.X / 10.0, n1.Y / 10.0, n1.Z / 10.0)); } List <int[]> t3 = new List <int[]>(); List <int[]> l2 = new List <int[]>(); for (int i = 0; i < model.elems.Count; i++) { if (model.elems[i] is ModelShell e) { var m = e.mesh; for (int j = 0; j < m.Faces.Count; j++) { t3.Add(new int[] { e.fe_node_ind[m.Faces[j][0]], e.fe_node_ind[m.Faces[j][1]], e.fe_node_ind[m.Faces[j][2]] }); } } if (model.elems[i] is ModelBeam b) { l2.Add(new int[] { b.fe_node_ind[0], b.fe_node_ind[1] }); } } FEResults fer = new FEResults() { PointsPos = points.Select(p => new MWPoint3D(p.X, p.Y, p.Z)).ToList(), PointsDisps = pointDisps.Select(p => new MWVector3D(p.X, p.Y, p.Z)).ToList(), T3 = t3, L2 = l2, MaxDeflection = pointDisps.Max(p => Math.Abs(p.Z)) * 1e3, MaxDrift = pointDisps.Max(d => Math.Sqrt(d.X * d.X + d.Y * d.Y)) * 1e3, NumberElems = model.elems.Count }; return(fer); //return (points.Select(p => new MWPoint3D(p.X, p.Y, p.Z)).ToList(), t3); }
public void CantileverEigenfrequency() { // make temporary changes to the the ini-file and units-conversion INIReader.ClearSingleton(); UnitsConversionFactory.ClearSingleton(); var ini = INIReader.Instance(); ini.Values["UnitsSystem"] = "imperial"; ini.Values["gravity"] = "9.80665"; var k3d = new Toolkit(); var E = 70000; // (kip/ft2) == 486111.1 (psi) var gamma = 1.0; // (kip/ft3) var unit_material = new FemMaterial_Isotrop("unit", "unit", E, 0.5 * E, 0.5 * E, gamma, 1.0, -1.0, FemMaterial.FlowHypothesis.mises, 1.0, null); var b = 6; // (inch) var t = 3; // (inch) // Iy = 108 inch^4 // g = 20.833 lb/inch var unit_crosec = k3d.CroSec.Box(b, b, b, t, t, t, 0, 0, unit_material); var elems = new List <BuilderBeam>() { k3d.Part.IndexToBeam(0, 1, "A", unit_crosec), }; var L = 10.0; // in feet var points = new List <Point3> { new Point3(), new Point3(L, 0, 0) }; var supports = new List <Support> { k3d.Support.Support(0, k3d.Support.SupportFixedConditions) }; var model = k3d.Model.AssembleModel(elems, supports, null, out var info, out var mass, out var cog, out var msg, out var runtimeWarning, new List <Joint>(), points); // calculate the natural vibrations int from_shape_ind = 1; int shapes_num = 1; int max_iter = 100; double eps = 1e-8; var disp_dummy = new List <double>(); var scaling = EigenShapesScalingType.matrix; model = k3d.Algorithms.NaturalVibes(model, from_shape_ind, shapes_num, max_iter, eps, disp_dummy, scaling, out var nat_frequencies, out var modal_masses, out var participation_facs, out var participation_facs_disp, out model); // calculate the expected value of the first eigen-frequency // see Young, W. C., Budynas, R. G.(2002). Roark's Formulas for Stress and Strain . // 7nd Edition, McGraw-Hill, Chapter 16 , pp 767 - 768 var E_ = E * 1000.0 * Math.Pow(UnitConversionCollection.inch_to_ft, 2); var I_ = unit_crosec.Iyy / Math.Pow(UnitConversionCollection.inch_to_ft, 4); var w_ = unit_crosec.A * gamma * 1000.0 * UnitConversionCollection.inch_to_ft; var g_ = UnitConversionCollection.g_IU / UnitConversionCollection.inch_to_ft; var L_ = L / UnitConversionCollection.inch_to_ft; var Kn = 3.52; var f1_expected = Kn / 2.0 / Math.PI * Math.Sqrt(E_ * I_ * g_ / w_ / Math.Pow(L_, 4)); Assert.AreEqual(nat_frequencies[0], f1_expected, 1e-2); // clear temporary changes to the the ini-file and units-conversion INIReader.ClearSingleton(); UnitsConversionFactory.ClearSingleton(); ini = INIReader.Instance(); // switch back to SI units ini.Values["UnitsSystem"] = "SI"; }
public void JsonSerialization_Model() { var k3d = new Toolkit(); var E = 70000; var gamma = 1.0; var unit_material = new FemMaterial_Isotrop("unit", "unit", E, 0.5 * E, 0.5 * E, gamma, 1.0, -1.0, FemMaterial.FlowHypothesis.mises, 1.0, null); var b = 6; // cm var t = 3; // cm var unit_crosec = k3d.CroSec.Box(b, b, b, t, t, t, 0, 0, unit_material); unit_crosec.Az = 1e10; // make cross section rigid in shear var elems = new List <BuilderBeam>() { k3d.Part.IndexToBeam(0, 1, "A", unit_crosec), }; var L = 10.0; //m var points = new List <Point3> { new Point3(), new Point3(L, 0, 0) }; var supports = new List <Support> { k3d.Support.Support(0, k3d.Support.SupportFixedConditions) }; var Fz = 1; // kN var loads = new List <Load> { k3d.Load.PointLoad(points[1], new Vector3(0, 0, -Fz)) }; var model = k3d.Model.AssembleModel(elems, supports, loads, out var info, out var mass, out var cog, out var msg, out var runtimeWarning, new List <Joint>(), points); // json serialization/de-serialization //--- var json_settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }; // node serialization //--- var node_json = JsonConvert.SerializeObject(model.nodes[0]); File.WriteAllText("node.json", node_json); var node_dser = JsonConvert.DeserializeObject <Karamba.Nodes.Node>(node_json); Assert.IsTrue(model.nodes[0].ToString() == node_dser.ToString()); // element serialization //--- // var elements_output = JsonConvert.SerializeObject(model.elems); var elements_json = JsonConvert.SerializeObject(model.elems, Formatting.Indented, json_settings); File.WriteAllText("elements.json", elements_json); var elements_dser = JsonConvert.DeserializeObject <List <ModelElement> >(elements_json, json_settings); Assert.IsTrue(model.elems[0].ToString() == elements_dser[0].ToString()); // model serialization //--- var model_json = JsonConvert.SerializeObject(model, Formatting.Indented, json_settings); File.WriteAllText("model.json", model_json); var model_dser = JsonConvert.DeserializeObject <Karamba.Models.Model>(model_json, json_settings); // calculate Th.I response var model_calc = k3d.Algorithms.AnalyzeThI(model_dser, out var max_disp, out var out_g, out var out_comp, out var message); var max_disp_expected = Fz * L * L * L / (3 * E * unit_crosec.Iyy); Assert.AreEqual(max_disp[0], max_disp_expected, 1E-6); }
public void SinglemassEigenfrequency_SI() { // make temporary changes to the the ini-file and units-conversion INIReader.ClearSingleton(); UnitsConversionFactory.ClearSingleton(); var ini = INIReader.Instance(); ini.Values["UnitsSystem"] = "SI"; ini.Values["UnitsSystem"] = "SI"; var gravity = 9.81; // m/s2 ini.Values["gravity"] = gravity.ToString(CultureInfo.InvariantCulture); ini.Values["UnitLength"] = "ft"; ini.Values["UnitForce"] = "MN"; ini.Values["UnitMass"] = "t"; var uc = UnitsConversionFactory.Conv(); gravity = uc.gravity().toBase(); // cm/s2 var k3d = new Toolkit(); var E = uc["N/cm2"].toBase(70); var gamma = uc["N/cm3"].toBase(1.0); // input is not scaled to base units var unit_material = new FemMaterial_Isotrop("unit", "unit", E, 0.5 * E, 0.5 * E, gamma, 1.0, -1.0, FemMaterial.FlowHypothesis.mises, 1.0, null); var b = 6; // (cm) var t = 3; // (cm) // input is scaled to base units var unit_crosec = k3d.CroSec.Box(b, b, b, t, t, t, 0, 0, unit_material); var elems = new List <BuilderBeam>() { k3d.Part.IndexToBeam(0, 1, "A", unit_crosec), }; elems[0].bending_stiff = false; var L = uc["cm"].toBase(10.0); var points = new List <Point3> { new Point3(), new Point3(L, 0, 0) }; var supports = new List <Support> { k3d.Support.Support(0, k3d.Support.SupportFixedConditions), k3d.Support.Support(1, new List <bool>() { false, true, true, true, true, true }) }; var model = k3d.Model.AssembleModel(elems, supports, null, out var info, out var mass, out var cog, out var msg, out var runtimeWarning, new List <Joint>(), points); // calculate the natural vibrations int from_shape_ind = 1; int shapes_num = 1; int max_iter = 100; double eps = 1e-8; var disp_dummy = new List <double>(); var scaling = EigenShapesScalingType.matrix; model = k3d.Algorithms.NaturalVibes(model, from_shape_ind, shapes_num, max_iter, eps, disp_dummy, scaling, out var nat_frequencies, out var modal_masses, out var participation_facs, out var participation_facs_disp, out model); var E_ = E; // N/cm2 var A_ = unit_crosec.A; // cm2 var L_ = L; // cm; var gamma_ = unit_material.gamma(); // N/cm3 var c = E_ * A_ / L; // N / m var m = A_ * L_ * gamma_ / gravity * 0.5; // kg var omega0 = Math.Sqrt(c / m); // rad / sec var f0 = omega0 / 2.0 / Math.PI; // 1 / sec = Hz Assert.AreEqual(nat_frequencies[0], f0, 1e-2); // clear temporary changes to the the ini-file and units-conversion INIReader.ClearSingleton(); UnitsConversionFactory.ClearSingleton(); ini = INIReader.Instance(); // switch back to SI units ini.Values["UnitsSystem"] = "SI"; }