示例#1
0
        /***************************************************/

        private static List <int> GetInterpolationOrder(TaperedProfile taperedProfile, List <double> newPositions)
        {
            List <int>    interpolationOrders = new List <int>();
            List <double> originalPositions   = new List <double>(taperedProfile.Profiles.Keys);

            for (int i = 0; i < newPositions.Count - 1; i++)
            {
                bool containsPosition     = taperedProfile.Profiles.ContainsKey(newPositions[i]);
                bool containsNextPosition = taperedProfile.Profiles.ContainsKey(newPositions[i + 1]);
                if (containsPosition)
                {
                    interpolationOrders.Add(taperedProfile.InterpolationOrder[originalPositions.IndexOf(newPositions[i])]);
                }
                else if (!containsPosition && !containsNextPosition)
                {
                    interpolationOrders.Add(taperedProfile.InterpolationOrder[originalPositions.IndexOf(newPositions[i - 1])]);
                }
                else if (containsNextPosition)
                {
                    if (taperedProfile.Profiles.ContainsKey(newPositions[i - 1]))
                    {
                        interpolationOrders.Add(taperedProfile.InterpolationOrder[originalPositions.IndexOf(newPositions[i - 1])]);
                    }
                    else
                    {
                        interpolationOrders.Add(taperedProfile.InterpolationOrder[originalPositions.IndexOf(newPositions[i - 2])]);
                    }
                }
            }

            return(interpolationOrders);
        }
示例#2
0
        public static TaperedProfile TaperedProfile(List <double> positions, List <IProfile> profiles, List <int> interpolationOrder = null)
        {
            //Checks for positions and profiles
            if (positions.Count != profiles.Count)
            {
                Reflection.Compute.RecordError("Number of positions and profiles provided are not equal");
                return(null);
            }
            else if (positions.Exists((double d) => { return(d > 1); }) || positions.Exists((double d) => { return(d < 0); }))
            {
                Reflection.Compute.RecordError("Positions must exist between 0 and 1 (inclusive)");
                return(null);
            }

            if (positions.Zip(positions.Skip(1), (a, b) => new { a, b }).Any(p => p.a > p.b))
            {
                Reflection.Compute.RecordError("Positions must be sorted in ascending order.");
                return(null);
            }

            //Checks for interpolationOrder
            if (interpolationOrder == null || interpolationOrder.Count == 0)
            {
                interpolationOrder = Enumerable.Repeat(1, positions.Count - 1).ToList();
            }
            else if (interpolationOrder.Count == 1)
            {
                interpolationOrder = Enumerable.Repeat(interpolationOrder.First(), positions.Count - 1).ToList();
            }
            else if (!(interpolationOrder.Count == positions.Count - 1))
            {
                Reflection.Compute.RecordError("InterpolationOrder is between the profiles provided. Therefore, the number of interpolationOrder should be one less (n - 1) than the number of profiles/positions.");
                return(null);
            }

            if (interpolationOrder.Any(x => x < 1))
            {
                Reflection.Compute.RecordError("The interpolationOrder values must be greater than 1.");
                return(null);
            }

            //Create ditionary for TaperedProfile
            SortedDictionary <double, IProfile> profileDict = new SortedDictionary <double, IProfile>();

            for (int i = 0; i < positions.Count; i++)
            {
                profileDict[positions[i]] = profiles[i];
            }

            ShapeType      shape          = GetShapeType(profiles);
            TaperedProfile taperedProfile = new TaperedProfile(profileDict, interpolationOrder, shape);

            return(taperedProfile);
        }
示例#3
0
        /***************************************************/

        private bool CreateProfile(string name, TaperedProfile profile)
        {
            profile.MapPositionDomain();

            IFGeometricLine lusasGeometricLine = (IFGeometricLine)d_LusasData.getAttribute("Line Geometric", name);

            lusasGeometricLine.setMultipleVarying(true);
            lusasGeometricLine.setNumberOfSections(profile.Profiles.Count);
            lusasGeometricLine.setValue("interpMethod", "Enhanced");
            lusasGeometricLine.setSpecifyInterp(true);
            lusasGeometricLine.setEqualSpacing(false);
            lusasGeometricLine.setSymmetry(false);
            lusasGeometricLine.setDistanceType("Parametric");

            List <double> keys = new List <double>(profile.Profiles.Keys);
            IProfile      iProfile;

            for (int i = 0; i < keys.Count; i++)
            {
                profile.Profiles.TryGetValue(keys[i], out iProfile);
                string profileName;
                if (i == 0)
                {
                    profileName = $"{name}-0";
                }
                else
                {
                    profileName = $"{name}-{keys[i]:G3}";
                }

                CreateProfile(profileName, iProfile as dynamic);
                lusasGeometricLine.setFromLibrary("User Sections", "Local", profileName, 0, 0, i);
                if (i == 0)
                {
                    lusasGeometricLine.setInterpolation("Constant", (double)keys[i], i);
                }
                else
                {
                    lusasGeometricLine.setInterpolation("Function", (double)keys[i], i, profile.InterpolationOrder[i - 1]);
                }
            }

            lusasGeometricLine.setVerticalAlignment("CenterToCenter");
            lusasGeometricLine.setHorizontalAlignment("CenterToCenter");
            lusasGeometricLine.setAlignmentSection(1);

            return(true);
        }
示例#4
0
        public static TaperedProfile MapPositionDomain(this TaperedProfile taperedProfile)
        {
            TaperedProfile newTaperedProfile = null;
            List <double>  positions         = new List <double>(taperedProfile.Profiles.Keys);

            if (!positions.Contains(0) && !positions.Contains(1))
            {
                List <double> newPositions = Compute.MapDomain(positions, positions);
                newTaperedProfile = Create.TaperedProfile(newPositions, new List <IProfile>(taperedProfile.Profiles.Values), taperedProfile.InterpolationOrder);
            }
            else
            {
                newTaperedProfile = taperedProfile;
            }

            return(newTaperedProfile);
        }
示例#5
0
        public static double VoidArea(this IProfile profile)
        {
            if (profile is TaperedProfile)
            {
                Engine.Reflection.Compute.RecordWarning("The sectional area of TaperedProfiles may vary along their length. The average area of the TaperedProfile has been returned, assuming that the section varies linearly.");
                TaperedProfile taperedProfile = profile as TaperedProfile;
                double         sum            = 0;
                for (int i = 0; i < taperedProfile.Profiles.Count - 1; i++)
                {
                    double temArea = (taperedProfile.Profiles.ElementAt(i).Value.VoidArea() + taperedProfile.Profiles.ElementAt(i + 1).Value.VoidArea()) / 2;
                    sum += temArea * System.Convert.ToDouble(taperedProfile.Profiles.ElementAt(i + 1).Key - taperedProfile.Profiles.ElementAt(i).Key);
                }
                return(sum);
            }

            List <PolyCurve> curvesZ = Engine.Geometry.Compute.IJoin(profile.Edges.ToList());

            int[] depth = new int[curvesZ.Count];
            if (curvesZ.Count > 1)
            {
                // find which is in which
                for (int i = 0; i < curvesZ.Count; i++)
                {
                    for (int j = 0; j < curvesZ.Count; j++)
                    {
                        if (i != j)
                        {
                            if (curvesZ[i].IsContaining(new List <Point>()
                            {
                                curvesZ[j].IStartPoint()
                            }))
                            {
                                depth[j]++;
                            }
                        }
                    }
                }
            }

            curvesZ = curvesZ.Where((x, i) => depth[i] != 0).ToList();
            depth   = depth.Where(x => x != 0).ToArray();

            // Using region integration as the Curves are defined on the XY-Plane.
            depth = depth.Select(x => x % 2 != 0 ? 1 : -1).ToArray();   // positive area as 1 and negative area as -1
            return(curvesZ.Select((x, i) => Math.Abs(x.IIntegrateRegion(0)) * depth[i]).Sum());
        }
示例#6
0
        /***************************************************/

        private bool SetProfile(TaperedProfile taperProfile, string sectionName, string matName)
        {
            //Check and fix taperProfile
            taperProfile.MapPositionDomain();

            //Decompose the taperProfile dictionary
            IProfile[] profiles  = taperProfile.Profiles.Values.ToArray();
            double[]   positions = taperProfile.Profiles.Keys.ToArray();

            //Add the sub-profiles to the model and create a list of names
            string[] profNames = new string[profiles.Length];
            for (int i = 0; i < profiles.Length; i++)
            {
                profNames[i] = !string.IsNullOrEmpty(profiles[i].Name)? profiles[i].Name : sectionName + $"_{i}";
                SetProfile(profiles[i] as dynamic, profNames[i], matName);
            }

            //initialize SAP inputs
            int nSegments = profiles.Length - 1;

            string[] startSec = new string[nSegments];
            string[] endSec   = new string[nSegments];
            double[] myLength = new double[nSegments];
            int[]    myType   = new int[nSegments];
            int[]    EI33     = taperProfile.InterpolationOrder.ToArray();
            int[]    EI22     = taperProfile.InterpolationOrder.ToArray();

            //Convert list of stations to list of segments
            for (int i = 1; i <= nSegments; i++)
            {
                startSec[i - 1] = profNames[i - 1];
                endSec[i - 1]   = profNames[i];
                myLength[i - 1] = positions[i] - positions[i - 1];
                myType[i - 1]   = 1;
            }

            //Send the tapered profile to SAP
            return(m_model.PropFrame.SetNonPrismatic(sectionName, nSegments, ref startSec, ref endSec, ref myLength, ref myType, ref EI33, ref EI22) == 0);
        }
示例#7
0
        /***************************************************/

        private bool SetProfile(TaperedProfile profile, string sectionName, IMaterialFragment material)
        {
            //Map Position domain to [0,1]
            profile.MapPositionDomain();

            // Create a section for each sub profile
            IProfile[] profiles = profile.Profiles.Values.ToArray();
            for (int i = 0; i < profiles.Length; i++)
            {
                ISetProfile(profiles[i], sectionName + "_SubSection" + i.ToString(), material);
            }

            // Declare some variables
            int num = profile.Profiles.Count - 1;

            string[] segmentStartProfile = new string[num];
            string[] segmentEndProfile   = new string[num];
            double[] length = new double[num];

            // Formatt section names and positions to ETABS standard
            double[] positions = profile.Profiles.Keys.ToArray();
            for (int i = 0; i < num; i++)
            {
                segmentStartProfile[i] = sectionName + "_SubSection" + (i).ToString();

                // Etabs reads this in mm, and multiplying strictly does not matter (since they're relative values), but is easier on the eyes in ETBAS later
                length[i]            = System.Convert.ToDouble(positions[i + 1] - positions[i]) * 1000;
                segmentEndProfile[i] = sectionName + "_SubSection" + (i + 1).ToString();
            }

            // Some array settings
            int[] type = length.Select(x => 1).ToArray <int>(); // Relative Length values, (No idea what happens or why someone would mix thease)
            int[] eI33 = length.Select(x => 1).ToArray <int>(); // Linear variation of EI33
            int[] eI22 = length.Select(x => 1).ToArray <int>(); // Linear variation of EI22
            Engine.Base.Compute.RecordNote("Tapered Sections Properties are set to vary linearly along the element in ETABS.");

            return(m_model.PropFrame.SetNonPrismatic(sectionName, num, ref segmentStartProfile, ref segmentEndProfile, ref length, ref type, ref eI33, ref eI22) == 0);
        }
示例#8
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static ISectionProperty ToSection(this IFAttribute lusasAttribute)
        {
            string attributeName = GetName(lusasAttribute);
            string attributeType = lusasAttribute.getAttributeType();

            int rows = lusasAttribute.countRows("A");

            IProfile        profile;
            GenericSection  section             = null;
            List <int>      interpolationOrders = new List <int>();
            List <double>   positions           = new List <double>();
            List <IProfile> profiles            = new List <IProfile>();

            for (int i = 0; i < rows; i++)
            {
                profile = ToProfile(lusasAttribute, i);
                double area    = lusasAttribute.getValue("A", i);
                double rgy     = lusasAttribute.getValue("ky", i);
                double rgz     = lusasAttribute.getValue("kz", i);
                double j       = lusasAttribute.getValue("J", i);
                double iy      = lusasAttribute.getValue("Iyy", i);
                double iz      = lusasAttribute.getValue("Izz", i);
                double iw      = lusasAttribute.getValue("Cw", i);
                double wely    = Math.Min(Math.Abs(lusasAttribute.getValue("Syt", i)), Math.Abs(lusasAttribute.getValue("Syb", i)));
                double welz    = Math.Min(Math.Abs(lusasAttribute.getValue("Szt", i)), Math.Abs(lusasAttribute.getValue("Szb", i)));
                double wply    = lusasAttribute.getValue("Zpy", i);
                double wplz    = lusasAttribute.getValue("Zpz", i);
                double centreZ = 0; //Eccentricity is handeled in the Bar not at the section
                double centreY = 0; //Eccentricity is handeled in the Bar not at the section
                double zt      = lusasAttribute.getValue("zt", i);
                double zb      = Math.Abs(lusasAttribute.getValue("zb", i));
                double yt      = Math.Abs(lusasAttribute.getValue("yb", i)); //Lusas Y-Axis is opposite to the BHoM Y-axis
                double yb      = lusasAttribute.getValue("yt", i);
                double asy     = lusasAttribute.getValue("Asy", i);
                double asz     = lusasAttribute.getValue("Asz", i);

                if (profile == null)
                {
                    return(null);
                }

                profile = Engine.Structure.Compute.Integrate(profile, oM.Geometry.Tolerance.MicroDistance).Item1;

                if (attributeType == "Multiple Varying Geometric")
                {
                    double position = lusasAttribute.getValue("distanceAlongBeam", i);
                    positions.Add(position);
                    profiles.Add(profile);
                }
                else
                {
                    section = new GenericSection(profile, area, rgy, rgz, j, iy, iz, iw, wely, welz, wply, wplz, centreZ, centreY, zt, zb, yt, yb, asy, asz);
                }
            }

            if (lusasAttribute.getAttributeType() == "Multiple Varying Geometric")
            {
                for (int i = 0; i < profiles.Count - 1; i++)
                {
                    interpolationOrders.Add(1);
                }
                TaperedProfile taperedProfile = Engine.Spatial.Create.TaperedProfile(positions, profiles, interpolationOrders);
                if (taperedProfile == null)
                {
                    return(null);
                }
                section = Engine.Structure.Create.GenericSectionFromProfile(taperedProfile);
            }

            section.Name = attributeName;

            int adapterNameId = lusasAttribute.getID();

            section.SetAdapterId(typeof(LusasId), adapterNameId);

            return(section);
        }
示例#9
0
        /***************************************************/
        /**** Private Methods                           ****/
        /***************************************************/

        private static List <TaperedProfile> MapTaperedProfile(List <Bar> bars, TaperedProfile taperedProfile)
        {
            //Check profiles have the same shape
            if (taperedProfile.Profiles.Values.Any(x => x.Shape != taperedProfile.Profiles.Values.First().Shape))
            {
                Reflection.Compute.RecordError("MapTaperedProfile does not support TaperedProfiles with different ShapeProfiles.");
                return(null);
            }

            //Get geometry of Bars
            List <Line> lines = bars.Select(x => x.Centreline()).ToList();

            //Checks bars form a single line
            List <Polyline> centrelines = lines.Join();

            if (lines.Join().Count > 1)
            {
                Reflection.Compute.RecordError("Bars provided do not form a single continuous line.");
                return(null);
            }


            Polyline centreline = centrelines[0];

            //Check bars are in order
            List <Point> midpoints        = lines.Select(x => x.PointAtParameter(0.5)).ToList();
            List <Point> orderedMidpoints = midpoints.SortAlongCurve(centreline);

            if (!midpoints.SequenceEqual(orderedMidpoints))
            {
                Reflection.Compute.RecordError("Bars provided are not sorted.");
                return(null);
            }

            List <double>   originalPositions = new List <double>(taperedProfile.Profiles.Keys);
            List <IProfile> originalProfiles  = new List <IProfile>(taperedProfile.Profiles.Values);

            List <TaperedProfile> taperedProfiles = new List <TaperedProfile>();

            //For each bar interpolate the profiles as necessary and create a TaperedProfile
            foreach (Bar bar in bars)
            {
                double startPosition = centreline.ParameterAtPoint(bar.StartNode.Position);
                double endPosition   = centreline.ParameterAtPoint(bar.EndNode.Position);
                double newLength     = endPosition - startPosition;

                List <double> positions = new List <double>(originalPositions);
                if (!positions.Contains(startPosition))
                {
                    positions.Add(startPosition);
                }
                if (!positions.Contains(endPosition))
                {
                    positions.Add(endPosition);
                }
                positions.Sort();

                int startIndex = positions.IndexOf(startPosition);
                int endIndex   = positions.IndexOf(endPosition);

                //These are required to create the new TaperedProfile mapped to the Bar
                List <IProfile> newProfiles            = new List <IProfile>();
                List <double>   newPositions           = new List <double>();
                List <int>      newInterpolationOrders = GetInterpolationOrder(taperedProfile, positions);


                //Cycle through the positions in the extents of the Bar to get the newProfile and newPosition
                for (int i = startIndex; i < endIndex + 1; i++)
                {
                    double   position = positions[i];
                    IProfile newProfile;
                    double   newPosition = 0;

                    if (position == 0)
                    {
                        //If the position is the same as the start of the TaperedProfile
                        taperedProfile.Profiles.TryGetValue(0, out newProfile);
                        newPosition = 0;
                    }
                    else if (position == 1)
                    {
                        //If the position is the same as the end of the TaperedProfile
                        taperedProfile.Profiles.TryGetValue(1, out newProfile);
                        newPosition = (1 - startPosition) / newLength;
                    }
                    else if (taperedProfile.Profiles.ContainsKey(position))
                    {
                        //If the position is equal to an existing position in the TaperedProfile
                        taperedProfile.Profiles.TryGetValue(position, out newProfile);
                        newPosition = (positions[i] - startPosition) / newLength;
                    }
                    else
                    {
                        //If the position is between existing positions in the TaperedProfile
                        IProfile preProfile;
                        IProfile postProfile;

                        double prePosition = positions[i - 1];
                        taperedProfile.Profiles.TryGetValue(prePosition, out preProfile);
                        //If the both new positions are between original positions
                        if (preProfile == null)
                        {
                            taperedProfile.Profiles.TryGetValue(positions[i - 2], out preProfile);
                            prePosition = positions[i - 2];
                        }

                        double postPosition = positions[i + 1];
                        taperedProfile.Profiles.TryGetValue(postPosition, out postProfile);
                        //If the both new positions are between original positions
                        if (postProfile == null)
                        {
                            taperedProfile.Profiles.TryGetValue(positions[i + 2], out postProfile);
                            postPosition = positions[i + 2];
                        }

                        double interpolationPosition = (position - prePosition) / (postPosition - prePosition);

                        //One less interpolationOrder than positions/profiles
                        int interpolationIndex    = Math.Min(i, newInterpolationOrders.Count - 1);
                        int newInterpolationOrder = newInterpolationOrders[interpolationIndex];

                        newProfile = Spatial.Compute.IInterpolateProfile(preProfile, postProfile, interpolationPosition, newInterpolationOrder);
                    }
                    newProfiles.Add(newProfile);
                    newPositions.Add(position);
                }
                if (endIndex == 1 || endIndex - startIndex == 1)
                {
                    taperedProfiles.Add(Spatial.Create.TaperedProfile(newPositions, newProfiles, newInterpolationOrders.GetRange(startIndex, 1)));
                }
                else
                {
                    taperedProfiles.Add(Spatial.Create.TaperedProfile(newPositions, newProfiles, newInterpolationOrders.GetRange(startIndex, (endIndex - startIndex))));
                }
            }

            return(taperedProfiles);
        }