From 807cf0295cc219a8230d5ff409c08e0886bb60d5 Mon Sep 17 00:00:00 2001 From: Maria Glimaker Date: Wed, 29 Apr 2026 11:47:16 +0100 Subject: [PATCH 1/2] Added design result methods --- Structure_Engine/Query/EvaluateResult.cs | 50 ++++++++++++++++ Structure_Engine/Query/FactorOfSafety.cs | 57 +++++++++++++++++++ .../Query/FactorOfSafetyUtilisation.cs | 56 ++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 Structure_Engine/Query/EvaluateResult.cs create mode 100644 Structure_Engine/Query/FactorOfSafety.cs create mode 100644 Structure_Engine/Query/FactorOfSafetyUtilisation.cs diff --git a/Structure_Engine/Query/EvaluateResult.cs b/Structure_Engine/Query/EvaluateResult.cs new file mode 100644 index 000000000..be575e4f6 --- /dev/null +++ b/Structure_Engine/Query/EvaluateResult.cs @@ -0,0 +1,50 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System.ComponentModel; +using BH.oM.Base.Attributes; +using BH.oM.Structure.Results; + +namespace BH.Engine.Structure +{ + public static partial class Query + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("Evaluates the design result by comparing Action and Resistance.")] + [Input("result", "The DesignResult containing Action, Resistance, RequiredFactorOfSafety, and CheckType used to evaluate the design condition.")] + [Output("Evaluation", "Returns \"Pass\" if the design satisfies the check condition, otherwise \"Fail\".")] + public static string EvaluateResult(this DesignResult result) + { + if (result == null || result.FactorOfSafetyUtilisation() == double.NaN) + { + Base.Compute.RecordError("Design result or factor of safety utilisation is null or invalid."); + return null; + } + return result.FactorOfSafetyUtilisation() <= 1.0 ? "Pass" : "Fail"; + } + /***************************************************/ + } +} + diff --git a/Structure_Engine/Query/FactorOfSafety.cs b/Structure_Engine/Query/FactorOfSafety.cs new file mode 100644 index 000000000..43218d4f3 --- /dev/null +++ b/Structure_Engine/Query/FactorOfSafety.cs @@ -0,0 +1,57 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.ComponentModel; +using BH.oM.Base.Attributes; +using BH.oM.Quantities.Attributes; +using BH.oM.Structure.Results; + +namespace BH.Engine.Structure +{ + public static partial class Query + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("The achieved factor of safety, calculated as Resistance divided by Action. A value greater than or equal to RequiredFactorOfSafety indicates a satisfactory design.")] + [Input("result", "DesignResult containing resistance and action.")] + [Output("FactorOfSafety", "The achieved factor of safety.", typeof(Ratio))] + public static double FactorOfSafety(this DesignResult result) + { + if (result == null || result.Resistance == double.NaN || result.Action == double.NaN) + { + Base.Compute.RecordError("Design result information is null or invalid."); + return double.NaN; + } + if (result.Action == 0.0) + { + Base.Compute.RecordError("Action is zero, cannot calculate factor of safety for this design result."); + return double.NaN; + } + return Math.Abs(result.Resistance / result.Action); + } + /***************************************************/ + } +} + diff --git a/Structure_Engine/Query/FactorOfSafetyUtilisation.cs b/Structure_Engine/Query/FactorOfSafetyUtilisation.cs new file mode 100644 index 000000000..495ccd277 --- /dev/null +++ b/Structure_Engine/Query/FactorOfSafetyUtilisation.cs @@ -0,0 +1,56 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System.ComponentModel; +using BH.oM.Base.Attributes; +using BH.oM.Quantities.Attributes; +using BH.oM.Structure.Results; + +namespace BH.Engine.Structure +{ + public static partial class Query + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("The utilisation of the factor of safety, calculated as RequiredFactorOfSafety divided by FactorOfSafety. A value less than or equal to 1.0 indicates a satisfactory design.")] + [Input("result", "DesignResult containing resistance, action and required factor of safety.")] + [Output("FactorOfSafetyUtilization", "The utilisation of the factor of safety.", typeof(Ratio))] + public static double FactorOfSafetyUtilisation(this DesignResult result) + { + if (result == null || result.RequiredFactorOfSafety == double.NaN || result.FactorOfSafety() == double.NaN) + { + Base.Compute.RecordError("Design result information is null or invalid."); + return double.NaN; + } + if (result.FactorOfSafety() == 0.0) + { + Base.Compute.RecordError("Factor of safety is zero, cannot calculate factor of safety utilisation for this design result."); + return double.NaN; + } + return result.RequiredFactorOfSafety / result.FactorOfSafety(); + } + /***************************************************/ + } +} + From 957da0d210e4d11a37ac506f02bf801659857ad9 Mon Sep 17 00:00:00 2001 From: Maria Glimaker Date: Wed, 29 Jul 2026 11:59:18 +0100 Subject: [PATCH 2/2] Added different outputs depending on the design check type --- Structure_Engine/Query/EvaluateResult.cs | 36 ++++++++++++++++--- Structure_Engine/Query/FactorOfSafety.cs | 18 +++++++--- .../Query/FactorOfSafetyUtilisation.cs | 21 +++++++---- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/Structure_Engine/Query/EvaluateResult.cs b/Structure_Engine/Query/EvaluateResult.cs index be575e4f6..9f2811d00 100644 --- a/Structure_Engine/Query/EvaluateResult.cs +++ b/Structure_Engine/Query/EvaluateResult.cs @@ -20,7 +20,9 @@ * along with this code. If not, see . */ +using System; using System.ComponentModel; +using BH.oM.Analytical.Results; using BH.oM.Base.Attributes; using BH.oM.Structure.Results; @@ -32,17 +34,43 @@ public static partial class Query /**** Public Methods ****/ /***************************************************/ - [Description("Evaluates the design result by comparing Action and Resistance.")] + [Description("Evaluates the design result by comparing Action and Resistance according to the specified check type. " + + "Capacity checks use factor of safety utilisation (RequiredFactorOfSafety / FactorOfSafety), " + + "while UpperBound and LowerBound checks verify that the response satisfies the defined limit condition.")] [Input("result", "The DesignResult containing Action, Resistance, RequiredFactorOfSafety, and CheckType used to evaluate the design condition.")] [Output("Evaluation", "Returns \"Pass\" if the design satisfies the check condition, otherwise \"Fail\".")] public static string EvaluateResult(this DesignResult result) { - if (result == null || result.FactorOfSafetyUtilisation() == double.NaN) + if (result == null || double.IsNaN(result.Action) || double.IsNaN(result.Resistance)) { - Base.Compute.RecordError("Design result or factor of safety utilisation is null or invalid."); + Base.Compute.RecordError("Design result is null or contains invalid values."); return null; } - return result.FactorOfSafetyUtilisation() <= 1.0 ? "Pass" : "Fail"; + switch (result.CheckType) + { + case DesignCheckType.Capacity: + { + if (result.FactorOfSafetyUtilisation() == double.NaN) + { + Base.Compute.RecordError("Factor of safety utilisation is null or invalid."); + return null; + } + return result.FactorOfSafetyUtilisation() <= 1.0 ? "Pass" : "Fail"; + } + case DesignCheckType.UpperBound: + { + return result.Action <= result.Resistance ? "Pass" : "Fail"; + } + case DesignCheckType.LowerBound: + { + return result.Action >= result.Resistance ? "Pass" : "Fail"; + } + default: + { + Base.Compute.RecordError("Unknown check type, unable to evaluate result."); + return null; + } + } } /***************************************************/ } diff --git a/Structure_Engine/Query/FactorOfSafety.cs b/Structure_Engine/Query/FactorOfSafety.cs index 43218d4f3..caf822674 100644 --- a/Structure_Engine/Query/FactorOfSafety.cs +++ b/Structure_Engine/Query/FactorOfSafety.cs @@ -39,17 +39,27 @@ public static partial class Query [Output("FactorOfSafety", "The achieved factor of safety.", typeof(Ratio))] public static double FactorOfSafety(this DesignResult result) { - if (result == null || result.Resistance == double.NaN || result.Action == double.NaN) + if (result == null || double.IsNaN(result.Resistance) || double.IsNaN(result.Action)) { Base.Compute.RecordError("Design result information is null or invalid."); return double.NaN; } - if (result.Action == 0.0) + if (result.CheckType == DesignCheckType.Capacity) { - Base.Compute.RecordError("Action is zero, cannot calculate factor of safety for this design result."); + if (result.Action == 0.0) + { + Base.Compute.RecordError("Action is zero, cannot calculate factor of safety for this design result."); + return double.NaN; + } + + return Math.Abs(result.Resistance / result.Action); + } + else + { + Base.Compute.RecordWarning("Factor of safety is only applicable to capacity checks where Action <= Resistance. " + + "This result uses a different check type (UpperBound or LowerBound), for which a safety factor is not defined."); return double.NaN; } - return Math.Abs(result.Resistance / result.Action); } /***************************************************/ } diff --git a/Structure_Engine/Query/FactorOfSafetyUtilisation.cs b/Structure_Engine/Query/FactorOfSafetyUtilisation.cs index 495ccd277..469af4aba 100644 --- a/Structure_Engine/Query/FactorOfSafetyUtilisation.cs +++ b/Structure_Engine/Query/FactorOfSafetyUtilisation.cs @@ -38,17 +38,26 @@ public static partial class Query [Output("FactorOfSafetyUtilization", "The utilisation of the factor of safety.", typeof(Ratio))] public static double FactorOfSafetyUtilisation(this DesignResult result) { - if (result == null || result.RequiredFactorOfSafety == double.NaN || result.FactorOfSafety() == double.NaN) + if (result.CheckType == DesignCheckType.Capacity) { - Base.Compute.RecordError("Design result information is null or invalid."); - return double.NaN; + if (result == null || double.IsNaN(result.RequiredFactorOfSafety) || double.IsNaN(result.FactorOfSafety())) + { + Base.Compute.RecordError("Design result information is null or invalid."); + return double.NaN; + } + if (result.FactorOfSafety() == 0.0) + { + Base.Compute.RecordError("Factor of safety is zero, cannot calculate factor of safety utilisation for this design result."); + return double.NaN; + } + return result.RequiredFactorOfSafety / result.FactorOfSafety(); } - if (result.FactorOfSafety() == 0.0) + else { - Base.Compute.RecordError("Factor of safety is zero, cannot calculate factor of safety utilisation for this design result."); + Base.Compute.RecordWarning("Factor of safety is only applicable to capacity checks where Action <= Resistance. " + + "This result uses a different check type (UpperBound or LowerBound), for which a safety factor utilisation is not defined."); return double.NaN; } - return result.RequiredFactorOfSafety / result.FactorOfSafety(); } /***************************************************/ }