Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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";
        }
Example #7
0
        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);
        }
Example #8
0
        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";
        }