コード例 #1
0
        /***************************************************/

        // Convert Guanaco mesh to Rhino mesh.
        public static Rhino.Geometry.Mesh GetRhinoMesh(Mesh mesh, out List <LineCurve> barElements)
        {
            barElements = new List <LineCurve>();

            Rhino.Geometry.Mesh rhinoMesh = new Rhino.Geometry.Mesh();
            foreach (Node node in mesh.Nodes)
            {
                rhinoMesh.Vertices.Add(node.Location);
            }

            foreach (Element element in mesh.Elements)
            {
                if (element is Element2D)
                {
                    Element2D e       = element as Element2D;
                    int[]     nodeIds = e.Nodes.Take(e.PrimaryNodeCount).Select(n => n.Id.AsInteger).ToArray();

                    if (nodeIds.Length == 4)
                    {
                        rhinoMesh.Faces.AddFace(nodeIds[0], nodeIds[1], nodeIds[2], nodeIds[3]);
                    }
                    else if (nodeIds.Length == 3)
                    {
                        rhinoMesh.Faces.AddFace(nodeIds[0], nodeIds[1], nodeIds[2]);
                    }
                }
                else if (element is Element1D)
                {
                    Element1D e = element as Element1D;
                    barElements.Add(new LineCurve(rhinoMesh.Vertices[e.Nodes.First().Id.AsInteger], rhinoMesh.Vertices[e.Nodes.Last().Id.AsInteger]));
                }
            }

            return(rhinoMesh);
        }
コード例 #2
0
        /***************************************************/

        // Apply pressure load to the elements laying within tolerance from the pressure area.
        private void ApplyLoad(PressureLoad load)
        {
            foreach (Element e in this._mesh.Elements)
            {
                // Check if the element is 2D.
                Element2D el = e as Element2D;
                if (el == null)
                {
                    continue;
                }

                // Check if the element is adjoining to the pressure area (if all its vertices lie within tolerance) - if yes then apply the load.
                Point3d elC = el.GetCentroid();
                foreach (Brep s in load.Surfaces)
                {
                    bool broken = false;
                    foreach (Point3d v in el.GetVertices())
                    {
                        if (v.DistanceTo(s.ClosestPoint(v)) > this._tolerance)
                        {
                            broken = true;
                            break;
                        }
                    }

                    if (!broken)
                    {
                        el.AddPressure(load.LoadValue * 1);
                    }
                }
            }
        }
コード例 #3
0
        /***************************************************/

        // Apply infill load to the adjoining elements.
        private void ApplyLoad(InfillLoad load)
        {
            foreach (Element e in this._mesh.Elements)
            {
                // Check if the element is 2D.
                Element2D el = e as Element2D;
                if (el == null)
                {
                    continue;
                }

                Point3d  elC = el.GetCentroid();
                Vector3d elN = el.GetNormal();
                foreach (Infill i in load.Infills)
                {
                    // Check if the element is adjoining to the infill (if all its vertices lie within tolerance).
                    bool broken = false;
                    foreach (Point3d v in el.GetVertices())
                    {
                        if (v.DistanceTo(i.Volume.ClosestPoint(v)) > this._tolerance)
                        {
                            broken = true;
                            break;
                        }
                    }

                    // If the element is adjoining to the infill, apply the load based on location of the element and load function of the infill.
                    if (!broken)
                    {
                        // Flip normal of the element if it points outside the infill.
                        Point3d cpt = Point3d.Add(elC, elN * this._tolerance);
                        if (!i.Volume.IsPointInside(cpt, Rhino.RhinoMath.SqrtEpsilon, true))
                        {
                            el.FlipNormal();
                        }

                        // Check if the element is not surrounded by the infill from both sides - if it is then do nothing (no hydrostatic pressure).
                        else
                        {
                            cpt = Point3d.Add(elC, -elN * this._tolerance);
                            if (i.Volume.IsPointInside(cpt, Rhino.RhinoMath.SqrtEpsilon, true))
                            {
                                continue;
                            }
                        }

                        // Apply the load based on location of the element and load function of the infill.
                        string g = load.InfillDensity.ToString(GuanacoUtil.Invariant);
                        string x = (i.MaxZ - elC.Z).ToString(GuanacoUtil.Invariant);
                        string z = (i.MaxZ - i.MinZ).ToString(GuanacoUtil.Invariant);
                        string f = load.LoadFunction.Replace("g", g).Replace("x", x).Replace("z", z);
                        double p = GuanacoUtil.Evaluate(f);
                        el.AddPressure(-p);
                    }
                }
            }
        }
コード例 #4
0
ファイル: Panel.cs プロジェクト: PawelBee/Guanaco
        /***************************************************/

        // Assign elements to the component after meshing.
        public override void AssignElements(List <Element> elements)
        {
            this._elements = elements;
            foreach (Element element in elements)
            {
                Element2D e = element as Element2D;
                e.FEType = this._feType;
            }
        }
コード例 #5
0
        // Clone to a target mesh.
        public override GuanacoObject Clone(Mesh targetMesh, bool newID = false)
        {
            Element2D e = this.Clone(newID) as Element2D;

            if (targetMesh != null)
            {
                targetMesh.AddElement(e, this._id.AsInteger);
                e._nodes = this._nodes.Select(n => targetMesh.Nodes[n.Id.AsInteger]).ToList();
            }

            return(e);
        }
コード例 #6
0
ファイル: PreviewUtil.cs プロジェクト: PawelBee/Guanaco
        /***************************************************/

        // Populate the element with points - used for preview purposes to show pressure loads.
        public static List <Point3d> PopulateWithPoints(this Element2D element)
        {
            List <Point3d> corners = element.Nodes.Take(element.PrimaryNodeCount).Select(n => n.Location).ToList();
            Surface        srf;

            if (corners.Count == 3)
            {
                srf = NurbsSurface.CreateFromCorners(corners[0], corners[1], corners[2]);
            }
            else
            {
                srf = NurbsSurface.CreateFromCorners(corners[0], corners[1], corners[2], corners[3]);
            }

            corners.Add(corners[0]);
            Polyline perim   = new Polyline(corners);
            double   minDist = perim.Length * 0.01;

            List <Point3d> srfPts = new List <Point3d>();

            Interval uDomain = srf.Domain(0);
            Interval vDomain = srf.Domain(1);
            double   uMin    = uDomain.Min;
            double   uMax    = uDomain.Max;
            double   vMin    = vDomain.Min;
            double   vMax    = vDomain.Max;
            double   uStep   = (uMax - uMin) / 3;
            double   vStep   = (vMax - vMin) / 3;

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    srfPts.Add(srf.PointAt(uMin + i * uStep, vMin + j * vStep));
                }
            }

            Brep           srfBrep = srf.ToBrep();
            List <Point3d> pts     = new List <Point3d>();

            foreach (Point3d pt in srfPts)
            {
                if (srfBrep.ClosestPoint(pt).DistanceTo(pt) <= minDist && perim.ClosestPoint(pt).DistanceTo(pt) > minDist)
                {
                    pts.Add(pt);
                }
            }

            return(pts);
        }
コード例 #7
0
        /***************************************************/

        //Clone.
        public override GuanacoObject Clone(bool newID = false)
        {
            Element2D e = this.ShallowClone(newID) as Element2D;

            e._nodes       = this._nodes.Select(n => n.Clone(newID) as Node).ToList();
            e._orientation = new Vector3d[] { new Vector3d(this._orientation[0]), new Vector3d(this._orientation[1]) };
            e._results     = new Dictionary <string, double[]>(this._results);
            foreach (string r in this._results.Keys)
            {
                e._results[r] = this._results[r].ToArray();
            }
            e._parentCollection = null;
            e._id = null;
            return(e);
        }
コード例 #8
0
        /***************************************************/

        // Read results for 2D elements from the output file.
        public static void Read2DElementResults(Model model, ResultGroup resultType, int step = 0, double totalTime = 1.0)
        {
            if (model.Panels.Count == 0)
            {
                return;
            }

            // Find Ids of 2D elements.
            List <int> nonComposite2DIds = new List <int>();

            foreach (Element e in model.Mesh.Elements)
            {
                if (e is Element2D && !(e as Element2D).Composite)
                {
                    nonComposite2DIds.Add(e.Id.AsInteger);
                }
            }

            if (nonComposite2DIds.Count == 0)
            {
                return;
            }

            // Read result lines.
            string[] resLines = File.ReadAllLines(model.GetModelFilePath(GuanacoUtil.FileType.frd));
            string   line;

            // Find ids of vertices of each element.
            List <int[]> vertIds = new List <int[]>();
            int          elCount = 0;
            bool         elInfo  = false;

            for (int i = 0; i < resLines.Length; i++)
            {
                line = resLines[i].TrimStart(' ');
                if (!elInfo && line.StartsWith("3C"))
                {
                    elInfo = true;
                    continue;
                }
                else if (elInfo && line.StartsWith("-1"))
                {
                    int elId = int.Parse(line.Split(GuanacoUtil.Space, StringSplitOptions.RemoveEmptyEntries)[1]) - 1;
                    if (elId == nonComposite2DIds[elCount])
                    {
                        Element2D e = model.Mesh.Elements[elId] as Element2D;
                        i++;
                        line = resLines[i].TrimStart(' ');
                        int[] splt = line.Split(GuanacoUtil.Space, StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(s => int.Parse(s)).ToArray();
                        vertIds.Add(splt.Take(e.PrimaryNodeCount * 2).ToArray());

                        elCount++;
                        if (elCount == nonComposite2DIds.Count)
                        {
                            break;
                        }
                    }
                }
                else if (elInfo && line.StartsWith("-3"))
                {
                    break;
                }
            }

            // Read the results per each vertex.
            Dictionary <int, double[]> nodeValues = new Dictionary <int, double[]>();
            int resid = GetFirstResultLine(resLines, resultType, GuanacoUtil.FileType.frd, step, totalTime);

            line = resLines[resid];
            string start = "-1";

            while (start == "-1")
            {
                int      nodeId    = int.Parse(line.Substring(4, 9));
                double[] nodeValue = new double[6];
                int      i         = 13;

                for (int j = 0; j < 6; j++)
                {
                    string resultString = line.Substring(i, 12);
                    double resultValue  = double.NaN;

                    if (double.TryParse(resultString, GuanacoUtil.FloatNum, GuanacoUtil.Invariant, out resultValue))
                    {
                        nodeValue[j] = resultValue;
                    }
                    else if (resultString.Substring(9) == "INF")
                    {
                        nodeValue[j] = resultString[8] == '-' ? double.NegativeInfinity : double.PositiveInfinity;
                    }
                    else
                    {
                        throw new Exception("The result format is incorrect, please inspect the result .frd file.");
                    }

                    i += 12;
                }

                nodeValues.Add(nodeId, nodeValue);
                resid++;
                line  = resLines[resid];
                start = line.Substring(1, 2);
            }

            // Assign the values to the elements.
            for (int i = 0; i < nonComposite2DIds.Count; i++)
            {
                Element2D e         = model.Mesh.Elements[nonComposite2DIds[i]] as Element2D;
                int       vertCount = vertIds[i].Length;
                Type      type      = null;

                switch (resultType)
                {
                case ResultGroup.Stress:
                    type = typeof(Stress2D);
                    break;

                case ResultGroup.Strain:
                    type = typeof(Strain2D);
                    break;
                }

                string[] names = Enum.GetNames(type).Skip(1).ToArray();
                foreach (string name in names)
                {
                    if (!e.Results.ContainsKey(name))
                    {
                        e.AddResult(name, new double[vertCount]);
                    }
                }

                for (int j = 0; j < vertCount; j++)
                {
                    double[] vertValues = nodeValues[vertIds[i][j]];
                    for (int k = 0; k < names.Length; k++)
                    {
                        e.Results[names[k]][j] = vertValues[k];
                    }
                }
            }
        }
コード例 #9
0
        /***************************************************/

        // Apply support to the nodes laying within tolerance from the support geometry.
        private void ApplySupport(Support support)
        {
            foreach (GeometryBase g in support.Geometry)
            {
                if (g is Point)
                {
                    Point   p  = g as Point;
                    Point3d pt = p.Location;
                    foreach (Node node in this._mesh.Nodes)
                    {
                        if (node.Primary && node.Location.DistanceTo(pt) <= this._tolerance)
                        {
                            support.Nodes.Add(node);
                        }
                    }
                }
                else if (g is Curve)
                {
                    Curve  c = g as Curve;
                    double t;
                    foreach (Node node in this._mesh.Nodes)
                    {
                        if (node.Primary)
                        {
                            c.ClosestPoint(node.Location, out t);
                            if (c.PointAt(t).DistanceTo(node.Location) <= this._tolerance)
                            {
                                support.Nodes.Add(node);
                            }
                        }
                    }
                }
                else if (g is Brep)
                {
                    Brep b = g as Brep;
                    foreach (Node node in this._mesh.Nodes)
                    {
                        if (node.Primary)
                        {
                            Point3d bpt = b.ClosestPoint(node.Location);
                            if (node.Location.DistanceTo(bpt) <= this._tolerance)
                            {
                                support.Nodes.Add(node);
                            }
                        }
                    }
                }
                else
                {
                    throw new Exception("Unknown support geometry type! " + support.Name);
                }
            }

            // If the physical fixing of the support is chosen, then instead of fixing rotational stiffness within chosen nodes, fix translation in all nodes of the supported elements.
            if (support.SupportType.Physical)
            {
                List <Node> baseNodes = support.Nodes.ToList();
                foreach (Element e in this._mesh.Elements)
                {
                    Element2D el = e as Element2D;
                    if (e == null)
                    {
                        continue;
                    }

                    HashSet <Node> elNodes = new HashSet <Node>(el.Nodes.Take(el.PrimaryNodeCount));
                    foreach (Node node in baseNodes)
                    {
                        if (elNodes.Any(n => n == node))
                        {
                            support.Nodes.UnionWith(elNodes);
                            break;
                        }
                    }
                }
            }
        }
コード例 #10
0
        /***************************************************/

        // Build CalculiX input file.
        public virtual void BuildCCXFile(bool nonLinear)
        {
            List <string> outputLines = new List <string>();

            // Write mesh topology information.
            outputLines.AddRange(this._mesh.ToCCX());

            // Write support information.
            foreach (Support s in this._supports)
            {
                outputLines.AddRange(s.ToCCX());
            }

            // Write material information.
            foreach (Material m in this._materials.Items)
            {
                outputLines.AddRange((m as dynamic).ToCCX());
            }

            // Write bar information.
            foreach (Bar bar in this._bars)
            {
                outputLines.AddRange(bar.ToCCX());
            }

            // Write panel information.
            foreach (Panel panel in this._panels)
            {
                outputLines.AddRange(panel.ToCCX());
            }

            // Write information about the analysis mode.
            outputLines.Add(nonLinear ? "*STEP,NLGEOM" : "*STEP");
            outputLines.Add("*STATIC");

            // Set pressure and gravity loads (element loads).
            outputLines.Add("*DLOAD");
            foreach (Element element in this._mesh.Elements)
            {
                if (element is Element2D)
                {
                    Element2D e = element as Element2D;
                    if (e.Pressure != 0)
                    {
                        outputLines.Add(e.PressureToCCX());
                    }
                }
            }

            if (this._gravity.Length > 0)
            {
                outputLines.Add(String.Format("Eall, GRAV,{0},{1},{2},{3}", Gravity.Length, Gravity.X / Gravity.Length, Gravity.Y / Gravity.Length, Gravity.Z / Gravity.Length));
            }

            // Set nodal loads.
            outputLines.Add("*CLOAD");
            foreach (Node n in this._mesh.Nodes)
            {
                outputLines.AddRange(n.LoadToCCX());
            }

            // Set sections in which the bar results are to be calculated.
            foreach (Element e in this._mesh.Elements)
            {
                if (e is Element1D)
                {
                    outputLines.AddRange((e as Element1D).CCXSectionResults());
                }
            }

            // Set output format.
            outputLines.AddRange(new List <string> {
                "*EL FILE,GLOBAL=NO", "S, E", "*NODE PRINT,NSET=Nall,GLOBAL=YES", "U", "*END STEP"
            });

            // Write the information to file.
            TextWriter tw = new System.IO.StreamWriter(this.GetModelFilePath(GuanacoUtil.FileType.inp));

            foreach (String s in outputLines)
            {
                tw.WriteLine(s);
            }
            tw.Close();

            // Set the info about building the file.
            this._CCXFileBuilt = true;
        }
コード例 #11
0
ファイル: PreviewUtil.cs プロジェクト: PawelBee/Guanaco
        /***************************************************/

        // Calculate the display factors dependent on the size of the model and its elements.
        public static double[] sizeFactors(this Model model)
        {
            BoundingBox bBox = new BoundingBox(model.Mesh.Nodes.Select(x => x.Location));

            double forceFactor   = 0;
            double elementFactor = bBox.Diagonal.Length;

            foreach (Panel panel in model.Panels)
            {
                foreach (Element element in panel.Elements)
                {
                    Element2D      e         = element as Element2D;
                    List <Point3d> eVertices = e.GetVertices().ToList();
                    if (e.PrimaryNodeCount == 3)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            double edgeL = eVertices[i].DistanceTo(eVertices[(i + 1) % 3]);
                            if (edgeL <= elementFactor)
                            {
                                elementFactor = edgeL;
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            double diagL = eVertices[i].DistanceTo(eVertices[i + 2]);
                            if (diagL <= elementFactor)
                            {
                                elementFactor = diagL;
                            }
                        }
                    }

                    if (e.Pressure != 0 && Math.Abs(e.Pressure) >= forceFactor)
                    {
                        forceFactor = Math.Abs(e.Pressure);
                    }
                }
            }

            foreach (Bar bar in model.Bars)
            {
                foreach (Element element in bar.Elements)
                {
                    Element1D e         = element as Element1D;
                    Point3d[] eVertices = e.GetVertices().ToArray();

                    double l = eVertices[0].DistanceTo(eVertices[1]);
                    if (l <= elementFactor)
                    {
                        elementFactor = l;
                    }
                }
            }

            foreach (Node n in model.Mesh.Nodes)
            {
                if (n.ForceLoad.Length != 0 && Math.Abs(n.ForceLoad.Length) >= forceFactor)
                {
                    forceFactor = Math.Abs(n.ForceLoad.Length);
                }
            }

            elementFactor *= 0.3;

            return(new double[] { elementFactor, forceFactor });
        }
コード例 #12
0
ファイル: PreviewUtil.cs プロジェクト: PawelBee/Guanaco
        /***************************************************/

        // Create the preview of panels.
        public static void AddPanelPreview(this Rhino.Display.CustomDisplay display, Model model, IEnumerable <int> ids, out HashSet <int> nodeIds, double graphicFactor, double elementFactor, double textFactor, double forceFactor, bool showComponentNumbers, bool showElementNumbers, bool showLCS, bool showLoads, bool showLoadValues, bool showEdges, bool showThk = false, Grasshopper.GUI.Gradient.GH_Gradient gradient = null, string panelResultType = "None", bool showResultValues = false)
        {
            nodeIds = new HashSet <int>();
            if (model.Panels.Count == 0)
            {
                return;
            }

            // Take all results out first to determine min & max, otherwise could be done inside the loop.
            Dictionary <int, double> panelTopResults    = new Dictionary <int, double>();
            Dictionary <int, double> panelBottomResults = new Dictionary <int, double>();
            double panelMax = 0;
            double panelMin = 0;

            if (panelResultType != "None")
            {
                Dictionary <int, double[]> panelResults = model.Mesh.GetElementResults(panelResultType);
                foreach (KeyValuePair <int, double[]> elResult in panelResults)
                {
                    int      id              = elResult.Key;
                    double[] results         = elResult.Value;
                    int      halfResultCount = results.Length / 2;

                    panelTopResults.Add(id, results.Skip(halfResultCount).Average());
                    panelBottomResults.Add(id, results.Take(halfResultCount).Average());
                }

                panelMax = Math.Max(panelTopResults.Values.Max(), panelBottomResults.Values.Max());
                panelMin = Math.Min(panelTopResults.Values.Min(), panelBottomResults.Values.Min());
            }

            ids = ids.Count() == 0 ? Enumerable.Range(0, model.Panels.Count) : ids.Select(i => i - 1);

            foreach (int i in ids)
            {
                Panel panel = model.Panels[i];

                if (showComponentNumbers)
                {
                    Vector3d fOffset = panel.LCS.ZAxis * 0.002;
                    if (showThk)
                    {
                        fOffset += panel.LCS.ZAxis * 0.5 * panel.Thickness;
                    }

                    Plane fp = new Plane(panel.LCS.Origin + fOffset, panel.LCS.ZAxis);
                    Plane bp = new Plane(panel.LCS.Origin - fOffset, -panel.LCS.ZAxis);
                    Rhino.Display.Text3d ft = new Rhino.Display.Text3d("Panel " + panel.CCXId(), fp, elementFactor * 0.6 * textFactor);
                    Rhino.Display.Text3d bt = new Rhino.Display.Text3d("Panel " + panel.CCXId(), bp, elementFactor * 0.6 * textFactor);
                    ft.Bold = true;
                    bt.Bold = true;
                    display.AddText(ft, Color.DarkRed);
                    display.AddText(bt, Color.DarkRed);
                }

                foreach (Element element in panel.Elements)
                {
                    Element2D e   = element as Element2D;
                    int       eId = e.Id.AsInteger;
                    foreach (Node n in e.Nodes.Take(e.PrimaryNodeCount))
                    {
                        nodeIds.Add(n.Id.AsInteger);
                    }

                    Color bottomColor;
                    Color topColor;

                    if (panelResultType == "None")
                    {
                        bottomColor = topColor = Color.Aqua;
                    }
                    else
                    {
                        bottomColor = gradient.ColourAt((panelBottomResults[eId] - panelMin) / (panelMax - panelMin));
                        topColor    = gradient.ColourAt((panelTopResults[eId] - panelMin) / (panelMax - panelMin));
                    }

                    Point3d  centroid  = e.GetCentroid();
                    Vector3d normal    = e.GetNormal();
                    Vector3d minOffset = normal * 0.001;
                    Vector3d offset    = showThk ? normal * 0.5 * panel.Thickness : minOffset;

                    List <Point3d> front = new List <Point3d>();
                    List <Point3d> back  = new List <Point3d>();

                    foreach (Point3d v in e.GetVertices())
                    {
                        front.Add(v + offset);
                        back.Add(v - offset);
                    }
                    display.AddPolygon(front, topColor, Color.Black, true, showEdges);
                    display.AddPolygon(back, bottomColor, Color.Black, true, showEdges);

                    if (showThk)
                    {
                        front.Add(front[0]);
                        back.Add(back[0]);
                        for (int j = 0; j < front.Count - 1; j++)
                        {
                            List <Point3d> fv = front.GetRange(j, 2);
                            List <Point3d> bv = back.GetRange(j, 2);
                            bv.Reverse();
                            fv.AddRange(bv);
                            display.AddPolygon(fv, Color.Aqua, Color.Black, true, true);
                        }
                    }

                    Plane tp = new Plane(panel.LCS);
                    tp.Origin = centroid + offset + minOffset;
                    tp.XAxis *= -1;
                    tp.ZAxis *= -1;
                    Plane bp = new Plane(panel.LCS);
                    bp.Origin = centroid - offset - minOffset;

                    if (showResultValues && panelTopResults.Count != 0)
                    {
                        Rhino.Display.Text3d t1 = new Rhino.Display.Text3d(panelTopResults[eId].ToString("G2"), tp, elementFactor * 0.4 * textFactor);
                        t1.Bold = true;
                        display.AddText(t1, Color.Black);
                        Rhino.Display.Text3d t2 = new Rhino.Display.Text3d(panelBottomResults[eId].ToString("G2"), bp, elementFactor * 0.4 * textFactor);
                        t2.Bold = true;
                        display.AddText(t2, Color.Black);
                    }

                    if (showLCS)
                    {
                        display.AddVector(centroid, e.Orientation[0] * elementFactor * graphicFactor, Color.Red);
                        display.AddVector(centroid, e.Orientation[1] * elementFactor * graphicFactor, Color.Green);
                        display.AddVector(centroid, normal * elementFactor * graphicFactor, Color.Blue);
                    }

                    if (showLoads && e.Pressure != 0)
                    {
                        Vector3d       pv             = normal * e.Pressure / forceFactor * elementFactor * 5 * graphicFactor;
                        List <Point3d> pressurePoints = new List <Point3d>();
                        foreach (Point3d pt in e.PopulateWithPoints())
                        {
                            if (e.Pressure > 0)
                            {
                                display.AddVector(pt - pv - offset, pv);
                            }
                            else
                            {
                                display.AddVector(pt - pv + offset, pv);
                            }
                        }

                        if (showLoadValues)
                        {
                            Plane p;
                            if (e.Pressure > 0)
                            {
                                p = new Plane(e.GetCentroid() - pv * 1.1 - offset, Vector3d.XAxis, Vector3d.ZAxis);
                            }
                            else
                            {
                                p = new Plane(e.GetCentroid() - pv * 1.1 + offset, Vector3d.XAxis, Vector3d.ZAxis);
                            }

                            Rhino.Display.Text3d t = new Rhino.Display.Text3d(e.Pressure.ToString("G2"), p, elementFactor * 0.4 * textFactor);
                            t.Bold = true;
                            display.AddText(t, Color.Magenta);
                        }
                    }

                    if (showElementNumbers)
                    {
                        Rhino.Display.Text3d tt = new Rhino.Display.Text3d(e.CCXId(), tp, elementFactor * 0.4 * textFactor);
                        Rhino.Display.Text3d bt = new Rhino.Display.Text3d(e.CCXId(), bp, elementFactor * 0.4 * textFactor);
                        tt.Bold = true;
                        bt.Bold = true;
                        display.AddText(tt, Color.Black);
                        display.AddText(bt, Color.Black);
                    }
                }
            }
        }
コード例 #13
0
        /***************************************************/

        // Read mesh file and convert it to Guanaco mesh format.
        public static void ReadMesh(Model model, bool reducedIntegration)
        {
            // Create empty mesh, initiate local variables.
            int barCounter   = 0;
            int panelCounter = 0;

            bool nodeLines, elementLines, componentLines;

            nodeLines = elementLines = componentLines = false;
            string[] itemSep = new string[] { "," };

            // Read the mesh file.
            string                line;
            int                   elementOrder     = -1;
            int                   elementDimension = -1;
            List <int>            elementList      = new List <int>();
            Dictionary <int, int> elementPairs     = new Dictionary <int, int>();

            System.IO.StreamReader file = new System.IO.StreamReader(model.GetModelFilePath() + "_Mesh.inp");
            while ((line = file.ReadLine()) != null)
            {
                if (line.StartsWith("*NODE") && !line.StartsWith("*NODE "))
                {
                    nodeLines = true;
                    continue;
                }
                else if (nodeLines && line.StartsWith("*"))
                {
                    nodeLines = false;
                }

                // Create Guanaco node based on the given line of input file.
                else if (nodeLines)
                {
                    string[] nodeInfo = line.Replace("\n", "").Split(itemSep, StringSplitOptions.None);
                    double   x        = Double.Parse(nodeInfo[1], GuanacoUtil.FloatNum);
                    double   y        = Double.Parse(nodeInfo[2], GuanacoUtil.FloatNum);
                    double   z        = Double.Parse(nodeInfo[3], GuanacoUtil.FloatNum);
                    model.Mesh.AddNode(new Node(x, y, z));
                }

                if (line.StartsWith("*ELEMENT, type="))
                {
                    elementLines = true;
                    string elementShape = line.Replace(" ", "").Substring(14).Split(',')[0];
                    switch (elementShape)
                    {
                    case "T3D2":
                        elementOrder     = 1;
                        elementDimension = 1;
                        break;

                    case "T3D3":
                        elementOrder     = 2;
                        elementDimension = 1;
                        break;

                    case "CPS3":
                    case "CPS4":
                        elementOrder     = 1;
                        elementDimension = 2;
                        break;

                    case "CPS6":
                    case "CPS8":
                        elementOrder     = 2;
                        elementDimension = 2;
                        break;

                    default:
                        throw new Exception("Incorrect element type! Check if all elements in the .inp file are supported by Guanaco.");
                    }
                }

                else if (elementLines && line.StartsWith("*"))
                {
                    elementLines = false;
                }

                // Create Guanaco element based on the given line of input file.
                else if (elementLines)
                {
                    string[]    elInfo       = line.Replace("\n", "").Split(itemSep, StringSplitOptions.None);
                    List <Node> elementNodes = new List <Node>();
                    for (int i = 1; i < elInfo.Length; i++)
                    {
                        int id = int.Parse(elInfo[i]) - 1;
                        elementNodes.Add(model.Mesh.Nodes[id]);
                    }

                    Element el;
                    if (elementDimension == 1)
                    {
                        // Add element.
                        el = new Element1D(elementNodes, elementOrder, reducedIntegration);
                        model.Mesh.AddElement(el as Element1D);

                        // Set primary nodes of an element.
                        elementNodes[0].Primary = true;
                        elementNodes.Last().Primary = true;
                    }
                    else if (elementDimension == 2)
                    {
                        // Add element.
                        el = new Element2D(elementNodes, elementOrder, reducedIntegration);
                        model.Mesh.AddElement(el as Element2D);

                        // Set primary nodes of an element.
                        for (int i = 0; i < (el as Element2D).PrimaryNodeCount; i++)
                        {
                            elementNodes[i].Primary = true;
                        }
                    }
                    else
                    {
                        throw new Exception("Unsupported element found!");
                    }

                    elementPairs.Add(int.Parse(elInfo[0]), el.Id.AsInteger);
                }

                if (componentLines && !Char.IsDigit(line[0]))
                {
                    if (elementDimension == 1)
                    {
                        model.Bars[barCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList());
                        barCounter++;
                    }
                    else if (elementDimension == 2)
                    {
                        model.Panels[panelCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList());
                        panelCounter++;
                    }
                    elementList = new List <int>();
                }

                if (line.StartsWith("*ELSET,"))
                {
                    componentLines = true;

                    if (line.Contains("PhysicalLine"))
                    {
                        elementDimension = 1;
                    }
                    else if (line.Contains("PhysicalSurface"))
                    {
                        elementDimension = 2;
                    }
                    else
                    {
                        throw new Exception("Gmsh physical entity type not known.");
                    }
                }
                else if (componentLines && line.StartsWith("*"))
                {
                    componentLines = false;
                }

                // Assign the mesh elements to relevant components.
                else if (componentLines)
                {
                    string[] sa = line.Replace("\n", "").Split(itemSep, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string s in sa)
                    {
                        int id;
                        if (Int32.TryParse(s, out id))
                        {
                            elementList.Add(elementPairs[id]);
                        }
                    }
                }
            }

            if (elementList.Count > 0)
            {
                if (elementDimension == 1)
                {
                    model.Bars[barCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList());
                }
                else if (elementDimension == 2)
                {
                    model.Panels[panelCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList());
                }
            }

            file.Close();
        }