From d8eb739b56231882e202f87f4839154514951cab Mon Sep 17 00:00:00 2001 From: kpne Date: Wed, 6 Nov 2024 18:24:38 +0100 Subject: [PATCH 01/30] move geometrical properties to sectionproperties and have concreteproperties extend that instead of separate class --- ISectionProperties/IConcreteProperties.cs | 15 +++++++ ISectionProperties/IGeometricalProperties.cs | 19 -------- ISectionProperties/ISectionProperties.cs | 16 ++++++- SectionProperties.sln | 6 --- SectionProperties/GeometricalProperties.cs | 46 -------------------- SectionProperties/SectionProperties.cs | 36 +++++++++++++-- 6 files changed, 61 insertions(+), 77 deletions(-) create mode 100644 ISectionProperties/IConcreteProperties.cs delete mode 100644 ISectionProperties/IGeometricalProperties.cs delete mode 100644 SectionProperties/GeometricalProperties.cs diff --git a/ISectionProperties/IConcreteProperties.cs b/ISectionProperties/IConcreteProperties.cs new file mode 100644 index 0000000..8128de7 --- /dev/null +++ b/ISectionProperties/IConcreteProperties.cs @@ -0,0 +1,15 @@ +using OasysUnits; + +namespace MagmaWorks.Taxonomy.Sections.SectionProperties +{ + public interface IConcreteProperties : ISectionProperties + { + Length EffectiveDepthY { get; } + Length EffectiveDepthZ { get; } + Area CompressionReinforcementAreaY { get; } + Area CompressionReinforcementAreaZ { get; } + Area TensionReinforcementAreaY { get; } + Area TensionReinforcementAreaZ { get; } + Area ShearReinforcementArea { get; } + } +} diff --git a/ISectionProperties/IGeometricalProperties.cs b/ISectionProperties/IGeometricalProperties.cs deleted file mode 100644 index a826a4b..0000000 --- a/ISectionProperties/IGeometricalProperties.cs +++ /dev/null @@ -1,19 +0,0 @@ -using MagmaWorks.Geometry; -using OasysUnits; - -namespace MagmaWorks.Taxonomy.Sections.SectionProperties -{ - public interface IGeometricalProperties - { - ILocalDomain2d Extends { get; } - ILocalPoint2d Centroid { get; } - Length Perimeter { get; } - Area Area { get; } - SectionModulus ElasticSectionModulusYy { get; } - SectionModulus ElasticSectionModulusZz { get; } - AreaMomentOfInertia MomentOfInertiaYy { get; } - AreaMomentOfInertia MomentOfInertiaZz { get; } - Length RadiusOfGyrationYy { get; } - Length RadiusOfGyrationZz { get; } - } -} diff --git a/ISectionProperties/ISectionProperties.cs b/ISectionProperties/ISectionProperties.cs index 1085b10..b1236e8 100644 --- a/ISectionProperties/ISectionProperties.cs +++ b/ISectionProperties/ISectionProperties.cs @@ -1,7 +1,19 @@ -namespace MagmaWorks.Taxonomy.Sections.SectionProperties +using MagmaWorks.Geometry; +using OasysUnits; + +namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public interface ISectionProperties { - IGeometricalProperties GeometricalProperties { get; } + ILocalDomain2d Extends { get; } + ILocalPoint2d Centroid { get; } + Length Perimeter { get; } + Area Area { get; } + SectionModulus ElasticSectionModulusYy { get; } + SectionModulus ElasticSectionModulusZz { get; } + AreaMomentOfInertia MomentOfInertiaYy { get; } + AreaMomentOfInertia MomentOfInertiaZz { get; } + Length RadiusOfGyrationYy { get; } + Length RadiusOfGyrationZz { get; } } } diff --git a/SectionProperties.sln b/SectionProperties.sln index 0eee250..b6adda8 100644 --- a/SectionProperties.sln +++ b/SectionProperties.sln @@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MagmaWorks.Taxonomy.Section EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MagmaWorks.Taxonomy.Sections.SectionProperties", "SectionProperties\MagmaWorks.Taxonomy.Sections.SectionProperties.csproj", "{53294695-E114-4DA9-9F1A-F8E2C289DB60}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MagmaWorks.Taxonomy.Sections.SectionProperties.Serialization", "Serialization\MagmaWorks.Taxonomy.Sections.SectionProperties.Serialization.csproj", "{1E0D2D34-40B9-48C4-9A43-D8C078B2BCE4}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SectionPropertiesTests", "SectionPropertiesTests\SectionPropertiesTests.csproj", "{86D261B4-B15C-4F44-B655-CE127B7CC3C0}" EndProject Global @@ -25,10 +23,6 @@ Global {53294695-E114-4DA9-9F1A-F8E2C289DB60}.Debug|Any CPU.Build.0 = Debug|Any CPU {53294695-E114-4DA9-9F1A-F8E2C289DB60}.Release|Any CPU.ActiveCfg = Release|Any CPU {53294695-E114-4DA9-9F1A-F8E2C289DB60}.Release|Any CPU.Build.0 = Release|Any CPU - {1E0D2D34-40B9-48C4-9A43-D8C078B2BCE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1E0D2D34-40B9-48C4-9A43-D8C078B2BCE4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1E0D2D34-40B9-48C4-9A43-D8C078B2BCE4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1E0D2D34-40B9-48C4-9A43-D8C078B2BCE4}.Release|Any CPU.Build.0 = Release|Any CPU {86D261B4-B15C-4F44-B655-CE127B7CC3C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {86D261B4-B15C-4F44-B655-CE127B7CC3C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {86D261B4-B15C-4F44-B655-CE127B7CC3C0}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/SectionProperties/GeometricalProperties.cs b/SectionProperties/GeometricalProperties.cs deleted file mode 100644 index a4b4b3e..0000000 --- a/SectionProperties/GeometricalProperties.cs +++ /dev/null @@ -1,46 +0,0 @@ -using MagmaWorks.Geometry; -using MagmaWorks.Taxonomy.Profiles; -using OasysUnits; - -namespace MagmaWorks.Taxonomy.Sections.SectionProperties -{ - public class GeometricalProperties : IGeometricalProperties - { - public ILocalPoint2d Centroid - => _centroid ??= Utility.Centroid.CalculateCentroid(_profile); - public Length Perimeter - => _perimeter ??= Utility.PerimeterLength.CalculatePerimeter(_profile); - public ILocalDomain2d Extends => _domain ??= Utility.Extends.GetDomain(_profile); - public Area Area => _area ??= Utility.Area.CalculateArea(_profile); - public SectionModulus ElasticSectionModulusYy - => _elasticSectionModulusYy ??= Utility.SectionModulus.CalculateSectionModulusYy(_profile); - public SectionModulus ElasticSectionModulusZz - => _elasticSectionModulusZz ??= Utility.SectionModulus.CalculateSectionModulusZz(_profile); - public AreaMomentOfInertia MomentOfInertiaYy - => _momentOfInertiaYy ??= Utility.Inertia.CalculateInertiaYy(_profile); - public AreaMomentOfInertia MomentOfInertiaZz - => _momentOfInertiaZz ??= Utility.Inertia.CalculateInertiaZz(_profile); - public Length RadiusOfGyrationYy - => _radiusOfGyrationYy ??= Utility.RadiusOfGyration.CalculateRadiusOfGyrationYy(_profile); - public Length RadiusOfGyrationZz - => _radiusOfGyrationZz ??= Utility.RadiusOfGyration.CalculateRadiusOfGyrationZz(_profile); - - private ILocalPoint2d _centroid; - private Length? _perimeter; - private ILocalDomain2d _domain; - private Area? _area; - private SectionModulus? _elasticSectionModulusYy; - private SectionModulus? _elasticSectionModulusZz; - private AreaMomentOfInertia? _momentOfInertiaYy; - private AreaMomentOfInertia? _momentOfInertiaZz; - private Length? _radiusOfGyrationYy; - private Length? _radiusOfGyrationZz; - private IProfile _profile; - - private GeometricalProperties() { } - public GeometricalProperties(IProfile profile) - { - _profile = profile; - } - } -} diff --git a/SectionProperties/SectionProperties.cs b/SectionProperties/SectionProperties.cs index 4d5bb67..77038ff 100644 --- a/SectionProperties/SectionProperties.cs +++ b/SectionProperties/SectionProperties.cs @@ -1,16 +1,44 @@ -using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Geometry; +using MagmaWorks.Taxonomy.Profiles; +using OasysUnits; namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public class SectionProperties : ISectionProperties { - public IGeometricalProperties GeometricalProperties - => _geometricalProperties ??= new GeometricalProperties(_profile); + public ILocalPoint2d Centroid + => _centroid ??= Utility.Centroid.CalculateCentroid(_profile); + public Length Perimeter + => _perimeter ??= Utility.PerimeterLength.CalculatePerimeter(_profile); + public ILocalDomain2d Extends => _domain ??= Utility.Extends.GetDomain(_profile); + public Area Area => _area ??= Utility.Area.CalculateArea(_profile); + public SectionModulus ElasticSectionModulusYy + => _elasticSectionModulusYy ??= Utility.SectionModulus.CalculateSectionModulusYy(_profile); + public SectionModulus ElasticSectionModulusZz + => _elasticSectionModulusZz ??= Utility.SectionModulus.CalculateSectionModulusZz(_profile); + public AreaMomentOfInertia MomentOfInertiaYy + => _momentOfInertiaYy ??= Utility.Inertia.CalculateInertiaYy(_profile); + public AreaMomentOfInertia MomentOfInertiaZz + => _momentOfInertiaZz ??= Utility.Inertia.CalculateInertiaZz(_profile); + public Length RadiusOfGyrationYy + => _radiusOfGyrationYy ??= Utility.RadiusOfGyration.CalculateRadiusOfGyrationYy(_profile); + public Length RadiusOfGyrationZz + => _radiusOfGyrationZz ??= Utility.RadiusOfGyration.CalculateRadiusOfGyrationZz(_profile); - private IGeometricalProperties _geometricalProperties; + private ILocalPoint2d _centroid; + private Length? _perimeter; + private ILocalDomain2d _domain; + private Area? _area; + private SectionModulus? _elasticSectionModulusYy; + private SectionModulus? _elasticSectionModulusZz; + private AreaMomentOfInertia? _momentOfInertiaYy; + private AreaMomentOfInertia? _momentOfInertiaZz; + private Length? _radiusOfGyrationYy; + private Length? _radiusOfGyrationZz; private IProfile _profile; private SectionProperties() { } + public SectionProperties(ISection section) : this(section.Profile) { } public SectionProperties(IProfile profile) From 0c67fe15af3688fe1321975dfe128ebce6dac012 Mon Sep 17 00:00:00 2001 From: kpne Date: Wed, 6 Nov 2024 20:42:39 +0100 Subject: [PATCH 02/30] concrete properties --- ISectionProperties/IConcreteProperties.cs | 12 ++++++------ ISectionProperties/IConcreteSectionProperties.cs | 13 +++++++++++++ SectionProperties/SectionProperties.cs | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 ISectionProperties/IConcreteSectionProperties.cs diff --git a/ISectionProperties/IConcreteProperties.cs b/ISectionProperties/IConcreteProperties.cs index 8128de7..b92c449 100644 --- a/ISectionProperties/IConcreteProperties.cs +++ b/ISectionProperties/IConcreteProperties.cs @@ -4,12 +4,12 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public interface IConcreteProperties : ISectionProperties { - Length EffectiveDepthY { get; } - Length EffectiveDepthZ { get; } - Area CompressionReinforcementAreaY { get; } - Area CompressionReinforcementAreaZ { get; } - Area TensionReinforcementAreaY { get; } - Area TensionReinforcementAreaZ { get; } + Area ConcreteArea { get; } + Area LongitudinalReinforcementArea { get; } Area ShearReinforcementArea { get; } + IConcreteSectionProperties TensionNegativeYProperties { get; } + IConcreteSectionProperties TensionPositiveYProperties { get; } + IConcreteSectionProperties TensionNegativeZProperties { get; } + IConcreteSectionProperties TensionPositiveZProperties { get; } } } diff --git a/ISectionProperties/IConcreteSectionProperties.cs b/ISectionProperties/IConcreteSectionProperties.cs new file mode 100644 index 0000000..584ac60 --- /dev/null +++ b/ISectionProperties/IConcreteSectionProperties.cs @@ -0,0 +1,13 @@ +using OasysUnits; + +namespace MagmaWorks.Taxonomy.Sections.SectionProperties +{ + public interface IConcreteSectionProperties + { + Length EffectiveDepth { get; } + Length EffectiveWidth { get; } + Area CompressionReinforcementArea { get; } + Area TensionReinforcementArea { get; } + Area ConcreteArea { get; } + } +} diff --git a/SectionProperties/SectionProperties.cs b/SectionProperties/SectionProperties.cs index 77038ff..a60363e 100644 --- a/SectionProperties/SectionProperties.cs +++ b/SectionProperties/SectionProperties.cs @@ -37,7 +37,7 @@ public Length RadiusOfGyrationZz private Length? _radiusOfGyrationZz; private IProfile _profile; - private SectionProperties() { } + internal SectionProperties() { } public SectionProperties(ISection section) : this(section.Profile) { } From d330c6bd422e801812d48bc00d374a94b33cc7f7 Mon Sep 17 00:00:00 2001 From: kpne Date: Fri, 8 Nov 2024 15:08:23 +0100 Subject: [PATCH 03/30] fix bug in Z-profile part centroid --- SectionProperties/Utility/Parts/ProfileParts.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SectionProperties/Utility/Parts/ProfileParts.cs b/SectionProperties/Utility/Parts/ProfileParts.cs index 2622b6b..577374c 100644 --- a/SectionProperties/Utility/Parts/ProfileParts.cs +++ b/SectionProperties/Utility/Parts/ProfileParts.cs @@ -285,7 +285,7 @@ internal static List GetParts(IProfile profile) // top lip parts.Add(new TrapezoidalPart(z.Thickness, z.TopLip, new LocalPoint2d( - z.TopFlangeWidth - 1.5 * z.Thickness, + z.TopFlangeWidth - z.Thickness, z.Height / 2 - z.TopLip / 2))); // top flange parts.Add(new TrapezoidalPart(z.TopFlangeWidth - z.Thickness, z.Thickness, @@ -303,7 +303,7 @@ internal static List GetParts(IProfile profile) // bottom lip parts.Add(new TrapezoidalPart(z.Thickness, z.BottomLip, new LocalPoint2d( - -z.BottomFlangeWidth + 1.5 * z.Thickness, + -z.BottomFlangeWidth + z.Thickness, -z.Height / 2 + z.TopLip / 2))); return parts; From 51d6a78ee0959f84dffa068d69c3e876673fccc5 Mon Sep 17 00:00:00 2001 From: kpne Date: Fri, 8 Nov 2024 15:09:25 +0100 Subject: [PATCH 04/30] fix bug in Z part --- SectionPropertiesTests/Utility/InertiaTests.cs | 2 +- SectionPropertiesTests/Utility/RadiusOfGyrationTests.cs | 2 +- SectionPropertiesTests/Utility/SectionModulusTests.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SectionPropertiesTests/Utility/InertiaTests.cs b/SectionPropertiesTests/Utility/InertiaTests.cs index 80b8093..4b42f83 100644 --- a/SectionPropertiesTests/Utility/InertiaTests.cs +++ b/SectionPropertiesTests/Utility/InertiaTests.cs @@ -305,7 +305,7 @@ public void Z() // Assert Assert.Equal(472.585816E+6, Iyy.MillimetersToTheFourth, 0); - Assert.Equal(269785816, Izz.MillimetersToTheFourth, 0); + Assert.Equal(280585816, Izz.MillimetersToTheFourth, 0); } } } diff --git a/SectionPropertiesTests/Utility/RadiusOfGyrationTests.cs b/SectionPropertiesTests/Utility/RadiusOfGyrationTests.cs index 714cf4f..cad423b 100644 --- a/SectionPropertiesTests/Utility/RadiusOfGyrationTests.cs +++ b/SectionPropertiesTests/Utility/RadiusOfGyrationTests.cs @@ -303,7 +303,7 @@ public void Z() // Assert Assert.Equal(158.548, Ryy.Millimeters, 3); - Assert.Equal(119.793, Rzz.Millimeters, 3); + Assert.Equal(122.167, Rzz.Millimeters, 3); } } } diff --git a/SectionPropertiesTests/Utility/SectionModulusTests.cs b/SectionPropertiesTests/Utility/SectionModulusTests.cs index bb6c9d8..2525582 100644 --- a/SectionPropertiesTests/Utility/SectionModulusTests.cs +++ b/SectionPropertiesTests/Utility/SectionModulusTests.cs @@ -305,7 +305,7 @@ public void Z() // Assert Assert.Equal(2.146042E+6, Wyy.CubicMillimeters, 0); - Assert.Equal(1036789, Wzz.CubicMillimeters, 0); + Assert.Equal(1078294, Wzz.CubicMillimeters, 0); } } } From 610daf4a0dc5ddb51e9a40a3c473b3ee825bf5d9 Mon Sep 17 00:00:00 2001 From: kpne Date: Fri, 8 Nov 2024 17:03:20 +0100 Subject: [PATCH 05/30] remove part/zoned concrete section properties --- ISectionProperties/IConcreteProperties.cs | 15 --------------- ISectionProperties/IConcreteSectionProperties.cs | 14 +++++++++----- ...ks.Taxonomy.Sections.ISectionProperties.csproj | 2 +- 3 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 ISectionProperties/IConcreteProperties.cs diff --git a/ISectionProperties/IConcreteProperties.cs b/ISectionProperties/IConcreteProperties.cs deleted file mode 100644 index b92c449..0000000 --- a/ISectionProperties/IConcreteProperties.cs +++ /dev/null @@ -1,15 +0,0 @@ -using OasysUnits; - -namespace MagmaWorks.Taxonomy.Sections.SectionProperties -{ - public interface IConcreteProperties : ISectionProperties - { - Area ConcreteArea { get; } - Area LongitudinalReinforcementArea { get; } - Area ShearReinforcementArea { get; } - IConcreteSectionProperties TensionNegativeYProperties { get; } - IConcreteSectionProperties TensionPositiveYProperties { get; } - IConcreteSectionProperties TensionNegativeZProperties { get; } - IConcreteSectionProperties TensionPositiveZProperties { get; } - } -} diff --git a/ISectionProperties/IConcreteSectionProperties.cs b/ISectionProperties/IConcreteSectionProperties.cs index 584ac60..1221876 100644 --- a/ISectionProperties/IConcreteSectionProperties.cs +++ b/ISectionProperties/IConcreteSectionProperties.cs @@ -2,12 +2,16 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties { - public interface IConcreteSectionProperties + public interface IConcreteSectionProperties : ISectionProperties { - Length EffectiveDepth { get; } - Length EffectiveWidth { get; } - Area CompressionReinforcementArea { get; } - Area TensionReinforcementArea { get; } + Area TotalAreaOfReinforcement { get; } Area ConcreteArea { get; } + Ratio GeometricReinforcementRatio { get; } + Area ShearReinforcementArea { get; } + Length ShearReinforcementSpacing { get; } + AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy { get; } + AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz { get; } + Length ReinforcementRadiusOfGyrationYy { get; } + Length ReinforcementRadiusOfGyrationZz { get; } } } diff --git a/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj b/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj index d5f003e..6d79130 100644 --- a/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj +++ b/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj @@ -23,7 +23,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 5bb154c886aff839475e33dc075aebf1ebb7bc7f Mon Sep 17 00:00:00 2001 From: kpne Date: Fri, 8 Nov 2024 17:03:51 +0100 Subject: [PATCH 06/30] Add extends to parts and moment of intertia for perimeter profile (polygons) --- .../ConcreteSectionProperties.cs | 28 ++ ...Taxonomy.Sections.SectionProperties.csproj | 10 +- SectionProperties/Utility/Area.cs | 6 +- SectionProperties/Utility/Centroid.cs | 6 +- SectionProperties/Utility/Extends.cs | 15 +- SectionProperties/Utility/Inertia.cs | 26 +- .../Utility/Parts/EllipseQuarterPart.cs | 57 ++- SectionProperties/Utility/Parts/IPart.cs | 1 + .../Utility/Parts/TrapezoidalPart.cs | 17 +- SectionProperties/Utility/PerimeterLength.cs | 2 +- SectionProperties/Utility/PerimeterProfile.cs | 132 ++++++- SectionProperties/Utility/RadiusOfGyration.cs | 21 +- SectionProperties/Utility/Reinforcement.cs | 7 + SectionProperties/Utility/SectionModulus.cs | 24 +- .../SectionPropertiesTests.csproj | 2 +- .../Utility/ExtendsPartsTests.cs | 329 ++++++++++++++++++ .../Utility/PerimeterProfileTests.cs | 88 +++++ 17 files changed, 720 insertions(+), 51 deletions(-) create mode 100644 SectionProperties/ConcreteSectionProperties.cs create mode 100644 SectionProperties/Utility/Reinforcement.cs create mode 100644 SectionPropertiesTests/Utility/ExtendsPartsTests.cs create mode 100644 SectionPropertiesTests/Utility/PerimeterProfileTests.cs diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs new file mode 100644 index 0000000..d969209 --- /dev/null +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -0,0 +1,28 @@ +using OasysUnits; + +namespace MagmaWorks.Taxonomy.Sections.SectionProperties +{ + public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties + { + public Area TotalAreaOfReinforcement => throw new System.NotImplementedException(); + public Area ConcreteArea => throw new System.NotImplementedException(); + public Ratio GeometricReinforcementRatio => throw new System.NotImplementedException(); + public Area ShearReinforcementArea => throw new System.NotImplementedException(); + public Length ShearReinforcementSpacing => throw new System.NotImplementedException(); + public AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy => throw new System.NotImplementedException(); + public AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz => throw new System.NotImplementedException(); + public Length ReinforcementRadiusOfGyrationYy => throw new System.NotImplementedException(); + public Length ReinforcementRadiusOfGyrationZz => throw new System.NotImplementedException(); + + private Area _concreteArea; + private Area _longitudinalReinforcementArea; + private Area _shearReinforcementArea; + private IConcreteSection _section; + private ConcreteSectionProperties() { } + + public ConcreteSectionProperties(IConcreteSection section) : base(section.Profile) + { + _section = section; + } + } +} diff --git a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj index 4e1eaed..bb79838 100644 --- a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj +++ b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj @@ -23,8 +23,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -58,4 +58,10 @@ + + + <_Parameter1>SectionPropertiesTests + + + diff --git a/SectionProperties/Utility/Area.cs b/SectionProperties/Utility/Area.cs index aea90b2..21d2b1d 100644 --- a/SectionProperties/Utility/Area.cs +++ b/SectionProperties/Utility/Area.cs @@ -13,7 +13,11 @@ public static OasysUnits.Area CalculateArea(IProfile profile) return PerimeterProfile.CalculateArea(perim); } - List parts = ProfileParts.GetParts(profile); + return CalculateArea(ProfileParts.GetParts(profile)); + } + + internal static OasysUnits.Area CalculateArea(IList parts) + { OasysUnits.Area area = OasysUnits.Area.Zero; foreach (IPart part in parts) { diff --git a/SectionProperties/Utility/Centroid.cs b/SectionProperties/Utility/Centroid.cs index c67662c..f62006a 100644 --- a/SectionProperties/Utility/Centroid.cs +++ b/SectionProperties/Utility/Centroid.cs @@ -15,9 +15,13 @@ public static ILocalPoint2d CalculateCentroid(IProfile profile) return PerimeterProfile.CalculateCentroid(perim); } + return CalculateCentroid(ProfileParts.GetParts(profile)); + } + + internal static ILocalPoint2d CalculateCentroid(IList parts) + { Volume qz = Volume.Zero; Volume qy = Volume.Zero; - List parts = ProfileParts.GetParts(profile); OasysUnits.Area area = OasysUnits.Area.Zero; foreach (IPart part in parts) { diff --git a/SectionProperties/Utility/Extends.cs b/SectionProperties/Utility/Extends.cs index e067ea8..495c3ed 100644 --- a/SectionProperties/Utility/Extends.cs +++ b/SectionProperties/Utility/Extends.cs @@ -1,6 +1,8 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility @@ -114,11 +116,20 @@ public static ILocalDomain2d GetDomain(IProfile profile) } } - private static LocalDomain2d CreateDomain(Length maxY, Length minY, Length maxZ, Length minZ) + internal static LocalDomain2d CreateDomain(Length maxY, Length minY, Length maxZ, Length minZ) { var max = new LocalPoint2d(maxY, maxZ); var min = new LocalPoint2d(minY, minZ); return new LocalDomain2d(max, min); } + + internal static ILocalDomain2d GetDomain(IList parts) + { + Length maxY = parts.Select(p => p.Extends.Max.Y).Max(); + Length minY = parts.Select(p => p.Extends.Min.Y).Min(); + Length maxZ = parts.Select(p => p.Extends.Max.Z).Max(); + Length minZ = parts.Select(p => p.Extends.Min.Z).Min(); + return CreateDomain(maxY, minY, maxZ, minZ); + } } } diff --git a/SectionProperties/Utility/Inertia.cs b/SectionProperties/Utility/Inertia.cs index a6ebc9f..53e2c4f 100644 --- a/SectionProperties/Utility/Inertia.cs +++ b/SectionProperties/Utility/Inertia.cs @@ -12,8 +12,17 @@ public static class Inertia { public static AreaMomentOfInertia CalculateInertiaYy(IProfile profile) { - List parts = ProfileParts.GetParts(profile); - ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(profile); + if (profile is IPerimeter perim) + { + return PerimeterProfile.CalculateInertiaYy(perim); + } + + return CalculateInertiaYy(ProfileParts.GetParts(profile)); + } + + internal static AreaMomentOfInertia CalculateInertiaYy(IList parts) + { + ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(parts); AreaMomentOfInertia inertia = AreaMomentOfInertia.Zero; foreach (IPart part in parts) { @@ -26,8 +35,17 @@ public static AreaMomentOfInertia CalculateInertiaYy(IProfile profile) public static AreaMomentOfInertia CalculateInertiaZz(IProfile profile) { - List parts = ProfileParts.GetParts(profile); - ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(profile); + if (profile is IPerimeter perim) + { + return PerimeterProfile.CalculateInertiaZz(perim); + } + + return CalculateInertiaZz(ProfileParts.GetParts(profile)); + } + + internal static AreaMomentOfInertia CalculateInertiaZz(IList parts) + { + ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(parts); AreaMomentOfInertia inertia = AreaMomentOfInertia.Zero; foreach (IPart part in parts) { diff --git a/SectionProperties/Utility/Parts/EllipseQuarterPart.cs b/SectionProperties/Utility/Parts/EllipseQuarterPart.cs index 516a636..26183e8 100644 --- a/SectionProperties/Utility/Parts/EllipseQuarterPart.cs +++ b/SectionProperties/Utility/Parts/EllipseQuarterPart.cs @@ -11,6 +11,8 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts public Length a { get; } public Length b { get; } public ILocalPoint2d ElasticCentroid { get; } + public ILocalDomain2d Extends { get; } + private const double Factor = Math.PI / 16 - 4 / (9 * Math.PI); @@ -23,6 +25,41 @@ public EllipseQuarterPart(Length y, Length z, ILocalPoint2d corner, bool mirrorY Y = corner.Y + 4.0 * a.Abs() / (3.0 * Math.PI) * (mirrorY ? -1 : 1), Z = corner.Z + 4.0 * b.Abs() / (3.0 * Math.PI) * (mirrorZ ? -1 : 1), }; + Length maxY = mirrorY + ? corner.Y + : corner.Y + a.Abs(); + Length minY = mirrorY + ? corner.Y - a.Abs() + : corner.Y; + Length maxZ = mirrorZ + ? corner.Z + : corner.Z + b.Abs(); + Length minZ = mirrorZ + ? corner.Z - b.Abs() + : corner.Z; + Extends = Utility.Extends.CreateDomain(maxY, minY, maxZ, minZ); + } + + public static IList CreateFullEllipse(Length y, Length z, ILocalPoint2d position = null) + { + position ??= new LocalPoint2d(); + return new List() + { + new EllipseQuarterPart(y / 2, z / 2, position, false, false), + new EllipseQuarterPart(y / 2, z / 2, position, true, false), + new EllipseQuarterPart(y / 2, z / 2, position, true, true), + new EllipseQuarterPart(y / 2, z / 2, position, false, true), + }; + } + + public static IList CreateCircle(Length diameter, ILocalPoint2d position = null) + { + if (diameter.Value < 0) + { + return CreateFullEllipse(diameter, diameter.Abs(), position); + } + + return CreateFullEllipse(diameter, diameter, position); } public OasysUnits.Area GetArea() @@ -49,25 +86,9 @@ public AreaMomentOfInertia GetMomentOfInertiaZz() return new AreaMomentOfInertia(Factor * Math.Pow(a.As(unit), 3) * b.As(unit), res.Unit); } - public static IList CreateFullEllipse(Length y, Length z) - { - return new List() - { - new EllipseQuarterPart(y / 2, z / 2, new LocalPoint2d(), false, false), - new EllipseQuarterPart(y / 2, z / 2, new LocalPoint2d(), true, false), - new EllipseQuarterPart(y / 2, z / 2, new LocalPoint2d(), true, true), - new EllipseQuarterPart(y / 2, z / 2, new LocalPoint2d(), false, true), - }; - } - - public static IList CreateCircle(Length diameter) + private void SetExtends(ILocalPoint2d corner, bool mirrorY = false, bool mirrorZ = false) { - if (diameter.Value < 0) - { - return CreateFullEllipse(diameter, diameter.Abs()); - } - - return CreateFullEllipse(diameter, diameter); + } } } diff --git a/SectionProperties/Utility/Parts/IPart.cs b/SectionProperties/Utility/Parts/IPart.cs index c48257e..4dad400 100644 --- a/SectionProperties/Utility/Parts/IPart.cs +++ b/SectionProperties/Utility/Parts/IPart.cs @@ -6,6 +6,7 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts internal interface IPart { public ILocalPoint2d ElasticCentroid { get; } + public ILocalDomain2d Extends { get; } public OasysUnits.Area GetArea(); public AreaMomentOfInertia GetMomentOfInertiaYy(); public AreaMomentOfInertia GetMomentOfInertiaZz(); diff --git a/SectionProperties/Utility/Parts/TrapezoidalPart.cs b/SectionProperties/Utility/Parts/TrapezoidalPart.cs index a5be00a..f68aaf2 100644 --- a/SectionProperties/Utility/Parts/TrapezoidalPart.cs +++ b/SectionProperties/Utility/Parts/TrapezoidalPart.cs @@ -11,6 +11,7 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts public Length a { get; } public Length h { get; } public ILocalPoint2d ElasticCentroid { get; } + public ILocalDomain2d Extends => GetExtends(); public TrapezoidalPart(Length y, Length z, ILocalPoint2d centre) { @@ -29,7 +30,7 @@ public TrapezoidalPart(Length yTop, Length yBottom, Length z, ILocalPoint2d midH b = yTop; a = yBottom; h = z; - Length e = h / 3 * (a + 2 * b) / (a + b); + Length e = h / 3 * (a.Abs() + 2 * b.Abs()) / (a.Abs() + b.Abs()); var centroid = new LocalPoint2d() { @@ -86,5 +87,19 @@ public AreaMomentOfInertia GetMomentOfInertiaZz() h.As(unit) * (Math.Pow(a.As(unit), 4) - Math.Pow(b.As(unit), 4)) / (48 * (a.As(unit) - b.As(unit))), res.Unit); } + + private ILocalDomain2d GetExtends() + { + Length maxY = a.Abs() > b.Abs() + ? a.Abs() / 2 + ElasticCentroid.Y + : b.Abs() / 2 + ElasticCentroid.Y; + Length minY = a.Abs() > b.Abs() + ? ElasticCentroid.Y - a.Abs() / 2 + : ElasticCentroid.Y - b.Abs() / 2; + Length e = h / 3 * (a.Abs() + 2 * b.Abs()) / (a.Abs() + b.Abs()); + Length maxZ = ElasticCentroid.Z + h - e; + Length minZ = ElasticCentroid.Z - e; + return Utility.Extends.CreateDomain(maxY, minY, maxZ, minZ); + } } } diff --git a/SectionProperties/Utility/PerimeterLength.cs b/SectionProperties/Utility/PerimeterLength.cs index b1ed3f2..3a7c00e 100644 --- a/SectionProperties/Utility/PerimeterLength.cs +++ b/SectionProperties/Utility/PerimeterLength.cs @@ -10,7 +10,7 @@ public static class PerimeterLength { public static Length CalculatePerimeter(IProfile profile) { - IPerimeter perimeter = new Profiles.Perimeter(profile); + IPerimeter perimeter = new Perimeter(profile); Length length = Length.Zero; for (int i = 0; i < perimeter.OuterEdge.Points.Count - 1; i++) { diff --git a/SectionProperties/Utility/PerimeterProfile.cs b/SectionProperties/Utility/PerimeterProfile.cs index f2497a3..e51c036 100644 --- a/SectionProperties/Utility/PerimeterProfile.cs +++ b/SectionProperties/Utility/PerimeterProfile.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; @@ -9,24 +10,24 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility { internal static class PerimeterProfile { - internal static OasysUnits.Area CalculateArea(IPerimeter profile) + internal static OasysUnits.Area CalculateArea(IPerimeter perimeter) { - IPerimeter perimeter = new Profiles.Perimeter(profile); OasysUnits.Area area = CalculatePartArea(perimeter.OuterEdge.Points); - if (perimeter.VoidEdges != null) + if (perimeter.VoidEdges == null || perimeter.VoidEdges.Count == 0) { - foreach (ILocalPolygon2d hole in perimeter.VoidEdges) - { - area -= CalculatePartArea(hole.Points); - } + return area; + } + + foreach (ILocalPolygon2d hole in perimeter.VoidEdges) + { + area -= CalculatePartArea(hole.Points); } return area; } - internal static ILocalPoint2d CalculateCentroid(IPerimeter profile) + internal static ILocalPoint2d CalculateCentroid(IPerimeter perimeter) { - IPerimeter perimeter = new Profiles.Perimeter(profile); if (perimeter.VoidEdges == null || perimeter.VoidEdges.Count == 0) { return CalculatePartCentroid(perimeter.OuterEdge.Points); @@ -52,6 +53,117 @@ internal static ILocalPoint2d CalculateCentroid(IPerimeter profile) }; } + internal static AreaMomentOfInertia CalculateInertiaYy(IPerimeter perimeter) + { + IPerimeter centredOnElasticCentroid = MoveToElasticCentroid(perimeter); + AreaMomentOfInertia inertia = CalculatePartInertiaYy(centredOnElasticCentroid.OuterEdge.Points); + if (centredOnElasticCentroid.VoidEdges == null || centredOnElasticCentroid.VoidEdges.Count == 0) + { + return inertia; + } + + foreach (ILocalPolygon2d hole in centredOnElasticCentroid.VoidEdges) + { + inertia -= CalculatePartInertiaYy(hole.Points); + } + + return inertia; + } + + internal static AreaMomentOfInertia CalculateInertiaZz(IPerimeter perimeter) + { + IPerimeter centredOnElasticCentroid = MoveToElasticCentroid(perimeter); + AreaMomentOfInertia inertia = CalculatePartInertiaZz(centredOnElasticCentroid.OuterEdge.Points); + if (centredOnElasticCentroid.VoidEdges == null || centredOnElasticCentroid.VoidEdges.Count == 0) + { + return inertia; + } + + foreach (ILocalPolygon2d hole in centredOnElasticCentroid.VoidEdges) + { + inertia -= CalculatePartInertiaZz(hole.Points); + } + + return inertia; + } + + private static AreaMomentOfInertia CalculatePartInertiaYy(IList p) + { + double inertia = 0; + LengthUnit unit = p.FirstOrDefault().Z.Unit; + for (int i = 0; i < p.Count - 1; i++) + { + inertia += (p[i].Y.As(unit) * p[i + 1].Z.As(unit) - p[i + 1].Y.As(unit) * p[i].Z.As(unit)) + * (Math.Pow(p[i].Z.As(unit), 2) + p[i].Z.As(unit) * p[i + 1].Z.As(unit) + Math.Pow(p[i + 1].Z.As(unit), 2)); + } + + inertia = Math.Abs(inertia) / 12; + AreaMomentOfInertia m4 = AreaMomentOfInertia.Zero; + AreaMomentOfInertia.TryParse($"0 {Length.GetAbbreviation(unit)}⁴", out m4); + return new AreaMomentOfInertia(inertia, m4.Unit); + } + + private static AreaMomentOfInertia CalculatePartInertiaZz(IList p) + { + double inertia = 0; + LengthUnit unit = p.FirstOrDefault().Y.Unit; + for (int i = 0; i < p.Count - 1; i++) + { + inertia += (p[i].Y.As(unit) * p[i + 1].Z.As(unit) - p[i + 1].Y.As(unit) * p[i].Z.As(unit)) + * (Math.Pow(p[i].Y.As(unit), 2) + p[i].Y.As(unit) * p[i + 1].Y.As(unit) + Math.Pow(p[i + 1].Y.As(unit), 2)); + } + + inertia = Math.Abs(inertia) / 12; + AreaMomentOfInertia m4 = AreaMomentOfInertia.Zero; + AreaMomentOfInertia.TryParse($"0 {Length.GetAbbreviation(unit)}⁴", out m4); + return new AreaMomentOfInertia(inertia, m4.Unit); + } + + internal static IPerimeter MoveToElasticCentroid(IPerimeter perimeter) + { + ILocalPoint2d centroid = CalculateCentroid(perimeter); + ILocalPoint2d translation = new LocalPoint2d() + { + Y = centroid.Y * -1, + Z = centroid.Z * -1 + }; + + IList outerPoints = new List(); + foreach (ILocalPoint2d pt in perimeter.OuterEdge.Points) + { + outerPoints.Add(Move(pt, translation)); + } + ILocalPolygon2d outerEdge = new LocalPolygon2d(outerPoints); + + if (perimeter.VoidEdges == null || perimeter.VoidEdges.Count == 0) + { + return new Perimeter(outerEdge); + } + + IList voidEdges = new List(); + foreach (ILocalPolygon2d voidEdge in perimeter.VoidEdges) + { + IList voidPoints = new List(); + foreach (ILocalPoint2d pt in voidEdge.Points) + { + voidPoints.Add(Move(pt, translation)); + } + ILocalPolygon2d translatedVoidEdge = new LocalPolygon2d(voidPoints); + voidEdges.Add(translatedVoidEdge); + } + + return new Perimeter(outerEdge, voidEdges); + } + + private static ILocalPoint2d Move(ILocalPoint2d point, ILocalPoint2d translation) + { + return new LocalPoint2d() + { + Y = point.Y + translation.Y, + Z = point.Z + translation.Z, + }; + } + private static OasysUnits.Area CalculatePartArea(IList pts) { OasysUnits.Area res = OasysUnits.Area.Zero; diff --git a/SectionProperties/Utility/RadiusOfGyration.cs b/SectionProperties/Utility/RadiusOfGyration.cs index 1bc620b..dd01c3b 100644 --- a/SectionProperties/Utility/RadiusOfGyration.cs +++ b/SectionProperties/Utility/RadiusOfGyration.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility @@ -8,18 +10,29 @@ public static class RadiusOfGyration { public static Length CalculateRadiusOfGyrationYy(IProfile profile) { - OasysUnits.Area area = Area.CalculateArea(profile); - AreaMomentOfInertia inertia = Inertia.CalculateInertiaYy(profile); + return CalculateRadiusOfGyrationYy(ProfileParts.GetParts(profile)); + } + + internal static Length CalculateRadiusOfGyrationYy(IList parts) + { + OasysUnits.Area area = Area.CalculateArea(parts); + AreaMomentOfInertia inertia = Inertia.CalculateInertiaYy(parts); return CalculateRadiusOfGyration(area, inertia); } public static Length CalculateRadiusOfGyrationZz(IProfile profile) { - OasysUnits.Area area = Area.CalculateArea(profile); - AreaMomentOfInertia inertia = Inertia.CalculateInertiaZz(profile); + return CalculateRadiusOfGyrationZz(ProfileParts.GetParts(profile)); + } + + internal static Length CalculateRadiusOfGyrationZz(IList parts) + { + OasysUnits.Area area = Area.CalculateArea(parts); + AreaMomentOfInertia inertia = Inertia.CalculateInertiaZz(parts); return CalculateRadiusOfGyration(area, inertia); } + private static Length CalculateRadiusOfGyration(OasysUnits.Area area, AreaMomentOfInertia inertia) { Length.TryParse($"0 {OasysUnits.Area.GetAbbreviation(area.Unit).Replace("²", string.Empty)}", out Length unit); diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs new file mode 100644 index 0000000..8c5b3c1 --- /dev/null +++ b/SectionProperties/Utility/Reinforcement.cs @@ -0,0 +1,7 @@ +namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility +{ + public static class Reinforcement + { + + } +} diff --git a/SectionProperties/Utility/SectionModulus.cs b/SectionProperties/Utility/SectionModulus.cs index 6e478c7..7e06508 100644 --- a/SectionProperties/Utility/SectionModulus.cs +++ b/SectionProperties/Utility/SectionModulus.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; using OasysUnits.Units; @@ -10,17 +12,27 @@ public static class SectionModulus { public static OasysUnits.SectionModulus CalculateSectionModulusYy(IProfile profile) { - ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(profile); - ILocalDomain2d domain = Extends.GetDomain(profile); - AreaMomentOfInertia inertia = Inertia.CalculateInertiaYy(profile); + return CalculateSectionModulusYy(ProfileParts.GetParts(profile)); + } + + internal static OasysUnits.SectionModulus CalculateSectionModulusYy(IList parts) + { + ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(parts); + ILocalDomain2d domain = Extends.GetDomain(parts); + AreaMomentOfInertia inertia = Inertia.CalculateInertiaYy(parts); return CalculateSectionModulus(domain.Max.Z, domain.Min.Z, elasticCentroid.Z, inertia); } public static OasysUnits.SectionModulus CalculateSectionModulusZz(IProfile profile) { - ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(profile); - ILocalDomain2d domain = Extends.GetDomain(profile); - AreaMomentOfInertia inertia = Inertia.CalculateInertiaZz(profile); + return CalculateSectionModulusZz(ProfileParts.GetParts(profile)); + } + + internal static OasysUnits.SectionModulus CalculateSectionModulusZz(IList parts) + { + ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(parts); + ILocalDomain2d domain = Extends.GetDomain(parts); + AreaMomentOfInertia inertia = Inertia.CalculateInertiaZz(parts); return CalculateSectionModulus(domain.Max.Y, domain.Min.Y, elasticCentroid.Y, inertia); } diff --git a/SectionPropertiesTests/SectionPropertiesTests.csproj b/SectionPropertiesTests/SectionPropertiesTests.csproj index 3e571f7..ca6c324 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.csproj +++ b/SectionPropertiesTests/SectionPropertiesTests.csproj @@ -8,7 +8,7 @@ - + diff --git a/SectionPropertiesTests/Utility/ExtendsPartsTests.cs b/SectionPropertiesTests/Utility/ExtendsPartsTests.cs new file mode 100644 index 0000000..8a75962 --- /dev/null +++ b/SectionPropertiesTests/Utility/ExtendsPartsTests.cs @@ -0,0 +1,329 @@ +using MagmaWorks.Geometry; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; + +namespace SectionPropertiesTests +{ + public class ExtendsPartsTests + { + [Fact] + public void Angle() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateAngle().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(5.4, domain.Max.Y.Centimeters, 12); + Assert.Equal(0, domain.Min.Y.Centimeters, 12); + Assert.Equal(2.3, domain.Max.Z.Centimeters, 12); + Assert.Equal(0, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void C() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateC().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(10.04, domain.Max.Y.Centimeters, 12); + Assert.Equal(0, domain.Min.Y.Centimeters, 12); + Assert.Equal(20.03 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.03 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Channel() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateChannel().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(10.04, domain.Max.Y.Centimeters, 12); + Assert.Equal(0, domain.Min.Y.Centimeters, 12); + Assert.Equal(20.03 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.03 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Circle() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateCircle().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(30 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-30 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(30 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-30 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void CircularHollow() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateCircularHollow().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(20 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-20 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(20 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Cruciform() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateCruciform().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(5.4 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-5.4 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(2.3 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-2.3 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void CustomI() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateCustomI().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(25.0 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-25.0 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(20.0 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.0 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void DoubleAngle() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateDoubleAngle().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(5.4 + 0.25 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-5.4 - 0.25 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(2.3, domain.Max.Z.Centimeters, 12); + Assert.Equal(0, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void DoubleChannel() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateDoubleChannel().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(10.04 + 0.25 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-10.04 - 0.25 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(20.03 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.03 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Ellipse() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateEllipse().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(18 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-18 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(12 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-12 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void EllipseHollow() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateEllipseHollow().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(18 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-18 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(12 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-12 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void ParallelFlange() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateIParallelFlange().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(30 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-30 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(50 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-50 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void I() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateI().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(50.4 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-50.4 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(20.3 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.3 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Rectangle() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateRectangle().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(5.4 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-5.4 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(2.3 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-2.3 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void RectangularHollow() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateRectangularHollow().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(50.4 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-50.4 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(20.3 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.3 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void RoundedRectangle() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateRoundedRectangle().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(20.0 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-20.0 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(25.0 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-25.0 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void RoundedRectangularHollow() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateRoundedRectangularHollow().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(70.0 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-70.0 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(40.0 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-40.0 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Tee() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateTee().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(10.04 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-10.04 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(0, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.03, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Trapezoid() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateTrapezoid().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(15.04 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-15.04 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(20.03 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-20.03 / 2, domain.Min.Z.Centimeters, 12); + } + + [Fact] + public void Z() + { + // Assemble + List parts = ProfileParts.GetParts(TestUtility.Sections.CreateZ().Profile); + + // Act + ILocalDomain2d domain = Extends.GetDomain(parts); + + // Assert + Assert.Equal(20.0 - 2.0 / 2, domain.Max.Y.Centimeters, 12); + Assert.Equal(-30.0 + 2.0 / 2, domain.Min.Y.Centimeters, 12); + Assert.Equal(40.0 / 2, domain.Max.Z.Centimeters, 12); + Assert.Equal(-40.0 / 2, domain.Min.Z.Centimeters, 12); + } + } +} diff --git a/SectionPropertiesTests/Utility/PerimeterProfileTests.cs b/SectionPropertiesTests/Utility/PerimeterProfileTests.cs new file mode 100644 index 0000000..c15a1a9 --- /dev/null +++ b/SectionPropertiesTests/Utility/PerimeterProfileTests.cs @@ -0,0 +1,88 @@ +using System.Collections; +using System.Reflection; +using MagmaWorks.Geometry; +using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Sections; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; +using OasysUnits; +using SectionPropertiesTests.TestUtility; + +namespace SectionPropertiesTests +{ + public class PerimeterProfileTests + { + [Theory] + [ClassData(typeof(SectionGenerator))] + public void MoveToElasticCentroidTest(ISection section) + { + // Assemble + IPerimeter original = new Perimeter(section.Profile); + ILocalPoint2d originalCentroid = Centroid.CalculateCentroid(original); + + // Act + IPerimeter translatedPerimeter = PerimeterProfile.MoveToElasticCentroid(original); + ILocalPoint2d newCentroid = Centroid.CalculateCentroid(translatedPerimeter); + + // Assert + Assert.Equal(0, newCentroid.Y.Value, 12); + Assert.Equal(0, newCentroid.Z.Value, 12); + } + + [Theory] + [ClassData(typeof(SectionGenerator))] + public void MomentOfInertiaTests(ISection section) + { + // skip back to back profiles as they do not convert to a single Perimeter profile + if (section.Profile is IBackToBack) + { + return; + } + + // Assemble + AreaMomentOfInertia originalYy = Inertia.CalculateInertiaYy(section.Profile); + AreaMomentOfInertia originalZz = Inertia.CalculateInertiaZz(section.Profile); + IPerimeter perimeter = new Perimeter(section.Profile); + + // Act + AreaMomentOfInertia inertiaYy = Inertia.CalculateInertiaYy(perimeter); + AreaMomentOfInertia inertiaZz = Inertia.CalculateInertiaZz(perimeter); + + // Assert + Assert.Equal(originalYy.CentimetersToTheFourth, inertiaYy.CentimetersToTheFourth, 0.05 * inertiaYy.CentimetersToTheFourth); + Assert.Equal(originalZz.CentimetersToTheFourth, inertiaZz.CentimetersToTheFourth, 0.05 * inertiaZz.CentimetersToTheFourth); + } + + public class SectionGenerator : IEnumerable + { + private readonly List _data = GetAllComponents(); + + public IEnumerator GetEnumerator() + { + return _data.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + private static List GetAllComponents() + { + Type sectionGeneratorClass = typeof(Sections); + MethodInfo[] sectionMethods = sectionGeneratorClass.GetMethods() + .Where(x => x.IsPublic && x.IsStatic).ToArray(); + + var data = new List(); + foreach (MethodInfo method in sectionMethods) + { + object sect = method.Invoke(null, null); + { + data.Add([sect]); + } + } + + return data; + } + } + } +} From 0c818cb46e612e089b47cf453a57c6af5e56d9a1 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Fri, 8 Nov 2024 16:04:31 +0000 Subject: [PATCH 07/30] Fix code style issues with dotnet_format --- SectionProperties/Utility/Parts/EllipseQuarterPart.cs | 2 +- SectionProperties/Utility/Parts/TrapezoidalPart.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SectionProperties/Utility/Parts/EllipseQuarterPart.cs b/SectionProperties/Utility/Parts/EllipseQuarterPart.cs index 26183e8..a475243 100644 --- a/SectionProperties/Utility/Parts/EllipseQuarterPart.cs +++ b/SectionProperties/Utility/Parts/EllipseQuarterPart.cs @@ -88,7 +88,7 @@ public AreaMomentOfInertia GetMomentOfInertiaZz() private void SetExtends(ILocalPoint2d corner, bool mirrorY = false, bool mirrorZ = false) { - + } } } diff --git a/SectionProperties/Utility/Parts/TrapezoidalPart.cs b/SectionProperties/Utility/Parts/TrapezoidalPart.cs index f68aaf2..0bc48c3 100644 --- a/SectionProperties/Utility/Parts/TrapezoidalPart.cs +++ b/SectionProperties/Utility/Parts/TrapezoidalPart.cs @@ -94,7 +94,7 @@ private ILocalDomain2d GetExtends() ? a.Abs() / 2 + ElasticCentroid.Y : b.Abs() / 2 + ElasticCentroid.Y; Length minY = a.Abs() > b.Abs() - ? ElasticCentroid.Y - a.Abs() / 2 + ? ElasticCentroid.Y - a.Abs() / 2 : ElasticCentroid.Y - b.Abs() / 2; Length e = h / 3 * (a.Abs() + 2 * b.Abs()) / (a.Abs() + b.Abs()); Length maxZ = ElasticCentroid.Z + h - e; From e9c07e79630a2ef8f3ce9666dceabda1cb673dff Mon Sep 17 00:00:00 2001 From: kpne Date: Mon, 11 Nov 2024 17:40:25 +0100 Subject: [PATCH 08/30] Perimeter radius of gyration --- SectionProperties/Utility/PerimeterProfile.cs | 14 ++++++ SectionProperties/Utility/RadiusOfGyration.cs | 13 ++++- .../Utility/PerimeterProfileTests.cs | 47 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/SectionProperties/Utility/PerimeterProfile.cs b/SectionProperties/Utility/PerimeterProfile.cs index e51c036..548d5db 100644 --- a/SectionProperties/Utility/PerimeterProfile.cs +++ b/SectionProperties/Utility/PerimeterProfile.cs @@ -53,6 +53,20 @@ internal static ILocalPoint2d CalculateCentroid(IPerimeter perimeter) }; } + internal static Length CalculateRadiusOfGyrationYy(IPerimeter perimeter) + { + OasysUnits.Area area = CalculateArea(perimeter); + AreaMomentOfInertia inertia = CalculateInertiaYy(perimeter); + return RadiusOfGyration.CalculateRadiusOfGyration(area, inertia); + } + + internal static Length CalculateRadiusOfGyrationZz(IPerimeter perimeter) + { + OasysUnits.Area area = CalculateArea(perimeter); + AreaMomentOfInertia inertia = CalculateInertiaZz(perimeter); + return RadiusOfGyration.CalculateRadiusOfGyration(area, inertia); + } + internal static AreaMomentOfInertia CalculateInertiaYy(IPerimeter perimeter) { IPerimeter centredOnElasticCentroid = MoveToElasticCentroid(perimeter); diff --git a/SectionProperties/Utility/RadiusOfGyration.cs b/SectionProperties/Utility/RadiusOfGyration.cs index dd01c3b..b6bc134 100644 --- a/SectionProperties/Utility/RadiusOfGyration.cs +++ b/SectionProperties/Utility/RadiusOfGyration.cs @@ -10,6 +10,11 @@ public static class RadiusOfGyration { public static Length CalculateRadiusOfGyrationYy(IProfile profile) { + if (profile is IPerimeter perim) + { + return PerimeterProfile.CalculateRadiusOfGyrationYy(perim); + } + return CalculateRadiusOfGyrationYy(ProfileParts.GetParts(profile)); } @@ -22,6 +27,11 @@ internal static Length CalculateRadiusOfGyrationYy(IList parts) public static Length CalculateRadiusOfGyrationZz(IProfile profile) { + if (profile is IPerimeter perim) + { + return PerimeterProfile.CalculateRadiusOfGyrationZz(perim); + } + return CalculateRadiusOfGyrationZz(ProfileParts.GetParts(profile)); } @@ -32,8 +42,7 @@ internal static Length CalculateRadiusOfGyrationZz(IList parts) return CalculateRadiusOfGyration(area, inertia); } - - private static Length CalculateRadiusOfGyration(OasysUnits.Area area, AreaMomentOfInertia inertia) + internal static Length CalculateRadiusOfGyration(OasysUnits.Area area, AreaMomentOfInertia inertia) { Length.TryParse($"0 {OasysUnits.Area.GetAbbreviation(area.Unit).Replace("²", string.Empty)}", out Length unit); OasysUnits.Area.TryParse($"0 {Length.GetAbbreviation(unit.Unit)}²", out OasysUnits.Area m2); diff --git a/SectionPropertiesTests/Utility/PerimeterProfileTests.cs b/SectionPropertiesTests/Utility/PerimeterProfileTests.cs index c15a1a9..168194a 100644 --- a/SectionPropertiesTests/Utility/PerimeterProfileTests.cs +++ b/SectionPropertiesTests/Utility/PerimeterProfileTests.cs @@ -6,6 +6,7 @@ using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; using OasysUnits; using SectionPropertiesTests.TestUtility; +using Utility = MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; namespace SectionPropertiesTests { @@ -28,6 +29,52 @@ public void MoveToElasticCentroidTest(ISection section) Assert.Equal(0, newCentroid.Z.Value, 12); } + [Theory] + [ClassData(typeof(SectionGenerator))] + public void AreaTests(ISection section) + { + // skip back to back profiles as they do not convert to a single Perimeter profile + if (section.Profile is IBackToBack) + { + return; + } + + // Assemble + OasysUnits.Area originalA = Utility.Area.CalculateArea(section.Profile); + IPerimeter perimeter = new Perimeter(section.Profile); + + // Act + OasysUnits.Area area = Utility.Area.CalculateArea(perimeter); + + // Assert + Assert.Equal(originalA.SquareCentimeters, area.SquareCentimeters, 0.05 * area.SquareCentimeters); + } + + + [Theory] + [ClassData(typeof(SectionGenerator))] + public void RadiusOfGyrationTests(ISection section) + { + // skip back to back profiles as they do not convert to a single Perimeter profile + if (section.Profile is IBackToBack) + { + return; + } + + // Assemble + Length originalYy = RadiusOfGyration.CalculateRadiusOfGyrationYy(section.Profile); + Length originalZz = RadiusOfGyration.CalculateRadiusOfGyrationZz(section.Profile); + IPerimeter perimeter = new Perimeter(section.Profile); + + // Act + Length radiusOfGyrationYy = RadiusOfGyration.CalculateRadiusOfGyrationYy(perimeter); + Length radiusOfGyrationZz = RadiusOfGyration.CalculateRadiusOfGyrationZz(perimeter); + + // Assert + Assert.Equal(originalYy.Centimeters, radiusOfGyrationYy.Centimeters, 0.05 * radiusOfGyrationYy.Centimeters); + Assert.Equal(originalZz.Centimeters, radiusOfGyrationZz.Centimeters, 0.05 * radiusOfGyrationZz.Centimeters); + } + [Theory] [ClassData(typeof(SectionGenerator))] public void MomentOfInertiaTests(ISection section) From 6a07188961c1f9cc29c5fb32164939b66b4132ed Mon Sep 17 00:00:00 2001 From: kpne Date: Mon, 11 Nov 2024 17:49:13 +0100 Subject: [PATCH 09/30] perimeter section modulus --- SectionProperties/Utility/PerimeterProfile.cs | 17 +++++++++++++ SectionProperties/Utility/SectionModulus.cs | 12 ++++++++- .../Utility/PerimeterProfileTests.cs | 25 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/SectionProperties/Utility/PerimeterProfile.cs b/SectionProperties/Utility/PerimeterProfile.cs index 548d5db..459a144 100644 --- a/SectionProperties/Utility/PerimeterProfile.cs +++ b/SectionProperties/Utility/PerimeterProfile.cs @@ -3,6 +3,7 @@ using System.Linq; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; using OasysUnits.Units; @@ -101,6 +102,22 @@ internal static AreaMomentOfInertia CalculateInertiaZz(IPerimeter perimeter) return inertia; } + internal static OasysUnits.SectionModulus CalculateSectionModulusYy(IPerimeter perimeter) + { + ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(perimeter); + ILocalDomain2d domain = Extends.GetDomain(perimeter); + AreaMomentOfInertia inertia = Inertia.CalculateInertiaYy(perimeter); + return SectionModulus.CalculateSectionModulus(domain.Max.Z, domain.Min.Z, elasticCentroid.Z, inertia); + } + + internal static OasysUnits.SectionModulus CalculateSectionModulusZz(IPerimeter perimeter) + { + ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(perimeter); + ILocalDomain2d domain = Extends.GetDomain(perimeter); + AreaMomentOfInertia inertia = Inertia.CalculateInertiaZz(perimeter); + return SectionModulus.CalculateSectionModulus(domain.Max.Y, domain.Min.Y, elasticCentroid.Y, inertia); + } + private static AreaMomentOfInertia CalculatePartInertiaYy(IList p) { double inertia = 0; diff --git a/SectionProperties/Utility/SectionModulus.cs b/SectionProperties/Utility/SectionModulus.cs index 7e06508..f4de0b2 100644 --- a/SectionProperties/Utility/SectionModulus.cs +++ b/SectionProperties/Utility/SectionModulus.cs @@ -12,6 +12,11 @@ public static class SectionModulus { public static OasysUnits.SectionModulus CalculateSectionModulusYy(IProfile profile) { + if (profile is IPerimeter perim) + { + return PerimeterProfile.CalculateSectionModulusYy(perim); + } + return CalculateSectionModulusYy(ProfileParts.GetParts(profile)); } @@ -25,6 +30,11 @@ internal static OasysUnits.SectionModulus CalculateSectionModulusYy(IList public static OasysUnits.SectionModulus CalculateSectionModulusZz(IProfile profile) { + if (profile is IPerimeter perim) + { + return PerimeterProfile.CalculateSectionModulusZz(perim); + } + return CalculateSectionModulusZz(ProfileParts.GetParts(profile)); } @@ -36,7 +46,7 @@ internal static OasysUnits.SectionModulus CalculateSectionModulusZz(IList return CalculateSectionModulus(domain.Max.Y, domain.Min.Y, elasticCentroid.Y, inertia); } - private static OasysUnits.SectionModulus CalculateSectionModulus(Length dPos, Length dNeg, Length centroid, AreaMomentOfInertia inertia) + internal static OasysUnits.SectionModulus CalculateSectionModulus(Length dPos, Length dNeg, Length centroid, AreaMomentOfInertia inertia) { Length zpos = Distance(dPos, centroid); Length zneg = Distance(dNeg, centroid); diff --git a/SectionPropertiesTests/Utility/PerimeterProfileTests.cs b/SectionPropertiesTests/Utility/PerimeterProfileTests.cs index 168194a..7ae3228 100644 --- a/SectionPropertiesTests/Utility/PerimeterProfileTests.cs +++ b/SectionPropertiesTests/Utility/PerimeterProfileTests.cs @@ -6,6 +6,7 @@ using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; using OasysUnits; using SectionPropertiesTests.TestUtility; +using SectionModulus = MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.SectionModulus; using Utility = MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; namespace SectionPropertiesTests @@ -99,6 +100,30 @@ public void MomentOfInertiaTests(ISection section) Assert.Equal(originalZz.CentimetersToTheFourth, inertiaZz.CentimetersToTheFourth, 0.05 * inertiaZz.CentimetersToTheFourth); } + [Theory] + [ClassData(typeof(SectionGenerator))] + public void SectionModulusTests(ISection section) + { + // skip back to back profiles as they do not convert to a single Perimeter profile + if (section.Profile is IBackToBack) + { + return; + } + + // Assemble + OasysUnits.SectionModulus originalYy = SectionModulus.CalculateSectionModulusYy(section.Profile); + OasysUnits.SectionModulus originalZz = SectionModulus.CalculateSectionModulusZz(section.Profile); + IPerimeter perimeter = new Perimeter(section.Profile); + + // Act + OasysUnits.SectionModulus inertiaYy = SectionModulus.CalculateSectionModulusYy(perimeter); + OasysUnits.SectionModulus inertiaZz = SectionModulus.CalculateSectionModulusZz(perimeter); + + // Assert + Assert.Equal(originalYy.CubicCentimeters, inertiaYy.CubicCentimeters, 0.05 * inertiaYy.CubicCentimeters); + Assert.Equal(originalZz.CubicCentimeters, inertiaZz.CubicCentimeters, 0.05 * inertiaZz.CubicCentimeters); + } + public class SectionGenerator : IEnumerable { private readonly List _data = GetAllComponents(); From 8140ae24909b1e2806a82e105fa8dc6e46fb3ef4 Mon Sep 17 00:00:00 2001 From: kpne Date: Tue, 12 Nov 2024 21:10:54 +0100 Subject: [PATCH 10/30] reinforcement area and second moment of area --- .../IConcreteSectionProperties.cs | 3 +- .../ConcreteSectionProperties.cs | 32 ++++++++----- SectionProperties/Utility/Inertia.cs | 8 ++-- .../Utility/Parts/ProfileParts.cs | 8 ---- SectionProperties/Utility/Reinforcement.cs | 46 ++++++++++++++++++- 5 files changed, 71 insertions(+), 26 deletions(-) diff --git a/ISectionProperties/IConcreteSectionProperties.cs b/ISectionProperties/IConcreteSectionProperties.cs index 1221876..f4c2f9d 100644 --- a/ISectionProperties/IConcreteSectionProperties.cs +++ b/ISectionProperties/IConcreteSectionProperties.cs @@ -4,11 +4,10 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public interface IConcreteSectionProperties : ISectionProperties { - Area TotalAreaOfReinforcement { get; } + Area ReinforcemenArea { get; } Area ConcreteArea { get; } Ratio GeometricReinforcementRatio { get; } Area ShearReinforcementArea { get; } - Length ShearReinforcementSpacing { get; } AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy { get; } AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz { get; } Length ReinforcementRadiusOfGyrationYy { get; } diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs index d969209..7a5cdaf 100644 --- a/SectionProperties/ConcreteSectionProperties.cs +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -1,22 +1,32 @@ -using OasysUnits; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; +using OasysUnits; +using OasysUnits.Units; +using Area = OasysUnits.Area; namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties { - public Area TotalAreaOfReinforcement => throw new System.NotImplementedException(); - public Area ConcreteArea => throw new System.NotImplementedException(); - public Ratio GeometricReinforcementRatio => throw new System.NotImplementedException(); - public Area ShearReinforcementArea => throw new System.NotImplementedException(); - public Length ShearReinforcementSpacing => throw new System.NotImplementedException(); - public AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy => throw new System.NotImplementedException(); - public AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz => throw new System.NotImplementedException(); + public Area ReinforcemenArea => _reinforcementArea ??= Reinforcement.CalculateArea(_section.Rebars); + public Area ConcreteArea => base.Area - ReinforcemenArea; + public Ratio GeometricReinforcementRatio => + new Ratio(ConcreteArea.SquareMeters / ReinforcemenArea.SquareMeters, RatioUnit.DecimalFraction); + public Area ShearReinforcementArea => Reinforcement.CalculateArea(_section.Link) * 2; + public AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy => + _reinforcementSecondMomentOfAreaYy ??= Reinforcement.CalculateInertiaYy(_section); + public AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz => + _reinforcementSecondMomentOfAreaZz ??= Reinforcement.CalculateInertiaZz(_section); public Length ReinforcementRadiusOfGyrationYy => throw new System.NotImplementedException(); public Length ReinforcementRadiusOfGyrationZz => throw new System.NotImplementedException(); - private Area _concreteArea; - private Area _longitudinalReinforcementArea; - private Area _shearReinforcementArea; + + private Area? _concreteArea; + private Area? _reinforcementArea; + private Area? _shearReinforcementArea; + private AreaMomentOfInertia? _reinforcementSecondMomentOfAreaYy; + private AreaMomentOfInertia? _reinforcementSecondMomentOfAreaZz; + private Length? _reinforcementRadiusOfGyrationYy; + private Length? _reinforcementRadiusOfGyrationZz; private IConcreteSection _section; private ConcreteSectionProperties() { } diff --git a/SectionProperties/Utility/Inertia.cs b/SectionProperties/Utility/Inertia.cs index 53e2c4f..e122942 100644 --- a/SectionProperties/Utility/Inertia.cs +++ b/SectionProperties/Utility/Inertia.cs @@ -20,9 +20,9 @@ public static AreaMomentOfInertia CalculateInertiaYy(IProfile profile) return CalculateInertiaYy(ProfileParts.GetParts(profile)); } - internal static AreaMomentOfInertia CalculateInertiaYy(IList parts) + internal static AreaMomentOfInertia CalculateInertiaYy(IList parts, ILocalPoint2d elasticCentroid = null) { - ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(parts); + elasticCentroid ??= Centroid.CalculateCentroid(parts); AreaMomentOfInertia inertia = AreaMomentOfInertia.Zero; foreach (IPart part in parts) { @@ -43,9 +43,9 @@ public static AreaMomentOfInertia CalculateInertiaZz(IProfile profile) return CalculateInertiaZz(ProfileParts.GetParts(profile)); } - internal static AreaMomentOfInertia CalculateInertiaZz(IList parts) + internal static AreaMomentOfInertia CalculateInertiaZz(IList parts, ILocalPoint2d elasticCentroid = null) { - ILocalPoint2d elasticCentroid = Centroid.CalculateCentroid(parts); + elasticCentroid ??= Centroid.CalculateCentroid(parts); AreaMomentOfInertia inertia = AreaMomentOfInertia.Zero; foreach (IPart part in parts) { diff --git a/SectionProperties/Utility/Parts/ProfileParts.cs b/SectionProperties/Utility/Parts/ProfileParts.cs index 577374c..e3c3e89 100644 --- a/SectionProperties/Utility/Parts/ProfileParts.cs +++ b/SectionProperties/Utility/Parts/ProfileParts.cs @@ -307,14 +307,6 @@ internal static List GetParts(IProfile profile) -z.Height / 2 + z.TopLip / 2))); return parts; - //default: - // { - // IPerimeter perimeter = new Perimeter(profile); - // // mesh the perimeter - // // implement trianglepart - // // add each triangle - // return parts; - // } default: throw new System.Exception($"Unable to get parts for unknown Profile type {profile.GetType()}"); } diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs index 8c5b3c1..482546c 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Reinforcement.cs @@ -1,7 +1,51 @@ -namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility +using MagmaWorks.Geometry; +using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; +using OasysUnits; +using OasysUnits.Units; +using System; +using System.Collections.Generic; + +namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility { public static class Reinforcement { + public static OasysUnits.Area CalculateArea(IList rebars) + { + return Area.CalculateArea(GetParts(rebars)); + } + + public static OasysUnits.Area CalculateArea(IRebar rebar) + { + LengthUnit unit = rebar.Diameter.Unit; + OasysUnits.Area m2 = OasysUnits.Area.Zero; + OasysUnits.Area.TryParse($"0 {Length.GetAbbreviation(unit)}²", out m2); + return new OasysUnits.Area(Math.PI / 4 * Math.Pow(rebar.Diameter.As(unit), 2), m2.Unit); + } + + public static AreaMomentOfInertia CalculateInertiaYy(IConcreteSection section) + { + ILocalPoint2d concreteCentroid = Centroid.CalculateCentroid(section.Profile); + List rebars = GetParts(section.Rebars); + return Inertia.CalculateInertiaYy(rebars, concreteCentroid); + } + + public static AreaMomentOfInertia CalculateInertiaZz(IConcreteSection section) + { + ILocalPoint2d concreteCentroid = Centroid.CalculateCentroid(section.Profile); + List rebars = GetParts(section.Rebars); + return Inertia.CalculateInertiaZz(rebars, concreteCentroid); + } + + private static List GetParts(IList rebars) + { + var parts = new List(); + foreach (ILongitudinalReinforcement rebar in rebars) + { + IList part = EllipseQuarterPart.CreateCircle(rebar.Rebar.Diameter, rebar.Position); + parts.AddRange(part); + } + return parts; + } } } From 5ef5b6f65d595e2b905d5fae06809f4e23f1a3a0 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Tue, 12 Nov 2024 20:11:38 +0000 Subject: [PATCH 11/30] Fix code style issues with dotnet_format --- SectionProperties/Utility/Reinforcement.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs index 482546c..ff85b1e 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Reinforcement.cs @@ -1,9 +1,9 @@ -using MagmaWorks.Geometry; +using System; +using System.Collections.Generic; +using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; using OasysUnits.Units; -using System; -using System.Collections.Generic; namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility { From 048fc2712f8a6869151d4b3137e001e53fbf292f Mon Sep 17 00:00:00 2001 From: kpne Date: Thu, 14 Nov 2024 11:15:53 +0100 Subject: [PATCH 12/30] reinforcement RadiusOfGyration --- .../ConcreteSectionProperties.cs | 9 +++++---- SectionProperties/Utility/Reinforcement.cs | 20 ++++++++++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs index 7a5cdaf..4988e64 100644 --- a/SectionProperties/ConcreteSectionProperties.cs +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -10,15 +10,16 @@ public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProp public Area ReinforcemenArea => _reinforcementArea ??= Reinforcement.CalculateArea(_section.Rebars); public Area ConcreteArea => base.Area - ReinforcemenArea; public Ratio GeometricReinforcementRatio => - new Ratio(ConcreteArea.SquareMeters / ReinforcemenArea.SquareMeters, RatioUnit.DecimalFraction); + new Ratio(ReinforcemenArea.SquareMeters / ConcreteArea.SquareMeters, RatioUnit.DecimalFraction); public Area ShearReinforcementArea => Reinforcement.CalculateArea(_section.Link) * 2; public AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy => _reinforcementSecondMomentOfAreaYy ??= Reinforcement.CalculateInertiaYy(_section); public AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz => _reinforcementSecondMomentOfAreaZz ??= Reinforcement.CalculateInertiaZz(_section); - public Length ReinforcementRadiusOfGyrationYy => throw new System.NotImplementedException(); - public Length ReinforcementRadiusOfGyrationZz => throw new System.NotImplementedException(); - + public Length ReinforcementRadiusOfGyrationYy => + _reinforcementRadiusOfGyrationYy ??= Reinforcement.CalculateRadiusOfGyrationYy(_section); + public Length ReinforcementRadiusOfGyrationZz => + _reinforcementRadiusOfGyrationZz ??= Reinforcement.CalculateRadiusOfGyrationZz(_section); private Area? _concreteArea; private Area? _reinforcementArea; diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs index 482546c..e3e3032 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Reinforcement.cs @@ -1,9 +1,9 @@ -using MagmaWorks.Geometry; +using System; +using System.Collections.Generic; +using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; using OasysUnits.Units; -using System; -using System.Collections.Generic; namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility { @@ -36,6 +36,20 @@ public static AreaMomentOfInertia CalculateInertiaZz(IConcreteSection section) return Inertia.CalculateInertiaZz(rebars, concreteCentroid); } + public static Length CalculateRadiusOfGyrationYy(IConcreteSection section) + { + OasysUnits.Area area = CalculateArea(section.Rebars); + AreaMomentOfInertia inertia = CalculateInertiaZz(section); + return RadiusOfGyration.CalculateRadiusOfGyration(area, inertia); + } + + public static Length CalculateRadiusOfGyrationZz(IConcreteSection section) + { + OasysUnits.Area area = CalculateArea(section.Rebars); + AreaMomentOfInertia inertia = CalculateInertiaZz(section); + return RadiusOfGyration.CalculateRadiusOfGyration(area, inertia); + } + private static List GetParts(IList rebars) { var parts = new List(); From 6cd74688d3d9e0072fcc558a350bf466ca9b57e9 Mon Sep 17 00:00:00 2001 From: kpne Date: Thu, 14 Nov 2024 16:21:10 +0100 Subject: [PATCH 13/30] update taxonomy nuget (WxD swap) --- ...Taxonomy.Sections.SectionProperties.csproj | 4 +-- .../SectionPropertiesTests.csproj | 2 +- .../TestUtility/ConcreteSections.cs | 32 +++++++++++++++++++ .../TestUtility/Sections.cs | 14 ++++---- 4 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 SectionPropertiesTests/TestUtility/ConcreteSections.cs diff --git a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj index bb79838..7f32346 100644 --- a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj +++ b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj @@ -23,8 +23,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SectionPropertiesTests/SectionPropertiesTests.csproj b/SectionPropertiesTests/SectionPropertiesTests.csproj index ca6c324..4e7a026 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.csproj +++ b/SectionPropertiesTests/SectionPropertiesTests.csproj @@ -8,7 +8,7 @@ - + diff --git a/SectionPropertiesTests/TestUtility/ConcreteSections.cs b/SectionPropertiesTests/TestUtility/ConcreteSections.cs new file mode 100644 index 0000000..f9f3309 --- /dev/null +++ b/SectionPropertiesTests/TestUtility/ConcreteSections.cs @@ -0,0 +1,32 @@ +using MagmaWorks.Geometry; +using MagmaWorks.Taxonomy.Profiles; +using OasysUnits.Units; +using OasysUnits; + +namespace SectionPropertiesTests.TestUtility +{ + internal static class ConcreteSections + { + private static Perimeter PerimeterRectangle400x750() + { + LengthUnit unit = LengthUnit.Millimeter; + var solidEdge = new LocalPolygon2d(new List() + { + new LocalPoint2d() { Y = new Length(-200, unit), Z = new Length(-375, unit)}, + new LocalPoint2d() { Y = new Length(200, unit), Z = new Length(-375, unit)}, + new LocalPoint2d() { Y = new Length(200, unit), Z = new Length(375, unit)}, + new LocalPoint2d() { Y = new Length(-200, unit), Z = new Length(375, unit)}, + }); + + return new Perimeter(solidEdge); + } + + private static Rectangle Rectangle400x750() + { + LengthUnit unit = LengthUnit.Millimeter; + Length width = new Length(400, unit); + Length height = new Length(750, unit); + return new Rectangle(width, height); + } + } +} diff --git a/SectionPropertiesTests/TestUtility/Sections.cs b/SectionPropertiesTests/TestUtility/Sections.cs index 1334b55..7557816 100644 --- a/SectionPropertiesTests/TestUtility/Sections.cs +++ b/SectionPropertiesTests/TestUtility/Sections.cs @@ -115,7 +115,7 @@ public static ISection CreateEllipse() { var h = new Length(12, LengthUnit.Centimeter); var w = new Length(18, LengthUnit.Centimeter); - IEllipse prfl = new Ellipse(h, w); + IEllipse prfl = new Ellipse(w, h); return MockSection(prfl); } @@ -124,7 +124,7 @@ public static ISection CreateEllipseHollow() var h = new Length(12, LengthUnit.Centimeter); var w = new Length(18, LengthUnit.Centimeter); var thk = new Length(14.3, LengthUnit.Millimeter); - IEllipseHollow prfl = new EllipseHollow(h, w, thk); + IEllipseHollow prfl = new EllipseHollow(w, h, thk); return MockSection(prfl); } @@ -148,7 +148,7 @@ public static ISection CreateRectangle() { var h = new Length(2.3, LengthUnit.Centimeter); var w = new Length(5.4, LengthUnit.Centimeter); - IRectangle prfl = new Rectangle(h, w); + IRectangle prfl = new Rectangle(w, h); return MockSection(prfl); } @@ -157,7 +157,7 @@ public static ISection CreateRectangularHollow() var h = new Length(20.3, LengthUnit.Centimeter); var w = new Length(50.4, LengthUnit.Centimeter); var thk = new Length(10.9, LengthUnit.Millimeter); - IRectangularHollow prfl = new RectangularHollow(h, w, thk); + IRectangularHollow prfl = new RectangularHollow(w, h, thk); return MockSection(prfl); } @@ -167,7 +167,7 @@ public static ISection CreateRoundedRectangle() var w = new Length(20, LengthUnit.Centimeter); var h1 = new Length(20, LengthUnit.Centimeter); var w1 = new Length(10, LengthUnit.Centimeter); - IRoundedRectangle prfl = new RoundedRectangle(h, w, h1, w1); + IRoundedRectangle prfl = new RoundedRectangle(w, h, w1, h1); return MockSection(prfl); } @@ -178,7 +178,7 @@ public static ISection CreateRoundedRectangularHollow() var h1 = new Length(30, LengthUnit.Centimeter); var w1 = new Length(50, LengthUnit.Centimeter); var thk = new Length(5.5, LengthUnit.Millimeter); - IRoundedRectangularHollow prfl = new RoundedRectangularHollow(h, w, h1, w1, thk); + IRoundedRectangularHollow prfl = new RoundedRectangularHollow(w, h, w1, h1, thk); return MockSection(prfl); } @@ -197,7 +197,7 @@ public static ISection CreateTrapezoid() var h = new Length(200.3, LengthUnit.Millimeter); var wTop = new Length(100.4, LengthUnit.Millimeter); var wBottom = new Length(150.4, LengthUnit.Millimeter); - ITrapezoid prfl = new Trapezoid(h, wTop, wBottom); + ITrapezoid prfl = new Trapezoid(wTop, wBottom, h); return MockSection(prfl); } From b58cff34f790d688ac7e89f11354676a16f6931c Mon Sep 17 00:00:00 2001 From: Lint Action Date: Thu, 14 Nov 2024 15:21:59 +0000 Subject: [PATCH 14/30] Fix code style issues with dotnet_format --- SectionPropertiesTests/TestUtility/ConcreteSections.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SectionPropertiesTests/TestUtility/ConcreteSections.cs b/SectionPropertiesTests/TestUtility/ConcreteSections.cs index f9f3309..f961910 100644 --- a/SectionPropertiesTests/TestUtility/ConcreteSections.cs +++ b/SectionPropertiesTests/TestUtility/ConcreteSections.cs @@ -1,7 +1,7 @@ using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; -using OasysUnits.Units; using OasysUnits; +using OasysUnits.Units; namespace SectionPropertiesTests.TestUtility { From 53f019ec4fae3ffbea84825b3131e74251ac8901 Mon Sep 17 00:00:00 2001 From: kpne Date: Thu, 14 Nov 2024 17:48:45 +0100 Subject: [PATCH 15/30] faster area calc --- SectionProperties/Utility/Reinforcement.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs index e3e3032..5f0dcfc 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Reinforcement.cs @@ -1,17 +1,30 @@ using System; +using System.Linq; using System.Collections.Generic; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; using OasysUnits.Units; +using System.IO; namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility { public static class Reinforcement { + private const double PiFactor = Math.PI / 4; + public static OasysUnits.Area CalculateArea(IList rebars) { - return Area.CalculateArea(GetParts(rebars)); + LengthUnit unit = rebars.FirstOrDefault().Rebar.Diameter.Unit; + double area = 0; + foreach(ILongitudinalReinforcement reinforcement in rebars) + { + area += PiFactor * Math.Pow(reinforcement.Rebar.Diameter.As(unit), 2); + } + + OasysUnits.Area m2 = OasysUnits.Area.Zero; + OasysUnits.Area.TryParse($"0 {Length.GetAbbreviation(unit)}²", out m2); + return new OasysUnits.Area(area, m2.Unit); } public static OasysUnits.Area CalculateArea(IRebar rebar) @@ -19,7 +32,7 @@ public static OasysUnits.Area CalculateArea(IRebar rebar) LengthUnit unit = rebar.Diameter.Unit; OasysUnits.Area m2 = OasysUnits.Area.Zero; OasysUnits.Area.TryParse($"0 {Length.GetAbbreviation(unit)}²", out m2); - return new OasysUnits.Area(Math.PI / 4 * Math.Pow(rebar.Diameter.As(unit), 2), m2.Unit); + return new OasysUnits.Area(PiFactor * Math.Pow(rebar.Diameter.As(unit), 2), m2.Unit); } public static AreaMomentOfInertia CalculateInertiaYy(IConcreteSection section) @@ -39,7 +52,7 @@ public static AreaMomentOfInertia CalculateInertiaZz(IConcreteSection section) public static Length CalculateRadiusOfGyrationYy(IConcreteSection section) { OasysUnits.Area area = CalculateArea(section.Rebars); - AreaMomentOfInertia inertia = CalculateInertiaZz(section); + AreaMomentOfInertia inertia = CalculateInertiaYy(section); return RadiusOfGyration.CalculateRadiusOfGyration(area, inertia); } From 731054b4223394b61011c147f3dca755a1a901bb Mon Sep 17 00:00:00 2001 From: kpne Date: Thu, 14 Nov 2024 17:48:58 +0100 Subject: [PATCH 16/30] concrete section and reinforcement tests --- .../ConcreteSectionPropertiesTests.cs | 150 ++++++++++++++++++ .../TestUtility/ConcreteSections.cs | 93 +++++++++++ 2 files changed, 243 insertions(+) create mode 100644 SectionPropertiesTests/ConcreteSectionPropertiesTests.cs diff --git a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs new file mode 100644 index 0000000..f889702 --- /dev/null +++ b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs @@ -0,0 +1,150 @@ +using System.Collections; +using System.Reflection; +using MagmaWorks.Taxonomy.Sections; +using MagmaWorks.Taxonomy.Sections.SectionProperties; +using MagmaWorks.Taxonomy.Serialization.Sections.SectionProperties.Extensions; +using SectionPropertiesTests.TestUtility; + +namespace SectionPropertiesTests +{ + public class ConcreteSectionPropertiesTests + { + [Fact] + public void ReinforcementAreaTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Perimeter(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expected = 2 * Math.PI / 4 * Math.Pow(12, 2) + + 4 * Math.PI / 4 * Math.Pow(20, 2); + Assert.Equal(expected, props.ReinforcemenArea.SquareMillimeters, 9); + } + + [Fact] + public void ConcreteAreaTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Rectangle(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expectedReinforcementArea = 2 * Math.PI / 4 * Math.Pow(12, 2) + + 4 * Math.PI / 4 * Math.Pow(20, 2); + double expected = 400 * 750 - expectedReinforcementArea; + Assert.Equal(expected, props.ConcreteArea.SquareMillimeters, 9); + } + + [Fact] + public void GeometricReinforcementRatioTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Perimeter(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expectedReinforcementArea = 2 * Math.PI / 4 * Math.Pow(12, 2) + + 4 * Math.PI / 4 * Math.Pow(20, 2); + double expectedConcreteArea = 400 * 750 - expectedReinforcementArea; + double expected = expectedReinforcementArea / expectedConcreteArea; + Assert.Equal(expected, props.GeometricReinforcementRatio.DecimalFractions, 9); + } + + [Fact] + public void ShearReinforcementAreaTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Rectangle(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expected = 2 * Math.PI / 4 * Math.Pow(10, 2); + Assert.Equal(expected, props.ShearReinforcementArea.SquareMillimeters, 9); + } + + [Fact] + public void ReinforcementSecondMomentOfAreaYyTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Perimeter(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expected = 2 * (Math.PI / 64 * Math.Pow(12, 4) + + (Math.PI / 4 * Math.Pow(12, 2) * Math.Pow(334, 2))); + expected += 4 * (Math.PI / 64 * Math.Pow(20, 4) + + (Math.PI / 4 * Math.Pow(20, 2) * Math.Pow(330, 2))); + Assert.Equal(expected, props.ReinforcementSecondMomentOfAreaYy.MillimetersToTheFourth, 9); + } + + [Fact] + public void ReinforcementSecondMomentOfAreaZzTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Rectangle(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expected = 2 * (Math.PI / 64 * Math.Pow(12, 4) + + (Math.PI / 4 * Math.Pow(12, 2) * Math.Pow(159, 2))); + expected += 2 * (Math.PI / 64 * Math.Pow(20, 4) + + (Math.PI / 4 * Math.Pow(20, 2) * Math.Pow(155, 2))); + expected += 2 * (Math.PI / 64 * Math.Pow(20, 4) + + (Math.PI / 4 * Math.Pow(20, 2) * Math.Pow(51.666667, 2))); + Assert.Equal(expected, props.ReinforcementSecondMomentOfAreaZz.MillimetersToTheFourth, 9); + } + + [Fact] + public void ReinforcementRadiusOfGyrationYyTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Perimeter(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expected = 2 * (Math.PI / 64 * Math.Pow(12, 4) + + (Math.PI / 4 * Math.Pow(12, 2) * Math.Pow(334, 2))); + expected += 4 * (Math.PI / 64 * Math.Pow(20, 4) + + (Math.PI / 4 * Math.Pow(20, 2) * Math.Pow(330, 2))); + expected /= 2 * Math.PI / 4 * Math.Pow(12, 2) + + 4 * Math.PI / 4 * Math.Pow(20, 2); + Assert.Equal(Math.Sqrt(expected), props.ReinforcementRadiusOfGyrationYy.Millimeters, 9); + } + + [Fact] + public void ReinforcementRadiusOfGyrationZzTest() + { + // Assemble + ConcreteSection setion = ConcreteSections.Rectangle(); + + // Act + var props = new ConcreteSectionProperties(setion); + + // Assert + double expected = 2 * (Math.PI / 64 * Math.Pow(12, 4) + + (Math.PI / 4 * Math.Pow(12, 2) * Math.Pow(159, 2))); + expected += 2 * (Math.PI / 64 * Math.Pow(20, 4) + + (Math.PI / 4 * Math.Pow(20, 2) * Math.Pow(155, 2))); + expected += 2 * (Math.PI / 64 * Math.Pow(20, 4) + + (Math.PI / 4 * Math.Pow(20, 2) * Math.Pow(51.666667, 2))); + expected /= 2 * Math.PI / 4 * Math.Pow(12, 2) + + 4 * Math.PI / 4 * Math.Pow(20, 2); + Assert.Equal(Math.Sqrt(expected), props.ReinforcementRadiusOfGyrationZz.Millimeters, 9); + } + } +} diff --git a/SectionPropertiesTests/TestUtility/ConcreteSections.cs b/SectionPropertiesTests/TestUtility/ConcreteSections.cs index f9f3309..4f3863b 100644 --- a/SectionPropertiesTests/TestUtility/ConcreteSections.cs +++ b/SectionPropertiesTests/TestUtility/ConcreteSections.cs @@ -1,12 +1,88 @@ using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Sections; using OasysUnits.Units; using OasysUnits; +using MagmaWorks.Taxonomy.Materials; namespace SectionPropertiesTests.TestUtility { internal static class ConcreteSections { + internal static ConcreteSection Perimeter() + { + LengthUnit unit = LengthUnit.Millimeter; + IMaterial material = new MockMaterial(); + IProfile profile = PerimeterRectangle400x750(); + double link = 10; + double cover = 25; + var rebars = new List() + { + Rebar(12, -200, 375, link, cover), + Rebar(12, 200, 375, link, cover), + Rebar(20, -200, -375, link, cover), + Rebar(20, -51.666667, -330), + Rebar(20, 51.666667, -330), + Rebar(20, 200, -375, link, cover), + }; + + return new ConcreteSection(material, profile, rebars, Bar(link), new Length(cover, unit)); + } + + internal static ConcreteSection Rectangle() + { + LengthUnit unit = LengthUnit.Millimeter; + IMaterial material = new MockMaterial(); + IProfile profile = Rectangle400x750(); + double link = 10; + double cover = 25; + var rebars = new List() + { + Rebar(12, -200, 375, link, cover), + Rebar(12, 200, 375, link, cover), + Rebar(20, -200, -375, link, cover), + Rebar(20, -51.666667, -330), + Rebar(20, 51.666667, -330), + Rebar(20, 200, -375, link, cover), + }; + + return new ConcreteSection(material, profile, rebars, Bar(link), new Length(cover, unit)); + } + + private static LongitudinalReinforcement Rebar(double dia, double edgeY, double edgeZ, double link, double cover) + { + LengthUnit unit = LengthUnit.Millimeter; + double posY = edgeY > 0 + ? edgeY - link - cover - dia / 2 + : edgeY + link + cover + dia / 2; + double posZ = edgeZ > 0 + ? edgeZ - link - cover - dia / 2 + : edgeZ + link + cover + dia / 2; + return new LongitudinalReinforcement(Bar(dia), + new LocalPoint2d() + { + Y = new Length(posY, unit), + Z = new Length(posZ, unit) + }); + } + + private static LongitudinalReinforcement Rebar(double dia, double posY, double posZ) + { + LengthUnit unit = LengthUnit.Millimeter; + return new LongitudinalReinforcement(Bar(dia), + new LocalPoint2d() + { + Y = new Length(posY, unit), + Z = new Length(posZ, unit) + }); + } + + private static Rebar Bar(double dia) + { + Length diameter = new Length(dia, LengthUnit.Millimeter); + return new Rebar(new MockMaterial(), diameter); + } + private static Perimeter PerimeterRectangle400x750() { LengthUnit unit = LengthUnit.Millimeter; @@ -28,5 +104,22 @@ private static Rectangle Rectangle400x750() Length height = new Length(750, unit); return new Rectangle(width, height); } + + private static Circle CircleD550() + { + LengthUnit unit = LengthUnit.Millimeter; + Length diameter = new Length(550, unit); + return new Circle(diameter); + } + + private static Tee Tee800x500() + { + LengthUnit unit = LengthUnit.Millimeter; + Length width = new Length(800, unit); + Length height = new Length(500, unit); + Length flange = new Length(150, unit); + Length web = new Length(90, unit); + return new Tee(height, width, flange, web); + } } } From a61c8792178f9f0d70a545b09d0776cf265764ee Mon Sep 17 00:00:00 2001 From: Lint Action Date: Thu, 14 Nov 2024 16:50:53 +0000 Subject: [PATCH 17/30] Fix code style issues with dotnet_format --- SectionProperties/Utility/Reinforcement.cs | 6 +++--- SectionPropertiesTests/TestUtility/ConcreteSections.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs index 5f0dcfc..6b1e090 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Reinforcement.cs @@ -1,11 +1,11 @@ using System; -using System.Linq; using System.Collections.Generic; +using System.IO; +using System.Linq; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; using OasysUnits.Units; -using System.IO; namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility { @@ -17,7 +17,7 @@ public static OasysUnits.Area CalculateArea(IList re { LengthUnit unit = rebars.FirstOrDefault().Rebar.Diameter.Unit; double area = 0; - foreach(ILongitudinalReinforcement reinforcement in rebars) + foreach (ILongitudinalReinforcement reinforcement in rebars) { area += PiFactor * Math.Pow(reinforcement.Rebar.Diameter.As(unit), 2); } diff --git a/SectionPropertiesTests/TestUtility/ConcreteSections.cs b/SectionPropertiesTests/TestUtility/ConcreteSections.cs index 4f3863b..2e2f10e 100644 --- a/SectionPropertiesTests/TestUtility/ConcreteSections.cs +++ b/SectionPropertiesTests/TestUtility/ConcreteSections.cs @@ -1,9 +1,9 @@ using MagmaWorks.Geometry; +using MagmaWorks.Taxonomy.Materials; using MagmaWorks.Taxonomy.Profiles; using MagmaWorks.Taxonomy.Sections; -using OasysUnits.Units; using OasysUnits; -using MagmaWorks.Taxonomy.Materials; +using OasysUnits.Units; namespace SectionPropertiesTests.TestUtility { @@ -45,7 +45,7 @@ internal static ConcreteSection Rectangle() Rebar(20, 51.666667, -330), Rebar(20, 200, -375, link, cover), }; - + return new ConcreteSection(material, profile, rebars, Bar(link), new Length(cover, unit)); } From b3dc51c37524f3c224feb672d2936b29d4efdbd2 Mon Sep 17 00:00:00 2001 From: kpne Date: Fri, 15 Nov 2024 09:01:04 +0100 Subject: [PATCH 18/30] remove unused usings --- SectionProperties/Utility/PerimeterProfile.cs | 1 - SectionProperties/Utility/Reinforcement.cs | 1 - SectionPropertiesTests/ConcreteSectionPropertiesTests.cs | 3 --- SectionPropertiesTests/Utility/PerimeterTests.cs | 3 +-- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/SectionProperties/Utility/PerimeterProfile.cs b/SectionProperties/Utility/PerimeterProfile.cs index 459a144..168f7bd 100644 --- a/SectionProperties/Utility/PerimeterProfile.cs +++ b/SectionProperties/Utility/PerimeterProfile.cs @@ -3,7 +3,6 @@ using System.Linq; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; -using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; using OasysUnits; using OasysUnits.Units; diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs index 6b1e090..3679fd0 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Reinforcement.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility.Parts; diff --git a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs index f889702..20da699 100644 --- a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs +++ b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs @@ -1,8 +1,5 @@ -using System.Collections; -using System.Reflection; using MagmaWorks.Taxonomy.Sections; using MagmaWorks.Taxonomy.Sections.SectionProperties; -using MagmaWorks.Taxonomy.Serialization.Sections.SectionProperties.Extensions; using SectionPropertiesTests.TestUtility; namespace SectionPropertiesTests diff --git a/SectionPropertiesTests/Utility/PerimeterTests.cs b/SectionPropertiesTests/Utility/PerimeterTests.cs index 39b0dd4..cb578c0 100644 --- a/SectionPropertiesTests/Utility/PerimeterTests.cs +++ b/SectionPropertiesTests/Utility/PerimeterTests.cs @@ -1,5 +1,4 @@ -using MagmaWorks.Geometry; -using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Profiles; using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; using OasysUnits; From 56d28a3e02fafa8bc296d6e62641a9c5081ffa3b Mon Sep 17 00:00:00 2001 From: kpne Date: Fri, 15 Nov 2024 16:43:04 +0100 Subject: [PATCH 19/30] Effective Depth for SectionFace --- .../IConcreteSectionProperties.cs | 6 +- ISectionProperties/SectionFace.cs | 11 ++++ .../ConcreteSectionProperties.cs | 17 +++-- SectionProperties/Utility/Reinforcement.cs | 65 ++++++++++++++++++- .../ConcreteSectionPropertiesTests.cs | 49 +++++++++++++- 5 files changed, 134 insertions(+), 14 deletions(-) create mode 100644 ISectionProperties/SectionFace.cs diff --git a/ISectionProperties/IConcreteSectionProperties.cs b/ISectionProperties/IConcreteSectionProperties.cs index f4c2f9d..2cbee09 100644 --- a/ISectionProperties/IConcreteSectionProperties.cs +++ b/ISectionProperties/IConcreteSectionProperties.cs @@ -4,13 +4,15 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public interface IConcreteSectionProperties : ISectionProperties { - Area ReinforcemenArea { get; } + Area TotalReinforcemenArea { get; } Area ConcreteArea { get; } Ratio GeometricReinforcementRatio { get; } - Area ShearReinforcementArea { get; } + Area CrossSectionalShearReinforcementArea { get; } AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy { get; } AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz { get; } Length ReinforcementRadiusOfGyrationYy { get; } Length ReinforcementRadiusOfGyrationZz { get; } + Length EffectiveDepth(SectionFace face); + Area ReinforcementArea(SectionFace face); } } diff --git a/ISectionProperties/SectionFace.cs b/ISectionProperties/SectionFace.cs new file mode 100644 index 0000000..2e98f11 --- /dev/null +++ b/ISectionProperties/SectionFace.cs @@ -0,0 +1,11 @@ + +namespace MagmaWorks.Taxonomy.Sections.SectionProperties +{ + public enum SectionFace + { + Top, + LeftSide, + RightSide, + Bottom, + } +} diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs index 4988e64..5820646 100644 --- a/SectionProperties/ConcreteSectionProperties.cs +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -7,11 +7,11 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties { - public Area ReinforcemenArea => _reinforcementArea ??= Reinforcement.CalculateArea(_section.Rebars); - public Area ConcreteArea => base.Area - ReinforcemenArea; + public Area TotalReinforcemenArea => _reinforcementArea ??= Reinforcement.CalculateArea(_section.Rebars); + public Area ConcreteArea => base.Area - TotalReinforcemenArea; public Ratio GeometricReinforcementRatio => - new Ratio(ReinforcemenArea.SquareMeters / ConcreteArea.SquareMeters, RatioUnit.DecimalFraction); - public Area ShearReinforcementArea => Reinforcement.CalculateArea(_section.Link) * 2; + new Ratio(TotalReinforcemenArea.SquareMeters / ConcreteArea.SquareMeters, RatioUnit.DecimalFraction); + public Area CrossSectionalShearReinforcementArea => Reinforcement.CalculateArea(_section.Link) * 2; public AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy => _reinforcementSecondMomentOfAreaYy ??= Reinforcement.CalculateInertiaYy(_section); public AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz => @@ -21,19 +21,22 @@ public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProp public Length ReinforcementRadiusOfGyrationZz => _reinforcementRadiusOfGyrationZz ??= Reinforcement.CalculateRadiusOfGyrationZz(_section); - private Area? _concreteArea; private Area? _reinforcementArea; - private Area? _shearReinforcementArea; private AreaMomentOfInertia? _reinforcementSecondMomentOfAreaYy; private AreaMomentOfInertia? _reinforcementSecondMomentOfAreaZz; private Length? _reinforcementRadiusOfGyrationYy; private Length? _reinforcementRadiusOfGyrationZz; - private IConcreteSection _section; + private readonly IConcreteSection _section; private ConcreteSectionProperties() { } public ConcreteSectionProperties(IConcreteSection section) : base(section.Profile) { _section = section; } + + public Length EffectiveDepth(SectionFace face) + => Reinforcement.CalculateEffectiveDepth(_section, face); + public Area ReinforcementArea(SectionFace face) + => Reinforcement.CalculateArea(_section, face); } } diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Reinforcement.cs index 3679fd0..e219aa7 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Reinforcement.cs @@ -12,7 +12,7 @@ public static class Reinforcement { private const double PiFactor = Math.PI / 4; - public static OasysUnits.Area CalculateArea(IList rebars) + public static OasysUnits.Area CalculateArea(IEnumerable rebars) { LengthUnit unit = rebars.FirstOrDefault().Rebar.Diameter.Unit; double area = 0; @@ -34,6 +34,67 @@ public static OasysUnits.Area CalculateArea(IRebar rebar) return new OasysUnits.Area(PiFactor * Math.Pow(rebar.Diameter.As(unit), 2), m2.Unit); } + public static OasysUnits.Area CalculateArea(IConcreteSection section, SectionFace face) + { + ILocalPoint2d concreteCentroid = Centroid.CalculateCentroid(section.Profile); + switch (face) + { + case SectionFace.Top: + return CalculateArea(section.Rebars.Where(r => r.Position.Z > concreteCentroid.Z)); + + case SectionFace.Bottom: + return CalculateArea(section.Rebars.Where(r => r.Position.Z < concreteCentroid.Z)); + + case SectionFace.LeftSide: + return CalculateArea(section.Rebars.Where(r => r.Position.Y > concreteCentroid.Y)); + + case SectionFace.RightSide: + return CalculateArea(section.Rebars.Where(r => r.Position.Y > concreteCentroid.Y)); + + default: + throw new NotImplementedException($"Unknown Face type {face}"); + } + } + + public static Length CalculateEffectiveDepth(IConcreteSection section, SectionFace face) + { + ILocalPoint2d concreteCentroid = Centroid.CalculateCentroid(section.Profile); + ILocalDomain2d extends = Extends.GetDomain(section.Profile); + switch (face) + { + case SectionFace.Top: + { + List rebars = GetParts(section.Rebars.Where(r => r.Position.Z > concreteCentroid.Z)); + ILocalPoint2d rebarsCentroid = Centroid.CalculateCentroid(rebars); + return rebarsCentroid.Z - extends.Min.Z; + } + + case SectionFace.Bottom: + { + List rebars = GetParts(section.Rebars.Where(r => r.Position.Z < concreteCentroid.Z)); + ILocalPoint2d rebarsCentroid = Centroid.CalculateCentroid(rebars); + return extends.Max.Z - rebarsCentroid.Z; + } + + case SectionFace.LeftSide: + { + List rebars = GetParts(section.Rebars.Where(r => r.Position.Y > concreteCentroid.Y)); + ILocalPoint2d rebarsCentroid = Centroid.CalculateCentroid(rebars); + return rebarsCentroid.Y - extends.Min.Y; + } + + case SectionFace.RightSide: + { + List rebars = GetParts(section.Rebars.Where(r => r.Position.Y < concreteCentroid.Y)); + ILocalPoint2d rebarsCentroid = Centroid.CalculateCentroid(rebars); + return extends.Max.Y - rebarsCentroid.Y; + } + + default: + throw new NotImplementedException($"Unknown Face type {face}"); + } + } + public static AreaMomentOfInertia CalculateInertiaYy(IConcreteSection section) { ILocalPoint2d concreteCentroid = Centroid.CalculateCentroid(section.Profile); @@ -62,7 +123,7 @@ public static Length CalculateRadiusOfGyrationZz(IConcreteSection section) return RadiusOfGyration.CalculateRadiusOfGyration(area, inertia); } - private static List GetParts(IList rebars) + private static List GetParts(IEnumerable rebars) { var parts = new List(); foreach (ILongitudinalReinforcement rebar in rebars) diff --git a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs index 20da699..d6b88bd 100644 --- a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs +++ b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs @@ -1,5 +1,6 @@ using MagmaWorks.Taxonomy.Sections; using MagmaWorks.Taxonomy.Sections.SectionProperties; +using OasysUnits; using SectionPropertiesTests.TestUtility; namespace SectionPropertiesTests @@ -7,7 +8,7 @@ namespace SectionPropertiesTests public class ConcreteSectionPropertiesTests { [Fact] - public void ReinforcementAreaTest() + public void TotalReinforcementAreaTest() { // Assemble ConcreteSection setion = ConcreteSections.Perimeter(); @@ -18,7 +19,7 @@ public void ReinforcementAreaTest() // Assert double expected = 2 * Math.PI / 4 * Math.Pow(12, 2) + 4 * Math.PI / 4 * Math.Pow(20, 2); - Assert.Equal(expected, props.ReinforcemenArea.SquareMillimeters, 9); + Assert.Equal(expected, props.TotalReinforcemenArea.SquareMillimeters, 9); } [Fact] @@ -65,7 +66,7 @@ public void ShearReinforcementAreaTest() // Assert double expected = 2 * Math.PI / 4 * Math.Pow(10, 2); - Assert.Equal(expected, props.ShearReinforcementArea.SquareMillimeters, 9); + Assert.Equal(expected, props.CrossSectionalShearReinforcementArea.SquareMillimeters, 9); } [Fact] @@ -143,5 +144,47 @@ public void ReinforcementRadiusOfGyrationZzTest() + 4 * Math.PI / 4 * Math.Pow(20, 2); Assert.Equal(Math.Sqrt(expected), props.ReinforcementRadiusOfGyrationZz.Millimeters, 9); } + + [Theory] + [InlineData(750 / 2 + 330, SectionFace.Bottom)] + [InlineData(750 / 2 + 334, SectionFace.Top)] + [InlineData(311.824858898, SectionFace.RightSide)] + [InlineData(311.824858898, SectionFace.LeftSide)] + public void EffectiveDepthTest(double expected, SectionFace face) + { + // Assemble + ConcreteSection setion = ConcreteSections.Rectangle(); + + // Act + var props = new ConcreteSectionProperties(setion); + Length d = props.EffectiveDepth(face); + + // Assert + Assert.Equal(expected, d.Millimeters, 9); + } + + [Theory] + [InlineData(new double[] { 20, 20, 20, 20}, SectionFace.Bottom)] + [InlineData(new double[] { 12, 12 }, SectionFace.Top)] + [InlineData(new double[] { 12, 20, 20 }, SectionFace.RightSide)] + [InlineData(new double[] { 12, 20, 20 }, SectionFace.LeftSide)] + public void ReinforcementAreaTest(double[] expectedDiameters, SectionFace face) + { + // Assemble + ConcreteSection setion = ConcreteSections.Rectangle(); + + // Act + var props = new ConcreteSectionProperties(setion); + Area d = props.ReinforcementArea(face); + + // Assert + double expected = 0; + foreach (double dia in expectedDiameters) + { + expected += Math.PI / 4 * Math.Pow(dia, 2); + } + + Assert.Equal(expected, d.SquareMillimeters, 9); + } } } From 92c649d926257337340f627997aefb1284173eb9 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Fri, 15 Nov 2024 15:43:58 +0000 Subject: [PATCH 20/30] Fix code style issues with dotnet_format --- SectionProperties/ConcreteSectionProperties.cs | 2 +- SectionPropertiesTests/ConcreteSectionPropertiesTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs index 5820646..83c0b78 100644 --- a/SectionProperties/ConcreteSectionProperties.cs +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -36,7 +36,7 @@ public ConcreteSectionProperties(IConcreteSection section) : base(section.Profil public Length EffectiveDepth(SectionFace face) => Reinforcement.CalculateEffectiveDepth(_section, face); - public Area ReinforcementArea(SectionFace face) + public Area ReinforcementArea(SectionFace face) => Reinforcement.CalculateArea(_section, face); } } diff --git a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs index d6b88bd..99dce9a 100644 --- a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs +++ b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs @@ -164,7 +164,7 @@ public void EffectiveDepthTest(double expected, SectionFace face) } [Theory] - [InlineData(new double[] { 20, 20, 20, 20}, SectionFace.Bottom)] + [InlineData(new double[] { 20, 20, 20, 20 }, SectionFace.Bottom)] [InlineData(new double[] { 12, 12 }, SectionFace.Top)] [InlineData(new double[] { 12, 20, 20 }, SectionFace.RightSide)] [InlineData(new double[] { 12, 20, 20 }, SectionFace.LeftSide)] From 3e7ab1d87dc479833600131b33e89f7bee849e75 Mon Sep 17 00:00:00 2001 From: kpne Date: Tue, 26 Nov 2024 09:44:33 +0100 Subject: [PATCH 21/30] Spelling --- ISectionProperties/IConcreteSectionProperties.cs | 2 +- SectionProperties/ConcreteSectionProperties.cs | 9 +++++---- ...ks.Taxonomy.Sections.SectionProperties.csproj | 1 + SectionProperties/SectionProperties.cs | 3 ++- .../ConcreteSectionPropertiesTests.cs | 2 +- SectionPropertiesTests/SectionPropertiesTests.cs | 16 ++++++++-------- .../SectionPropertiesTests.csproj | 1 + 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/ISectionProperties/IConcreteSectionProperties.cs b/ISectionProperties/IConcreteSectionProperties.cs index 2cbee09..196e9b7 100644 --- a/ISectionProperties/IConcreteSectionProperties.cs +++ b/ISectionProperties/IConcreteSectionProperties.cs @@ -4,7 +4,7 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public interface IConcreteSectionProperties : ISectionProperties { - Area TotalReinforcemenArea { get; } + Area TotalReinforcementArea { get; } Area ConcreteArea { get; } Ratio GeometricReinforcementRatio { get; } Area CrossSectionalShearReinforcementArea { get; } diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs index 5820646..b403e67 100644 --- a/SectionProperties/ConcreteSectionProperties.cs +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -1,16 +1,17 @@ using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; +using MagmaWorks.Taxonomy.Serialization; using OasysUnits; using OasysUnits.Units; using Area = OasysUnits.Area; namespace MagmaWorks.Taxonomy.Sections.SectionProperties { - public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties + public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties, ITaxonomySerializable { - public Area TotalReinforcemenArea => _reinforcementArea ??= Reinforcement.CalculateArea(_section.Rebars); - public Area ConcreteArea => base.Area - TotalReinforcemenArea; + public Area TotalReinforcementArea => _reinforcementArea ??= Reinforcement.CalculateArea(_section.Rebars); + public Area ConcreteArea => base.Area - TotalReinforcementArea; public Ratio GeometricReinforcementRatio => - new Ratio(TotalReinforcemenArea.SquareMeters / ConcreteArea.SquareMeters, RatioUnit.DecimalFraction); + new Ratio(TotalReinforcementArea.SquareMeters / ConcreteArea.SquareMeters, RatioUnit.DecimalFraction); public Area CrossSectionalShearReinforcementArea => Reinforcement.CalculateArea(_section.Link) * 2; public AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy => _reinforcementSecondMomentOfAreaYy ??= Reinforcement.CalculateInertiaYy(_section); diff --git a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj index 7f32346..a3d31de 100644 --- a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj +++ b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj @@ -24,6 +24,7 @@ + all diff --git a/SectionProperties/SectionProperties.cs b/SectionProperties/SectionProperties.cs index a60363e..e5401d9 100644 --- a/SectionProperties/SectionProperties.cs +++ b/SectionProperties/SectionProperties.cs @@ -1,10 +1,11 @@ using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; +using MagmaWorks.Taxonomy.Serialization; using OasysUnits; namespace MagmaWorks.Taxonomy.Sections.SectionProperties { - public class SectionProperties : ISectionProperties + public class SectionProperties : ISectionProperties, ITaxonomySerializable { public ILocalPoint2d Centroid => _centroid ??= Utility.Centroid.CalculateCentroid(_profile); diff --git a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs index d6b88bd..7f7b298 100644 --- a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs +++ b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs @@ -19,7 +19,7 @@ public void TotalReinforcementAreaTest() // Assert double expected = 2 * Math.PI / 4 * Math.Pow(12, 2) + 4 * Math.PI / 4 * Math.Pow(20, 2); - Assert.Equal(expected, props.TotalReinforcemenArea.SquareMillimeters, 9); + Assert.Equal(expected, props.TotalReinforcementArea.SquareMillimeters, 9); } [Fact] diff --git a/SectionPropertiesTests/SectionPropertiesTests.cs b/SectionPropertiesTests/SectionPropertiesTests.cs index 705e320..c421be0 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.cs +++ b/SectionPropertiesTests/SectionPropertiesTests.cs @@ -18,14 +18,14 @@ public void ConstructorTest(ISection section) TestObjectsPropertiesAreNotNull(sectionProperties); } - //[Theory] - //[ClassData(typeof(SectionGenerator))] - //public void DeserializeTest(ISection section) - //{ - // ISectionProperties sectionProperties = new SectionProperties(section); - // Assert.NotNull(sectionProperties); - // TestObjectsSurvivesJsonRoundtrip(sectionProperties); - //} + [Theory] + [ClassData(typeof(SectionGenerator))] + public void DeserializeTest(ISection section) + { + ISectionProperties sectionProperties = new SectionProperties(section); + Assert.NotNull(sectionProperties); + TestObjectsSurvivesJsonRoundtrip(sectionProperties); + } public class SectionGenerator : IEnumerable { diff --git a/SectionPropertiesTests/SectionPropertiesTests.csproj b/SectionPropertiesTests/SectionPropertiesTests.csproj index 4e7a026..0e68793 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.csproj +++ b/SectionPropertiesTests/SectionPropertiesTests.csproj @@ -9,6 +9,7 @@ + From 3f680be0f1301f93d8be9702c5d75ec26284beb1 Mon Sep 17 00:00:00 2001 From: kpne Date: Mon, 16 Dec 2024 10:38:05 +0100 Subject: [PATCH 22/30] upgrade references and fix tests --- ...axonomy.Sections.ISectionProperties.csproj | 3 ++- ISectionProperties/SectionFace.cs | 11 ----------- .../ConcreteSectionProperties.cs | 17 ++++++++--------- ...Taxonomy.Sections.SectionProperties.csproj | 8 ++++---- SectionProperties/Utility/PerimeterProfile.cs | 16 ++++++++-------- .../Utility/{Reinforcement.cs => Rebar.cs} | 10 +++++----- .../ConcreteSectionPropertiesTests.cs | 8 ++++---- .../SectionPropertiesTests.cs | 19 ------------------- .../SectionPropertiesTests.csproj | 6 +++--- .../TestUtility/ConcreteSections.cs | 12 ++++++------ .../TestUtility/MockMaterial.cs | 7 +++++-- .../TestUtility/Sections.cs | 15 ++++++++------- 12 files changed, 53 insertions(+), 79 deletions(-) delete mode 100644 ISectionProperties/SectionFace.cs rename SectionProperties/Utility/{Reinforcement.cs => Rebar.cs} (96%) diff --git a/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj b/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj index 6d79130..3f7f286 100644 --- a/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj +++ b/ISectionProperties/MagmaWorks.Taxonomy.Sections.ISectionProperties.csproj @@ -22,7 +22,8 @@ - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ISectionProperties/SectionFace.cs b/ISectionProperties/SectionFace.cs deleted file mode 100644 index 2e98f11..0000000 --- a/ISectionProperties/SectionFace.cs +++ /dev/null @@ -1,11 +0,0 @@ - -namespace MagmaWorks.Taxonomy.Sections.SectionProperties -{ - public enum SectionFace - { - Top, - LeftSide, - RightSide, - Bottom, - } -} diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs index 111c89f..a2dc877 100644 --- a/SectionProperties/ConcreteSectionProperties.cs +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -8,19 +8,19 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties { public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties, ITaxonomySerializable { - public Area TotalReinforcementArea => _reinforcementArea ??= Reinforcement.CalculateArea(_section.Rebars); + public Area TotalReinforcementArea => _reinforcementArea ??= Rebar.CalculateArea(_section.Rebars); public Area ConcreteArea => base.Area - TotalReinforcementArea; public Ratio GeometricReinforcementRatio => new Ratio(TotalReinforcementArea.SquareMeters / ConcreteArea.SquareMeters, RatioUnit.DecimalFraction); - public Area CrossSectionalShearReinforcementArea => Reinforcement.CalculateArea(_section.Link) * 2; + public Area CrossSectionalShearReinforcementArea => Rebar.CalculateArea(_section.Link) * 2; public AreaMomentOfInertia ReinforcementSecondMomentOfAreaYy => - _reinforcementSecondMomentOfAreaYy ??= Reinforcement.CalculateInertiaYy(_section); + _reinforcementSecondMomentOfAreaYy ??= Rebar.CalculateInertiaYy(_section); public AreaMomentOfInertia ReinforcementSecondMomentOfAreaZz => - _reinforcementSecondMomentOfAreaZz ??= Reinforcement.CalculateInertiaZz(_section); + _reinforcementSecondMomentOfAreaZz ??= Rebar.CalculateInertiaZz(_section); public Length ReinforcementRadiusOfGyrationYy => - _reinforcementRadiusOfGyrationYy ??= Reinforcement.CalculateRadiusOfGyrationYy(_section); + _reinforcementRadiusOfGyrationYy ??= Rebar.CalculateRadiusOfGyrationYy(_section); public Length ReinforcementRadiusOfGyrationZz => - _reinforcementRadiusOfGyrationZz ??= Reinforcement.CalculateRadiusOfGyrationZz(_section); + _reinforcementRadiusOfGyrationZz ??= Rebar.CalculateRadiusOfGyrationZz(_section); private Area? _reinforcementArea; private AreaMomentOfInertia? _reinforcementSecondMomentOfAreaYy; @@ -28,7 +28,6 @@ public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProp private Length? _reinforcementRadiusOfGyrationYy; private Length? _reinforcementRadiusOfGyrationZz; private readonly IConcreteSection _section; - private ConcreteSectionProperties() { } public ConcreteSectionProperties(IConcreteSection section) : base(section.Profile) { @@ -36,8 +35,8 @@ public ConcreteSectionProperties(IConcreteSection section) : base(section.Profil } public Length EffectiveDepth(SectionFace face) - => Reinforcement.CalculateEffectiveDepth(_section, face); + => Rebar.CalculateEffectiveDepth(_section, face); public Area ReinforcementArea(SectionFace face) - => Reinforcement.CalculateArea(_section, face); + => Rebar.CalculateArea(_section, face); } } diff --git a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj index a3d31de..ec6d03a 100644 --- a/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj +++ b/SectionProperties/MagmaWorks.Taxonomy.Sections.SectionProperties.csproj @@ -22,10 +22,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SectionProperties/Utility/PerimeterProfile.cs b/SectionProperties/Utility/PerimeterProfile.cs index 168f7bd..24690fe 100644 --- a/SectionProperties/Utility/PerimeterProfile.cs +++ b/SectionProperties/Utility/PerimeterProfile.cs @@ -18,7 +18,7 @@ internal static OasysUnits.Area CalculateArea(IPerimeter perimeter) return area; } - foreach (ILocalPolygon2d hole in perimeter.VoidEdges) + foreach (ILocalPolyline2d hole in perimeter.VoidEdges) { area -= CalculatePartArea(hole.Points); } @@ -37,7 +37,7 @@ internal static ILocalPoint2d CalculateCentroid(IPerimeter perimeter) ILocalPoint2d edgeCentroid = CalculatePartCentroid(perimeter.OuterEdge.Points); Volume qz = edgeArea * edgeCentroid.Y; Volume qy = edgeArea * edgeCentroid.Z; - foreach (ILocalPolygon2d hole in perimeter.VoidEdges) + foreach (ILocalPolyline2d hole in perimeter.VoidEdges) { OasysUnits.Area holeArea = CalculatePartArea(hole.Points); ILocalPoint2d holeCentroid = CalculatePartCentroid(hole.Points); @@ -76,7 +76,7 @@ internal static AreaMomentOfInertia CalculateInertiaYy(IPerimeter perimeter) return inertia; } - foreach (ILocalPolygon2d hole in centredOnElasticCentroid.VoidEdges) + foreach (ILocalPolyline2d hole in centredOnElasticCentroid.VoidEdges) { inertia -= CalculatePartInertiaYy(hole.Points); } @@ -93,7 +93,7 @@ internal static AreaMomentOfInertia CalculateInertiaZz(IPerimeter perimeter) return inertia; } - foreach (ILocalPolygon2d hole in centredOnElasticCentroid.VoidEdges) + foreach (ILocalPolyline2d hole in centredOnElasticCentroid.VoidEdges) { inertia -= CalculatePartInertiaZz(hole.Points); } @@ -163,22 +163,22 @@ internal static IPerimeter MoveToElasticCentroid(IPerimeter perimeter) { outerPoints.Add(Move(pt, translation)); } - ILocalPolygon2d outerEdge = new LocalPolygon2d(outerPoints); + ILocalPolyline2d outerEdge = new LocalPolyline2d(outerPoints); if (perimeter.VoidEdges == null || perimeter.VoidEdges.Count == 0) { return new Perimeter(outerEdge); } - IList voidEdges = new List(); - foreach (ILocalPolygon2d voidEdge in perimeter.VoidEdges) + IList voidEdges = new List(); + foreach (ILocalPolyline2d voidEdge in perimeter.VoidEdges) { IList voidPoints = new List(); foreach (ILocalPoint2d pt in voidEdge.Points) { voidPoints.Add(Move(pt, translation)); } - ILocalPolygon2d translatedVoidEdge = new LocalPolygon2d(voidPoints); + ILocalPolyline2d translatedVoidEdge = new LocalPolyline2d(voidPoints); voidEdges.Add(translatedVoidEdge); } diff --git a/SectionProperties/Utility/Reinforcement.cs b/SectionProperties/Utility/Rebar.cs similarity index 96% rename from SectionProperties/Utility/Reinforcement.cs rename to SectionProperties/Utility/Rebar.cs index e219aa7..503d77c 100644 --- a/SectionProperties/Utility/Reinforcement.cs +++ b/SectionProperties/Utility/Rebar.cs @@ -8,7 +8,7 @@ namespace MagmaWorks.Taxonomy.Sections.SectionProperties.Utility { - public static class Reinforcement + public static class Rebar { private const double PiFactor = Math.PI / 4; @@ -45,10 +45,10 @@ public static OasysUnits.Area CalculateArea(IConcreteSection section, SectionFac case SectionFace.Bottom: return CalculateArea(section.Rebars.Where(r => r.Position.Z < concreteCentroid.Z)); - case SectionFace.LeftSide: + case SectionFace.Left: return CalculateArea(section.Rebars.Where(r => r.Position.Y > concreteCentroid.Y)); - case SectionFace.RightSide: + case SectionFace.Right: return CalculateArea(section.Rebars.Where(r => r.Position.Y > concreteCentroid.Y)); default: @@ -76,14 +76,14 @@ public static Length CalculateEffectiveDepth(IConcreteSection section, SectionFa return extends.Max.Z - rebarsCentroid.Z; } - case SectionFace.LeftSide: + case SectionFace.Left: { List rebars = GetParts(section.Rebars.Where(r => r.Position.Y > concreteCentroid.Y)); ILocalPoint2d rebarsCentroid = Centroid.CalculateCentroid(rebars); return rebarsCentroid.Y - extends.Min.Y; } - case SectionFace.RightSide: + case SectionFace.Right: { List rebars = GetParts(section.Rebars.Where(r => r.Position.Y < concreteCentroid.Y)); ILocalPoint2d rebarsCentroid = Centroid.CalculateCentroid(rebars); diff --git a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs index 7b3a9c0..3856520 100644 --- a/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs +++ b/SectionPropertiesTests/ConcreteSectionPropertiesTests.cs @@ -148,8 +148,8 @@ public void ReinforcementRadiusOfGyrationZzTest() [Theory] [InlineData(750 / 2 + 330, SectionFace.Bottom)] [InlineData(750 / 2 + 334, SectionFace.Top)] - [InlineData(311.824858898, SectionFace.RightSide)] - [InlineData(311.824858898, SectionFace.LeftSide)] + [InlineData(311.824858898, SectionFace.Right)] + [InlineData(311.824858898, SectionFace.Left)] public void EffectiveDepthTest(double expected, SectionFace face) { // Assemble @@ -166,8 +166,8 @@ public void EffectiveDepthTest(double expected, SectionFace face) [Theory] [InlineData(new double[] { 20, 20, 20, 20 }, SectionFace.Bottom)] [InlineData(new double[] { 12, 12 }, SectionFace.Top)] - [InlineData(new double[] { 12, 20, 20 }, SectionFace.RightSide)] - [InlineData(new double[] { 12, 20, 20 }, SectionFace.LeftSide)] + [InlineData(new double[] { 12, 20, 20 }, SectionFace.Right)] + [InlineData(new double[] { 12, 20, 20 }, SectionFace.Left)] public void ReinforcementAreaTest(double[] expectedDiameters, SectionFace face) { // Assemble diff --git a/SectionPropertiesTests/SectionPropertiesTests.cs b/SectionPropertiesTests/SectionPropertiesTests.cs index c421be0..7936793 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.cs +++ b/SectionPropertiesTests/SectionPropertiesTests.cs @@ -18,15 +18,6 @@ public void ConstructorTest(ISection section) TestObjectsPropertiesAreNotNull(sectionProperties); } - [Theory] - [ClassData(typeof(SectionGenerator))] - public void DeserializeTest(ISection section) - { - ISectionProperties sectionProperties = new SectionProperties(section); - Assert.NotNull(sectionProperties); - TestObjectsSurvivesJsonRoundtrip(sectionProperties); - } - public class SectionGenerator : IEnumerable { private readonly List _data = GetAllComponents(); @@ -69,15 +60,5 @@ private void TestObjectsPropertiesAreNotNull(object obj) Assert.NotNull(property.GetValue(obj)); } } - - private void TestObjectsSurvivesJsonRoundtrip(T obj) where T : ISectionProperties - { - string json = obj.ToJson(); - Assert.NotNull(json); - Assert.True(json.Length > 0); - T deserialized = json.FromJson(); - Assert.NotNull(deserialized); - Assert.Equivalent(obj, deserialized); - } } } diff --git a/SectionPropertiesTests/SectionPropertiesTests.csproj b/SectionPropertiesTests/SectionPropertiesTests.csproj index 0e68793..8d870d3 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.csproj +++ b/SectionPropertiesTests/SectionPropertiesTests.csproj @@ -8,9 +8,9 @@ - - - + + + diff --git a/SectionPropertiesTests/TestUtility/ConcreteSections.cs b/SectionPropertiesTests/TestUtility/ConcreteSections.cs index 2e2f10e..f86f398 100644 --- a/SectionPropertiesTests/TestUtility/ConcreteSections.cs +++ b/SectionPropertiesTests/TestUtility/ConcreteSections.cs @@ -12,7 +12,7 @@ internal static class ConcreteSections internal static ConcreteSection Perimeter() { LengthUnit unit = LengthUnit.Millimeter; - IMaterial material = new MockMaterial(); + IMaterial material = new MockMaterial(MaterialType.Concrete); IProfile profile = PerimeterRectangle400x750(); double link = 10; double cover = 25; @@ -26,13 +26,13 @@ internal static ConcreteSection Perimeter() Rebar(20, 200, -375, link, cover), }; - return new ConcreteSection(material, profile, rebars, Bar(link), new Length(cover, unit)); + return new ConcreteSection(profile, material, Bar(link), new Length(cover, unit), rebars); } internal static ConcreteSection Rectangle() { LengthUnit unit = LengthUnit.Millimeter; - IMaterial material = new MockMaterial(); + IMaterial material = new MockMaterial(MaterialType.Concrete); IProfile profile = Rectangle400x750(); double link = 10; double cover = 25; @@ -46,7 +46,7 @@ internal static ConcreteSection Rectangle() Rebar(20, 200, -375, link, cover), }; - return new ConcreteSection(material, profile, rebars, Bar(link), new Length(cover, unit)); + return new ConcreteSection(profile, material, Bar(link), new Length(cover, unit), rebars); } private static LongitudinalReinforcement Rebar(double dia, double edgeY, double edgeZ, double link, double cover) @@ -80,13 +80,13 @@ private static LongitudinalReinforcement Rebar(double dia, double posY, double p private static Rebar Bar(double dia) { Length diameter = new Length(dia, LengthUnit.Millimeter); - return new Rebar(new MockMaterial(), diameter); + return new Rebar(new MockMaterial(MaterialType.Reinforcement), diameter); } private static Perimeter PerimeterRectangle400x750() { LengthUnit unit = LengthUnit.Millimeter; - var solidEdge = new LocalPolygon2d(new List() + var solidEdge = new LocalPolyline2d(new List() { new LocalPoint2d() { Y = new Length(-200, unit), Z = new Length(-375, unit)}, new LocalPoint2d() { Y = new Length(200, unit), Z = new Length(-375, unit)}, diff --git a/SectionPropertiesTests/TestUtility/MockMaterial.cs b/SectionPropertiesTests/TestUtility/MockMaterial.cs index 87a4e29..411c7ff 100644 --- a/SectionPropertiesTests/TestUtility/MockMaterial.cs +++ b/SectionPropertiesTests/TestUtility/MockMaterial.cs @@ -4,8 +4,11 @@ namespace SectionPropertiesTests.TestUtility { internal class MockMaterial : IMaterial { - public MaterialType Type => MaterialType.Generic; + public MaterialType Type { get; set; } - public MockMaterial() { } + public MockMaterial(MaterialType type = MaterialType.Generic) + { + Type = type; + } } } diff --git a/SectionPropertiesTests/TestUtility/Sections.cs b/SectionPropertiesTests/TestUtility/Sections.cs index 7557816..991f204 100644 --- a/SectionPropertiesTests/TestUtility/Sections.cs +++ b/SectionPropertiesTests/TestUtility/Sections.cs @@ -15,6 +15,7 @@ public class MockHEB500 : IIParallelFlange public Length Width => new Length(300, LengthUnit.Millimeter); public Length FlangeThickness => new Length(28, LengthUnit.Millimeter); public Length WebThickness => new Length(14.5, LengthUnit.Millimeter); + public string Description => "HE500B"; public MockHEB500() { } } @@ -216,7 +217,7 @@ public static ISection CreateZ() public static ISection PerimeterVoided() { LengthUnit unit = LengthUnit.Centimeter; - var solidEdge = new LocalPolygon2d(new List() + var solidEdge = new LocalPolyline2d(new List() { new LocalPoint2d() { Y = new Length(-8, unit), Z = new Length(-5, unit)}, new LocalPoint2d() { Y = new Length(-8, unit), Z = new Length(6, unit)}, @@ -224,7 +225,7 @@ public static ISection PerimeterVoided() new LocalPoint2d() { Y = new Length(8, unit), Z = new Length(-5, unit)}, new LocalPoint2d() { Y = new Length(-8, unit), Z = new Length(-5, unit)}, }); - var voidEdge = new LocalPolygon2d(new List() + var voidEdge = new LocalPolyline2d(new List() { new LocalPoint2d() { Y = new Length(-7, unit), Z = new Length(5, unit)}, new LocalPoint2d() { Y = new Length(7, unit), Z = new Length(5, unit)}, @@ -233,14 +234,14 @@ public static ISection PerimeterVoided() new LocalPoint2d() { Y = new Length(-7, unit), Z = new Length(5, unit)}, }); - IPerimeter profile = new Perimeter(solidEdge, new List() { voidEdge }); + IPerimeter profile = new Perimeter(solidEdge, new List() { voidEdge }); return MockSection(profile); } public static ISection Perimeter() { LengthUnit unit = LengthUnit.Millimeter; - var solidEdge = new LocalPolygon2d(new List() + var solidEdge = new LocalPolyline2d(new List() { new LocalPoint2d() { Y = new Length(-650, unit), Z = new Length(200, unit)}, new LocalPoint2d() { Y = new Length(650, unit), Z = new Length(200, unit)}, @@ -262,7 +263,7 @@ public static ISection Perimeter() public static ISection CreateRectangleShaped() { LengthUnit unit = LengthUnit.Millimeter; - var solidEdge = new LocalPolygon2d(new List() + var solidEdge = new LocalPolyline2d(new List() { new LocalPoint2d() { Y = new Length(-50, unit), Z = new Length(-250, unit)}, new LocalPoint2d() { Y = new Length(50, unit), Z = new Length(-250, unit)}, @@ -278,7 +279,7 @@ public static ISection CreateRectangleShaped() public static ISection CreateZShaped() { LengthUnit unit = LengthUnit.Meter; - var solidEdge = new LocalPolygon2d(new List() + var solidEdge = new LocalPolyline2d(new List() { new LocalPoint2d() { Y = new Length(0.75, unit), Z = new Length(0, unit)}, new LocalPoint2d() { Y = new Length(2, unit), Z = new Length(0, unit)}, @@ -298,7 +299,7 @@ public static ISection CreateZShaped() private static ISection MockSection(T profile) where T : IProfile { IMaterial material = new MockMaterial(); - return new Section(material, profile); + return new Section(profile, material); } } } From 0ddcd2f06ff2bec60071f5ef3dc551c5aede512e Mon Sep 17 00:00:00 2001 From: kpne Date: Mon, 16 Dec 2024 10:44:58 +0100 Subject: [PATCH 23/30] Remove serialization references --- SectionProperties/ConcreteSectionProperties.cs | 3 +-- SectionProperties/SectionProperties.cs | 3 +-- SectionPropertiesTests/SectionPropertiesTests.cs | 1 - SectionPropertiesTests/SectionPropertiesTests.csproj | 1 - 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/SectionProperties/ConcreteSectionProperties.cs b/SectionProperties/ConcreteSectionProperties.cs index a2dc877..c9b9a26 100644 --- a/SectionProperties/ConcreteSectionProperties.cs +++ b/SectionProperties/ConcreteSectionProperties.cs @@ -1,12 +1,11 @@ using MagmaWorks.Taxonomy.Sections.SectionProperties.Utility; -using MagmaWorks.Taxonomy.Serialization; using OasysUnits; using OasysUnits.Units; using Area = OasysUnits.Area; namespace MagmaWorks.Taxonomy.Sections.SectionProperties { - public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties, ITaxonomySerializable + public class ConcreteSectionProperties : SectionProperties, IConcreteSectionProperties { public Area TotalReinforcementArea => _reinforcementArea ??= Rebar.CalculateArea(_section.Rebars); public Area ConcreteArea => base.Area - TotalReinforcementArea; diff --git a/SectionProperties/SectionProperties.cs b/SectionProperties/SectionProperties.cs index e5401d9..a60363e 100644 --- a/SectionProperties/SectionProperties.cs +++ b/SectionProperties/SectionProperties.cs @@ -1,11 +1,10 @@ using MagmaWorks.Geometry; using MagmaWorks.Taxonomy.Profiles; -using MagmaWorks.Taxonomy.Serialization; using OasysUnits; namespace MagmaWorks.Taxonomy.Sections.SectionProperties { - public class SectionProperties : ISectionProperties, ITaxonomySerializable + public class SectionProperties : ISectionProperties { public ILocalPoint2d Centroid => _centroid ??= Utility.Centroid.CalculateCentroid(_profile); diff --git a/SectionPropertiesTests/SectionPropertiesTests.cs b/SectionPropertiesTests/SectionPropertiesTests.cs index 7936793..1f98c3d 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.cs +++ b/SectionPropertiesTests/SectionPropertiesTests.cs @@ -2,7 +2,6 @@ using System.Reflection; using MagmaWorks.Taxonomy.Sections; using MagmaWorks.Taxonomy.Sections.SectionProperties; -using MagmaWorks.Taxonomy.Serialization.Sections.SectionProperties.Extensions; using SectionPropertiesTests.TestUtility; namespace SectionPropertiesTests diff --git a/SectionPropertiesTests/SectionPropertiesTests.csproj b/SectionPropertiesTests/SectionPropertiesTests.csproj index 8d870d3..d760de6 100644 --- a/SectionPropertiesTests/SectionPropertiesTests.csproj +++ b/SectionPropertiesTests/SectionPropertiesTests.csproj @@ -26,7 +26,6 @@ - From 5d8c6bd78af9de3a5b34ce6f03f809a44d07ef79 Mon Sep 17 00:00:00 2001 From: Kristjan Nielsen Date: Mon, 16 Dec 2024 11:00:05 +0100 Subject: [PATCH 24/30] Update on-pull-request.yml --- .github/workflows/on-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml index fb42253..101e3eb 100644 --- a/.github/workflows/on-pull-request.yml +++ b/.github/workflows/on-pull-request.yml @@ -8,4 +8,4 @@ on: jobs: pr-ci: - uses: magmaworks/actions/.github/workflows/on-pull-request.yml@main + uses: magmaworks/actions/.github/workflows/on-pull-request.yml@codecov From 8f1515e87cf692e9659923d205b47c468d0ec145 Mon Sep 17 00:00:00 2001 From: Kristjan Nielsen Date: Mon, 16 Dec 2024 11:50:51 +0100 Subject: [PATCH 25/30] Update on-pull-request.yml From 3bba33764087599ea1fd9abcf305ac8b8adcb1e9 Mon Sep 17 00:00:00 2001 From: Kristjan Nielsen Date: Mon, 16 Dec 2024 11:55:21 +0100 Subject: [PATCH 26/30] Update on-pull-request.yml From fbbfcf55e5d1eca5574d334c28a4bceb215cbb60 Mon Sep 17 00:00:00 2001 From: Kristjan Nielsen Date: Mon, 16 Dec 2024 12:09:48 +0100 Subject: [PATCH 27/30] Update on-pull-request.yml From 82c59d511f21c21f935b95e77ae132feaf567aed Mon Sep 17 00:00:00 2001 From: Kristjan Nielsen Date: Mon, 16 Dec 2024 12:16:36 +0100 Subject: [PATCH 28/30] Update on-pull-request.yml From 76da9c0d243ae8b4c52c1b737cb0f89eec994fb2 Mon Sep 17 00:00:00 2001 From: Kristjan Nielsen Date: Mon, 16 Dec 2024 12:38:37 +0100 Subject: [PATCH 29/30] Update on-pull-request.yml --- .github/workflows/on-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml index 101e3eb..fb42253 100644 --- a/.github/workflows/on-pull-request.yml +++ b/.github/workflows/on-pull-request.yml @@ -8,4 +8,4 @@ on: jobs: pr-ci: - uses: magmaworks/actions/.github/workflows/on-pull-request.yml@codecov + uses: magmaworks/actions/.github/workflows/on-pull-request.yml@main From b7895192a1caa0084eb5d2c92d53cb0b5654d989 Mon Sep 17 00:00:00 2001 From: kpne Date: Mon, 16 Dec 2024 12:51:29 +0100 Subject: [PATCH 30/30] remove unused constructor --- SectionProperties/SectionProperties.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/SectionProperties/SectionProperties.cs b/SectionProperties/SectionProperties.cs index a60363e..54e0498 100644 --- a/SectionProperties/SectionProperties.cs +++ b/SectionProperties/SectionProperties.cs @@ -37,8 +37,6 @@ public Length RadiusOfGyrationZz private Length? _radiusOfGyrationZz; private IProfile _profile; - internal SectionProperties() { } - public SectionProperties(ISection section) : this(section.Profile) { } public SectionProperties(IProfile profile)