diff --git a/FieldVisualizer/Entities/ColorMaps/IValueColorArray.cs b/FieldVisualizer/Entities/ColorMaps/IValueColorArray.cs new file mode 100644 index 0000000..1bed0b5 --- /dev/null +++ b/FieldVisualizer/Entities/ColorMaps/IValueColorArray.cs @@ -0,0 +1,13 @@ +using System.Windows.Media; + +namespace FieldVisualizer.Entities.ColorMaps +{ + public interface IValueColorArray + { + double AverageValue { get; set; } + Color BottomColor { get; set; } + double BottomValue { get; set; } + Color TopColor { get; set; } + double TopValue { get; set; } + } +} \ No newline at end of file diff --git a/FieldVisualizer/Entities/ColorMaps/IValueColorRange.cs b/FieldVisualizer/Entities/ColorMaps/IValueColorRange.cs index 395993c..85063a2 100644 --- a/FieldVisualizer/Entities/ColorMaps/IValueColorRange.cs +++ b/FieldVisualizer/Entities/ColorMaps/IValueColorRange.cs @@ -11,25 +11,8 @@ namespace FieldVisualizer.Entities.ColorMaps /// Flag of activity /// bool IsActive { get; set; } - /// - /// Minimum value of range - /// - double BottomValue { get; set; } - /// - /// Average value of range - /// - double AverageValue { get; set; } - /// - /// Maximum value of range - /// - double TopValue {get;set;} - /// - /// Color correspondent to minimum value - /// - Color BottomColor { get; set; } - /// - /// Color correspondent to maximum value - /// - Color TopColor { get; set; } + IValueColorArray ExactValues { get; } + IValueColorArray RoundedValues { get; } + } } diff --git a/FieldVisualizer/Entities/ColorMaps/ValueColorArray.cs b/FieldVisualizer/Entities/ColorMaps/ValueColorArray.cs new file mode 100644 index 0000000..66cd001 --- /dev/null +++ b/FieldVisualizer/Entities/ColorMaps/ValueColorArray.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace FieldVisualizer.Entities.ColorMaps +{ + public class ValueColorArray : IValueColorArray + { + /// + /// Minimum value of range + /// + public double BottomValue { get; set; } + /// + /// Average value of range + /// + public double AverageValue { get; set; } + /// + /// Maximum value of range + /// + public double TopValue { get; set; } + /// + /// Color correspondent to minimum value + /// + public Color BottomColor { get; set; } + /// + /// Color correspondent to maximum value + /// + public Color TopColor { get; set; } + } +} diff --git a/FieldVisualizer/Entities/ColorMaps/ValueColorRange.cs b/FieldVisualizer/Entities/ColorMaps/ValueColorRange.cs index 695cca3..6813268 100644 --- a/FieldVisualizer/Entities/ColorMaps/ValueColorRange.cs +++ b/FieldVisualizer/Entities/ColorMaps/ValueColorRange.cs @@ -7,15 +7,10 @@ namespace FieldVisualizer.Entities.ColorMaps { /// public bool IsActive { get; set; } - /// - public double BottomValue { get; set; } - /// - public double AverageValue { get; set; } - /// - public double TopValue { get; set; } - /// - public Color BottomColor { get; set; } - /// - public Color TopColor { get; set; } + + public IValueColorArray ExactValues { get; private set; } = new ValueColorArray(); + + public IValueColorArray RoundedValues { get; private set; } = new ValueColorArray(); + } } diff --git a/FieldVisualizer/Services/ColorServices/ColorOperations.cs b/FieldVisualizer/Services/ColorServices/ColorOperations.cs index 9b3148d..412f247 100644 --- a/FieldVisualizer/Services/ColorServices/ColorOperations.cs +++ b/FieldVisualizer/Services/ColorServices/ColorOperations.cs @@ -1,6 +1,7 @@ using FieldVisualizer.Entities.ColorMaps; using FieldVisualizer.Entities.Values; using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Services; using System; using System.Collections.Generic; using System.Text; @@ -11,6 +12,7 @@ namespace FieldVisualizer.Services.ColorServices public static class ColorOperations { const byte Alpha = 0xff; + static IMathRoundLogic roundLogic = new SmartRoundLogic(); /// /// /// @@ -23,15 +25,18 @@ namespace FieldVisualizer.Services.ColorServices var colorRanges = new List(); foreach (var valueRange in valueRanges) { - IValueColorRange valueColorRange = new ValueColorRange + var valueColorRange = new ValueColorRange { IsActive = true, - BottomValue = valueRange.BottomValue, - AverageValue = (valueRange.BottomValue + valueRange.TopValue) / 2, - TopValue = valueRange.TopValue }; - valueColorRange.BottomColor = GetColorByValue(fullRange, colorMap, valueColorRange.BottomValue); - valueColorRange.TopColor = GetColorByValue(fullRange, colorMap, valueColorRange.TopValue); + valueColorRange.ExactValues.BottomValue = valueRange.BottomValue; + valueColorRange.ExactValues.AverageValue = (valueRange.BottomValue + valueRange.TopValue) / 2; + valueColorRange.ExactValues.TopValue = valueRange.TopValue; + valueColorRange.ExactValues.BottomColor = GetColorByValue(fullRange, colorMap, valueColorRange.ExactValues.BottomValue); + valueColorRange.ExactValues.TopColor = GetColorByValue(fullRange, colorMap, valueColorRange.ExactValues.TopValue); + valueColorRange.RoundedValues.BottomValue = roundLogic.RoundValue(valueColorRange.ExactValues.BottomValue); + valueColorRange.RoundedValues.AverageValue = roundLogic.RoundValue(valueColorRange.ExactValues.AverageValue); + valueColorRange.RoundedValues.TopValue = roundLogic.RoundValue(valueColorRange.ExactValues.TopValue); colorRanges.Add(valueColorRange); } return colorRanges; @@ -85,11 +90,16 @@ namespace FieldVisualizer.Services.ColorServices return map.Colors[^1]; } double colorPerc = 1d / (map.Colors.Count - 1d); // % of each block of color. the last is the "100% Color" - double blockOfColor = valPerc / colorPerc;// the integer part repersents how many block to skip + double blockOfColor = valPerc / colorPerc;// the integer part represents how many block to skip int blockIdx = (int)Math.Truncate(blockOfColor);// Idx of double valPercResidual = valPerc - (blockIdx * colorPerc);//remove the part represented of block double percOfColor = valPercResidual / colorPerc;// % of color of this block that will be filled + //in some cases due to accuracy of double type percent of color may be less than zero + if (percOfColor <= 0d) + { + return map.Colors[blockIdx]; + } Color c = GetColorByColorMap(map, blockIdx, percOfColor); return c; } diff --git a/FieldVisualizer/ViewModels/FieldViewerViewModels/FieldViewerViewModel.cs b/FieldVisualizer/ViewModels/FieldViewerViewModels/FieldViewerViewModel.cs index 540abf1..ca3b3a0 100644 --- a/FieldVisualizer/ViewModels/FieldViewerViewModels/FieldViewerViewModel.cs +++ b/FieldVisualizer/ViewModels/FieldViewerViewModels/FieldViewerViewModel.cs @@ -9,6 +9,7 @@ using FieldVisualizer.Services.ColorServices; using FieldVisualizer.Services.PrimitiveServices; using FieldVisualizer.Services.ValueRanges; using FieldVisualizer.Windows.UserControls; +using StructureHelperCommon.Services; using System; using System.Collections.Generic; using System.ComponentModel; @@ -22,6 +23,7 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels { public class FieldViewerViewModel : ViewModelBase, IDataErrorInfo { + private IMathRoundLogic roundLogic = new SmartRoundLogic() { DigitQuant = 3 }; public ICommand RebuildCommand { get; } public ICommand ZoomInCommand { get; } public ICommand ZoomOutCommand { get; } @@ -159,8 +161,8 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels private ColorMapsTypes _ColorMapType; private IColorMap _ColorMap; private IValueRange valueRange; - private IEnumerable _ValueRanges; - private IEnumerable _ValueColorRanges; + private IEnumerable valueRanges; + private IEnumerable valueColorRanges; private bool setMinValue; private bool setMaxValue; private double crossLineX; @@ -190,7 +192,7 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels if ((PrimitiveSet is null) == false) { ProcessPrimitives(); - Legend.ValueColorRanges = _ValueColorRanges; + Legend.ValueColorRanges = valueColorRanges; Legend.Refresh(); } } @@ -257,14 +259,14 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels { SolidColorBrush brush = new SolidColorBrush(); brush.Color = ColorOperations.GetColorByValue(valueRange, _ColorMap, valuePrimitive.Value); - foreach (var valueRange in _ValueColorRanges) + foreach (var valueRange in valueColorRanges) { - if (valuePrimitive.Value >= valueRange.BottomValue & valuePrimitive.Value <= valueRange.TopValue & (!valueRange.IsActive)) + if (valuePrimitive.Value >= valueRange.ExactValues.BottomValue & valuePrimitive.Value <= valueRange.ExactValues.TopValue & (!valueRange.IsActive)) { brush.Color = Colors.Gray; } } - shape.ToolTip = valuePrimitive.Value; + shape.ToolTip = roundLogic.RoundValue(valuePrimitive.Value); shape.Tag = valuePrimitive; shape.Fill = brush; Canvas.SetLeft(shape, valuePrimitive.CenterX - addX - dX); @@ -301,10 +303,24 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels { UserValueRange.TopValue = UserValueRange.BottomValue; } - if (SetMinValue) { valueRange.BottomValue = UserValueRange.BottomValue; } else { UserValueRange.BottomValue = valueRange.BottomValue; } - if (SetMaxValue) { valueRange.TopValue = UserValueRange.TopValue; } else { UserValueRange.TopValue = valueRange.TopValue; } - _ValueRanges = ValueRangeOperations.DivideValueRange(valueRange, RangeNumber); - _ValueColorRanges = ColorOperations.GetValueColorRanges(valueRange, _ValueRanges, _ColorMap); + if (SetMinValue == true) + { + valueRange.BottomValue = UserValueRange.BottomValue; + } + else + { + UserValueRange.BottomValue = valueRange.BottomValue; + } + if (SetMaxValue == true) + { + valueRange.TopValue = UserValueRange.TopValue; + } + else + { + UserValueRange.TopValue = valueRange.TopValue; + } + valueRanges = ValueRangeOperations.DivideValueRange(valueRange, RangeNumber); + valueColorRanges = ColorOperations.GetValueColorRanges(valueRange, valueRanges, _ColorMap); } private void SetCrossLine(object commandParameter) { diff --git a/FieldVisualizer/Windows/UserControls/VerticalLegend.xaml b/FieldVisualizer/Windows/UserControls/VerticalLegend.xaml index 5116791..58c8315 100644 --- a/FieldVisualizer/Windows/UserControls/VerticalLegend.xaml +++ b/FieldVisualizer/Windows/UserControls/VerticalLegend.xaml @@ -20,23 +20,23 @@ - + - + - - + + - - + + - + diff --git a/FieldVisualizer/Windows/WndFieldViewer.xaml b/FieldVisualizer/Windows/WndFieldViewer.xaml index 7362c15..7a290d6 100644 --- a/FieldVisualizer/Windows/WndFieldViewer.xaml +++ b/FieldVisualizer/Windows/WndFieldViewer.xaml @@ -6,7 +6,7 @@ xmlns:FieldViewerControl="clr-namespace:FieldVisualizer.Windows.UserControls" xmlns:local="clr-namespace:FieldVisualizer.Windows" mc:Ignorable="d" - Title="FieldViewer" Height="800" Width="1200" WindowStartupLocation="CenterOwner"> + Title="FieldViewer" Height="800" Width="1200" MinHeight="400" MinWidth="800" MaxHeight="1000" MaxWidth="1500" WindowStartupLocation="CenterScreen" ShowInTaskbar="False"> diff --git a/StructureHelper/App.xaml b/StructureHelper/App.xaml index 04fc9ba..70db8cc 100644 --- a/StructureHelper/App.xaml +++ b/StructureHelper/App.xaml @@ -19,6 +19,7 @@ + diff --git a/StructureHelper/Infrastructure/Enums/CalculatorTypes.cs b/StructureHelper/Infrastructure/Enums/CalculatorTypes.cs index 8383ce8..fd4e157 100644 --- a/StructureHelper/Infrastructure/Enums/CalculatorTypes.cs +++ b/StructureHelper/Infrastructure/Enums/CalculatorTypes.cs @@ -10,6 +10,7 @@ namespace StructureHelper.Infrastructure.Enums { ForceCalculator, LimitCurveCalculator, + CrackCalculator, FireCalculator } } diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/Area.cs b/StructureHelper/Infrastructure/UI/Converters/Units/Area.cs index 383fb7f..74a112d 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/Area.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/Area.cs @@ -14,7 +14,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units internal class Area : UnitBase { public override UnitTypes UnitType { get => UnitTypes.Area; } - public override IUnit CurrentUnit { get => CommonOperation.GetUnit(UnitType, "mm2"); } + public override IUnit CurrentUnit { get => UnitLogic.GetUnit(UnitType, "mm2"); } public override string UnitName { get => "Area"; } } } diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/CrackWidth.cs b/StructureHelper/Infrastructure/UI/Converters/Units/CrackWidth.cs new file mode 100644 index 0000000..e520311 --- /dev/null +++ b/StructureHelper/Infrastructure/UI/Converters/Units/CrackWidth.cs @@ -0,0 +1,28 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Services; +using StructureHelperCommon.Services.Units; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelper.Infrastructure.UI.Converters.Units +{ + internal class CrackWidth : UnitBase + { + public CrackWidth() + { + OperationLogic = new ConvertUnitLogic() + { + MathRoundLogic = new FixedRoundLogic() + { + DigitQuant = 3 + } + }; + } + public override UnitTypes UnitType { get => UnitTypes.Length; } + public override IUnit CurrentUnit { get => UnitLogic.GetUnit(UnitType, "mm"); } + public override string UnitName { get => "Length"; } + } +} diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/Curvature.cs b/StructureHelper/Infrastructure/UI/Converters/Units/Curvature.cs index ec5a34b..1a34053 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/Curvature.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/Curvature.cs @@ -11,7 +11,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units internal class Curvature : UnitBase { public override UnitTypes UnitType { get => UnitTypes.Curvature; } - public override IUnit CurrentUnit { get => CommonOperation.GetUnit(UnitType, "1/mm"); } + public override IUnit CurrentUnit { get => UnitLogic.GetUnit(UnitType, "1/mm"); } public override string UnitName { get => "Curvature"; } } } diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/Force.cs b/StructureHelper/Infrastructure/UI/Converters/Units/Force.cs index 408660d..941f47d 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/Force.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/Force.cs @@ -13,7 +13,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units internal class Force : UnitBase { public override UnitTypes UnitType { get => UnitTypes.Force; } - public override IUnit CurrentUnit { get => CommonOperation.GetUnit(UnitType, "kN"); } + public override IUnit CurrentUnit { get => UnitLogic.GetUnit(UnitType, "kN"); } public override string UnitName { get => "Force"; } } } diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/Length.cs b/StructureHelper/Infrastructure/UI/Converters/Units/Length.cs index 5cac7d1..e4a01e1 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/Length.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/Length.cs @@ -5,8 +5,9 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units { internal class Length : UnitBase { + public override UnitTypes UnitType { get => UnitTypes.Length; } - public override IUnit CurrentUnit { get => CommonOperation.GetUnit(UnitType, "mm"); } + public override IUnit CurrentUnit { get => UnitLogic.GetUnit(UnitType, "mm"); } public override string UnitName { get => "Length"; } } } diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/Moment.cs b/StructureHelper/Infrastructure/UI/Converters/Units/Moment.cs index 76f8d6d..f260d7a 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/Moment.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/Moment.cs @@ -11,7 +11,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units internal class Moment : UnitBase { public override UnitTypes UnitType { get => UnitTypes.Moment; } - public override IUnit CurrentUnit { get => CommonOperation.GetUnit(UnitType, "kNm"); } + public override IUnit CurrentUnit { get => UnitLogic.GetUnit(UnitType, "kNm"); } public override string UnitName { get => "Moment"; } } } diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/PlainDouble.cs b/StructureHelper/Infrastructure/UI/Converters/Units/PlainDouble.cs index e4958d1..48cd0ac 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/PlainDouble.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/PlainDouble.cs @@ -12,6 +12,8 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units { internal class PlainDouble : IValueConverter { + IConvertUnitLogic operationLogic = new ConvertUnitLogic(); + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { try @@ -28,7 +30,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units { try { - return CommonOperation.ConvertToDoubleChangeComma((string)value); + return ProcessString.ConvertCommaToCultureSettings((string)value); } catch (Exception) { diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/Stress.cs b/StructureHelper/Infrastructure/UI/Converters/Units/Stress.cs index eec20ab..f07de25 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/Stress.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/Stress.cs @@ -1,4 +1,5 @@ using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Services; using StructureHelperCommon.Services.Units; using System; using System.Collections.Generic; @@ -12,8 +13,19 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units { internal class Stress : UnitBase { + public override UnitTypes UnitType { get => UnitTypes.Stress; } - public override IUnit CurrentUnit { get => CommonOperation.GetUnit(UnitType, "MPa"); } + public override IUnit CurrentUnit { get => UnitLogic.GetUnit(UnitType, "MPa"); } public override string UnitName { get => "Stress"; } + public Stress() + { + OperationLogic = new ConvertUnitLogic() + { + MathRoundLogic = new SmartRoundLogic() + { + DigitQuant = 3 + } + }; + } } } diff --git a/StructureHelper/Infrastructure/UI/Converters/Units/UnitBase.cs b/StructureHelper/Infrastructure/UI/Converters/Units/UnitBase.cs index ef778b0..4955cf1 100644 --- a/StructureHelper/Infrastructure/UI/Converters/Units/UnitBase.cs +++ b/StructureHelper/Infrastructure/UI/Converters/Units/UnitBase.cs @@ -1,4 +1,7 @@ using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Parameters; +using StructureHelperCommon.Services; using StructureHelperCommon.Services.Units; using System; using System.Collections.Generic; @@ -14,19 +17,61 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units { internal abstract class UnitBase : IValueConverter { + IMathRoundLogic roundLogic = new DirectRoundLogic(); + public IConvertUnitLogic OperationLogic { get; set; } = new ConvertUnitLogic(); + public IGetUnitLogic UnitLogic { get; set; } = new GetUnitLogic(); public abstract UnitTypes UnitType { get; } public abstract IUnit CurrentUnit { get; } public abstract string UnitName { get;} + /// + /// From variable to user + /// + /// + /// + /// + /// + /// public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - return CommonOperation.Convert(CurrentUnit, UnitName, value); + var pair = OperationLogic.Convert(CurrentUnit, UnitName, value); + var result = pair.Value; + if (parameter is not null) + { + if (parameter is string paramString) + { + var logic = new ProcessDoublePairLogic() { DigitPlace = DigitPlace.Any }; + var paramPair = logic.GetValuePairByString(paramString); + string paramTextPart = paramPair.Text.ToLower(); + int paramValuePart = (int)paramPair.Value; + if (paramTextPart == "smart") + { + roundLogic = new SmartRoundLogic() { DigitQuant = paramValuePart }; + } + else if (paramTextPart == "fixed") + { + roundLogic = new FixedRoundLogic() { DigitQuant = paramValuePart }; + } + result = roundLogic.RoundValue(result); + } + } + string strValue = $"{result} {pair.Text}"; + return strValue; } - + /// + /// From user to variable + /// + /// + /// + /// + /// + /// public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { try { - return CommonOperation.ConvertBack(UnitType, CurrentUnit, value); + double result = OperationLogic.ConvertBack(UnitType, CurrentUnit, value); + + return result; } catch (Exception) { diff --git a/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml b/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml index deaeb92..7e48c6e 100644 --- a/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml +++ b/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml @@ -1,8 +1,8 @@  - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml.cs new file mode 100644 index 0000000..1bd09b0 --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml.cs @@ -0,0 +1,36 @@ +using StructureHelperLogics.NdmCalculations.Cracking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews +{ + /// + /// Логика взаимодействия для CrackResultView.xaml + /// + public partial class CrackResultView : Window + { + private readonly CrackResultViewModel viewModel; + + public CrackResultView(CrackResultViewModel viewModel) + { + this.viewModel = viewModel; + InitializeComponent(); + this.DataContext = this.viewModel; + } + public CrackResultView(CrackResult result) : this(new CrackResultViewModel(result)) + { + + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultViewModel.cs new file mode 100644 index 0000000..9682c08 --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultViewModel.cs @@ -0,0 +1,51 @@ +using StructureHelper.Infrastructure; +using StructureHelperLogics.NdmCalculations.Cracking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews +{ + public class CrackResultViewModel : ViewModelBase + { + IShowCrackIsoFieldsLogic showCrackIsoFieldsLogic => new ShowCrackIsoFieldsLogic(); + private CrackResult crackResult; + private RelayCommand? showIsoFieldCommand; + private RelayCommand? showRebarsCommand; + + public TupleCrackResult SelectedResult { get; set; } + public List TupleResults => CrackResult.TupleResults; + public ICommand ShowRebarsCommand + { + get + { + return showRebarsCommand ??= new RelayCommand(o => + { + var wnd = new TupleCrackResultView(SelectedResult); + wnd.ShowDialog(); + }, o => SelectedResult != null && SelectedResult.IsValid); + } + } + + public ICommand ShowIsoFieldCommand + { + get + { + return showIsoFieldCommand ??= new RelayCommand(o => + { + showCrackIsoFieldsLogic.ShowIsoField(SelectedResult.RebarResults); + }, o => SelectedResult != null && SelectedResult.IsValid); + } + } + + public CrackResult CrackResult => crackResult; + + public CrackResultViewModel(CrackResult crackResult) + { + this.crackResult = crackResult; + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/Cracks.xaml b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/Cracks.xaml new file mode 100644 index 0000000..0064bfd --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/Cracks.xaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/IShowCrackIsoFieldsLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/IShowCrackIsoFieldsLogic.cs new file mode 100644 index 0000000..0377302 --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/IShowCrackIsoFieldsLogic.cs @@ -0,0 +1,10 @@ +using StructureHelperLogics.NdmCalculations.Cracking; +using System.Collections.Generic; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews +{ + public interface IShowCrackIsoFieldsLogic + { + void ShowIsoField(IEnumerable rebarResults); + } +} \ No newline at end of file diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/ShowCrackIsoFieldsLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/ShowCrackIsoFieldsLogic.cs new file mode 100644 index 0000000..deef0fe --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/ShowCrackIsoFieldsLogic.cs @@ -0,0 +1,37 @@ +using StructureHelper.Services.Reports.CalculationReports; +using StructureHelper.Services.ResultViewers; +using StructureHelper.Windows.Errors; +using StructureHelper.Windows.ViewModels.Errors; +using StructureHelperLogics.NdmCalculations.Cracking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews +{ + public class ShowCrackIsoFieldsLogic : IShowCrackIsoFieldsLogic + { + private IsoFieldReport isoFieldReport; + + public void ShowIsoField(IEnumerable rebarResults) + { + try + { + var primitiveSets = ShowIsoFieldResult.GetPrimitiveSets(rebarResults, CrackResultFuncFactory.GetResultFuncs()); + isoFieldReport = new IsoFieldReport(primitiveSets); + isoFieldReport.Show(); + } + catch (Exception ex) + { + var vm = new ErrorProcessor() + { + ShortText = "Errors apearred during showing isofield, see detailed information", + DetailText = $"{ex}" + }; + new ErrorMessage(vm).ShowDialog(); + } + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml new file mode 100644 index 0000000..94b8a54 --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml.cs new file mode 100644 index 0000000..042665c --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml.cs @@ -0,0 +1,35 @@ +using StructureHelperLogics.NdmCalculations.Cracking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews +{ + /// + /// Логика взаимодействия для TupleCrackResultView.xaml + /// + public partial class TupleCrackResultView : Window + { + TupleCrackResultViewModel viewModel; + public TupleCrackResultView(TupleCrackResultViewModel viewModel) + { + InitializeComponent(); + this.viewModel = viewModel; + DataContext = this.viewModel; + } + public TupleCrackResultView(TupleCrackResult crackResult) : this(new TupleCrackResultViewModel(crackResult)) + { + + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultViewModel.cs new file mode 100644 index 0000000..8f5d5d5 --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultViewModel.cs @@ -0,0 +1,46 @@ +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using StructureHelper.Infrastructure; +using StructureHelper.Services.Reports.CalculationReports; +using StructureHelper.Services.ResultViewers; +using StructureHelper.Windows.Errors; +using StructureHelper.Windows.ViewModels.Errors; +using StructureHelperLogics.NdmCalculations.Cracking; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews +{ + public class TupleCrackResultViewModel : ViewModelBase + { + IShowCrackIsoFieldsLogic showCrackIsoFieldsLogic => new ShowCrackIsoFieldsLogic(); + private TupleCrackResult crackResult; + private RelayCommand showIsoFieldCommand; + private IsoFieldReport isoFieldReport; + + public TupleCrackResult CrackResult => crackResult; + public List RebarResults => crackResult.RebarResults; + public RebarCrackResult SelectedResult { get; set; } + public string WindowTitle => "Result of calculation of cracks for action " + crackResult.InputData.TupleName; + public ICommand ShowIsoFieldCommand + { + get + { + return showIsoFieldCommand ??= new RelayCommand(o => + { + showCrackIsoFieldsLogic.ShowIsoField(crackResult.RebarResults); + }); + } + } + public TupleCrackResultViewModel(TupleCrackResult crackResult) + { + this.crackResult = crackResult; + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/DiagramFactory.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/DiagramFactory.cs new file mode 100644 index 0000000..2b74dd7 --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/DiagramFactory.cs @@ -0,0 +1,68 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Parameters; +using StructureHelperCommon.Services.Units; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews +{ + /// + /// Create array of common values + /// + public class DiagramFactory + { + IConvertUnitLogic operationLogic = new ConvertUnitLogic(); + IGetUnitLogic unitLogic = new GetUnitLogic(); + private ArrayParameter arrayParameter; + /// + /// Collection of force results + /// + public List TupleList { get; set; } + + //public Action SetProgress { get; set; } + + public ArrayParameter GetCommonArray() + { + var labels = LabelsFactory.GetCommonLabels(); + arrayParameter = new ArrayParameter(TupleList.Count(), labels); + Calculate(); + return arrayParameter; + } + + private void Calculate() + { + var data = arrayParameter.Data; + for (int i = 0; i < TupleList.Count(); i++) + { + var valueList = ProcessResult(i); + for (int j = 0; j < valueList.Count; j++) + { + data[i, j] = valueList[j]; + } + //SetProgress?.Invoke(i); + } + } + + + private List ProcessResult(int i) + { + var unitForce = unitLogic.GetUnit(UnitTypes.Force); + var unitMoment = unitLogic.GetUnit(UnitTypes.Moment); + var unitCurvature = unitLogic.GetUnit(UnitTypes.Curvature); + + return new List + { + TupleList[i].DesignForceTuple.ForceTuple.Mx * unitMoment.Multiplyer, + TupleList[i].DesignForceTuple.ForceTuple.My * unitMoment.Multiplyer, + TupleList[i].DesignForceTuple.ForceTuple.Nz * unitForce.Multiplyer, + TupleList[i].LoaderResults.ForceStrainPair.StrainMatrix.Kx * unitCurvature.Multiplyer, + TupleList[i].LoaderResults.ForceStrainPair.StrainMatrix.Ky * unitCurvature.Multiplyer, + TupleList[i].LoaderResults.ForceStrainPair.StrainMatrix.EpsZ + }; + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/IValuePointDiagramLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/IValuePointDiagramLogic.cs new file mode 100644 index 0000000..a4919bf --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/IValuePointDiagramLogic.cs @@ -0,0 +1,18 @@ +using StructureHelper.Windows.Forces; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Parameters; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using System.Collections.Generic; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews.ForceResultLogic +{ + public interface IValuePointDiagramLogic + { + ForceCalculator Calculator { get; set; } + PointPrimitiveLogic PrimitiveLogic { get; set; } + IEnumerable TupleList { get; set; } + ValueDelegatesLogic ValueDelegatesLogic { get; set; } + + GenericResult> GetArrayParameter(); + } +} \ No newline at end of file diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs index 2a5f059..625265f 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs @@ -25,10 +25,12 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu const string ForceUnitString = "kN"; const string MomentUnitString = "kNm"; + IConvertUnitLogic operationLogic; + //private List> arrayParameters; private IResult result; - private IUnit unitForce = CommonOperation.GetUnit(UnitTypes.Force, ForceUnitString); - private IUnit unitMoment = CommonOperation.GetUnit(UnitTypes.Moment, MomentUnitString); + private IUnit unitForce; + private IUnit unitMoment; private int stepCount; private static GeometryNames GeometryNames => ProgramSetting.GeometryNames; @@ -48,7 +50,11 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu stepCount *= InputData.CalcTerms.Count(); stepCount *= InputData.PredicateEntries.Count(); //arrayParameters = new(); - } + operationLogic = new ConvertUnitLogic(); + IGetUnitLogic unitLogic = new GetUnitLogic(); + unitForce = unitLogic.GetUnit(UnitTypes.Force, ForceUnitString); + unitMoment = unitLogic.GetUnit(UnitTypes.Moment, MomentUnitString); + } private void DoCalculations() { diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InterpolateValuePointsLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InterpolateValuePointsLogic.cs new file mode 100644 index 0000000..fc1d066 --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InterpolateValuePointsLogic.cs @@ -0,0 +1,86 @@ +using StructureHelper.Windows.Forces; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Forces; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using StructureHelper.Infrastructure.UI.DataContexts; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Calculators; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews.ForceResultLogic +{ + public class InterpolateValuePointsLogic + { + private InterpolationProgressLogic interpolationLogic; + private ValuePointsInterpolateViewModel viewModel; + private IResult result; + private ValuePointsInterpolationInputData inputData; + public ForcesTupleResult SelectedResult { get; set; } + public IEnumerable NdmPrimitives { get; set; } + public ForceCalculator ForceCalculator { get; set; } + + + public ILongProcessLogic ProgressLogic { get; set; } + public ShowProgressLogic ShowProgressLogic { get; set; } + + public void InterpolateValuePoints() + { + var tuple = SelectedResult.DesignForceTuple ?? throw new StructureHelperException(ErrorStrings.NullReference + ": Design force combination"); + PrepareInputData(tuple); + viewModel = new ValuePointsInterpolateViewModel(inputData); + if (ShowDialog() == false) { return; }; + ShowDiagram(result); + } + + private void PrepareInputData(IDesignForceTuple tuple) + { + inputData = new ValuePointsInterpolationInputData() + { + FinishDesignForce = tuple.Clone() as IDesignForceTuple, + LimitState = tuple.LimitState, + CalcTerm = tuple.CalcTerm, + }; + inputData.PrimitiveBases.AddRange(PrimitiveOperations.ConvertNdmPrimitivesToPrimitiveBase(NdmPrimitives)); + } + + private bool ShowDialog() + { + var wnd = new ValuePointsInterpolateView(viewModel); + wnd.ShowDialog(); + if (wnd.DialogResult != true) { return false; } + interpolationLogic = new InterpolationProgressLogic(ForceCalculator, viewModel.ForceInterpolationViewModel.Result); + ProgressLogic = interpolationLogic; + ShowProgressLogic = new(interpolationLogic) + { + WindowTitle = "Interpolate forces", + }; + ShowProgressLogic.Show(); + result = interpolationLogic.InterpolateCalculator.Result; + return true; + } + + private void ShowDiagram(IResult result) + { + if (result.IsValid == false) { return; } + if (result is not IForcesResults) + { + throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(IForcesResults), result)); + } + var tupleResult = result as IForcesResults; + var pointGraphLogic = new ShowValuePointDiagramLogic() + { + Calculator = interpolationLogic.InterpolateCalculator, + PrimitiveLogic = viewModel.PrimitiveLogic, + ValueDelegatesLogic = viewModel.ValueDelegatesLogic, + TupleList = tupleResult.ForcesResultList + }; + pointGraphLogic.ShowWindow(); + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LabelsFactory.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LabelsFactory.cs index db6552e..47f58ca 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LabelsFactory.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LabelsFactory.cs @@ -11,9 +11,11 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews { public static class LabelsFactory { - private static IUnit unitForce = CommonOperation.GetUnit(UnitTypes.Force); - private static IUnit unitMoment = CommonOperation.GetUnit(UnitTypes.Moment); - private static IUnit unitCurvature = CommonOperation.GetUnit(UnitTypes.Curvature); + static IConvertUnitLogic operationLogic = new ConvertUnitLogic(); + static IGetUnitLogic unitLogic = new GetUnitLogic(); + private static IUnit unitForce = unitLogic.GetUnit(UnitTypes.Force); + private static IUnit unitMoment = unitLogic.GetUnit(UnitTypes.Moment); + private static IUnit unitCurvature = unitLogic.GetUnit(UnitTypes.Curvature); private static GeometryNames GeometryNames => ProgramSetting.GeometryNames; public static List GetCommonLabels() { diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackResultLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackResultLogic.cs index 04445c5..f03902b 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackResultLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackResultLogic.cs @@ -18,6 +18,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu internal class ShowCrackResultLogic { private CrackForceCalculator calculator; + private ITriangulatePrimitiveLogic triangulateLogic; public static GeometryNames GeometryNames => ProgramSetting.GeometryNames; public LimitStates LimitState { get; set; } @@ -42,7 +43,13 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu calculator.TraceLogger = new ShiftTraceLogger(); calculator.StartTuple = startDesignTuple; calculator.EndTuple = finishDesignTuple; - calculator.NdmCollection = NdmPrimitivesService.GetNdms(ndmPrimitives, LimitState, CalcTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = ndmPrimitives, + LimitState = LimitState, + CalcTerm = CalcTerm + }; + calculator.NdmCollection = triangulateLogic.GetNdms(); calculator.Run(); var result = (CrackForceResult)calculator.Result; if (result.IsValid) diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs index 4410f59..54eccf4 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs @@ -19,14 +19,14 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu internal void Show() { - var inputData = new CrackWidthCalculatorInputData() + var inputData = new TupleCrackInputData() { - LimitState = LimitState, - CalcTerm = CalcTerm, - ForceTuple = ForceTuple, - NdmPrimitives = ndmPrimitives + //LimitState = LimitState, + //CalcTerm = CalcTerm, + LongTermTuple = ForceTuple, + Primitives = ndmPrimitives }; - var calculator = new CrackWidthCalculator() { InputData = inputData }; + var calculator = new TupleCrackCalculator() { InputData = inputData }; calculator.Run(); var result = calculator.Result; diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowDiagramLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowDiagramLogic.cs index 8e42820..033e827 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowDiagramLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowDiagramLogic.cs @@ -58,9 +58,12 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu { validTupleList = tupleList.Where(x => x.IsValid == true).ToList(); - var labels = LabelsFactory.GetCommonLabels(); - arrayParameter = new ArrayParameter(validTupleList.Count(), labels); - Calculate(); + var factory = new DiagramFactory() + { + TupleList = validTupleList, + //SetProgress = SetProgress, + }; + arrayParameter = factory.GetCommonArray(); } public ShowDiagramLogic(IEnumerable tupleList, IEnumerable ndmPrimitives) @@ -69,37 +72,5 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu this.ndmPrimitives = ndmPrimitives; validTupleList = tupleList.Where(x => x.IsValid == true).ToList(); } - - private void Calculate() - { - var data = arrayParameter.Data; - for (int i = 0; i < validTupleList.Count(); i++) - { - var valueList = ProcessResult(i); - for (int j = 0; j < valueList.Count; j++) - { - data[i, j] = valueList[j]; - } - SetProgress?.Invoke(i); - } - } - - - private List ProcessResult(int i) - { - var unitForce = CommonOperation.GetUnit(UnitTypes.Force); - var unitMoment = CommonOperation.GetUnit(UnitTypes.Moment); - var unitCurvature = CommonOperation.GetUnit(UnitTypes.Curvature); - - return new List - { - validTupleList[i].DesignForceTuple.ForceTuple.Mx * unitMoment.Multiplyer, - validTupleList[i].DesignForceTuple.ForceTuple.My * unitMoment.Multiplyer, - validTupleList[i].DesignForceTuple.ForceTuple.Nz * unitForce.Multiplyer, - validTupleList[i].LoaderResults.ForceStrainPair.StrainMatrix.Kx * unitCurvature.Multiplyer, - validTupleList[i].LoaderResults.ForceStrainPair.StrainMatrix.Ky * unitCurvature.Multiplyer, - validTupleList[i].LoaderResults.ForceStrainPair.StrainMatrix.EpsZ - }; - } } } diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowProgressLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowProgressLogic.cs index ecf5414..23c4e20 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowProgressLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowProgressLogic.cs @@ -1,4 +1,5 @@ using StructureHelper.Windows.CalculationWindows.ProgressViews; +using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; @@ -11,7 +12,7 @@ using System.Windows.Forms; namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews { - internal class ShowProgressLogic + public class ShowProgressLogic { private ShowProgressViewModel progressViewModel; private ShowProgressView wndProgress; @@ -82,8 +83,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu } catch (Exception ex) { - - throw; + throw new StructureHelperException(ex); } } } diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowValuePointDiagramLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowValuePointDiagramLogic.cs index f527fcc..abcc47d 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowValuePointDiagramLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowValuePointDiagramLogic.cs @@ -1,11 +1,17 @@ -using StructureHelper.Infrastructure.UI.DataContexts; +using LoaderCalculator.Data.Materials.MaterialBuilders; +using LoaderCalculator.Data.Ndms; +using StructureHelper.Infrastructure.UI.DataContexts; using StructureHelper.Services.ResultViewers; +using StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews.ForceResultLogic; using StructureHelper.Windows.Forces; using StructureHelper.Windows.Graphs; using StructureHelper.Windows.ViewModels.Errors; +using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Models.Parameters; using StructureHelperCommon.Models.Shapes; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; @@ -17,45 +23,43 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews { - public class ShowValuePointDiagramLogic : ILongProcessLogic + public class ShowValuePointDiagramLogic //: ILongProcessLogic { private ArrayParameter arrayParameter; - private IEnumerable tupleList; - private IEnumerable ndmPrimitives; - private List validTupleList; - private List<(PrimitiveBase PrimitiveBase, List>)> valuePoints; - private List resultFuncList; + private IValuePointDiagramLogic pointDiagramLogic; + public IEnumerable TupleList { get; set; } public ForceCalculator Calculator { get; set; } public PointPrimitiveLogic PrimitiveLogic { get; set; } public ValueDelegatesLogic ValueDelegatesLogic { get; set; } - public int StepCount => throw new NotImplementedException(); + //public int StepCount => throw new NotImplementedException(); - public Action SetProgress { get; set; } - public bool Result { get; set; } - public IShiftTraceLogger? TraceLogger { get; set; } - public ShowValuePointDiagramLogic(IEnumerable tupleList, IEnumerable ndmPrimitives) + //public Action SetProgress { get; set; } + //public bool Result { get; set; } + //public IShiftTraceLogger? TraceLogger { get; set; } + public ShowValuePointDiagramLogic(IValuePointDiagramLogic pointDiagramLogic) { - this.tupleList = tupleList; - this.ndmPrimitives = ndmPrimitives; - validTupleList = this.tupleList.Where(x => x.IsValid == true).ToList(); - valuePoints = new List<(PrimitiveBase PrimitiveBase, List>)>(); - foreach (var item in PrimitiveLogic.Collection.CollectionItems) - { - var pointsCount = item.Item.ValuePoints.SelectedCount; - if (pointsCount > 0) - { - var points = item.Item.ValuePoints.SelectedItems.ToList(); - var primitive = item.Item.PrimitiveBase; - valuePoints.Add((primitive, points)); - } - } + this.pointDiagramLogic = pointDiagramLogic; + } + public ShowValuePointDiagramLogic() : this(new ValuePointDiagramLogic()) + { + } public void ShowWindow() { + var result = GetResult(); + if (result.IsValid != true) + { + SafetyProcessor.ShowMessage(ErrorStrings.DataIsInCorrect, result.Description); + return; + } + arrayParameter = result.Value; SafetyProcessor.RunSafeProcess(() => { var series = new Series(arrayParameter) @@ -71,32 +75,14 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews }, ErrorStrings.ErrorDuring("building chart")); } - public void WorkerDoWork(object sender, DoWorkEventArgs e) + private GenericResult> GetResult() { - Show(); - Result = true; - } - - public void WorkerProgressChanged(object sender, ProgressChangedEventArgs e) - { - //Nothing to do - } - - public void WorkerRunWorkCompleted(object sender, RunWorkerCompletedEventArgs e) - { - //Nothing to do - } - - private void Show() - { - - } - - private List GetColumnNames() - { - var columnNames = LabelsFactory.GetCommonLabels(); - - return columnNames; + pointDiagramLogic.TupleList = TupleList; + pointDiagramLogic.PrimitiveLogic = PrimitiveLogic; + pointDiagramLogic.Calculator = Calculator; + pointDiagramLogic.ValueDelegatesLogic = ValueDelegatesLogic; + var results = pointDiagramLogic.GetArrayParameter(); + return results; } } } diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ValuePointDiagramLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ValuePointDiagramLogic.cs new file mode 100644 index 0000000..b08bb5c --- /dev/null +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ValuePointDiagramLogic.cs @@ -0,0 +1,173 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelper.Infrastructure.UI.DataContexts; +using StructureHelper.Services.ResultViewers; +using StructureHelper.Windows.Forces; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Parameters; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews.ForceResultLogic +{ + public class ValuePointDiagramLogic : IValuePointDiagramLogic + { + private ArrayParameter arrayParameter; + private List<(INamedAreaPoint areaPoint, INdmPrimitive ndmPrimitive)> pointCollection; + private List validTuplesList; + private ArrayParameter arrayOfValuesByPoint; + private IEnumerable selectedDelegates; + private string exceptionMessage; + + public IEnumerable TupleList { get; set; } + public ForceCalculator Calculator { get; set; } + public PointPrimitiveLogic PrimitiveLogic { get; set; } + public ValueDelegatesLogic ValueDelegatesLogic { get; set; } + + public GenericResult> GetArrayParameter() + { + SetParameters(); + var checkResult = CheckParameters(); + if (checkResult != true) + { + return GetFalseResult(); + } + PrepareArray(); + return GetValidResult(); + } + + private GenericResult> GetValidResult() + { + int i = 0; + foreach (var tuple in validTuplesList) + { + ProcessPointByTuple(tuple, i); + i++; + } + arrayParameter.AddArray(arrayOfValuesByPoint); + return new GenericResult>() + { + IsValid = true, + Value = arrayParameter + }; + } + private GenericResult> GetFalseResult() + { + return new GenericResult>() + { + IsValid = false, + Description = exceptionMessage + }; + } + private void SetParameters() + { + GetPointCollection(); + selectedDelegates = ValueDelegatesLogic.ResultFuncs.SelectedItems; + validTuplesList = TupleList + .Where(x => x.IsValid == true) + .ToList(); + } + private bool CheckParameters() + { + var result = true; + exceptionMessage = ErrorStrings.DataIsInCorrect; + if (pointCollection.Any() == false) + { + exceptionMessage += ", point collection is null"; + result = false; + } + if (selectedDelegates.Any() == false) + { + exceptionMessage += ", value expression collection is null"; + result = false; + } + if (validTuplesList.Any() == false) + { + exceptionMessage += ", force list is empty"; + result = false; + } + return result; + } + private void GetPointCollection() + { + pointCollection = new(); + foreach (var primitiveValuePoint in PrimitiveLogic.Collection.CollectionItems) + { + foreach (var selectedPoint in primitiveValuePoint.Item.ValuePoints.SelectedItems) + { + var newPoint = (selectedPoint, primitiveValuePoint.Item.PrimitiveBase.GetNdmPrimitive()); + pointCollection.Add(newPoint); + } + } + } + private void ProcessPointByTuple(IForcesTupleResult tuple, int i) + { + var values = new List(); + var strainMatrix = tuple.LoaderResults.ForceStrainPair.StrainMatrix; + + foreach (var valuePoint in pointCollection) + { + var ndm = GetMockNdm(valuePoint, tuple); + + foreach (var valDelegate in selectedDelegates) + { + double val = valDelegate.ResultFunction.Invoke(strainMatrix, ndm) * valDelegate.UnitFactor; + values.Add(val); + } + } + arrayOfValuesByPoint.AddRow(i, values); + } + private void PrepareArray() + { + var factory = new DiagramFactory() + { + TupleList = validTuplesList, + //SetProgress = SetProgress, + }; + arrayParameter = factory.GetCommonArray(); + + var labels = GetValueLabels(selectedDelegates); + arrayOfValuesByPoint = new ArrayParameter(validTuplesList.Count(), labels); + } + private INdm GetMockNdm((INamedAreaPoint areaPoint, INdmPrimitive ndmPrimitive) valuePoint, IForcesTupleResult tuple) + { + var limitState = tuple.DesignForceTuple.LimitState; + var calcTerm = tuple.DesignForceTuple.CalcTerm; + var material = valuePoint.ndmPrimitive.HeadMaterial.GetLoaderMaterial(limitState, calcTerm); + var userPrestrain = valuePoint.ndmPrimitive.UsersPrestrain; + var autoPrestrain = valuePoint.ndmPrimitive.AutoPrestrain; + var ndm = new Ndm() + { + Area = valuePoint.areaPoint.Area, + CenterX = valuePoint.areaPoint.Point.X, + CenterY = valuePoint.areaPoint.Point.Y, + Material = material, + }; + ndm.Prestrain = (userPrestrain.Mx + autoPrestrain.Mx) * valuePoint.areaPoint.Point.Y + + (userPrestrain.My + autoPrestrain.My) * valuePoint.areaPoint.Point.X + + userPrestrain.Nz + autoPrestrain.Nz; + return ndm; + } + private List GetValueLabels(IEnumerable selectedDelegates) + { + List strings = new(); + foreach (var valuePoint in pointCollection) + { + foreach (var deleg in selectedDelegates) + { + string s = valuePoint.ndmPrimitive.Name; + s += "_" + valuePoint.areaPoint.Name; + s += "_" + deleg.Name + ", " + deleg.UnitName; + strings.Add(s); + } + } + return strings; + } + } +} diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml index 4b48b33..c059250 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml @@ -6,7 +6,7 @@ xmlns:local="clr-namespace:StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews" d:DataContext="{d:DesignInstance local:ForcesResultsViewModel}" mc:Ignorable="d" - Title="Calculation Results" Height="350" Width="850" MinHeight="300" MinWidth="400" WindowStartupLocation="CenterScreen"> + Title="Calculation Results" Height="350" Width="850" MinHeight="300" MinWidth="400" WindowStartupLocation="CenterScreen" ShowInTaskbar="False"> @@ -25,7 +25,11 @@ - + @@ -59,13 +63,11 @@ - - - - - - - - - - - - - - - + + - - @@ -338,7 +352,16 @@ - + + + + + + + + + + diff --git a/StructureHelper/Windows/MainWindow/CrossSectionViewModel.cs b/StructureHelper/Windows/MainWindow/CrossSectionViewModel.cs index 37c5e69..51a5d3b 100644 --- a/StructureHelper/Windows/MainWindow/CrossSectionViewModel.cs +++ b/StructureHelper/Windows/MainWindow/CrossSectionViewModel.cs @@ -29,6 +29,8 @@ namespace StructureHelper.Windows.MainWindow { private ICrossSection section; private ICrossSectionRepository repository => section.SectionRepository; + private ITriangulatePrimitiveLogic triangulateLogic; + public CrossSectionVisualPropertyVM VisualProperty { get; private set; } @@ -172,7 +174,13 @@ namespace StructureHelper.Windows.MainWindow MovePrimitiveToGravityCenterCommand = new RelayCommand(o => { if (CheckMaterials() == false) { return;} - var ndms = NdmPrimitivesService.GetNdms(repository.Primitives, LimitStates.SLS, CalcTerms.ShortTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = repository.Primitives, + LimitState = LimitStates.SLS, + CalcTerm = CalcTerms.ShortTerm + }; + var ndms = triangulateLogic.GetNdms(); var center = GeometryOperations.GetGravityCenter(ndms); foreach (var item in PrimitiveLogic.Items) { diff --git a/StructureHelper/Windows/UserControls/MultiplyDouble.xaml.cs b/StructureHelper/Windows/UserControls/MultiplyDouble.xaml.cs index 365ccdf..856725e 100644 --- a/StructureHelper/Windows/UserControls/MultiplyDouble.xaml.cs +++ b/StructureHelper/Windows/UserControls/MultiplyDouble.xaml.cs @@ -25,6 +25,7 @@ namespace StructureHelper.Windows.UserControls /// public partial class MultiplyDouble : UserControl { + IConvertUnitLogic operationLogic = new ConvertUnitLogic(); public event EventHandler ValueChanged; public MultiplyDouble() @@ -40,7 +41,7 @@ namespace StructureHelper.Windows.UserControls try { string s = (string)o; - double factor = CommonOperation.ConvertToDoubleChangeComma(s); + double factor = ProcessString.ConvertCommaToCultureSettings(s); ChangeValue(factor); } catch(Exception ex) diff --git a/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs b/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs index 1145ff7..5bafcf7 100644 --- a/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs +++ b/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs @@ -55,7 +55,7 @@ namespace StructureHelper.Windows.ViewModels.Calculations.CalculationResult private void ShowIsoField() { IStrainMatrix strainMatrix = SelectedResult.LoaderResults.ForceStrainPair.StrainMatrix; - var primitiveSets = ShowIsoFieldResult.GetPrimitiveSets(strainMatrix, ndms, ResultFuncFactory.GetResultFuncs()); + var primitiveSets = ShowIsoFieldResult.GetPrimitiveSets(strainMatrix, ndms, ForceResultFuncFactory.GetResultFuncs()); isoFieldReport = new IsoFieldReport(primitiveSets); isoFieldReport.Show(); } diff --git a/StructureHelper/Windows/ViewModels/Forces/ActionsViewModel.cs b/StructureHelper/Windows/ViewModels/Forces/ActionsViewModel.cs index 0a829bf..7fccf0d 100644 --- a/StructureHelper/Windows/ViewModels/Forces/ActionsViewModel.cs +++ b/StructureHelper/Windows/ViewModels/Forces/ActionsViewModel.cs @@ -1,18 +1,13 @@ using StructureHelper.Infrastructure.Enums; -using StructureHelper.Models.Materials; using StructureHelper.Services.Settings; using StructureHelper.Windows.Forces; using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; using StructureHelperLogics.Models.CrossSections; -using StructureHelperLogics.Models.Materials; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using StructureHelperLogics.NdmCalculations.Cracking; using System.Windows.Forms; namespace StructureHelper.Windows.ViewModels.Forces @@ -98,24 +93,40 @@ namespace StructureHelper.Windows.ViewModels.Forces { bool result = true; var calcRepository = repository.CalculatorsList; - foreach (var item in calcRepository) + foreach (var calc in calcRepository) { - if (item is IForceCalculator) + if (calc is IForceCalculator) { - var forceCalculator = item as IForceCalculator; - var containSelected = forceCalculator.ForceActions.Contains(SelectedItem); - if (containSelected) - { - var dialogResultCalc = MessageBox.Show($"Action is contained in calculator {item.Name}", "Please, confirm deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (dialogResultCalc == DialogResult.Yes) - { - forceCalculator.ForceActions.Remove(SelectedItem); - } - else result = false; - } + var forceCombinations = calc as IHasForceCombinations; + result = DeleteActionFromHost(result, calc, forceCombinations); + } + else if (calc is CrackCalculator calculator) + { + var forceCombinations = calculator.InputData as IHasForceCombinations; + result = DeleteActionFromHost(result, calc, forceCombinations); + } + else + { + throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(ICalculator), calc)); } } return result; } + + private bool DeleteActionFromHost(bool result, ICalculator item, IHasForceCombinations? forceCombinations) + { + var containSelected = forceCombinations.ForceActions.Contains(SelectedItem); + if (containSelected) + { + var dialogResultCalc = MessageBox.Show($"Action is contained in calculator {item.Name}", "Please, confirm deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + if (dialogResultCalc == DialogResult.Yes) + { + forceCombinations.ForceActions.Remove(SelectedItem); + } + else result = false; + } + + return result; + } } } diff --git a/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs b/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs index 1e0d167..41e100a 100644 --- a/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs +++ b/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs @@ -1,7 +1,10 @@ -using StructureHelper.Infrastructure; +using LoaderCalculator; +using StructureHelper.Infrastructure; using StructureHelper.Infrastructure.Enums; +using StructureHelper.Windows.CalculationWindows.CalculatorsViews; using StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews; using StructureHelper.Windows.CalculationWindows.ProgressViews; +using StructureHelper.Windows.Errors; using StructureHelper.Windows.ViewModels.Calculations.Calculators; using StructureHelper.Windows.ViewModels.Errors; using StructureHelperCommon.Infrastructures.Exceptions; @@ -10,6 +13,8 @@ using StructureHelperCommon.Models.Calculators; using StructureHelperLogics.Models.CrossSections; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; using StructureHelperLogics.NdmCalculations.Analyses.Logics; +using StructureHelperLogics.NdmCalculations.Cracking; +using System; using System.Windows; using System.Windows.Forms; using MessageBox = System.Windows.Forms.MessageBox; @@ -25,32 +30,79 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections private InteractionDiagramLogic interactionDiagramLogic; public override void AddMethod(object parameter) + { + if (CheckParameter(parameter) == false) { return; } + AddCalculator(parameter); + base.AddMethod(parameter); + } + + private void AddCalculator(object parameter) { var parameterType = (CalculatorTypes)parameter; if (parameterType == CalculatorTypes.ForceCalculator) { - NewItem = new ForceCalculator() - { - Name = "New force calculator", - TraceLogger = new ShiftTraceLogger(), - }; + AddForceCalculator(); } else if (parameterType == CalculatorTypes.LimitCurveCalculator) { - var inputData = new LimitCurveInputData(repository.Primitives); - NewItem = new LimitCurvesCalculator() - { - Name = "New interaction diagram calculator", - InputData = inputData, - TraceLogger = new ShiftTraceLogger(), - }; + AddLimitCurveCalculator(); + } + else if (parameterType == CalculatorTypes.CrackCalculator) + { + AddCrackCalculator(); } else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(parameterType)); } - base.AddMethod(parameter); } + + private void AddCrackCalculator() + { + var inputData = new CrackInputData(); + var calculator = new CrackCalculator(inputData, new CheckCrackCalculatorInputDataLogic(inputData)) + { + Name = "New crack calculator", + TraceLogger = new ShiftTraceLogger(), + }; + NewItem = calculator; + } + + private void AddLimitCurveCalculator() + { + var inputData = new LimitCurveInputData(repository.Primitives); + NewItem = new LimitCurvesCalculator() + { + Name = "New interaction diagram calculator", + InputData = inputData, + TraceLogger = new ShiftTraceLogger(), + }; + } + + private void AddForceCalculator() + { + NewItem = new ForceCalculator() + { + Name = "New force calculator", + TraceLogger = new ShiftTraceLogger(), + }; + } + + private bool CheckParameter(object parameter) + { + if (parameter is null) + { + SafetyProcessor.ShowMessage(ErrorStrings.ParameterIsNull, "It is imposible to add object cause parameter is null"); + return false; + } + if (parameter is not CalculatorTypes) + { + SafetyProcessor.ShowMessage(ErrorStrings.ExpectedWas(typeof(CalculatorTypes), parameter), "Parameter is not correspondent to any type of calculator"); + return false; + } + return true; + } + public override void EditMethod(object parameter) { SafetyProcessor.RunSafeProcess(EditCalculator, $"Error of editing: {SelectedItem.Name}"); @@ -59,20 +111,18 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections private void EditCalculator() { - if (SelectedItem is ForceCalculator) - { - var calculator = SelectedItem as ForceCalculator; - EditForceCalculator(calculator); - } - else if (SelectedItem is LimitCurvesCalculator) - { - var calculator = SelectedItem as LimitCurvesCalculator; - EditLimitCurveCalculator(calculator); - } - else - { - throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(SelectedItem)); - } + if (SelectedItem is ForceCalculator forceCalculator) { EditForceCalculator(forceCalculator);} + else if (SelectedItem is LimitCurvesCalculator limitCurvesCalculator) { EditLimitCurveCalculator(limitCurvesCalculator); } + else if (SelectedItem is CrackCalculator crackCalculator) { EditCrackCalculator(crackCalculator);} + else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(SelectedItem));} + } + + private void EditCrackCalculator(CrackCalculator calculator) + { + var calculatorCopy = calculator.Clone() as CrackCalculator; + var vm = new CrackCalculatorInputDataViewModel(repository.Primitives, repository.ForceActions, calculator); + var wnd = new CrackCalculatorInputDataView(vm); + ShowWindow(calculator, calculatorCopy, wnd); } private void EditLimitCurveCalculator(LimitCurvesCalculator calculator) @@ -134,7 +184,6 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections } if (SelectedItem is LimitCurvesCalculator calculator) { - var inputData = calculator.InputData; ShowInteractionDiagramByInputData(calculator); } else @@ -143,13 +192,20 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections var result = SelectedItem.Result; if (result.IsValid == false) { - MessageBox.Show(result.Description, "Check data for analisys", MessageBoxButtons.OK, MessageBoxIcon.Warning); + var vm = new ErrorProcessor() + { + ShortText = "Errors apearred during calculations, see detailed information", + DetailText = SelectedItem.Result.Description + }; + new ErrorMessage(vm).ShowDialog(); + return; } else { ProcessResult(); } } + if (SelectedItem.TraceLogger is not null) { var wnd = new TraceDocumentView(SelectedItem.TraceLogger.TraceLoggerEntries); @@ -171,13 +227,17 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections private void ProcessResult() { - if (SelectedItem is IForceCalculator) + if (SelectedItem is ForceCalculator forceCalculator) { - var calculator = SelectedItem as ForceCalculator; - var vm = new ForcesResultsViewModel(calculator); + var vm = new ForcesResultsViewModel(forceCalculator); var wnd = new ForceResultsView(vm); wnd.ShowDialog(); } + else if (SelectedItem is CrackCalculator crackCalculator) + { + var wnd = new CrackResultView(crackCalculator.Result as CrackResult); + wnd.ShowDialog(); + } else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(SelectedItem)); diff --git a/StructureHelper/Windows/ViewModels/NdmCrossSections/PrimitiveViewModelLogic.cs b/StructureHelper/Windows/ViewModels/NdmCrossSections/PrimitiveViewModelLogic.cs index 790fb4a..f438ee2 100644 --- a/StructureHelper/Windows/ViewModels/NdmCrossSections/PrimitiveViewModelLogic.cs +++ b/StructureHelper/Windows/ViewModels/NdmCrossSections/PrimitiveViewModelLogic.cs @@ -7,6 +7,8 @@ using StructureHelper.Windows.PrimitiveTemplates.RCs.Beams; using StructureHelper.Windows.PrimitiveTemplates.RCs.RectangleBeam; using StructureHelper.Windows.Services; using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Materials; using StructureHelperCommon.Models.Shapes; using StructureHelperLogics.Models.CrossSections; @@ -14,6 +16,7 @@ using StructureHelperLogics.Models.Primitives; using StructureHelperLogics.Models.Templates.CrossSections.RCs; using StructureHelperLogics.Models.Templates.RCs; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Cracking; using StructureHelperLogics.NdmCalculations.Primitives; using System; using System.Collections.Generic; @@ -135,9 +138,24 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections { if (calc is IForceCalculator) { - var forceCalc = calc as IForceCalculator; + var forceCalc = calc as IHasPrimitives; forceCalc.Primitives.Remove(ndmPrimitive); } + else if (calc is LimitCurvesCalculator calculator) + { + //to do + //var forceCalc = calculator.InputData as IHasPrimitives; + //forceCalc.Primitives.Remove(ndmPrimitive); + } + else if (calc is CrackCalculator crackCalculator) + { + var forceCalc = crackCalculator.InputData as IHasPrimitives; + forceCalc.Primitives.Remove(ndmPrimitive); + } + else + { + throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(ICalculator), calc)); + } } foreach (var primitive in repository.Primitives) { diff --git a/StructureHelperCommon/Infrastructures/Exceptions/StructureHelperException.cs b/StructureHelperCommon/Infrastructures/Exceptions/StructureHelperException.cs index ab76f9d..0bf94cf 100644 --- a/StructureHelperCommon/Infrastructures/Exceptions/StructureHelperException.cs +++ b/StructureHelperCommon/Infrastructures/Exceptions/StructureHelperException.cs @@ -7,5 +7,9 @@ namespace StructureHelperCommon.Infrastructures.Exceptions public StructureHelperException(string errorString) : base(errorString) { } + public StructureHelperException(Exception ex) : this(ex.Message) + { + + } } } diff --git a/StructureHelperCommon/Infrastructures/Interfaces/ICheckInputDataLogic.cs b/StructureHelperCommon/Infrastructures/Interfaces/ICheckInputDataLogic.cs new file mode 100644 index 0000000..5cf6ab5 --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Interfaces/ICheckInputDataLogic.cs @@ -0,0 +1,14 @@ +using StructureHelperCommon.Models.Calculators; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Infrastructures.Interfaces +{ + public interface ICheckInputDataLogic : ICheckLogic + { + IInputData InputData { get; set; } + } +} diff --git a/StructureHelperCommon/Infrastructures/Interfaces/ICheckLogic.cs b/StructureHelperCommon/Infrastructures/Interfaces/ICheckLogic.cs new file mode 100644 index 0000000..dbefc5f --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Interfaces/ICheckLogic.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Infrastructures.Interfaces +{ + public interface ICheckLogic : ILogic + { + string CheckResult { get; } + bool Check(); + } +} diff --git a/StructureHelperCommon/Infrastructures/Interfaces/IHasForceCombinations.cs b/StructureHelperCommon/Infrastructures/Interfaces/IHasForceCombinations.cs index a9422bd..3fe260b 100644 --- a/StructureHelperCommon/Infrastructures/Interfaces/IHasForceCombinations.cs +++ b/StructureHelperCommon/Infrastructures/Interfaces/IHasForceCombinations.cs @@ -5,6 +5,9 @@ namespace StructureHelperCommon.Infrastructures.Interfaces { public interface IHasForceCombinations { + /// + /// Collection of force actions + /// List ForceActions { get; } } } diff --git a/StructureHelperCommon/Models/Calculators/GenericResult.cs b/StructureHelperCommon/Models/Calculators/GenericResult.cs new file mode 100644 index 0000000..c03c6d6 --- /dev/null +++ b/StructureHelperCommon/Models/Calculators/GenericResult.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Calculators +{ + public class GenericResult : IResult + { + public bool IsValid { get; set; } + public string? Description { get; set; } + public T? Value { get; set; } + } +} diff --git a/StructureHelperCommon/Models/Loggers/LoggerStrings.cs b/StructureHelperCommon/Models/Loggers/LoggerStrings.cs index 60f5776..1f6e3b0 100644 --- a/StructureHelperCommon/Models/Loggers/LoggerStrings.cs +++ b/StructureHelperCommon/Models/Loggers/LoggerStrings.cs @@ -10,6 +10,7 @@ namespace StructureHelperCommon.Models.Loggers { public static string DimensionLess => "(dimensionless)"; public static string MethodBasedOn => "Method of calculation based on "; + public static string CalculationError => "Some errors happened during calculations: "; public static string CalculationHasDone => "Calculation has done succesfully"; public static string Summary => "Summary"; public static string Maximum => "Maximum"; diff --git a/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs b/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs index fc07e65..8031064 100644 --- a/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs +++ b/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs @@ -33,8 +33,16 @@ namespace StructureHelperCommon.Models.Materials { GetLoaderOptions(); IBuilderDirector director = GetMaterialDirector(); - var material = director.BuildMaterial(); - return material; + try + { + var material = director.BuildMaterial(); + return material; + } + catch (System.Exception) + { + + throw; + } } private IBuilderDirector GetMaterialDirector() diff --git a/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs b/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs index 69016d0..d1786ea 100644 --- a/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs +++ b/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs @@ -16,7 +16,7 @@ namespace StructureHelperCommon.Models.Materials { private ConcreteLogicOptions options; private MaterialCommonOptionLogic optionLogic; - private FactorLogic factorLogic; + public ConcreteMaterialOptionLogic(ConcreteLogicOptions options) { @@ -32,10 +32,6 @@ namespace StructureHelperCommon.Models.Materials var concreteOptions = materialOptions as ConcreteOptions; optionLogic = new MaterialCommonOptionLogic(options); optionLogic.SetMaterialOptions(concreteOptions); - factorLogic = new FactorLogic(options.SafetyFactors); - var strength = factorLogic.GetTotalFactor(options.LimitState, options.CalcTerm); - concreteOptions.ExternalFactor.Compressive = strength.Compressive; - concreteOptions.ExternalFactor.Tensile = strength.Tensile; concreteOptions.WorkInTension = options.WorkInTension; concreteOptions.RelativeHumidity = options.RelativeHumidity; concreteOptions.Age = options.Age; diff --git a/StructureHelperCommon/Models/Materials/ICrackedMaterial.cs b/StructureHelperCommon/Models/Materials/ICrackedMaterial.cs new file mode 100644 index 0000000..0643713 --- /dev/null +++ b/StructureHelperCommon/Models/Materials/ICrackedMaterial.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Materials +{ + public interface ICrackedMaterial + { + bool TensionForULS { get; set; } + bool TensionForSLS { get; set; } + } +} diff --git a/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs b/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs index c85cb09..1f31608 100644 --- a/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs +++ b/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs @@ -240,7 +240,7 @@ namespace StructureHelperCommon.Models.Materials.Libraries Code = code, Name = "A400", InitModulus = 2e11d, - MainStrength = 400e6d + MainStrength = 390e6d }, new ReinforcementMaterialEntity(new Guid("045b54b1-0bbf-41fd-a27d-aeb20f600bb4")) { diff --git a/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs b/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs index 80097e1..f5b1f7d 100644 --- a/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs +++ b/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs @@ -1,12 +1,16 @@ -using StructureHelperCommon.Infrastructures.Enums; +using LoaderCalculator.Data.Materials.MaterialBuilders; +using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Materials.Libraries; using LCMB = LoaderCalculator.Data.Materials.MaterialBuilders; +using SHEnums = StructureHelperCommon.Infrastructures.Enums; namespace StructureHelperCommon.Models.Materials { public class MaterialCommonOptionLogic : IMaterialOptionLogic { private IMaterialLogicOptions options; + private FactorLogic factorLogic; public MaterialCommonOptionLogic(IMaterialLogicOptions options) { @@ -17,6 +21,58 @@ namespace StructureHelperCommon.Models.Materials { materialOptions.InitModulus = options.MaterialEntity.InitModulus; materialOptions.Strength = options.MaterialEntity.MainStrength; + ProcessCodeType(materialOptions); + ProcessLimitState(materialOptions); + ProcessCalcTerm(materialOptions); + ProcessExternalFactors(materialOptions); + } + + private void ProcessExternalFactors(IMaterialOptions materialOptions) + { + factorLogic = new FactorLogic(options.SafetyFactors); + var strength = factorLogic.GetTotalFactor(options.LimitState, options.CalcTerm); + materialOptions.ExternalFactor.Compressive = strength.Compressive; + materialOptions.ExternalFactor.Tensile = strength.Tensile; + } + + private void ProcessCalcTerm(IMaterialOptions materialOptions) + { + if (options.CalcTerm == CalcTerms.ShortTerm) + { + materialOptions.IsShortTerm = true; + } + else if (options.CalcTerm == CalcTerms.LongTerm) + { + materialOptions.IsShortTerm = false; + } + else + { + throw new StructureHelperException(ErrorStrings.LoadTermIsNotValid); + } + } + + private void ProcessLimitState(IMaterialOptions materialOptions) + { + if (options.LimitState == SHEnums.LimitStates.ULS) + { + materialOptions.LimitState = LCMB.LimitStates.Collapse; + } + else if (options.LimitState == SHEnums.LimitStates.SLS) + { + materialOptions.LimitState = LCMB.LimitStates.ServiceAbility; + } + else if (options.LimitState == SHEnums.LimitStates.Special) + { + materialOptions.LimitState = LCMB.LimitStates.Special; + } + else + { + throw new StructureHelperException(ErrorStrings.LimitStatesIsNotValid); + } + } + + private void ProcessCodeType(IMaterialOptions materialOptions) + { if (options.MaterialEntity.CodeType == CodeTypes.EuroCode_2_1990) { materialOptions.CodesType = LCMB.CodesType.EC2_1990; @@ -25,23 +81,10 @@ namespace StructureHelperCommon.Models.Materials { materialOptions.CodesType = LCMB.CodesType.SP63_2018; } - else { throw new StructureHelperException($"{ErrorStrings.ObjectTypeIsUnknown} : {materialOptions.CodesType}"); } - if (options.LimitState == LimitStates.ULS) + else { - materialOptions.LimitState = LCMB.LimitStates.Collapse; + throw new StructureHelperException($"{ErrorStrings.ObjectTypeIsUnknown} : {materialOptions.CodesType}"); } - else if (options.LimitState == LimitStates.SLS) - { - materialOptions.LimitState = LCMB.LimitStates.ServiceAbility; - } - else if (options.LimitState == LimitStates.Special) - { - materialOptions.LimitState = LCMB.LimitStates.Special; - } - else { throw new StructureHelperException(ErrorStrings.LimitStatesIsNotValid); } - if (options.CalcTerm == CalcTerms.ShortTerm) { materialOptions.IsShortTerm = true; } - else if (options.CalcTerm == CalcTerms.LongTerm) { materialOptions.IsShortTerm = false; } - else { throw new StructureHelperException(ErrorStrings.LoadTermIsNotValid); } } } } diff --git a/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs b/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs index 6104cdd..ac246ee 100644 --- a/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs +++ b/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs @@ -30,8 +30,17 @@ namespace StructureHelperCommon.Models.Materials { GetLoaderOptions(); IBuilderDirector director = GetMaterialDirector(); - var material = director.BuildMaterial(); - return material; + try + { + var material = director.BuildMaterial(); + return material; + } + catch (System.Exception) + { + + throw; + } + } private IBuilderDirector GetMaterialDirector() @@ -43,7 +52,10 @@ namespace StructureHelperCommon.Models.Materials private void GetLoaderOptions() { - materialOptions = new ReinforcementOptions() { DiagramType = DiagramType}; + materialOptions = new ReinforcementOptions() + { + DiagramType = DiagramType, + }; optionLogic = new MaterialCommonOptionLogic(options); optionLogic.SetMaterialOptions(materialOptions); } diff --git a/StructureHelperCommon/Models/Parameters/ArrayParameter.cs b/StructureHelperCommon/Models/Parameters/ArrayParameter.cs index 0b3df4f..59e2b05 100644 --- a/StructureHelperCommon/Models/Parameters/ArrayParameter.cs +++ b/StructureHelperCommon/Models/Parameters/ArrayParameter.cs @@ -43,5 +43,62 @@ namespace StructureHelperCommon.Models.Parameters } } public ArrayParameter(int rowCount, List columnLabels) : this(rowCount, columnLabels.Count, columnLabels) { } + public void AddArray(IArrayParameter array) + { + var rowCount = array.Data.GetLength(0); + int existingRowCount = this.Data.GetLength(0); + if (rowCount != existingRowCount) + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": number of rows in new array {rowCount} is not equal existing row count {existingRowCount}"); + } + var existingColumnCount = this.Data.GetLength(1); + var newColumnCount = array.Data.GetLength(1); + var totalCount = existingColumnCount + newColumnCount; + var newData = new T[rowCount, totalCount]; + var lackColumns = existingColumnCount - ColumnLabels.Count; + if (lackColumns > 0) + { + for (int i = 0; i < lackColumns; i++) + { + ColumnLabels.Add(string.Empty); + } + } + ColumnLabels.AddRange(array.ColumnLabels); + for (int i = 0; i < rowCount; i++) + { + for (int j = 0; j < existingColumnCount; j++) + { + newData[i, j] = Data[i, j]; + } + for (int j = 0; j < newColumnCount; j++) + { + newData[i, existingColumnCount + j] = array.Data[i,j]; + } + } + Data = newData; + } + + public void AddRow(int rowNumber, IEnumerable values) + { + CheckParams(rowNumber, values); + var valueList = values.ToList(); + for (int i = 0; i < values.Count(); i++) + { + Data[rowNumber, i] = valueList[i]; + } + } + + private void CheckParams(int rowNumber, IEnumerable values) + { + int rowCount = Data.GetLength(0) - 1; + if (rowNumber > rowCount) + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": number of rows {rowNumber} is greater than length of array {rowCount}"); + } + if (values.Count() != Data.GetLength(1)) + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": number of colums in values {values.Count()} is not equal existing column count {Data.GetLength(1)}"); + } + } } } diff --git a/StructureHelperCommon/Models/Parameters/IProcessValuePairLogic.cs b/StructureHelperCommon/Models/Parameters/IProcessValuePairLogic.cs new file mode 100644 index 0000000..94d7e76 --- /dev/null +++ b/StructureHelperCommon/Models/Parameters/IProcessValuePairLogic.cs @@ -0,0 +1,7 @@ +namespace StructureHelperCommon.Models.Parameters +{ + public interface IProcessValuePairLogic + { + ValuePair GetValuePairByString(string s); + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Models/Parameters/IValuePair.cs b/StructureHelperCommon/Models/Parameters/IValuePair.cs new file mode 100644 index 0000000..6dbdce0 --- /dev/null +++ b/StructureHelperCommon/Models/Parameters/IValuePair.cs @@ -0,0 +1,12 @@ +namespace StructureHelperCommon.Models.Parameters +{ + /// + /// Represent pair of value with text + /// + /// + public interface IValuePair + { + string Text { get; set; } + T Value { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Models/Parameters/IValueParameter.cs b/StructureHelperCommon/Models/Parameters/IValueParameter.cs index afdb75f..4f82874 100644 --- a/StructureHelperCommon/Models/Parameters/IValueParameter.cs +++ b/StructureHelperCommon/Models/Parameters/IValueParameter.cs @@ -7,14 +7,12 @@ using System.Windows.Media; namespace StructureHelperCommon.Models.Parameters { - public interface IValueParameter + public interface IValueParameter : IValuePair { bool IsValid { get; set; } string Name { get; set; } string ShortName { get; set; } Color Color { get; set; } - string MeasurementUnit { get; set; } - T Value { get; set; } string Description { get; set; } } } diff --git a/StructureHelperCommon/Models/Parameters/ProcessDoublePairLogic.cs b/StructureHelperCommon/Models/Parameters/ProcessDoublePairLogic.cs new file mode 100644 index 0000000..f55c098 --- /dev/null +++ b/StructureHelperCommon/Models/Parameters/ProcessDoublePairLogic.cs @@ -0,0 +1,65 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Services.Units; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Media.Media3D; + +namespace StructureHelperCommon.Models.Parameters +{ + public enum DigitPlace + { + Start, + Any + } + public class ProcessDoublePairLogic : IProcessValuePairLogic + { + const string digitalPattern = @"^[-]?[+]?\d*\.?\,?\d*"; + const string allowedPattern = @"[0-9]|\.|\,"; + const string characterPattern = "[a-z]+$"; + const string target = ""; + + public DigitPlace DigitPlace { get; set; } = DigitPlace.Start; + + public ValuePair GetValuePairByString(string s) + { + s = s.Replace(" ", string.Empty); + + Regex regexText = new (allowedPattern); + string textString = regexText.Replace(s, target); + var textMatch = Regex.Match(textString, characterPattern, RegexOptions.IgnoreCase); + if (textMatch.Success == true) + { + textString = textMatch.Value.ToLower(); + } + var digitalOnlyString = DigitPlace == DigitPlace.Start ? s : s.ToLower().Replace(textString, string.Empty); + var match = Regex.Match(digitalOnlyString, digitalPattern); + if (match.Success == true) + { + return GetDoubleValue(textString, match); + } + throw new StructureHelperException(ErrorStrings.DataIsInCorrect); + } + + private static ValuePair GetDoubleValue(string textString, Match match) + { + string digitalString = match.Value; + if (digitalString != string.Empty || digitalString != "") + { + double digit = ProcessString.ConvertCommaToCultureSettings(digitalString); + return new ValuePair() + { + Value = digit, + Text = textString + }; + } + else + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": value does not contain digital simbols"); + } + } + } +} diff --git a/StructureHelperCommon/Services/Units/StringDoublePair.cs b/StructureHelperCommon/Models/Parameters/ValuePair.cs similarity index 53% rename from StructureHelperCommon/Services/Units/StringDoublePair.cs rename to StructureHelperCommon/Models/Parameters/ValuePair.cs index 7e2cb34..8454961 100644 --- a/StructureHelperCommon/Services/Units/StringDoublePair.cs +++ b/StructureHelperCommon/Models/Parameters/ValuePair.cs @@ -4,11 +4,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StructureHelperCommon.Services.Units +namespace StructureHelperCommon.Models.Parameters { - internal class StringDoublePair : IStringDoublePair + /// + public class ValuePair : IValuePair { - public double Digit { get; set; } public string Text { get; set; } + public T Value { get; set; } } } diff --git a/StructureHelperCommon/Models/Parameters/ValueParameter.cs b/StructureHelperCommon/Models/Parameters/ValueParameter.cs index 1e008ba..18d8625 100644 --- a/StructureHelperCommon/Models/Parameters/ValueParameter.cs +++ b/StructureHelperCommon/Models/Parameters/ValueParameter.cs @@ -13,7 +13,7 @@ namespace StructureHelperCommon.Models.Parameters public string Name { get; set; } public string ShortName { get; set; } public Color Color { get; set; } - public string MeasurementUnit { get; set; } + public string Text { get; set; } public T Value { get; set; } public string Description { get; set; } } diff --git a/StructureHelperCommon/Models/Sections/Logics/AccidentalEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/AccidentalEccentricityLogic.cs deleted file mode 100644 index f90df30..0000000 --- a/StructureHelperCommon/Models/Sections/Logics/AccidentalEccentricityLogic.cs +++ /dev/null @@ -1,90 +0,0 @@ -using StructureHelperCommon.Models.Forces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia -//All rights reserved. - -namespace StructureHelperCommon.Models.Sections -{ - public class AccidentalEccentricityLogic : IAccidentalEccentricityLogic - { - private double lengthFactor; - private double sizeFactor; - private double minEccentricity; - - public double Length { get; set; } - public double SizeX { get; set; } - public double SizeY { get; set; } - public IForceTuple InitialForceTuple { get; set; } - public IShiftTraceLogger? TraceLogger { get; set; } - public AccidentalEccentricityLogic() - { - lengthFactor = 600d; - sizeFactor = 30d; - minEccentricity = 0.01d; - } - public ForceTuple GetForceTuple() - { - var lengthEccetricity = Length / lengthFactor; - TraceLogger?.AddMessage(string.Format("Accidental eccentricity by length ea = {0} / {1} = {2}", Length, lengthFactor, lengthEccetricity)); - var sizeXEccetricity = SizeX / sizeFactor; - TraceLogger?.AddMessage(string.Format("Accidental eccentricity by SizeX ea ={0} / {1} = {2}", SizeX, sizeFactor, sizeXEccetricity)); - var sizeYEccetricity = SizeY / sizeFactor; - TraceLogger?.AddMessage(string.Format("Accidental eccentricity by SizeY ea ={0} / {1} = {2}", SizeY, sizeFactor, sizeYEccetricity)); - TraceLogger?.AddMessage(string.Format("Minimum accidental eccentricity ea = {0}", minEccentricity)); - var xEccentricity = Math.Abs(InitialForceTuple.My / InitialForceTuple.Nz); - TraceLogger?.AddMessage(string.Format("Actual eccentricity e0,x = {0}", xEccentricity)); - var yEccentricity = Math.Abs(InitialForceTuple.Mx / InitialForceTuple.Nz); - TraceLogger?.AddMessage(string.Format("Actual eccentricity e0,y = {0}", yEccentricity)); - - var xFullEccentricity = new List() - { - lengthEccetricity, - sizeXEccetricity, - minEccentricity, - xEccentricity - } - .Max(); - string mesEx = string.Format("Eccentricity e,x = max({0}; {1}; {2}; {3}) = {4}", - lengthEccetricity, sizeXEccetricity, - minEccentricity, xEccentricity, - xFullEccentricity); - TraceLogger?.AddMessage(mesEx); - var yFullEccentricity = new List() - { - lengthEccetricity, - sizeYEccetricity, - minEccentricity, - yEccentricity - } - .Max(); - string mesEy = string.Format("Eccentricity e,y = max({0}; {1}; {2}; {3}) = {4}", - lengthEccetricity, sizeYEccetricity, - minEccentricity, yEccentricity, - yFullEccentricity); - TraceLogger?.AddMessage(mesEy); - var xSign = InitialForceTuple.Mx == 0d ? -1d : Math.Sign(InitialForceTuple.Mx); - var ySign = InitialForceTuple.My == 0d ? -1d : Math.Sign(InitialForceTuple.My); - var mx = (-1d) * InitialForceTuple.Nz * yFullEccentricity * xSign; - var my = (-1d) * InitialForceTuple.Nz * xFullEccentricity * ySign; - TraceLogger?.AddMessage(string.Format("Bending moment arbitrary X-axis Mx = {0} * {1} = {2}", InitialForceTuple.Nz, yFullEccentricity, mx), TraceLogStatuses.Debug); - TraceLogger?.AddMessage(string.Format("Bending moment arbitrary Y-axis My = {0} * {1} = {2}", InitialForceTuple.Nz, xFullEccentricity, my), TraceLogStatuses.Debug); - - var newTuple = new ForceTuple() - { - Mx = mx, - My = my, - Nz = InitialForceTuple.Nz, - Qx = InitialForceTuple.Qx, - Qy = InitialForceTuple.Qy, - Mz = InitialForceTuple.Mz, - }; - TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(newTuple)); - return newTuple; - } - } -} diff --git a/StructureHelperCommon/Models/Sections/Logics/ForceTupleCopier.cs b/StructureHelperCommon/Models/Sections/Logics/ForceTupleCopier.cs new file mode 100644 index 0000000..d57fbdf --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/ForceTupleCopier.cs @@ -0,0 +1,23 @@ +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class ForceTupleCopier : IProcessorLogic + { + public IForceTuple InputForceTuple { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public ForceTupleCopier(IForceTuple forceTuple) + { + InputForceTuple = forceTuple; + } + public IForceTuple GetValue() + { + return InputForceTuple.Clone() as IForceTuple; + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/ForceTupleMoveToPointDecorator.cs b/StructureHelperCommon/Models/Sections/Logics/ForceTupleMoveToPointDecorator.cs new file mode 100644 index 0000000..eaf8c73 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/ForceTupleMoveToPointDecorator.cs @@ -0,0 +1,32 @@ +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Shapes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class ForceTupleMoveToPointDecorator : IProcessorDecorator + { + public IPoint2D Point2D { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + /// + /// Internal source of ForceTuple + /// + public IProcessorLogic ForceTupleLogics { get; } + public ForceTupleMoveToPointDecorator(IProcessorLogic procLogic) + { + ForceTupleLogics = procLogic; + } + public IForceTuple GetValue() + { + ForceTupleLogics.TraceLogger = TraceLogger; + var newTuple = ForceTupleLogics.GetValue(); + newTuple.Mx += newTuple.Nz * Point2D.Y; + newTuple.My -= newTuple.Nz * Point2D.X; + return newTuple; + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IAccidentalEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IAccidentalEccentricityLogic.cs deleted file mode 100644 index 27c9d2c..0000000 --- a/StructureHelperCommon/Models/Sections/Logics/IAccidentalEccentricityLogic.cs +++ /dev/null @@ -1,38 +0,0 @@ -using StructureHelperCommon.Infrastructures.Interfaces; -using StructureHelperCommon.Models.Forces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperCommon.Models.Sections -{ - /// - /// Logic for calculating of value of accidental eccentricity - /// - public interface IAccidentalEccentricityLogic : ILogic - { - /// - /// Properties of compressed member - /// - double Length { get;set;} - /// - /// Size of cross-section along X-axis, m - /// - double SizeX { get; set; } - /// - /// Size of cross-section along Y-axis, m - /// - double SizeY { get; set; } - /// - /// Initial tuple of force - /// - IForceTuple InitialForceTuple { get; set; } - /// - /// Returns new force tuple with accidental eccentricity - /// - /// - ForceTuple GetForceTuple(); - } -} diff --git a/StructureHelperCommon/Models/Sections/Logics/IHasInputForce.cs b/StructureHelperCommon/Models/Sections/Logics/IHasInputForce.cs new file mode 100644 index 0000000..03fc403 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IHasInputForce.cs @@ -0,0 +1,17 @@ +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IHasInputForce + { + /// + /// Initial tuple of force + /// + IForceTuple InputForceTuple { get; set; } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IProcessorDecorator.cs b/StructureHelperCommon/Models/Sections/Logics/IProcessorDecorator.cs new file mode 100644 index 0000000..517aa22 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IProcessorDecorator.cs @@ -0,0 +1,14 @@ +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IProcessorDecorator : IProcessorLogic + { + IProcessorLogic ForceTupleLogics { get; } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IProcessorLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IProcessorLogic.cs new file mode 100644 index 0000000..cf90cc0 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IProcessorLogic.cs @@ -0,0 +1,22 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections +{ + /// + /// Logic for calculating of some value + /// + public interface IProcessorLogic : ILogic + { + /// + /// Returns new value + /// + /// + T GetValue(); + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IRcAccEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IRcAccEccentricityLogic.cs new file mode 100644 index 0000000..4f929af --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IRcAccEccentricityLogic.cs @@ -0,0 +1,12 @@ +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IRcAccEccentricityLogic : IProcessorLogic<(double ex, double ey)> + { + double Length { get; set; } + double SizeX { get; set; } + double SizeY { get; set; } + IShiftTraceLogger? TraceLogger { get; set; } + + (double ex, double ey) GetValue(); + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Models/Sections/Logics/IRcEccentricityAxisLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IRcEccentricityAxisLogic.cs new file mode 100644 index 0000000..9c8695d --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IRcEccentricityAxisLogic.cs @@ -0,0 +1,8 @@ +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IRcEccentricityAxisLogic : IProcessorLogic + { + double Length { get; set; } + double Size { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Models/Sections/Logics/RcAccEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/RcAccEccentricityLogic.cs new file mode 100644 index 0000000..5db7f39 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/RcAccEccentricityLogic.cs @@ -0,0 +1,54 @@ +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class RcAccEccentricityLogic : IRcAccEccentricityLogic + { + private const string accEccMessage = "Accidental eccentricity along {0}-axis"; + /// + /// Properties of compressed member + /// + public double Length { get; set; } + /// + /// Size of cross-section along X-axis, m + /// + public double SizeX { get; set; } + /// + /// Size of cross-section along Y-axis, m + /// + public double SizeY { get; set; } + /// + public IShiftTraceLogger? TraceLogger { get; set; } + private IRcEccentricityAxisLogic eccentricityLogic; + public RcAccEccentricityLogic(IRcEccentricityAxisLogic eccentricityLogic) + { + this.eccentricityLogic = eccentricityLogic; + } + public RcAccEccentricityLogic() : this(new RcEccentricityAxisLogic()) + { + + } + public (double ex, double ey) GetValue() + { + eccentricityLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(string.Format(accEccMessage, "x")); + eccentricityLogic.Length = Length; + eccentricityLogic.Size = SizeX; + var xFullEccentricity = eccentricityLogic.GetValue(); + TraceLogger?.AddMessage(string.Format(accEccMessage, "y")); + eccentricityLogic.Size = SizeY; + var yFullEccentricity = eccentricityLogic.GetValue(); + return (xFullEccentricity, yFullEccentricity); + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/RcEccentricityAxisLogic.cs b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityAxisLogic.cs new file mode 100644 index 0000000..30e581e --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityAxisLogic.cs @@ -0,0 +1,57 @@ +using StructureHelperCommon.Models.Loggers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class RcEccentricityAxisLogic : IRcEccentricityAxisLogic + { + private readonly double lengthFactor; + private readonly double sizeFactor; + private readonly double minEccentricity; + + /// + /// Properties of compressed member + /// + public double Length { get; set; } + /// + /// Size of cross-section along X-axis, m + /// + public double Size { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public RcEccentricityAxisLogic() + { + lengthFactor = 600d; + sizeFactor = 30d; + minEccentricity = 0.01d; + } + public double GetValue() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + var lengthEccetricity = Length / lengthFactor; + TraceLogger?.AddMessage(string.Format("Length of member = {0}(m)", Length)); + TraceLogger?.AddMessage(string.Format("Accidental eccentricity by length e,a = {0}(m) / {1} = {2}(m)", Length, lengthFactor, lengthEccetricity)); + TraceLogger?.AddMessage(string.Format("Size of cross-section of member = {0}(m)", Size)); + var sizeXEccetricity = Size / sizeFactor; + TraceLogger?.AddMessage(string.Format("Accidental eccentricity by size e,a ={0}(m) / {1} = {2}(m)", Size, sizeFactor, sizeXEccetricity)); ; + TraceLogger?.AddMessage(string.Format("In any case, minimum accidental eccentricity e,a = {0}(m)", minEccentricity)); + + var fullEccentricity = new List() + { + lengthEccetricity, + sizeXEccetricity, + minEccentricity, + } + .Max(); + string mesEcc = string.Format("Maximum accidental eccentricity e,a = max({0}(m); {1}(m); {2}(m)) = {3}(m)", + lengthEccetricity, sizeXEccetricity, + minEccentricity, + fullEccentricity); + TraceLogger?.AddMessage(mesEcc); + return fullEccentricity; + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/RcEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityLogic.cs new file mode 100644 index 0000000..1743674 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityLogic.cs @@ -0,0 +1,100 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Sections.Logics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperCommon.Models.Sections +{ + public class RcEccentricityLogic : IProcessorLogic, IHasInputForce + { + private const string fstAxisName = "x"; + private const string sndAxisName = "y"; + private const string actualEccMessage = "Actual eccentricity e0,{0} = {1}(m)"; + private const string maxEccentricityMessage = "Eccentricity e,{0} = max({1}(m); {2}(m)) = {3}(m)"; + private const string OutPutBendingMomentMessage = "Bending moment arbitrary {0}-axis M{0} = Nz * e,{0} = {1}(N) * {2}(m) = {3}(N*m)"; + + /// + /// Properties of compressed member + /// + public double Length { get; set; } + /// + /// Size of cross-section along X-axis, m + /// + public double SizeX { get; set; } + /// + /// Size of cross-section along Y-axis, m + /// + public double SizeY { get; set; } + /// + public IForceTuple? InputForceTuple { get; set; } + /// + public IShiftTraceLogger? TraceLogger { get; set; } + public IRcAccEccentricityLogic EccentricityLogic { get; private set; } + + public RcEccentricityLogic(IRcAccEccentricityLogic eccentricityLogic) + { + EccentricityLogic = eccentricityLogic; + } + + public RcEccentricityLogic() : this(new RcAccEccentricityLogic()) + { + + } + + public IForceTuple GetValue() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + if (InputForceTuple is null) + { + string errorString = ErrorStrings.NullReference + $": {nameof(InputForceTuple)}"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + + EccentricityLogic.Length = Length; + EccentricityLogic.SizeX = SizeX; + EccentricityLogic.SizeY = SizeY; + EccentricityLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + + var (ex, ey) = EccentricityLogic.GetValue(); + + var xEccentricity = Math.Abs(InputForceTuple.My / InputForceTuple.Nz); + TraceLogger?.AddMessage(string.Format(actualEccMessage, fstAxisName, xEccentricity)); + var yEccentricity = Math.Abs(InputForceTuple.Mx / InputForceTuple.Nz); + TraceLogger?.AddMessage(string.Format(actualEccMessage, sndAxisName, yEccentricity)); + + var xFullEccentricity = Math.Max(ex, xEccentricity); + var yFullEccentricity = Math.Max(ey, yEccentricity); + string mesEx = string.Format(maxEccentricityMessage, fstAxisName, ex, xEccentricity, xFullEccentricity); + TraceLogger?.AddMessage(mesEx); + string mesEy = string.Format(maxEccentricityMessage, sndAxisName, ey, yEccentricity, yFullEccentricity); + TraceLogger?.AddMessage(mesEy); + var xSign = InputForceTuple.Mx == 0d ? -1d : Math.Sign(InputForceTuple.Mx); + var ySign = InputForceTuple.My == 0d ? -1d : Math.Sign(InputForceTuple.My); + var mx = (-1d) * InputForceTuple.Nz * yFullEccentricity * xSign; + var my = (-1d) * InputForceTuple.Nz * xFullEccentricity * ySign; + TraceLogger?.AddMessage(string.Format(OutPutBendingMomentMessage, fstAxisName, InputForceTuple.Nz, yFullEccentricity, mx), TraceLogStatuses.Debug); + TraceLogger?.AddMessage(string.Format(OutPutBendingMomentMessage, sndAxisName, InputForceTuple.Nz, xFullEccentricity, my), TraceLogStatuses.Debug); + + var newTuple = new ForceTuple() + { + Mx = mx, + My = my, + Nz = InputForceTuple.Nz, + Qx = InputForceTuple.Qx, + Qy = InputForceTuple.Qy, + Mz = InputForceTuple.Mz, + }; + TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(newTuple)); + return newTuple; + } + } +} diff --git a/StructureHelperCommon/Services/DirectRoundLogic.cs b/StructureHelperCommon/Services/DirectRoundLogic.cs new file mode 100644 index 0000000..cb82161 --- /dev/null +++ b/StructureHelperCommon/Services/DirectRoundLogic.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Services +{ + public class DirectRoundLogic : IMathRoundLogic + { + public double RoundValue(double value) + { + return value; + } + } +} diff --git a/StructureHelperCommon/Services/FixedRoundLogic.cs b/StructureHelperCommon/Services/FixedRoundLogic.cs new file mode 100644 index 0000000..d36d747 --- /dev/null +++ b/StructureHelperCommon/Services/FixedRoundLogic.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Services +{ + public class FixedRoundLogic : IDigitRoundLogic + { + public int DigitQuant { get; set; } + + /// + /// Умное окруление до нужного числа значащих цифр, например (12345, 3) дает результат 12300, например (0.12345, 3) дает результат 0,123 + /// + /// + /// + /// + public double RoundValue(double value) + { + double roundedValue = Math.Round(value, DigitQuant); + return roundedValue; + } + } +} diff --git a/StructureHelperCommon/Services/Forces/ForceTupleService.cs b/StructureHelperCommon/Services/Forces/ForceTupleService.cs index ab74200..2e51453 100644 --- a/StructureHelperCommon/Services/Forces/ForceTupleService.cs +++ b/StructureHelperCommon/Services/Forces/ForceTupleService.cs @@ -20,13 +20,6 @@ namespace StructureHelperCommon.Services.Forces target.Clear(); SumTupleToTarget(source, target, factor); } - public static IForceTuple MoveTupleIntoPoint(IForceTuple forceTuple, IPoint2D point2D) - { - var newTuple = forceTuple.Clone() as IForceTuple; - newTuple.Mx += newTuple.Nz * point2D.Y; - newTuple.My -= newTuple.Nz * point2D.X; - return newTuple; - } public static IForceTuple SumTuples(IForceTuple first, IForceTuple second, double factor = 1d) { CheckTuples(first, second); diff --git a/StructureHelperCommon/Services/IDigitRoundLogic.cs b/StructureHelperCommon/Services/IDigitRoundLogic.cs new file mode 100644 index 0000000..7b1246e --- /dev/null +++ b/StructureHelperCommon/Services/IDigitRoundLogic.cs @@ -0,0 +1,7 @@ +namespace StructureHelperCommon.Services +{ + public interface IDigitRoundLogic : IMathRoundLogic + { + int DigitQuant { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Services/IMathRoundLogic.cs b/StructureHelperCommon/Services/IMathRoundLogic.cs new file mode 100644 index 0000000..3aca8d1 --- /dev/null +++ b/StructureHelperCommon/Services/IMathRoundLogic.cs @@ -0,0 +1,7 @@ +namespace StructureHelperCommon.Services +{ + public interface IMathRoundLogic + { + double RoundValue(double value); + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Services/SmartRoundLogic.cs b/StructureHelperCommon/Services/SmartRoundLogic.cs new file mode 100644 index 0000000..7b0d6c8 --- /dev/null +++ b/StructureHelperCommon/Services/SmartRoundLogic.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Services +{ + public class SmartRoundLogic : IDigitRoundLogic + { + public int DigitQuant { get; set; } = 3; + + /// + /// Умное окруление до нужного числа значащих цифр, например (12345, 3) дает результат 12300, например (0.12345, 3) дает результат 0,123 + /// + /// + /// + /// + public double RoundValue(double value) + { + if (value == 0d) return 0d; + double valueOrder = Math.Log10(Math.Abs(value)); + int order = Convert.ToInt32(Math.Ceiling(valueOrder)); + double requiredOrder = Math.Pow(10, DigitQuant - order); + double roundedAbsValue = Math.Round(Math.Abs(value) * requiredOrder) / requiredOrder; + double roundedValue = Math.Sign(value) * roundedAbsValue; + return roundedValue; + } + } +} diff --git a/StructureHelperCommon/Services/Units/CommonOperation.cs b/StructureHelperCommon/Services/Units/CommonOperation.cs deleted file mode 100644 index 3e91fde..0000000 --- a/StructureHelperCommon/Services/Units/CommonOperation.cs +++ /dev/null @@ -1,116 +0,0 @@ -using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Infrastructures.Exceptions; -using StructureHelperCommon.Services.Units; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; -using System.Windows.Documents; - -namespace StructureHelperCommon.Services.Units -{ - public static class CommonOperation - { - private static IEnumerable units = UnitsFactory.GetUnitCollection(); - - public static double ConvertToDoubleChangeComma(string s) - { - double result; - if (!double.TryParse(s, NumberStyles.Any, CultureInfo.CurrentCulture, out result) && - !double.TryParse(s, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) && - !double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) - { - throw new StructureHelperException($"{ErrorStrings.IncorrectValue}: {s}"); - } - return result; - } - - public static IStringDoublePair DivideIntoStringDoublePair(string s) - { - s = s.Replace(" ", ""); - //string digitPattern = @"^[-]?[+]?\d+(\.?)|(\,?)\d*"; - string digitPattern = @"^[-]?[+]?\d*\.?\,?\d*"; - string textPattern = @"[0-9]|\.|\,"; - string caracterPattern = "[a-z]+$"; - string target = ""; - Regex regexText = new Regex(textPattern); - string textString = regexText.Replace(s, target); - var textMatch = Regex.Match(textString, caracterPattern, RegexOptions.IgnoreCase); - if (textMatch.Success) {textString = textMatch.Value.ToLower();} - var match = Regex.Match(s, digitPattern); - if (match.Success) - { - string digitString = match.Value; - double digit = ConvertToDoubleChangeComma(digitString); - return new StringDoublePair() { Digit = digit, Text = textString }; - } - throw new StructureHelperException(ErrorStrings.DataIsInCorrect); - } - - public static IUnit GetUnit(UnitTypes unitType, string unitName = null) - { - if (unitName is null) - { - var boolResult = DefaultUnitNames.TryGetValue(unitType, out unitName); - if (boolResult == false) - { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": unit type{unitType} is unknown"); - } - } - return units.Where(u => u.UnitType == unitType & u.Name == unitName).Single(); - } - - public static Dictionary DefaultUnitNames => new() - { - { UnitTypes.Length, "m"}, - { UnitTypes.Area, "m2"}, - { UnitTypes.Force, "kN" }, - { UnitTypes.Moment, "kNm"}, - { UnitTypes.Stress, "MPa"}, - { UnitTypes.Curvature, "1/m"}, - }; - - - public static string Convert(IUnit unit, string unitName, object value) - { - double val; - if (value != null) { val = (double)value; } - else { throw new Exception($"{unitName} value is null"); } - val *= unit.Multiplyer; - string strValue = $"{val} {unit.Name}"; - return strValue; - } - - public static double ConvertBack(UnitTypes unitType, IUnit unit, object value) - { - double val; - double multy; - double coefficient = unit.Multiplyer; - var strVal = value as string; - IStringDoublePair pair = DivideIntoStringDoublePair(strVal); - try - { - multy = GetMultiplyer(unitType, pair.Text); - } - catch (Exception ex) - { - multy = coefficient; - } - val = pair.Digit / multy; - return val; - } - - public static double GetMultiplyer(UnitTypes unitType, string unitName) - { - try - { - return units.Where(u => u.UnitType == unitType & u.Name == unitName).Single().Multiplyer; - } - catch (Exception ex) - { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ex); - } - } - } -} diff --git a/StructureHelperCommon/Services/Units/ConvertUnitLogic.cs b/StructureHelperCommon/Services/Units/ConvertUnitLogic.cs new file mode 100644 index 0000000..0dbcbc1 --- /dev/null +++ b/StructureHelperCommon/Services/Units/ConvertUnitLogic.cs @@ -0,0 +1,85 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Parameters; +using StructureHelperCommon.Services.Units; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; +using System.Windows.Documents; + +namespace StructureHelperCommon.Services.Units +{ + public class ConvertUnitLogic : IConvertUnitLogic + { + private static IEnumerable units = UnitsFactory.GetUnitCollection(); + private static IProcessValuePairLogic pairLogic = new ProcessDoublePairLogic(); + + public IMathRoundLogic MathRoundLogic { get; set; } = new DirectRoundLogic(); + + public ValuePair Convert(IUnit unit, string unitName, object value) + { + double val; + if (value != null) + { + try + { + val = (double)value; + } + catch (Exception ex) + { + throw new StructureHelperException($"{ErrorStrings.IncorrectValue}"); + } + } + else + { + throw new StructureHelperException($"{ErrorStrings.ParameterIsNull}: {unitName}"); + } + val *= unit.Multiplyer; + var pair = new ValuePair + { + Text = unit.Name, + Value = val + }; + return pair; + } + + public double ConvertBack(UnitTypes unitType, IUnit unit, object value) + { + double val; + double multy; + double factor = unit.Multiplyer; + var strVal = value as string; + var pair = pairLogic.GetValuePairByString(strVal); + try + { + multy = GetMultiplyer(unitType, pair.Text); + } + catch (Exception ex) + { + multy = factor; + } + val = pair.Value / multy; + return val; + } + + private double GetMultiplyer(UnitTypes unitType, string unitName) + { + try + { + return units + .Where(u => + u.UnitType == unitType + & + u.Name == unitName) + .Single() + .Multiplyer; + } + catch (Exception ex) + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ex); + } + } + } +} diff --git a/StructureHelperCommon/Services/Units/GetUnitLogic.cs b/StructureHelperCommon/Services/Units/GetUnitLogic.cs new file mode 100644 index 0000000..ea68c44 --- /dev/null +++ b/StructureHelperCommon/Services/Units/GetUnitLogic.cs @@ -0,0 +1,50 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Services.Units +{ + public class GetUnitLogic : IGetUnitLogic + { + private static IEnumerable units = UnitsFactory.GetUnitCollection(); + private Dictionary defaultUnitNames; + + + public GetUnitLogic() + { + defaultUnitNames = new() + { + { UnitTypes.Length, "m"}, + { UnitTypes.Area, "m2"}, + { UnitTypes.Force, "kN" }, + { UnitTypes.Moment, "kNm"}, + { UnitTypes.Stress, "MPa"}, + { UnitTypes.Curvature, "1/m"}, + }; + } + + public IUnit GetUnit(UnitTypes unitType, string unitName = null) + { + if (unitName is null) + { + var boolResult = defaultUnitNames.TryGetValue(unitType, out unitName); + if (boolResult == false) + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": unit type{unitType} is unknown"); + } + } + return units + .Where(u => + u.UnitType == unitType + & + u.Name == unitName) + .Single(); + } + + + } +} diff --git a/StructureHelperCommon/Services/Units/IConvertUnitLogic.cs b/StructureHelperCommon/Services/Units/IConvertUnitLogic.cs new file mode 100644 index 0000000..683b2cd --- /dev/null +++ b/StructureHelperCommon/Services/Units/IConvertUnitLogic.cs @@ -0,0 +1,13 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Parameters; +using System.Collections.Generic; + +namespace StructureHelperCommon.Services.Units +{ + public interface IConvertUnitLogic + { + IMathRoundLogic MathRoundLogic { get; set; } + ValuePair Convert(IUnit unit, string unitName, object value); + double ConvertBack(UnitTypes unitType, IUnit unit, object value); + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Services/Units/IGetUnitLogic.cs b/StructureHelperCommon/Services/Units/IGetUnitLogic.cs new file mode 100644 index 0000000..40fba7a --- /dev/null +++ b/StructureHelperCommon/Services/Units/IGetUnitLogic.cs @@ -0,0 +1,9 @@ +using StructureHelperCommon.Infrastructures.Enums; + +namespace StructureHelperCommon.Services.Units +{ + public interface IGetUnitLogic + { + IUnit GetUnit(UnitTypes unitType, string unitName = null); + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Services/Units/IStringDoublePair.cs b/StructureHelperCommon/Services/Units/IStringDoublePair.cs deleted file mode 100644 index 6856098..0000000 --- a/StructureHelperCommon/Services/Units/IStringDoublePair.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperCommon.Services.Units -{ - public interface IStringDoublePair - { - double Digit { get; } - string Text { get; } - } -} diff --git a/StructureHelperCommon/Services/Units/ProcessString.cs b/StructureHelperCommon/Services/Units/ProcessString.cs new file mode 100644 index 0000000..4cf1978 --- /dev/null +++ b/StructureHelperCommon/Services/Units/ProcessString.cs @@ -0,0 +1,25 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Services.Units +{ + public static class ProcessString + { + public static double ConvertCommaToCultureSettings(string s) + { + double result; + if (!double.TryParse(s, NumberStyles.Any, CultureInfo.CurrentCulture, out result) && + !double.TryParse(s, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) && + !double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) + { + throw new StructureHelperException($"{ErrorStrings.IncorrectValue}: {s}"); + } + return result; + } + } +} diff --git a/StructureHelperCommon/Services/Units/UnitsFactory.cs b/StructureHelperCommon/Services/Units/UnitsFactory.cs index 53fd969..0219cba 100644 --- a/StructureHelperCommon/Services/Units/UnitsFactory.cs +++ b/StructureHelperCommon/Services/Units/UnitsFactory.cs @@ -5,6 +5,10 @@ namespace StructureHelperCommon.Services.Units { public static class UnitsFactory { + /// + /// Returns collection of unit + /// + /// public static List GetUnitCollection() { List units = new List(); @@ -28,8 +32,8 @@ namespace StructureHelperCommon.Services.Units type = UnitTypes.Moment; units.Add(new Unit() { UnitType = type, Name = "Nm", Multiplyer = 1d }); units.Add(new Unit() { UnitType = type, Name = "kNm", Multiplyer = 1e-3d }); - units.Add(new Unit() { UnitType = type, Name = "kgfm", Multiplyer = 9.8d }); - units.Add(new Unit() { UnitType = type, Name = "tfm", Multiplyer = 9.8e-3d }); + units.Add(new Unit() { UnitType = type, Name = "kgfm", Multiplyer = 9.81d }); + units.Add(new Unit() { UnitType = type, Name = "tfm", Multiplyer = 9.81e-3d }); type = UnitTypes.Curvature; units.Add(new Unit() { UnitType = type, Name = "1/m", Multiplyer = 1d }); units.Add(new Unit() { UnitType = type, Name = "1/mm", Multiplyer = 1e-3d }); diff --git a/StructureHelperLogics/Models/Materials/IConcreteLibMaterial.cs b/StructureHelperLogics/Models/Materials/IConcreteLibMaterial.cs index ee1fd73..1b8c339 100644 --- a/StructureHelperLogics/Models/Materials/IConcreteLibMaterial.cs +++ b/StructureHelperLogics/Models/Materials/IConcreteLibMaterial.cs @@ -1,4 +1,5 @@ -using StructureHelperCommon.Models.Materials.Libraries; +using StructureHelperCommon.Models.Materials; +using StructureHelperCommon.Models.Materials.Libraries; using System; using System.Collections.Generic; using System.Linq; @@ -7,10 +8,8 @@ using System.Threading.Tasks; namespace StructureHelperLogics.Models.Materials { - public interface IConcreteLibMaterial : ILibMaterial + public interface IConcreteLibMaterial : ILibMaterial, ICrackedMaterial { - bool TensionForULS { get; set; } - bool TensionForSLS { get; set; } /// /// Humidity of concrete /// diff --git a/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs b/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs index c4823bd..7f5d3d6 100644 --- a/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs +++ b/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs @@ -1,6 +1,7 @@ using StructureHelperCommon.Models; using StructureHelperCommon.Models.Calculators; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Cracking; namespace StructureHelperLogics.Models.Templates.CrossSections { @@ -8,14 +9,21 @@ namespace StructureHelperLogics.Models.Templates.CrossSections { public IEnumerable GetNdmCalculators() { - var calculators = new List + var calculators = new List(); + var forceCalculator = new ForceCalculator() { - new ForceCalculator() - { - Name = "New Force Calculator", - TraceLogger = new ShiftTraceLogger() - } + Name = "New Force Calculator", + TraceLogger = new ShiftTraceLogger() }; + calculators.Add(forceCalculator); + CrackInputData newInputData = new CrackInputData(); + var checkLogic = new CheckCrackCalculatorInputDataLogic(newInputData); + var crackCalculator = new CrackCalculator(newInputData, checkLogic) + { + Name = "New Crack Calculator", + TraceLogger = new ShiftTraceLogger() + }; + calculators.Add(crackCalculator); return calculators; } } diff --git a/StructureHelperLogics/Models/Templates/CrossSections/RCs/SectionTemplate.cs b/StructureHelperLogics/Models/Templates/CrossSections/RCs/SectionTemplate.cs index dedcb13..7ce2603 100644 --- a/StructureHelperLogics/Models/Templates/CrossSections/RCs/SectionTemplate.cs +++ b/StructureHelperLogics/Models/Templates/CrossSections/RCs/SectionTemplate.cs @@ -4,6 +4,7 @@ using StructureHelperCommon.Models.Forces; using StructureHelperLogics.Models.CrossSections; using StructureHelperLogics.Models.Templates.RCs; using StructureHelperLogics.NdmCalculations.Analyses; +using StructureHelperLogics.NdmCalculations.Cracking; using StructureHelperLogics.NdmCalculations.Primitives; using System; using System.Collections.Generic; @@ -62,6 +63,10 @@ namespace StructureHelperLogics.Models.Templates.CrossSections.RCs var forceCalculator = calculator as IHasForceCombinations; forceCalculator.ForceActions.AddRange(combinations); } + if (calculator is CrackCalculator crackCalculator) + { + crackCalculator.InputData.ForceActions.AddRange(combinations); + } } } private void AddAllPrimitivesToCalculator() @@ -73,6 +78,10 @@ namespace StructureHelperLogics.Models.Templates.CrossSections.RCs var primitiveCalculator = calculator as IHasPrimitives; primitiveCalculator.Primitives.AddRange(primitives); } + if (calculator is CrackCalculator crackCalculator) + { + crackCalculator.InputData.Primitives.AddRange(primitives); + } } } } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs index 93e7fc2..1101562 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs @@ -1,12 +1,12 @@ using LoaderCalculator.Data.Ndms; using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Models; using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; using StructureHelperCommon.Models.Sections; +using StructureHelperCommon.Models.Sections.Logics; using StructureHelperCommon.Models.Shapes; -using StructureHelperCommon.Services.Forces; using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics; using StructureHelperLogics.NdmCalculations.Buckling; using StructureHelperLogics.NdmCalculations.Primitives; @@ -19,6 +19,10 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces static readonly ForceCalculatorUpdateStrategy updateStrategy = new(); private readonly IForceTupleCalculator forceTupleCalculator; private ForcesResults result; + private IProcessorLogic eccentricityLogic; + private ForceTupleBucklingLogic bucklingLogic; + private ITriangulatePrimitiveLogic triangulateLogic; + public string Name { get; set; } public List LimitStatesList { get; private set; } @@ -34,8 +38,9 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public void Run() { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); var checkResult = CheckInputData(); - if (checkResult != "") + if (checkResult != string.Empty) { Result = new ForcesResults() { @@ -44,11 +49,8 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces }; return; } - else - { - GetCombinations(); - CalculateResult(); - } + GetCombinations(); + CalculateResult(); } private void CalculateResult() @@ -93,43 +95,36 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces IForcesTupleResult tupleResult; LimitStates limitState = tuple.LimitState; CalcTerms calcTerm = tuple.CalcTerm; - var ndms = NdmPrimitivesService.GetNdms(Primitives, limitState, calcTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = Primitives, + LimitState = limitState, + CalcTerm = calcTerm, + TraceLogger = TraceLogger + }; + var ndms = triangulateLogic.GetNdms(); IPoint2D point2D; + IProcessorLogic forcelogic = new ForceTupleCopier(tuple.ForceTuple); if (combination.SetInGravityCenter == true) { var (Cx, Cy) = LoaderCalculator.Logics.Geometry.GeometryOperations.GetGravityCenter(ndms); - point2D = new Point2D(){ X = Cx, Y = Cy }; + point2D = new Point2D() { X = Cx, Y = Cy }; + forcelogic = new ForceTupleMoveToPointDecorator(forcelogic) { Point2D = point2D}; } - else point2D = combination.ForcePoint; - var newTuple = ForceTupleService.MoveTupleIntoPoint(tuple.ForceTuple, point2D); - TraceLogger?.AddMessage($"Input force combination"); + var newTuple = forcelogic.GetValue(); + TraceLogger?.AddMessage("Input force combination"); TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(newTuple)); if (CompressedMember.Buckling == true) { if (newTuple.Nz >= 0d) { TraceLogger?.AddMessage(string.Format("Second order effect is not considered as Nz={0} >= 0", newTuple.Nz)); + tupleResult = GetForceResult(limitState, calcTerm, ndms, newTuple); } else { - TraceLogger?.AddMessage("Get eccentricity for full load"); - newTuple = ProcessAccEccentricity(ndms, newTuple); - var buckResult = GetForceTupleByBuckling(combination, limitState, calcTerm, ndms, newTuple); - if (buckResult.isValid == true) - { - newTuple = buckResult.tuple; - } - else - { - return new ForcesTupleResult() - { - IsValid = false, - DesignForceTuple = tuple, - Description = buckResult.description, - }; - } - } - tupleResult = GetForceResult(limitState, calcTerm, ndms, newTuple); + tupleResult = ProcessCompressedMember(combination, tuple, ndms, newTuple); + } } else { @@ -143,10 +138,19 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces return tupleResult; } - private (bool isValid, IForceTuple tuple, string description) GetForceTupleByBuckling(IForceCombinationList combination, LimitStates limitState, CalcTerms calcTerm, List ndms, IForceTuple newTuple) + private IForcesTupleResult ProcessCompressedMember(IForceCombinationList combination, IDesignForceTuple tuple, List ndms, IForceTuple newTuple) { - var tuple = newTuple.Clone() as IForceTuple; - var inputData = new BucklingInputData() + IForcesTupleResult tupleResult; + LimitStates limitState = tuple.LimitState; + CalcTerms calcTerm = tuple.CalcTerm; + + TraceLogger?.AddMessage("Get eccentricity for full load"); + eccentricityLogic = new ProcessEccentricity(CompressedMember, ndms, newTuple) + { + TraceLogger = TraceLogger ?? null + }; + newTuple = eccentricityLogic.GetValue(); + var buclingInputData = new BucklingInputData() { Combination = combination, LimitState = limitState, @@ -154,127 +158,48 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces Ndms = ndms, ForceTuple = newTuple }; - var bucklingResult = ProcessBuckling(inputData); - - if (bucklingResult.IsValid != true) + bucklingLogic = new ForceTupleBucklingLogic(buclingInputData) { - TraceLogger?.AddMessage(bucklingResult.Description, TraceLogStatuses.Error); - return (false, tuple, $"Buckling result:\n{bucklingResult.Description}"); + CompressedMember = CompressedMember, + Accuracy = Accuracy, + Primitives = Primitives, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + var buckResult = bucklingLogic.GetForceTupleByBuckling(); + if (buckResult.IsValid == true) + { + newTuple = buckResult.Value; } else { - tuple = CalculateBuckling(tuple, bucklingResult); - TraceLogger?.AddMessage(string.Intern("Force combination with considering of second order effects")); - TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(tuple)); + return new ForcesTupleResult() + { + IsValid = false, + DesignForceTuple = tuple, + Description = buckResult.Description, + }; } - - return (true, tuple, string.Empty); + TraceLogger?.AddMessage(string.Intern("Result of second order was obtained succesfully, new force combination was obtained")); + tupleResult = GetForceResult(limitState, calcTerm, ndms, newTuple); + return tupleResult; } private IForcesTupleResult GetForceResult(LimitStates limitState, CalcTerms calcTerm, List ndms, IForceTuple newTuple) { + TraceLogger?.AddMessage("Calculation of cross-section is started"); var tupleResult = GetPrimitiveStrainMatrix(ndms, newTuple, Accuracy); tupleResult.DesignForceTuple.LimitState = limitState; tupleResult.DesignForceTuple.CalcTerm = calcTerm; tupleResult.DesignForceTuple.ForceTuple = newTuple; return tupleResult; - } - private IForceTuple ProcessAccEccentricity(List ndms, IForceTuple tuple) - { - var newTuple = tuple.Clone() as IForceTuple; - var accLogic = new AccidentalEccentricityLogic() - { - Length = CompressedMember.GeometryLength, - SizeX = ndms.Max(x => x.CenterX) - ndms.Min(x => x.CenterX), - SizeY = ndms.Max(x => x.CenterY) - ndms.Min(x => x.CenterY), - InitialForceTuple = newTuple, - }; - if (TraceLogger is not null) - { - accLogic.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - newTuple = accLogic.GetForceTuple(); - return newTuple; - } - - private IConcreteBucklingResult ProcessBuckling(BucklingInputData inputData) - { - IForceTuple resultTuple; - IForceTuple longTuple; - if (inputData.CalcTerm == CalcTerms.LongTerm) - { - longTuple = inputData.ForceTuple; - } - else - { - longTuple = GetLongTuple(inputData.Combination.DesignForces, inputData.LimitState); - } - TraceLogger?.AddMessage("Get eccentricity for long term load"); - longTuple = ProcessAccEccentricity(inputData.Ndms, longTuple); - var bucklingCalculator = GetBucklingCalculator(CompressedMember, inputData.LimitState, inputData.CalcTerm, inputData.ForceTuple, longTuple); - if (TraceLogger is not null) - { - bucklingCalculator.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - bucklingCalculator.Run(); - var bucklingResult = bucklingCalculator.Result as IConcreteBucklingResult; - - return bucklingResult; - } - - private IForceTuple GetLongTuple(List designForces, LimitStates limitState) - { - IForceTuple longTuple; - try - { - longTuple = designForces - .Where(x => x.LimitState == limitState & x.CalcTerm == CalcTerms.LongTerm) - .Single() - .ForceTuple; - } - catch (Exception) - { - longTuple = new ForceTuple(); - } - return longTuple; - } - - private IConcreteBucklingCalculator GetBucklingCalculator(ICompressedMember compressedMember, LimitStates limitStates, CalcTerms calcTerms, IForceTuple calcTuple, IForceTuple longTuple) - { - var options = new ConcreteBucklingOptions() - { - CompressedMember = compressedMember, - LimitState = limitStates, - CalcTerm = calcTerms, - CalcForceTuple = calcTuple, - LongTermTuple = longTuple, - Primitives = Primitives - }; - var bucklingCalculator = new ConcreteBucklingCalculator(options, Accuracy); - return bucklingCalculator; - } - - private ForceTuple CalculateBuckling(IForceTuple calcTuple, IConcreteBucklingResult bucklingResult) - { - var newTuple = calcTuple.Clone() as ForceTuple; - newTuple.Mx *= bucklingResult.EtaFactorAlongY; - newTuple.My *= bucklingResult.EtaFactorAlongX; - return newTuple; - } - - private string CheckInputData() { - string result = ""; - try + string result = string.Empty; + if (! Primitives.Any()) { - NdmPrimitivesService.CheckPrimitives(Primitives); - } - catch (Exception ex) - { - result += ex; + result += "Calculator does not contain any primitives \n"; } if (ForceActions.Count == 0) { @@ -286,8 +211,20 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces } if (CalcTermsList.Count == 0) { - result += "Calculator does not contain any duration \n"; + result += "Calculator does not contain any calc term \n"; } + //try + //{ + // triangulateLogic = new TriangulatePrimitiveLogic() + // { + // Primitives = Primitives + // }; + // triangulateLogic.CheckPrimitives(Primitives); + //} + //catch (Exception ex) + //{ + // result += ex; + //} return result; } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/Factories/PredicateFactory.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/Factories/PredicateFactory.cs index a0e746b..7947d3c 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/Factories/PredicateFactory.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/Factories/PredicateFactory.cs @@ -83,7 +83,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces private bool IsSectionCracked(IPoint2D point2D) { logger?.TraceLoggerEntries.Clear(); - var logic = new HoleSectionCrackedLogic(); + var logic = new SectionCrackedLogic(); var point3D = ConvertLogic.GetPoint3D(point2D); tuple = new() { diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs index e160803..b463e6d 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs @@ -60,14 +60,16 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces private void MultiThreadProc(IEnumerable points) { Task[] tasks = new Task[points.Count()]; - for (int i = 0; i < points.Count(); i++) + int pointCount = points.Count(); + List PointList = points.ToList(); + for (int i = 0; i < pointCount; i++) { - var point = points.ToList()[i]; + var point = PointList[i]; tasks[i] = new Task(() => FindResultPoint(point)); tasks[i].Start(); } Task.WaitAll(tasks); - for (int j = 0; j < points.Count(); j++) + for (int j = 0; j < pointCount; j++) { var taskResult = tasks[j].Result; resultList.Add(taskResult); diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs index 83db6dc..65984d0 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs @@ -15,6 +15,8 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { private LimitCurvesResult result; private int curvesIterationCount; + private ITriangulatePrimitiveLogic triangulateLogic; + private LimitCurvesCalculatorUpdateStrategy updateStrategy => new(); public Guid Id { get; } @@ -78,7 +80,14 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { foreach (var calcTerm in InputData.CalcTerms) { - var ndms = NdmPrimitivesService.GetNdms(primitiveSeries.Collection, limitState, calcTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = primitiveSeries.Collection, + LimitState = limitState, + CalcTerm = calcTerm, + TraceLogger = TraceLogger + }; + var ndms = triangulateLogic.GetNdms(); TraceLogger?.AddMessage($"Number of elementary parts N={ndms.Count()} were obtainded succesfully"); TraceLogger?.AddMessage($"Summary area of elementary parts Asum={ndms.Sum(x=>x.Area * x.StressScale)}", TraceLogStatuses.Debug); foreach (var predicateEntry in InputData.PredicateEntries) diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs index 0a412a5..63295aa 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs @@ -50,7 +50,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces Point2D minPoint = new(), maxPoint = new(); foreach (var item in ndmCollection) { - var strain = stressLogic.GetTotalStrain(strainMatrix, item); + var strain = stressLogic.GetSectionStrain(strainMatrix, item); if (strain < minStrain) { minStrain = strain; diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ExportGeometryResultToCSVLogic.cs b/StructureHelperLogics/NdmCalculations/Analyses/ExportGeometryResultToCSVLogic.cs index 8c6ba64..d701a1e 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ExportGeometryResultToCSVLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ExportGeometryResultToCSVLogic.cs @@ -55,7 +55,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses { item.Name, item.ShortName, - item.MeasurementUnit, + item.Text, item.Value.ToString(), item.Description }; diff --git a/StructureHelperLogics/NdmCalculations/Analyses/Logics/CalculatorUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Analyses/Logics/CalculatorUpdateStrategy.cs index 46423ab..cc6eada 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/Logics/CalculatorUpdateStrategy.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/Logics/CalculatorUpdateStrategy.cs @@ -5,6 +5,7 @@ using StructureHelperCommon.Services; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve; using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics; +using StructureHelperLogics.NdmCalculations.Cracking; using StructureHelperLogics.NdmCalculations.Primitives; using System; using System.Collections.Generic; @@ -28,6 +29,10 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.Logics { new LimitCurvesCalculatorUpdateStrategy().Update(limitCurves, (LimitCurvesCalculator)sourceObject); } + else if (targetObject is CrackCalculator crackCalculator) + { + new CrackCalculatorUpdateStrategy().Update(crackCalculator, (CrackCalculator)sourceObject); + } else { ErrorCommonProcessor.ObjectTypeIsUnknown(typeof(INdmPrimitive), sourceObject.GetType()); diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs index a0b557a..88884c6 100644 --- a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs @@ -2,6 +2,7 @@ using LoaderCalculator.Data.Ndms; using LoaderCalculator.Logics; using LoaderCalculator.Logics.Geometry; +using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Models; using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; @@ -24,6 +25,7 @@ namespace StructureHelperLogics.NdmCalculations.Buckling private List concreteNdms; private List otherNdms; IForcesTupleResult forcesResults; + private ITriangulatePrimitiveLogic triangulateLogic; public string Name { get; set; } @@ -52,11 +54,77 @@ namespace StructureHelperLogics.NdmCalculations.Buckling Accuracy = accuracy; var allPrimitives = options.Primitives; - ndmCollection = NdmPrimitivesService.GetNdms(allPrimitives, options.LimitState, options.CalcTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = allPrimitives, + LimitState = options.LimitState, + CalcTerm = options.CalcTerm + }; + ndmCollection = triangulateLogic.GetNdms(); concreteNdms = ndmCollection.Where(x => x.Material is ICrackMaterial).ToList(); otherNdms = ndmCollection.Except(concreteNdms).ToList(); } + public void Run() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(LoggerStrings.MethodBasedOn + "SP63.13330.2018"); + var checkResult = CheckInputData(); + if (checkResult != "") + { + ProcessFalseResult(checkResult); + return; + } + else + { + ProcessValidResult(); + } + TraceLogger?.AddMessage(LoggerStrings.CalculationHasDone); + } + + private void ProcessValidResult() + { + var phiLLogic = GetPhiLogic(); + var (DeltaLogicAboutX, DeltaLogicAboutY) = GetDeltaLogics(); + stiffnessLogicX = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutX); + stiffnessLogicY = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutY); + if (TraceLogger is not null) + { + stiffnessLogicX.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + stiffnessLogicY.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + } + criticalForceLogic = new EilerCriticalForceLogic(); + if (TraceLogger is not null) + { + criticalForceLogic.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + } + + var (EtaFactorX, EtaFactorY) = GetBucklingCoefficients(); + var messageString = "Eta factor orbitrary {0} axis, Eta{0} = {1} (dimensionless)"; + var messageStringX = string.Format(messageString, "X", EtaFactorX); + var messageStringY = string.Format(messageString, "Y", EtaFactorY); + TraceLogger?.AddMessage(messageStringX); + TraceLogger?.AddMessage(messageStringY); + Result = new ConcreteBucklingResult() + { + IsValid = true, + EtaFactorAlongX = EtaFactorX, + EtaFactorAlongY = EtaFactorY + }; + } + + private void ProcessFalseResult(string checkResult) + { + TraceLogger?.AddMessage(checkResult, TraceLogStatuses.Error); + Result = new ConcreteBucklingResult() + { + IsValid = false, + Description = checkResult, + EtaFactorAlongX = double.PositiveInfinity, + EtaFactorAlongY = double.PositiveInfinity + }; + } + private (IConcreteDeltaELogic DeltaLogicX, IConcreteDeltaELogic DeltaLogicY) GetDeltaLogics() { IForceTuple forceTuple = options.CalcForceTuple; @@ -66,6 +134,15 @@ namespace StructureHelperLogics.NdmCalculations.Buckling } var eccentricityAlongX = options.CalcForceTuple.My / forceTuple.Nz; var eccentricityAlongY = options.CalcForceTuple.Mx / forceTuple.Nz; + const string eccMesssage = "Eccentricity along {0}-axis e{0} = {1}(N * m) / {2}(N) = {3}(m)"; + TraceLogger?.AddMessage(string.Format(eccMesssage, + "x", + options.CalcForceTuple.My, forceTuple.Nz, + eccentricityAlongX)); + TraceLogger?.AddMessage(string.Format(eccMesssage, + "y", + options.CalcForceTuple.Mx, forceTuple.Nz, + eccentricityAlongY)); var sizeAlongX = ndmCollection.Max(x => x.CenterX) - ndmCollection.Min(x => x.CenterX); var sizeAlongY = ndmCollection.Max(x => x.CenterY) - ndmCollection.Min(x => x.CenterY); var DeltaElogicAboutX = new DeltaELogicSP63(eccentricityAlongY, sizeAlongY); @@ -82,7 +159,7 @@ namespace StructureHelperLogics.NdmCalculations.Buckling { const string sumStif = "Summary stiffness"; var gravityCenter = GeometryOperations.GetGravityCenter(ndmCollection); - string message = string.Format("Gravity center, x = {0}, y = {1}", gravityCenter.Cx, gravityCenter.Cy); + string message = string.Format("Gravity center, x = {0}(m), y = {1}(m)", gravityCenter.Cx, gravityCenter.Cy); TraceLogger?.AddMessage(message); if (TraceLogger is not null) { @@ -128,7 +205,7 @@ namespace StructureHelperLogics.NdmCalculations.Buckling var stressLogic = new StressLogic(); foreach (var item in ndmCollection) { - var strain = stressLogic.GetTotalStrain(strains, item); + var strain = stressLogic.GetSectionStrain(strains, item); if (strain > maxStrain) { maxStrain = strain; @@ -152,55 +229,7 @@ namespace StructureHelperLogics.NdmCalculations.Buckling return calculator; } - public void Run() - { - TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); - TraceLogger?.AddMessage(LoggerStrings.MethodBasedOn + "SP63.13330.2018"); - var checkResult = CheckInputData(); - if (checkResult != "") - { - TraceLogger?.AddMessage(checkResult, TraceLogStatuses.Error); - Result = new ConcreteBucklingResult() - { - IsValid = false, - Description = checkResult, - EtaFactorAlongX = double.PositiveInfinity, - EtaFactorAlongY = double.PositiveInfinity - }; - return; - } - else - { - var phiLLogic = GetPhiLogic(); - var (DeltaLogicAboutX, DeltaLogicAboutY) = GetDeltaLogics(); - stiffnessLogicX = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutX); - stiffnessLogicY = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutY); - if (TraceLogger is not null) - { - stiffnessLogicX.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - stiffnessLogicY.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - criticalForceLogic = new EilerCriticalForceLogic(); - if (TraceLogger is not null) - { - criticalForceLogic.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - - var (EtaFactorX, EtaFactorY) = GetBucklingCoefficients(); - var messageString = "Eta factor orbitrary {0} axis, Eta{0} = {1} (dimensionless)"; - var messageStringX = string.Format(messageString, "X", EtaFactorX); - var messageStringY = string.Format(messageString, "Y", EtaFactorY); - TraceLogger?.AddMessage(messageStringX); - TraceLogger?.AddMessage(messageStringY); - Result = new ConcreteBucklingResult() - { - IsValid = true, - EtaFactorAlongX = EtaFactorX, - EtaFactorAlongY = EtaFactorY - }; - } - TraceLogger?.AddMessage(LoggerStrings.CalculationHasDone); - } + private string CheckInputData() { diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ForceTupleBucklingLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/ForceTupleBucklingLogic.cs new file mode 100644 index 0000000..e3e0d09 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ForceTupleBucklingLogic.cs @@ -0,0 +1,136 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using StructureHelperCommon.Models.Sections; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperCommon.Models.Loggers; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class ForceTupleBucklingLogic : IForceTupleBucklingLogic + { + private IProcessorLogic eccentricityLogic; + private BucklingInputData bucklingInputData; + + public ICompressedMember CompressedMember { get; set; } + public IAccuracy Accuracy { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public IEnumerable Primitives { get; set; } + + public ForceTupleBucklingLogic(BucklingInputData inputData) + { + bucklingInputData = inputData; + } + + public GenericResult GetForceTupleByBuckling() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + + var tuple = bucklingInputData.ForceTuple.Clone() as IForceTuple; + + var bucklingResult = ProcessBuckling(bucklingInputData); + + if (bucklingResult.IsValid != true) + { + TraceLogger?.AddMessage(bucklingResult.Description, TraceLogStatuses.Error); + var tupleResult = new GenericResult() + { + IsValid = false, + Description = $"Buckling result:\n{bucklingResult.Description}", + Value = tuple + }; + return tupleResult; + } + else + { + tuple = CalculateBuckling(tuple, bucklingResult); + TraceLogger?.AddMessage(string.Intern("Force combination with considering of second order effects")); + TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(tuple)); + } + var trueTupleResult = new GenericResult() + { + IsValid = true, + Description = string.Empty, + Value = tuple + }; + return trueTupleResult; + } + + private IConcreteBucklingResult ProcessBuckling(BucklingInputData inputData) + { + IForceTuple resultTuple; + IForceTuple longTuple; + if (inputData.CalcTerm == CalcTerms.LongTerm) + { + longTuple = inputData.ForceTuple; + } + else + { + longTuple = GetLongTuple(inputData.Combination.DesignForces, inputData.LimitState); + } + TraceLogger?.AddMessage("Get eccentricity for long term load"); + eccentricityLogic = new ProcessEccentricity(CompressedMember, inputData.Ndms, longTuple) + { + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + longTuple = eccentricityLogic.GetValue(); + var bucklingCalculator = GetBucklingCalculator(inputData.LimitState, inputData.CalcTerm, inputData.ForceTuple, longTuple); + if (TraceLogger is not null) + { + bucklingCalculator.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + } + bucklingCalculator.Run(); + var bucklingResult = bucklingCalculator.Result as IConcreteBucklingResult; + + return bucklingResult; + } + + private IForceTuple GetLongTuple(List designForces, LimitStates limitState) + { + IForceTuple longTuple; + try + { + longTuple = designForces + .Where(x => x.LimitState == limitState & x.CalcTerm == CalcTerms.LongTerm) + .Single() + .ForceTuple; + } + catch (Exception) + { + longTuple = new ForceTuple(); + } + return longTuple; + } + + private IConcreteBucklingCalculator GetBucklingCalculator(LimitStates limitStates, CalcTerms calcTerms, IForceTuple calcTuple, IForceTuple longTuple) + { + var options = new ConcreteBucklingOptions() + { + CompressedMember = CompressedMember, + LimitState = limitStates, + CalcTerm = calcTerms, + CalcForceTuple = calcTuple, + LongTermTuple = longTuple, + Primitives = Primitives + }; + var bucklingCalculator = new ConcreteBucklingCalculator(options, Accuracy); + return bucklingCalculator; + } + + private ForceTuple CalculateBuckling(IForceTuple calcTuple, IConcreteBucklingResult bucklingResult) + { + var newTuple = calcTuple.Clone() as ForceTuple; + newTuple.Mx *= bucklingResult.EtaFactorAlongY; + newTuple.My *= bucklingResult.EtaFactorAlongX; + return newTuple; + } + + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IForceTupleBucklingLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/IForceTupleBucklingLogic.cs new file mode 100644 index 0000000..2fcd9f8 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IForceTupleBucklingLogic.cs @@ -0,0 +1,13 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public interface IForceTupleBucklingLogic : ILogic + { + GenericResult GetForceTupleByBuckling(); + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ProcessEccentricity.cs b/StructureHelperLogics/NdmCalculations/Buckling/ProcessEccentricity.cs new file mode 100644 index 0000000..8932242 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ProcessEccentricity.cs @@ -0,0 +1,57 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Sections; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using StructureHelperCommon.Models.Loggers; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class ProcessEccentricity : IProcessorLogic + { + private IProcessorLogic eccentricityLogic; + + public ICompressedMember CompressedMember { get; private set; } + public IEnumerable Ndms { get; private set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public IForceTuple InputForceTuple { get; set; } + + private double sizeX; + private double sizeY; + + public ProcessEccentricity(IProcessorLogic eccentricityLogic) + { + this.eccentricityLogic = eccentricityLogic; + } + public ProcessEccentricity(ICompressedMember compressedMember, IEnumerable ndms, IForceTuple initialForceTuple) + { + CompressedMember = compressedMember; + Ndms = ndms; + InputForceTuple = initialForceTuple; + sizeX = ndms.Max(x => x.CenterX) - ndms.Min(x => x.CenterX); + sizeY = ndms.Max(x => x.CenterY) - ndms.Min(x => x.CenterY); + eccentricityLogic = new RcEccentricityLogic() + { + InputForceTuple = InputForceTuple, + Length = CompressedMember.GeometryLength, + SizeX = sizeX, + SizeY = sizeY, + }; + } + + public IForceTuple GetValue() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage("Get eccentricity taking into account accidental eccentricity"); + TraceLogger?.AddMessage(string.Format("Cross-section size along x-axis dx = {0}, along y-axis dy = {1}", sizeX, sizeY)); + + eccentricityLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + var newTuple = eccentricityLogic.GetValue(); + return newTuple; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/AverageDiameterLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/AverageDiameterLogic.cs deleted file mode 100644 index 23cde59..0000000 --- a/StructureHelperLogics/NdmCalculations/Cracking/AverageDiameterLogic.cs +++ /dev/null @@ -1,33 +0,0 @@ -using LoaderCalculator.Data.Ndms; -using StructureHelperCommon.Infrastructures.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.NdmCalculations.Cracking -{ - public class AverageDiameterLogic : IAverageDiameterLogic - { - public IEnumerable Rebars { get; set; } - - public double GetAverageDiameter() - { - Check(); - var rebarArea = Rebars - .Sum(x => x.Area); - var rebarCount = Rebars.Count(); - var averageArea = rebarArea / rebarCount; - var diameter = Math.Sqrt(averageArea / Math.PI); - return diameter; - } - private void Check() - { - if (!Rebars.Any()) - { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": rebars count must be greater then zero"); - } - } - } -} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CheckCrackCalculatorInputDataLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/CheckCrackCalculatorInputDataLogic.cs new file mode 100644 index 0000000..676ed3e --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CheckCrackCalculatorInputDataLogic.cs @@ -0,0 +1,119 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Logic of checking of input data for crack calcultor + /// + public class CheckCrackCalculatorInputDataLogic : ICheckInputDataLogic + { + private string checkResult; + private CrackInputData inputData; + private bool result; + + public IInputData InputData + { + get => inputData; + set + { + if (value is CrackInputData data) + { + inputData = data; + } + else + { + throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(CrackInputData), value)); + } + } + } + + public string CheckResult => checkResult; + + public IShiftTraceLogger? TraceLogger { get; set; } + public CheckCrackCalculatorInputDataLogic(CrackInputData inputData) + { + this.inputData = inputData; + } + public bool Check() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Debug); + result = true; + checkResult = string.Empty; + CheckPrimitives(); + CheckActions(); + return result; + } + + private void CheckActions() + { + if (inputData.ForceActions is null || (!inputData.ForceActions.Any())) + { + result = false; + string message = "Calculator does not contain any actions\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + }; + } + + private void CheckPrimitives() + { + if (inputData.Primitives is null || (!inputData.Primitives.Any())) + { + result = false; + string message = "Calculator does not contain any primitives\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + else + { + foreach (var primitive in inputData.Primitives) + { + if (primitive is RebarPrimitive rebar) + { + CheckRebar(rebar); + } + } + } + } + + private void CheckRebar(RebarPrimitive rebar) + { + if (rebar.HostPrimitive is null) + { + result = false; + string message = $"Primitive {rebar.Name} does not have a host\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + else + { + bool isPrimitivesContainRebarHost = inputData.Primitives.Contains(rebar.HostPrimitive); + if (isPrimitivesContainRebarHost == false) + { + result = false; + string message = $"Host {rebar.Name}({rebar.HostPrimitive.Name}) is not included in primitives\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + } + if (rebar.HostPrimitive.HeadMaterial.HelperMaterial is not ICrackedMaterial) + { + result = false; + string message = $"Material of host of {rebar.Name} does not support cracking\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CheckTupleCalculatorInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/CheckTupleCalculatorInputData.cs new file mode 100644 index 0000000..a22968b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CheckTupleCalculatorInputData.cs @@ -0,0 +1,44 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CheckTupleCalculatorInputData : ICheckInputDataLogic + { + private string checkResult; + private TupleCrackInputData inputData; + private bool result; + + public IInputData InputData + { + get => inputData; set + { + if (value is TupleCrackInputData data) + { + inputData = data; + } + else + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect); + } + } + } + + public string CheckResult => checkResult; + + public IShiftTraceLogger? TraceLogger { get; set; } + + public bool Check() + { + result = true; + return result; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs new file mode 100644 index 0000000..3ff8f64 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs @@ -0,0 +1,116 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Infrastructures.Settings; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackCalculator : ICalculator + { + const LimitStates limitState = LimitStates.SLS; + const CalcTerms longTerm = CalcTerms.LongTerm; + const CalcTerms shortTerm = CalcTerms.ShortTerm; + private const double maxSizeOfCrossSection = 1d; + private CrackResult result; + private IGetTupleInputDatasLogic datasLogic; + private CrackCalculatorUpdateStrategy updateStrategy = new(); + private ICheckInputDataLogic checkInputDataLogic; + + public string Name { get; set; } + public CrackInputData InputData { get; set; } + public IResult Result => result; + + public IShiftTraceLogger? TraceLogger { get; set; } + public CrackCalculator(CrackInputData inputData, ICheckInputDataLogic checkInputDataLogic) + { + InputData = inputData; + this.checkInputDataLogic = checkInputDataLogic; + } + + public object Clone() + { + CrackInputData crackInputData = new CrackInputData(); + var checkDataLogic = new CheckCrackCalculatorInputDataLogic(InputData); + var newItem = new CrackCalculator(crackInputData, checkDataLogic); + updateStrategy.Update(newItem, this); + return newItem; + } + + public void Run() + { + PrepareNewResult(); + CheckInputData(); + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + try + { + ProcessCalculations(); + TraceLogger?.AddMessage(LoggerStrings.CalculationHasDone); + } + catch (Exception ex) + { + result.IsValid = false; + result.Description += ex; + TraceLogger?.AddMessage(LoggerStrings.CalculationError + ex, TraceLogStatuses.Error); + } + } + + private void CheckInputData() + { + checkInputDataLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + if (checkInputDataLogic.Check() == false) + { + result.IsValid = false; + result.Description += checkInputDataLogic.CheckResult; + } + } + + private void ProcessCalculations() + { + datasLogic = new GetTupleInputDatasLogic(InputData.Primitives, InputData.ForceActions, InputData.UserCrackInputData) + { + LimitState = limitState, + LongTerm = longTerm, + ShortTerm = shortTerm, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + var dx = InputData.Primitives.Max(x => x.GetValuePoints().Max(y => y.Point.X)) - InputData.Primitives.Min(x => x.GetValuePoints().Min(y => y.Point.X)); + var dy = InputData.Primitives.Max(x => x.GetValuePoints().Max(y => y.Point.Y)) - InputData.Primitives.Min(x => x.GetValuePoints().Min(y => y.Point.Y)); + if (dx > maxSizeOfCrossSection || dy > maxSizeOfCrossSection) + { + string message = $"At least one of size of cross-section is greater than ultimate size MaxSize = {maxSizeOfCrossSection}(m)"; + result.Description += "Warning! " + message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Warning); + } + var datas = datasLogic.GetTupleInputDatas(); + foreach (var data in datas) + { + var calculator = new TupleCrackCalculator() + { + InputData = data, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + calculator.Run(); + var calcResult = calculator.Result as TupleCrackResult; + result.TupleResults.Add(calcResult); + } + } + + private void PrepareNewResult() + { + result = new CrackResult + { + IsValid = true, + Description = string.Empty + }; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculatorUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculatorUpdateStrategy.cs new file mode 100644 index 0000000..72afe64 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculatorUpdateStrategy.cs @@ -0,0 +1,24 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackCalculatorUpdateStrategy : IUpdateStrategy + { + private CrackInputDataUpdateStrategy crackInputDataUpdateStrategy => new(); + public void Update(CrackCalculator targetObject, CrackCalculator sourceObject) + { + if (ReferenceEquals(targetObject, sourceObject)) { return; } + CheckObject.CompareTypes(targetObject, sourceObject); + + targetObject.Name = sourceObject.Name; + targetObject.InputData ??= new(); + crackInputDataUpdateStrategy.Update(targetObject.InputData, sourceObject.InputData); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackForceCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackForceCalculator.cs index b1290d7..3f09923 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackForceCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackForceCalculator.cs @@ -13,7 +13,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking { public class CrackForceCalculator : ICalculator { - static readonly CrackedLogic crackedLogic = new(); + private CrackedLogic crackedLogic; ExpSofteningLogic softeningLogic = new(); static readonly CrackStrainLogic crackStrainLogic = new(); static readonly SofteningFactorLogic softeningFactorLogic = new(); @@ -30,13 +30,14 @@ namespace StructureHelperLogics.NdmCalculations.Cracking public IShiftTraceLogger? TraceLogger { get; set; } - public CrackForceCalculator(IForceTupleCalculator forceTupleCalculator) + public CrackForceCalculator(CrackedLogic crackedLogic) { StartTuple ??= new ForceTuple(); Accuracy ??= new Accuracy() { IterationAccuracy = 0.0001d, MaxIterationCount = 10000 }; - this.forceTupleCalculator = forceTupleCalculator; + forceTupleCalculator = new ForceTupleCalculator(); + this.crackedLogic = crackedLogic; } - public CrackForceCalculator() : this(new ForceTupleCalculator()) + public CrackForceCalculator() : this(new CrackedLogic()) { } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackInputData.cs new file mode 100644 index 0000000..4105123 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackInputData.cs @@ -0,0 +1,35 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackInputData : IInputData, IHasPrimitives, IHasForceCombinations + { + /// + public List Primitives { get; private set; } + /// + public List ForceActions { get; private set; } + public UserCrackInputData UserCrackInputData { get; private set; } + public CrackInputData() + { + Primitives = new(); + ForceActions = new(); + UserCrackInputData = new() + { + SetSofteningFactor = true, + SofteningFactor = 1d, + SetLengthBetweenCracks = true, + LengthBetweenCracks = 0.4d, + UltimateLongCrackWidth = 0.0003d, + UltimateShortCrackWidth = 0.0004d + }; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackInputDataUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackInputDataUpdateStrategy.cs new file mode 100644 index 0000000..d018e8f --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackInputDataUpdateStrategy.cs @@ -0,0 +1,26 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackInputDataUpdateStrategy : IUpdateStrategy + { + private UserCrackInputDataUpdateStrategy userCrackInputDataUpdateStrategy => new(); + public void Update(CrackInputData targetObject, CrackInputData sourceObject) + { + if (ReferenceEquals(targetObject, sourceObject)) { return; } + CheckObject.CompareTypes(targetObject, sourceObject); + targetObject.ForceActions.Clear(); + targetObject.ForceActions.AddRange(sourceObject.ForceActions); + targetObject.Primitives.Clear(); + targetObject.Primitives.AddRange(sourceObject.Primitives); + + userCrackInputDataUpdateStrategy.Update(targetObject.UserCrackInputData, sourceObject.UserCrackInputData); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculatorResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackResult.cs similarity index 50% rename from StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculatorResult.cs rename to StructureHelperLogics/NdmCalculations/Cracking/CrackResult.cs index 0afdafe..7775cbf 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculatorResult.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackResult.cs @@ -5,17 +5,19 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + namespace StructureHelperLogics.NdmCalculations.Cracking { - public class CrackWidthCalculatorResult : IResult + public class CrackResult : IResult { public bool IsValid { get; set; } - public string Description { get; set; } - public List RebarResults { get; set; } - - public CrackWidthCalculatorResult() + public string? Description { get; set; } + public List TupleResults {get;set;} + public CrackResult() { - RebarResults = new List(); + TupleResults = new(); } } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculator.cs deleted file mode 100644 index 7d1e22e..0000000 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculator.cs +++ /dev/null @@ -1,125 +0,0 @@ -using LoaderCalculator.Data.Ndms; -using StructureHelperCommon.Infrastructures.Exceptions; -using StructureHelperCommon.Models; -using StructureHelperCommon.Models.Calculators; -using StructureHelperCommon.Models.Forces; -using StructureHelperCommon.Services.Forces; -using StructureHelperLogics.NdmCalculations.Analyses.ByForces; -using StructureHelperLogics.NdmCalculations.Primitives; -using StructureHelperLogics.Services.NdmPrimitives; - -namespace StructureHelperLogics.NdmCalculations.Cracking -{ - public class CrackWidthCalculator : ICalculator - { - static readonly ILengthBetweenCracksLogic lengthLogic = new LengthBetweenCracksLogicSP63(); - CrackWidthCalculatorResult result; - private IEnumerable ndmPrimitives; - private List? rebarPrimitives; - private IEnumerable ndmCollection; - private CrackForceResult crackForceResult; - private StrainTuple strainTuple; - - public string Name { get; set; } - public CrackWidthCalculatorInputData InputData { get; set; } - public IResult Result => result; - - public IShiftTraceLogger? TraceLogger { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public void Run() - { - result = new() { IsValid = true, Description = ""}; - try - { - ProcessCalculations(); - } - catch (Exception ex) - { - result.IsValid = false; - result.Description += ex; - } - - } - - private void ProcessCalculations() - { - CheckInputData(); - Triangulate(); - CalcStrainMatrix(); - CalcCrackForce(); - var crackInputData = GetCrackInputData(); - var calculator = new CrackWidthSimpleCalculator { InputData = crackInputData }; - foreach (var item in rebarPrimitives) - { - crackInputData.RebarPrimitive = item; - calculator.Run(); - var rebarResult = calculator.Result as CrackWidthSimpleCalculatorResult; - if (crackForceResult.IsSectionCracked == false) - { - rebarResult.CrackWidth = 0d; - } - result.RebarResults.Add(rebarResult); - } - } - - private void CalcStrainMatrix() - { - IForceTupleInputData inputData = new ForceTupleInputData() { NdmCollection = ndmCollection, Tuple = InputData.ForceTuple}; - IForceTupleCalculator calculator = new ForceTupleCalculator() { InputData = inputData }; - calculator.Run(); - var forceResult = calculator.Result as IForcesTupleResult; - strainTuple = TupleConverter.ConvertToStrainTuple(forceResult.LoaderResults.StrainMatrix); - } - - private CrackWidthSimpleCalculatorInputData GetCrackInputData() - { - lengthLogic.NdmCollection = ndmCollection; - lengthLogic.StrainMatrix = TupleConverter.ConvertToLoaderStrainMatrix(strainTuple); - var length = lengthLogic.GetLength(); - var crackInputData = new CrackWidthSimpleCalculatorInputData - { - PsiSFactor = crackForceResult.PsiS, - Length = length, - LimitState = InputData.LimitState, - StrainTuple = strainTuple - }; - return crackInputData; - } - - private void Triangulate() - { - ndmPrimitives = InputData.NdmPrimitives; - rebarPrimitives = new List(); - foreach (var item in ndmPrimitives) - { - if (item is RebarPrimitive) - { - rebarPrimitives.Add(item as RebarPrimitive); - } - } - ndmCollection = NdmPrimitivesService.GetNdms(ndmPrimitives, InputData.LimitState, InputData.CalcTerm); - } - - private void CalcCrackForce() - { - var calculator = new CrackForceCalculator(); - calculator.EndTuple = InputData.ForceTuple; - calculator.NdmCollection = ndmCollection; - calculator.Run(); - crackForceResult = calculator.Result as CrackForceResult; - } - - private void CheckInputData() - { - if (InputData.NdmPrimitives is null || InputData.NdmPrimitives.Count == 0) - { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": input data doesn't have any primitives"); - } - } - - public object Clone() - { - throw new NotImplementedException(); - } - } -} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculatorInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculatorInputData.cs deleted file mode 100644 index 607ad35..0000000 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthCalculatorInputData.cs +++ /dev/null @@ -1,19 +0,0 @@ -using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Models.Forces; -using StructureHelperLogics.NdmCalculations.Primitives; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.NdmCalculations.Cracking -{ - public class CrackWidthCalculatorInputData - { - public LimitStates LimitState { get; set; } - public CalcTerms CalcTerm { get; set; } - public IForceTuple ForceTuple { get; set; } - public List NdmPrimitives {get;set;} - } -} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs index 3a9637f..8cf70a9 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs @@ -1,4 +1,6 @@ using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; using System; using System.Collections.Generic; using System.Linq; @@ -11,44 +13,69 @@ namespace StructureHelperLogics.NdmCalculations.Cracking { CrackWidthLogicInputDataSP63 inputData; public ICrackWidthLogicInputData InputData {get;set;} + public IShiftTraceLogger? TraceLogger { get; set; } public double GetCrackWidth() { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage("Method of crack width calculation based on SP 63.13330.2018"); CheckOptions(); + TraceLogger?.AddMessage($"Term factor fi1 = {inputData.TermFactor}", TraceLogStatuses.Service); + TraceLogger?.AddMessage($"Bond factor fi2 = {inputData.BondFactor}", TraceLogStatuses.Service); + TraceLogger?.AddMessage($"Stress state factor fi3 = {inputData.StressStateFactor}", TraceLogStatuses.Service); + TraceLogger?.AddMessage($"PsiS factor PsiS = {inputData.PsiSFactor}", TraceLogStatuses.Service); + TraceLogger?.AddMessage($"Length between cracks Ls = {inputData.Length}", TraceLogStatuses.Service); //check if strain of concrete greater than strain of rebar - if (inputData.ConcreteStrain > inputData.RebarStrain) { return 0d; } - double width = (inputData.RebarStrain - inputData.ConcreteStrain) * inputData.Length; + double rebarElongation = inputData.RebarStrain - inputData.ConcreteStrain; + if (rebarElongation < 0d) + { + TraceLogger?.AddMessage($"Elongation of rebar is negative, may be rebar is under compression, width of crack a,crc = 0"); + return 0d; + } + TraceLogger?.AddMessage($"Rebar elongation Epsilon = {inputData.RebarStrain} - {inputData.ConcreteStrain} = {rebarElongation}(dimensionless)"); + double width = rebarElongation * inputData.Length; width *= inputData.TermFactor * inputData.BondFactor * inputData.StressStateFactor * inputData.PsiSFactor; + TraceLogger?.AddMessage($"Width of crack a,crc = {inputData.TermFactor} * {inputData.BondFactor} * {inputData.StressStateFactor} * {inputData.PsiSFactor} * {rebarElongation} * {inputData.Length}(m) = {width}(m)"); return width; } private void CheckOptions() { + string errorString = string.Empty; if (InputData is not CrackWidthLogicInputDataSP63) { - throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(CrackWidthLogicInputDataSP63), InputData.GetType())); + errorString = ErrorStrings.ExpectedWas(typeof(CrackWidthLogicInputDataSP63), InputData.GetType()); } inputData = InputData as CrackWidthLogicInputDataSP63; if (inputData.Length <=0d) { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": length between cracks L={inputData.Length} must be greate than zero"); + errorString = ErrorStrings.DataIsInCorrect + $": length between cracks Lcrc={inputData.Length} must be greater than zero"; } if (inputData.TermFactor <= 0d) { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": Term factor {inputData.TermFactor} must be greate than zero"); + errorString = ErrorStrings.DataIsInCorrect + $": Term factor fi1 {inputData.TermFactor} must be greater than zero"; + } if (inputData.BondFactor <= 0d) { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": Bond factor {inputData.BondFactor} must be greate than zero"); + errorString = ErrorStrings.DataIsInCorrect + $": Bond factor fi2 {inputData.BondFactor} must be greater than zero"; + } if (inputData.StressStateFactor <= 0d) { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": Bond factor {inputData.StressStateFactor} must be greate than zero"); + errorString = ErrorStrings.DataIsInCorrect + $": Stress factor fi3 factor {inputData.StressStateFactor} must be greater than zero"; + } if (inputData.PsiSFactor <= 0d) { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": PsiS factor {inputData.PsiSFactor} must be greate than zero"); + errorString = ErrorStrings.DataIsInCorrect + $": PsiS factor {inputData.PsiSFactor} must be greater than zero"; } + if (errorString != string.Empty) + { + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + TraceLogger?.AddMessage($"Checking parameters has done succefully", TraceLogStatuses.Service); } } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthRebarTupleResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthRebarTupleResult.cs new file mode 100644 index 0000000..409f295 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthRebarTupleResult.cs @@ -0,0 +1,18 @@ +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackWidthRebarTupleResult : ICrackWidthTupleResult + { + public double CrackWidth { get; set; } + public double UltimateCrackWidth { get; set; } + public bool IsCrackLessThanUltimate => CrackWidth <= UltimateCrackWidth; + public RebarStressResult RebarStressResult { get; set; } + public double SofteningFactor { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculator.cs deleted file mode 100644 index 03b423c..0000000 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculator.cs +++ /dev/null @@ -1,43 +0,0 @@ -using StructureHelperCommon.Models; -using StructureHelperCommon.Models.Calculators; - -namespace StructureHelperLogics.NdmCalculations.Cracking -{ - public class CrackWidthSimpleCalculator : ICalculator - { - ICrackWidthLogic crackWidthLogic = new CrackWidthLogicSP63(); - CrackWidthSimpleCalculatorResult result; - public string Name { get; set; } - public ICrackWidthSimpleCalculatorInputData InputData { get; set; } - public IResult Result => result; - - public Action ActionToOutputResults { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public IShiftTraceLogger? TraceLogger { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public void Run() - { - result = new() { IsValid = true}; - var crackWidthLogicType = CrackWidthLogicType.SP63; - var logicInputData = CrackWidthLogicInputDataFactory.GetCrackWidthLogicInputData(crackWidthLogicType, InputData); - crackWidthLogic.InputData = logicInputData; - double crackWidth = 0d; - try - { - crackWidth = crackWidthLogic.GetCrackWidth(); - } - catch (Exception ex) - { - result.IsValid = false; - result.Description += "\n" + ex; - } - result.RebarPrimitive = InputData.RebarPrimitive; - result.CrackWidth = crackWidth; - result.RebarStrain = logicInputData.RebarStrain; - result.ConcreteStrain = logicInputData.ConcreteStrain; - } - public object Clone() - { - throw new NotImplementedException(); - } - } -} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculatorInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculatorInputData.cs deleted file mode 100644 index 73980a6..0000000 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculatorInputData.cs +++ /dev/null @@ -1,22 +0,0 @@ -using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Models.Forces; -using StructureHelperLogics.NdmCalculations.Primitives; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.NdmCalculations.Cracking -{ - public class CrackWidthSimpleCalculatorInputData : ICrackWidthSimpleCalculatorInputData - { - public LimitStates LimitState { get; set; } - public CalcTerms CalcTerm { get; set; } - public StrainTuple StrainTuple { get; set; } - public double PsiSFactor { get; set; } - public double Length { get; set; } - public SectionStressStates StressState { get; set; } - public RebarPrimitive RebarPrimitive { get; set; } - } -} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthTupleResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthTupleResult.cs new file mode 100644 index 0000000..895de46 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthTupleResult.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackWidthTupleResult : ICrackWidthTupleResult + { + public double CrackWidth { get; set; } + public double UltimateCrackWidth { get; set; } + public bool IsCrackLessThanUltimate => CrackWidth <= UltimateCrackWidth; + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackedConcreteNdmLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackedConcreteNdmLogic.cs new file mode 100644 index 0000000..cb0b48d --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackedConcreteNdmLogic.cs @@ -0,0 +1,24 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackedConcreteNdmLogic : ISectionCrackedLogic + { + public INdm ConcreteNdm { get; set; } + public IForceTuple Tuple { get; set; } + public IEnumerable NdmCollection { get;set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public bool IsSectionCracked() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackedLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackedLogic.cs index 8ca8d87..4124ca3 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackedLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackedLogic.cs @@ -11,9 +11,9 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { - internal class CrackedLogic : ICrackedLogic + public class CrackedLogic : ICrackedLogic { - ISectionCrackedLogic sectionCrackedLogic; + private ISectionCrackedLogic sectionCrackedLogic; public IForceTuple StartTuple { get; set; } public IForceTuple EndTuple { get; set; } public IEnumerable NdmCollection { get; set; } @@ -23,16 +23,14 @@ namespace StructureHelperLogics.NdmCalculations.Cracking { sectionCrackedLogic = sectionLogic; } - public CrackedLogic() : this (new HoleSectionCrackedLogic()) + public CrackedLogic() : this (new SectionCrackedLogic()) { } public bool IsSectionCracked(double factor) { - if (TraceLogger is not null) - { - sectionCrackedLogic.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } + sectionCrackedLogic.TraceLogger ??= TraceLogger?.GetSimilarTraceLogger(50); + var actualTuple = ForceTupleService.InterpolateTuples(EndTuple, StartTuple, factor); sectionCrackedLogic.Tuple = actualTuple; sectionCrackedLogic.NdmCollection = NdmCollection; diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackedSectionTriangulationLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackedSectionTriangulationLogic.cs new file mode 100644 index 0000000..6f0c4f6 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackedSectionTriangulationLogic.cs @@ -0,0 +1,96 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.Models.Primitives; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.Services.NdmPrimitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class CrackedSectionTriangulationLogic : ICrackedSectionTriangulationLogic + { + const LimitStates limitState = LimitStates.SLS; + const CalcTerms shortTerm = CalcTerms.ShortTerm; + + private ITriangulatePrimitiveLogic triangulateLogic; + private string ndmPrimitiveCountMessage; + + public IEnumerable NdmPrimitives { get; private set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public CrackedSectionTriangulationLogic(IEnumerable ndmPrimitives) + { + NdmPrimitives = ndmPrimitives; + ndmPrimitiveCountMessage = $"Source collection containes {NdmPrimitives.Count()} primitives"; + triangulateLogic = new TriangulatePrimitiveLogic + { + Primitives = NdmPrimitives, + LimitState = limitState, + CalcTerm = shortTerm, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + } + public List GetNdmCollection() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(ndmPrimitiveCountMessage, TraceLogStatuses.Debug); + triangulateLogic = new TriangulatePrimitiveLogic() + { + LimitState = limitState, + CalcTerm = shortTerm, + Primitives = NdmPrimitives, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + return triangulateLogic.GetNdms(); + } + public List GetCrackedNdmCollection() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(ndmPrimitiveCountMessage, TraceLogStatuses.Debug); + triangulateLogic = new TriangulatePrimitiveLogic(new MeshCrackedConcreteLogic()) + { + LimitState = limitState, + CalcTerm = shortTerm, + Primitives = NdmPrimitives, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + return triangulateLogic.GetNdms(); + } + + public List GetRebarPrimitives() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(ndmPrimitiveCountMessage, TraceLogStatuses.Debug); + List rebarPrimitives = new(); + foreach (var item in NdmPrimitives) + { + if (item is RebarPrimitive rebar) + { + TraceLogger?.AddMessage($"Primitive {rebar.Name} is rebar primitive", TraceLogStatuses.Service); + rebarPrimitives.Add(rebar); + } + } + TraceLogger?.AddMessage($"Obtained {rebarPrimitives.Count} rebar primitives"); + return rebarPrimitives; + } + + public List GetElasticNdmCollection() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(ndmPrimitiveCountMessage, TraceLogStatuses.Debug); + triangulateLogic = new TriangulatePrimitiveLogic(new MeshElasticLogic()) + { + LimitState = limitState, + CalcTerm = shortTerm, + Primitives = NdmPrimitives, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + return triangulateLogic.GetNdms(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/EquivalentDiameterLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/EquivalentDiameterLogic.cs new file mode 100644 index 0000000..5e1515f --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/EquivalentDiameterLogic.cs @@ -0,0 +1,43 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class EquivalentDiameterLogic : IAverageDiameterLogic + { + public IEnumerable Rebars { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public double GetAverageDiameter() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + Check(); + var rebarArea = Rebars + .Sum(x => x.Area); + TraceLogger?.AddMessage($"Summary rebar area As = {rebarArea}(m^2)"); + var rebarCount = Rebars.Count(); + TraceLogger?.AddMessage($"Rebar count n = {rebarCount}"); + var averageArea = rebarArea / rebarCount; + TraceLogger?.AddMessage($"Equivalent rebar area As,eq = {averageArea}"); + var diameter = 2d * Math.Sqrt(averageArea / Math.PI); + TraceLogger?.AddMessage($"Equivalent rebar diameter ds,eq = 2 * Sqrt( PI / As,eq) = 2 * Sqrt( PI / {averageArea}) = {diameter}(m)"); + return diameter; + } + private void Check() + { + if (!Rebars.Any()) + { + string errorString = ErrorStrings.DataIsInCorrect + $": rebars count must be greater then zero"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/Factories/CrackWidthLogicInputDataFactory.cs b/StructureHelperLogics/NdmCalculations/Cracking/Factories/CrackWidthLogicInputDataFactory.cs index a3d8b7a..08bed13 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/Factories/CrackWidthLogicInputDataFactory.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/Factories/CrackWidthLogicInputDataFactory.cs @@ -1,53 +1,67 @@ -using LoaderCalculator.Logics; +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Services.Forces; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; using StructureHelperLogics.NdmCalculations.Triangulations; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Loggers; +using LoaderCalculator.Data.Materials; +using StructureHelperLogics.NdmCalculations.Primitives; namespace StructureHelperLogics.NdmCalculations.Cracking { - internal enum CrackWidthLogicType + internal class CrackWidthLogicInputDataFactory : ILogic { - SP63 - } - internal static class CrackWidthLogicInputDataFactory - { - static IStressLogic stressLogic => new StressLogic(); - public static ICrackWidthLogicInputData GetCrackWidthLogicInputData(CrackWidthLogicType logicType, ICrackWidthSimpleCalculatorInputData inputData) + private const double longTermFactor = 1.4d; + private const double shortTermFactor = 1d; + private IStressStateFactorLogic stressStateFactorLogic; + private ICrackSofteningLogic softeningLogic; + + public double RebarStrain { get; set; } + public double ConcreteStrain { get; set;} + + public CalcTerms CalcTerm { get; set; } + public RebarCrackInputData InputData { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public CrackWidthLogicInputDataFactory(ICrackSofteningLogic softeningLogic) { - if (logicType == CrackWidthLogicType.SP63) + this.softeningLogic = softeningLogic; + } + + public ICrackWidthLogicInputData GetCrackWidthLogicInputData() + { + stressStateFactorLogic = new StressStateFactorLogic() { - CrackWidthLogicInputDataSP63 data = new(); - ProcessBaseProps(inputData, data); - if (inputData.CalcTerm == CalcTerms.LongTerm) { data.TermFactor = 1.4d; } - else { data.TermFactor = 1d; } - data.PsiSFactor = inputData.PsiSFactor; - data.StressStateFactor = inputData.StressState is SectionStressStates.Tension ? 1.2d : 1.0d; - data.BondFactor = 0.5; - return data; + ForceTuple = InputData.ForceTuple, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + CrackWidthLogicInputDataSP63 data = new(); + if (CalcTerm == CalcTerms.LongTerm) + { + data.TermFactor = longTermFactor; } else { - throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); + data.TermFactor = shortTermFactor; } - - } - - private static void ProcessBaseProps(ICrackWidthSimpleCalculatorInputData inputData, ICrackWidthLogicInputData data) - { - var strainMatrix = TupleConverter.ConvertToLoaderStrainMatrix(inputData.StrainTuple); - var triangulationOptions = new TriangulationOptions { LimiteState = inputData.LimitState, CalcTerm = inputData.CalcTerm }; - var ndms = inputData.RebarPrimitive.GetNdms(triangulationOptions).ToArray(); - var concreteNdm = ndms[0]; - var rebarNdm = ndms[1]; - data.ConcreteStrain = concreteNdm.Prestrain;// stressLogic.GetTotalStrain(strainMatrix, concreteNdm) - stressLogic.GetTotalStrainWithPresrain(strainMatrix, concreteNdm); - data.RebarStrain = stressLogic.GetTotalStrainWithPresrain(strainMatrix, rebarNdm); - data.Length = inputData.Length; + data.PsiSFactor = softeningLogic.GetSofteningFactor(); + data.StressStateFactor = stressStateFactorLogic.GetStressStateFactor(); + data.BondFactor = 0.5d; + data.Length = InputData.Length; + data.ConcreteStrain = ConcreteStrain; + data.RebarStrain = RebarStrain; + return data; } } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/GetTupleInputDatasLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/GetTupleInputDatasLogic.cs new file mode 100644 index 0000000..82c15a2 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/GetTupleInputDatasLogic.cs @@ -0,0 +1,105 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperCommon.Infrastructures.Interfaces; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class GetTupleInputDatasLogic : IGetTupleInputDatasLogic + { + public List ForceActions { get; set; } + public List Primitives { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public LimitStates LimitState { get; set; } + public CalcTerms LongTerm { get; set; } + public CalcTerms ShortTerm { get; set; } + public UserCrackInputData UserCrackInputData { get; set; } + + public GetTupleInputDatasLogic(List primitives, List forceActions, UserCrackInputData userCrackInputData) + { + Primitives = primitives; + ForceActions = forceActions; + UserCrackInputData = userCrackInputData; + } + + public List GetTupleInputDatas() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + + List resultList = new(); + CheckInputData(); + foreach (var action in ForceActions) + { + var tuple = GetTuplesByActions(action); + if (tuple.isValid == false) + { + resultList.Add(new TupleCrackInputData() + { + IsValid = false, + }); + } + else + { + resultList.Add(new TupleCrackInputData() + { + IsValid = true, + TupleName = action.Name, + LongTermTuple = tuple.LongTuple, + ShortTermTuple = tuple.ShortTuple, + Primitives = Primitives, + UserCrackInputData = UserCrackInputData + }); + } + } + TraceLogger?.AddMessage(LoggerStrings.CalculationHasDone); + return resultList; + } + + private void CheckInputData() + { + if (ForceActions is null) + { + TraceLogger?.AddMessage("Force action list is null", TraceLogStatuses.Error); + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": {nameof(ForceActions)} is null"); + } + } + + private (bool isValid, IForceTuple? LongTuple, IForceTuple? ShortTuple) GetTuplesByActions(IForceAction action) + { + IForceTuple longTuple, shortTuple; + var combinations = action.GetCombinations().DesignForces; + try + { + longTuple = GetTupleByCombination(combinations, LimitState, LongTerm); + TraceLogger?.AddMessage("Long term force combination"); + TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(longTuple)); + shortTuple = GetTupleByCombination(combinations, LimitState, ShortTerm); + TraceLogger?.AddMessage("Short term force combination"); + TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(shortTuple)); + } + catch (Exception ex) + { + TraceLogger?.AddMessage("Force combination is not obtained: \n" + ex, TraceLogStatuses.Error); + return (false, null, null); + } + return (true, longTuple, shortTuple); + } + + private static IForceTuple GetTupleByCombination(List combinations, LimitStates limitState, CalcTerms calcTerm) + { + return combinations + .Where(x => x.LimitState == limitState & x.CalcTerm == calcTerm) + .Single() + .ForceTuple; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/IAverageDiameterLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/IAverageDiameterLogic.cs index 8ff8be3..573d15e 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/IAverageDiameterLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/IAverageDiameterLogic.cs @@ -1,4 +1,5 @@ using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Interfaces; using System; using System.Collections.Generic; using System.Linq; @@ -7,7 +8,7 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { - public interface IAverageDiameterLogic + public interface IAverageDiameterLogic : ILogic { IEnumerable Rebars { get; set; } double GetAverageDiameter(); diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthLogic.cs index 532995f..df024c5 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthLogic.cs @@ -1,4 +1,5 @@ -using System; +using StructureHelperCommon.Infrastructures.Interfaces; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,7 +10,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking /// /// Logic for calculating width of crack /// - public interface ICrackWidthLogic + public interface ICrackWidthLogic : ILogic { ICrackWidthLogicInputData InputData { get; set; } /// diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthSimpleCalculatorInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthSimpleCalculatorInputData.cs deleted file mode 100644 index 739e4a4..0000000 --- a/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthSimpleCalculatorInputData.cs +++ /dev/null @@ -1,25 +0,0 @@ -using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Models.Forces; -using StructureHelperLogics.NdmCalculations.Primitives; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.NdmCalculations.Cracking -{ - public interface ICrackWidthSimpleCalculatorInputData - { - LimitStates LimitState { get; set; } - CalcTerms CalcTerm { get; set; } - StrainTuple StrainTuple { get; set; } - double PsiSFactor { get; set; } - /// - /// Length between cracks in meters - /// - double Length { get; set; } - SectionStressStates StressState { get; set; } - RebarPrimitive RebarPrimitive { get; set; } - } -} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthTupleResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthTupleResult.cs new file mode 100644 index 0000000..19cdf81 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthTupleResult.cs @@ -0,0 +1,12 @@ +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public interface ICrackWidthTupleResult + { + /// + /// Calculated crack width + /// + double CrackWidth { get; set; } + bool IsCrackLessThanUltimate { get; } + double UltimateCrackWidth { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ICrackedSectionTriangulationLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/ICrackedSectionTriangulationLogic.cs new file mode 100644 index 0000000..6511dc3 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/ICrackedSectionTriangulationLogic.cs @@ -0,0 +1,42 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Logic for obtaining of collection of nms elementary part for regular and fully cracked section + /// + public interface ICrackedSectionTriangulationLogic : ILogic + { + /// + /// Source collection of ndm primitives + /// + IEnumerable NdmPrimitives { get; } + /// + /// Returns collection of ndm elementary parts + /// + /// + List GetNdmCollection(); + /// + /// Returns collection of ndm elementary parts where concrete doesn't work in tension + /// + /// + List GetCrackedNdmCollection(); + /// + /// Returns collection of ndm elementary parts where all material are elastic ones + /// + /// + List GetElasticNdmCollection(); + /// + /// Return collection of primitives which contain only rebars + /// + /// + List GetRebarPrimitives(); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/IGetTupleInputDatasLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/IGetTupleInputDatasLogic.cs new file mode 100644 index 0000000..26c8f93 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/IGetTupleInputDatasLogic.cs @@ -0,0 +1,16 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Forces; +using StructureHelperLogics.NdmCalculations.Primitives; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public interface IGetTupleInputDatasLogic : ILogic, IHasPrimitives, IHasForceCombinations + { + LimitStates LimitState { get; set; } + CalcTerms LongTerm { get; set; } + CalcTerms ShortTerm { get; set; } + List GetTupleInputDatas(); + UserCrackInputData UserCrackInputData { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ILengthBetweenCracksLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/ILengthBetweenCracksLogic.cs index 5226e07..93fe5df 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/ILengthBetweenCracksLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/ILengthBetweenCracksLogic.cs @@ -1,5 +1,6 @@ using LoaderCalculator.Data.Matrix; using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Interfaces; using System; using System.Collections.Generic; using System.Linq; @@ -8,10 +9,23 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { - public interface ILengthBetweenCracksLogic + /// + /// Interface of logic of obtaining of length between cracks + /// + public interface ILengthBetweenCracksLogic : ILogic { + /// + /// Full collection of ndm parts of cross-section + /// IEnumerable NdmCollection { get; set; } + /// + /// Strain matrix in cracked state + /// IStrainMatrix StrainMatrix { get; set; } + /// + /// Returns length between cracks + /// + /// Length betwenn cracks double GetLength(); } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ISectionCrackedLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/ISectionCrackedLogic.cs index 3fbbc1f..b6429c3 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/ISectionCrackedLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/ISectionCrackedLogic.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { - internal interface ISectionCrackedLogic : ILogic + public interface ISectionCrackedLogic : ILogic { IForceTuple Tuple { get; set; } IEnumerable NdmCollection { get; set; } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ICrackSofteningLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/IStressStateFactorLogic.cs similarity index 72% rename from StructureHelperLogics/NdmCalculations/Cracking/ICrackSofteningLogic.cs rename to StructureHelperLogics/NdmCalculations/Cracking/IStressStateFactorLogic.cs index 2f0feaa..bce3680 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/ICrackSofteningLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/IStressStateFactorLogic.cs @@ -7,8 +7,8 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { - public interface ICrackSofteningLogic : ILogic + public interface IStressStateFactorLogic : ILogic { - double GetSofteningFactor(); + double GetStressStateFactor(); } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ITensileAreaLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/ITensileConcreteAreaLogic.cs similarity index 82% rename from StructureHelperLogics/NdmCalculations/Cracking/ITensileAreaLogic.cs rename to StructureHelperLogics/NdmCalculations/Cracking/ITensileConcreteAreaLogic.cs index 47eab43..02543c6 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/ITensileAreaLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/ITensileConcreteAreaLogic.cs @@ -1,5 +1,6 @@ using LoaderCalculator.Data.Matrix; using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Models.Forces; using System; using System.Collections.Generic; @@ -12,7 +13,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking /// /// Logic fo calculating of tensile area of RC crosssection /// - public interface ITensileAreaLogic + public interface ITensileConcreteAreaLogic : ILogic { IEnumerable NdmCollection { get; set; } IStrainMatrix StrainMatrix { get; set; } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ITensionRebarAreaLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/ITensionRebarAreaLogic.cs new file mode 100644 index 0000000..b88bdbf --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/ITensionRebarAreaLogic.cs @@ -0,0 +1,28 @@ +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Logic for obtaining of summary area in tension zone of cracked cross-section + /// + public interface ITensionRebarAreaLogic : ILogic + { + + IStrainMatrix StrainMatrix { get; set; } + IEnumerable Rebars { get; set; } + double GetTensionRebarArea(); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs index 8e2811c..99d185f 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs @@ -1,5 +1,10 @@ using LoaderCalculator.Data.Matrix; using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.Services; using System; using System.Collections.Generic; using System.Linq; @@ -8,42 +13,115 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { + /// + /// Logic for obtaining of length between cracks according to SP63.13330.2018 + /// public class LengthBetweenCracksLogicSP63 : ILengthBetweenCracksLogic { const double minDiameterFactor = 10d; const double maxDiameterFactor = 40d; const double minLength = 0.1d; const double maxLength = 0.4d; - + private const double areaFactor = 0.5d; readonly IAverageDiameterLogic diameterLogic; - readonly ITensileAreaLogic tensileAreaLogic; + readonly ITensileConcreteAreaLogic concreteAreaLogic; + ITensionRebarAreaLogic rebarAreaLogic; + private IStressLogic stressLogic => new StressLogic(); + + /// public IEnumerable NdmCollection { get; set; } + /// public IStrainMatrix StrainMatrix { get; set; } - public LengthBetweenCracksLogicSP63(IAverageDiameterLogic diameterLogic, ITensileAreaLogic tensileAreaLogic) + /// + public IShiftTraceLogger? TraceLogger { get; set; } + + public LengthBetweenCracksLogicSP63(IAverageDiameterLogic diameterLogic, ITensileConcreteAreaLogic concreteAreaLogic, ITensionRebarAreaLogic rebarAreaLogic) { this.diameterLogic = diameterLogic; - this.tensileAreaLogic = tensileAreaLogic; + this.concreteAreaLogic = concreteAreaLogic; + this.rebarAreaLogic = rebarAreaLogic; } public LengthBetweenCracksLogicSP63() : this - ( new AverageDiameterLogic(), - new TensileAreaLogicSP63()) + ( new EquivalentDiameterLogic(), + new TensileConcreteAreaLogicSP63(), + new TensionRebarAreaByStrainLogic()) { } + /// public double GetLength() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + IEnumerable rebars = GetRebars(); + double rebarArea = GetRebarArea(rebars); + double rebarDiameter = GetAverageDiameter(rebars); + double concreteArea = GetConcreteArea(); + double length = GetLengthBetweenCracks(rebarArea, rebarDiameter, concreteArea); + return length; + } + + private IEnumerable GetRebars() { var rebars = NdmCollection .Where(x => x is RebarNdm) .Select(x => x as RebarNdm); - var rebarArea = rebars.Sum(x => x.Area * x.StressScale); - diameterLogic.Rebars = rebars; - var rebarDiameter = diameterLogic.GetAverageDiameter(); - tensileAreaLogic.NdmCollection = NdmCollection; - tensileAreaLogic.StrainMatrix = StrainMatrix; - var concreteArea = tensileAreaLogic.GetTensileArea(); - var length = concreteArea / rebarArea * rebarDiameter; - length = new List { length, minDiameterFactor * rebarDiameter, minLength }.Max(); - length = new List { length, maxDiameterFactor * rebarDiameter, maxLength }.Min(); + if (!rebars.Any()) + { + string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + + return rebars; + } + + private double GetLengthBetweenCracks(double rebarArea, double rebarDiameter, double concreteArea) + { + var length = areaFactor * concreteArea / rebarArea * rebarDiameter; + TraceLogger?.AddMessage($"Base length between cracks Lcrc = {areaFactor} * {concreteArea} / {rebarArea} * {rebarDiameter} = {length}(m)"); + double minLengthByDiameter = minDiameterFactor * rebarDiameter; + TraceLogger?.AddMessage($"Minimum length by diameter Lcrc = {minDiameterFactor} * {rebarDiameter} = {minLengthByDiameter}(m)"); + TraceLogger?.AddMessage($"Minimum absolute length Lcrc = {minLength}(m)"); + var restrictedByMinLength = new List { length, minLengthByDiameter, minLength }.Max(); + TraceLogger?.AddMessage($"Consider minimum length restriction Lcrc = max({length}(m), {minLengthByDiameter}(m), {minLength}(m)) = {length}(m)"); + double maxLengthByDiameter = maxDiameterFactor * rebarDiameter; + TraceLogger?.AddMessage($"Maximum length by diameter Lcrc = {maxDiameterFactor} * {rebarDiameter} = {maxLengthByDiameter}(m)"); + TraceLogger?.AddMessage($"Maximum absolute length Lcrc = {maxLength}(m)"); + var restrictedByMaxLength = new List { restrictedByMinLength, maxLengthByDiameter, maxLength }.Min(); + TraceLogger?.AddMessage($"Consider maximum length restriction Lcrc = max({restrictedByMinLength}(m), {maxLengthByDiameter}(m), {maxLength}(m)) = {restrictedByMaxLength}(m)"); + length = restrictedByMaxLength; + TraceLogger?.AddMessage($"Finally Lcrc = {length}(m)"); return length; } + + private double GetConcreteArea() + { + concreteAreaLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + concreteAreaLogic.NdmCollection = NdmCollection; + concreteAreaLogic.StrainMatrix = StrainMatrix; + var concreteArea = concreteAreaLogic.GetTensileArea(); + TraceLogger?.AddMessage($"Concrete effective area Ac,eff = {concreteArea}(m^2)"); + return concreteArea; + } + + private double GetAverageDiameter(IEnumerable rebars) + { + var tesileRebars = rebars + .Where(x => stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); + diameterLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + diameterLogic.Rebars = tesileRebars; + var rebarDiameter = diameterLogic.GetAverageDiameter(); + TraceLogger?.AddMessage($"Average rebar diameter ds = {rebarDiameter}"); + return rebarDiameter; + } + + private double GetRebarArea(IEnumerable rebars) + { + rebarAreaLogic.StrainMatrix = StrainMatrix; + rebarAreaLogic.Rebars = rebars; + rebarAreaLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + var rebarArea = rebarAreaLogic.GetTensionRebarArea(); + TraceLogger?.AddMessage($"Summary rebar area As = {rebarArea}(m^2)"); + return rebarArea; + } } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackCalculator.cs new file mode 100644 index 0000000..8affe0d --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackCalculator.cs @@ -0,0 +1,159 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.NdmCalculations.Primitives; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class RebarCrackCalculator : ICalculator + { + private ICrackSofteningLogic crackSofteningLogic; + private ICrackWidthLogic crackWidthLogic = new CrackWidthLogicSP63(); + private RebarCrackResult result; + private RebarStressResult rebarStressResult; + + public string Name { get; set; } + public RebarCrackCalculatorInputData InputData { get; set; } + public IResult Result => result; + + public Action ActionToOutputResults { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public void Run() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Debug); + result = new() + { + IsValid = true + }; + TraceLogger?.AddMessage($"Rebar primitive {InputData.RebarPrimitive.Name}"); + + //double acrc1 = GetCrackWidth() + + + crackWidthLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + try + { + GetSofteningLogic(InputData.LongRebarData); + rebarStressResult = GetRebarStressResult(InputData.LongRebarData); + var dataAcrc1 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.LongTerm); + var dataAcrc3 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.ShortTerm); + crackWidthLogic.InputData = dataAcrc1; + var acrc1 = crackWidthLogic.GetCrackWidth(); + var longRebarResult = new CrackWidthRebarTupleResult() + { + CrackWidth = acrc1, + UltimateCrackWidth = InputData.UserCrackInputData.UltimateLongCrackWidth, + RebarStressResult = rebarStressResult, + SofteningFactor = crackSofteningLogic.GetSofteningFactor() + }; + TraceLogger?.AddMessage($"Long crack width acrc = acrc,1 = {acrc1}(m)"); + TraceLogger?.AddMessage($"Ultimate long crack width acrc,ult = {longRebarResult.UltimateCrackWidth}(m)"); + TraceCrackResult(longRebarResult); + + + GetSofteningLogic(InputData.ShortRebarData); + rebarStressResult = GetRebarStressResult(InputData.ShortRebarData); + var dataAcrc2 = GetCrackWidthInputData(InputData.ShortRebarData, CalcTerms.ShortTerm); + + crackWidthLogic.InputData = dataAcrc3; + var acrc3 = crackWidthLogic.GetCrackWidth(); + crackWidthLogic.InputData = dataAcrc2; + var acrc2 = crackWidthLogic.GetCrackWidth(); + + double acrcShort = acrc1 + acrc2 - acrc3; + TraceLogger?.AddMessage($"Short crack width acrc = acrc,1 + acrc,2 - acrc,3 = {acrc1} + {acrc2} - {acrc3} = {acrcShort}(m)"); + var shortRebarResult = new CrackWidthRebarTupleResult() + { + CrackWidth = acrcShort, + UltimateCrackWidth = InputData.UserCrackInputData.UltimateShortCrackWidth, + RebarStressResult = rebarStressResult, + SofteningFactor = crackSofteningLogic.GetSofteningFactor() + }; + TraceCrackResult(shortRebarResult); + result.LongTermResult = longRebarResult; + result.ShortTermResult = shortRebarResult; + } + catch (Exception ex) + { + result.IsValid = false; + result.Description += "\n" + ex; + } + result.RebarPrimitive = InputData.RebarPrimitive; + } + + private void TraceCrackResult(CrackWidthRebarTupleResult rebarResult) + { + if (rebarResult.IsCrackLessThanUltimate == false) + { + TraceLogger?.AddMessage($"Checking crack width is failure, actual crack width acrc = {rebarResult.CrackWidth} > ultimate crack width acrc,ult = {rebarResult.UltimateCrackWidth}", TraceLogStatuses.Warning); + } + else + { + TraceLogger?.AddMessage($"Checking crack width is ok, actual crack width acrc = {rebarResult.CrackWidth} <= ultimate crack width acrc,ult = {rebarResult.UltimateCrackWidth}"); + } + } + + private void GetSofteningLogic(RebarCrackInputData rebarData) + { + if (InputData.UserCrackInputData.SetSofteningFactor == true) + { + crackSofteningLogic = new StabSoftetingLogic(InputData.UserCrackInputData.SofteningFactor) + { + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + } + else + { + crackSofteningLogic = new RebarStressSofteningLogic() + { + RebarPrimitive = InputData.RebarPrimitive, + InputData = rebarData, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + } + } + + private ICrackWidthLogicInputData GetCrackWidthInputData(RebarCrackInputData inputData, CalcTerms calcTerm) + { + + var factoryInputData = new CrackWidthLogicInputDataFactory(crackSofteningLogic) + { + CalcTerm = calcTerm, + InputData = inputData, + RebarStrain = rebarStressResult.RebarStrain, + ConcreteStrain = rebarStressResult.ConcreteStrain, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + var crackWidthInputData = factoryInputData.GetCrackWidthLogicInputData(); + return crackWidthInputData; + } + + public object Clone() + { + throw new NotImplementedException(); + } + + private RebarStressResult GetRebarStressResult(RebarCrackInputData inputData) + { + var calculator = new RebarStressCalculator() + { + ForceTuple = inputData.ForceTuple, + NdmCollection = inputData.CrackedNdmCollection, + RebarPrimitive = InputData.RebarPrimitive + }; + calculator.Run(); + var result = calculator.Result as RebarStressResult; + if (result.IsValid == false) + { + string errorString = LoggerStrings.CalculationError + result.Description; + TraceLogger?.AddMessage($"Rebar name: {InputData.RebarPrimitive.Name}\n" + errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + return result; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackCalculatorInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackCalculatorInputData.cs new file mode 100644 index 0000000..085847e --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackCalculatorInputData.cs @@ -0,0 +1,28 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models.Calculators; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Class of input data for rebar crack calculator + /// + public class RebarCrackCalculatorInputData : IInputData + { + /// + /// Long term rebar data + /// + public RebarCrackInputData? LongRebarData { get; set; } + /// + /// Short term rebar data + /// + public RebarCrackInputData? ShortRebarData { get; set; } + public RebarPrimitive RebarPrimitive { get; set; } + public UserCrackInputData UserCrackInputData { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackInputData.cs new file mode 100644 index 0000000..a100c6f --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackInputData.cs @@ -0,0 +1,21 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class RebarCrackInputData : IInputData + { + public IEnumerable CrackableNdmCollection { get; set; } + public IEnumerable CrackedNdmCollection { get; set; } + public ForceTuple ForceTuple { get; set; } + public double Length { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackResult.cs new file mode 100644 index 0000000..74a6548 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackResult.cs @@ -0,0 +1,33 @@ +using StructureHelperCommon.Models.Calculators; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Result of calculation of crack for specific result + /// + public class RebarCrackResult : IResult + { + /// + public bool IsValid { get; set; } + /// + public string Description { get; set; } + /// + /// Specific rebar primitive + /// + public RebarPrimitive RebarPrimitive { get; set; } + /// + /// Result of calculation of crack for long term + /// + public CrackWidthRebarTupleResult LongTermResult { get; set; } + /// + /// Result of calculation of crack for short term + /// + public CrackWidthRebarTupleResult ShortTermResult { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarStressCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressCalculator.cs new file mode 100644 index 0000000..52f0c5f --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressCalculator.cs @@ -0,0 +1,97 @@ +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Services.Forces; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.NdmCalculations.Triangulations; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class RebarStressCalculator : ICalculator + { + private IStressLogic stressLogic; + private Ndm concreteNdm; + private RebarNdm rebarNdm; + private RebarStressResult result; + + public ForceTuple ForceTuple { get; set; } + public IEnumerable NdmCollection { get; set; } + public RebarPrimitive RebarPrimitive { get; set; } + public string Name { get; set; } + + public IResult Result => result; + + public IShiftTraceLogger? TraceLogger { get; set; } + + public StrainTuple GetStrainTuple() + { + IForceTupleInputData inputData = new ForceTupleInputData() + { + NdmCollection = NdmCollection, + Tuple = ForceTuple + }; + IForceTupleCalculator calculator = new ForceTupleCalculator() + { + InputData = inputData, + //TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + calculator.Run(); + var forceResult = calculator.Result as IForcesTupleResult; + if (forceResult.IsValid == false) + { + //TraceLogger?.AddMessage(LoggerStrings.CalculationError + $": {forceResult.Description}", TraceLogStatuses.Error); + throw new StructureHelperException(ErrorStrings.CalculationError); + } + var strain = TupleConverter.ConvertToStrainTuple(forceResult.LoaderResults.StrainMatrix); + return strain; + } + public RebarStressCalculator(IStressLogic stressLogic) + { + this.stressLogic = stressLogic; + } + public RebarStressCalculator() : this(new StressLogic()) + { + + } + + + public void Run() + { + GetNdmCollectionFromPrimitives(); + result = new RebarStressResult() + { + IsValid = true, + Description = string.Empty + }; + var strainTuple = GetStrainTuple(); + result.StrainTuple = strainTuple; + var strainMatrix = TupleConverter.ConvertToLoaderStrainMatrix(strainTuple); + result.RebarStrain = stressLogic.GetSectionStrain(strainMatrix, rebarNdm); + result.RebarStress = stressLogic.GetStress(strainMatrix, rebarNdm); + result.ConcreteStrain = - concreteNdm.Prestrain; + } + + + private void GetNdmCollectionFromPrimitives() + { + var options = new TriangulationOptions() + { + CalcTerm = CalcTerms.ShortTerm, + LimiteState = LimitStates.SLS, + }; + concreteNdm = RebarPrimitive.GetConcreteNdm(options); + concreteNdm.StressScale = 1d; + rebarNdm = RebarPrimitive.GetRebarNdm(options); + } + + public object Clone() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculatorResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressResult.cs similarity index 56% rename from StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculatorResult.cs rename to StructureHelperLogics/NdmCalculations/Cracking/RebarStressResult.cs index c0e0461..c24bac3 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthSimpleCalculatorResult.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressResult.cs @@ -1,5 +1,5 @@ using StructureHelperCommon.Models.Calculators; -using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperCommon.Models.Forces; using System; using System.Collections.Generic; using System.Linq; @@ -8,12 +8,14 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { - public class CrackWidthSimpleCalculatorResult : IResult + public class RebarStressResult : IResult { + /// public bool IsValid { get; set; } - public string Description { get; set; } - public RebarPrimitive RebarPrimitive { get; set; } - public double CrackWidth { get; set; } + /// + public string? Description { get; set; } + public StrainTuple StrainTuple { get; set; } + public double RebarStress { get; set; } public double RebarStrain { get; set; } public double ConcreteStrain { get; set; } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/HoleSectionCrackedLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/SectionCrackedLogic.cs similarity index 84% rename from StructureHelperLogics/NdmCalculations/Cracking/HoleSectionCrackedLogic.cs rename to StructureHelperLogics/NdmCalculations/Cracking/SectionCrackedLogic.cs index 984958f..85772b9 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/HoleSectionCrackedLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/SectionCrackedLogic.cs @@ -5,18 +5,20 @@ using StructureHelperCommon.Models; using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using System.Diagnostics.Eventing.Reader; namespace StructureHelperLogics.NdmCalculations.Cracking { - internal class HoleSectionCrackedLogic : ISectionCrackedLogic + internal class SectionCrackedLogic : ISectionCrackedLogic { static readonly IStressLogic stressLogic = new StressLogic(); public IForceTuple Tuple { get; set; } + public IEnumerable CheckedNdmCollection { get; set; } public IEnumerable NdmCollection { get; set; } public Accuracy Accuracy { get; set; } public IShiftTraceLogger? TraceLogger { get; set; } - public HoleSectionCrackedLogic() + public SectionCrackedLogic() { if (Accuracy is null) { @@ -52,7 +54,16 @@ namespace StructureHelperLogics.NdmCalculations.Cracking throw new StructureHelperException(ErrorStrings.ResultIsNotValid + ": Result of Section Calculation is not valid"); } var strainMatrix = calcResult.LoaderResults.ForceStrainPair.StrainMatrix; - var isSectionCracked = stressLogic.IsSectionCracked(strainMatrix, NdmCollection); + IEnumerable checkedNdmCollection; + if (CheckedNdmCollection is null) + { + checkedNdmCollection = NdmCollection; + } + else + { + checkedNdmCollection = CheckedNdmCollection; + } + var isSectionCracked = stressLogic.IsSectionCracked(strainMatrix, checkedNdmCollection); if (isSectionCracked == true) { TraceLogger?.AddMessage($"Cracks are appeared in cross-section for current force combination"); diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ExpSofteningLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/ExpSofteningLogic.cs similarity index 96% rename from StructureHelperLogics/NdmCalculations/Cracking/ExpSofteningLogic.cs rename to StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/ExpSofteningLogic.cs index 65f2c63..22b42e0 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/ExpSofteningLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/ExpSofteningLogic.cs @@ -11,6 +11,9 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { + /// + /// Logic of calculating of factor of softening by power expression + /// public class ExpSofteningLogic : ICrackSofteningLogic { private double forceRatio; diff --git a/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/ICrackSofteningLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/ICrackSofteningLogic.cs new file mode 100644 index 0000000..32016ae --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/ICrackSofteningLogic.cs @@ -0,0 +1,21 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Logic of calculating of factor of softening in crack of RC structures + /// + public interface ICrackSofteningLogic : ILogic + { + /// + /// Returns softening factor + /// + /// + double GetSofteningFactor(); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/RebarStressSofteningLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/RebarStressSofteningLogic.cs new file mode 100644 index 0000000..eb5c8cb --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/RebarStressSofteningLogic.cs @@ -0,0 +1,197 @@ +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Services.Forces; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.NdmCalculations.Triangulations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class RebarStressSofteningLogic : ICrackSofteningLogic + { + /// + /// Rebar result immediately after cracking appearance + /// + private RebarStressResult crackRebarResult; + /// + /// Rebar resul for actual force combination + /// + private RebarStressResult actualRebarResult; + + + private INdm? concreteNdm; + private INdm? rebarNdm; + + private double rebarActualStrain; + private double concreteStrainActual; + private double rebarActualStress; + private double softeningFactor; + private double minValueOfFactor = 0.2d; + private RebarPrimitive rebarPrimitive; + private RebarCrackInputData inputData; + + public double MinValueOfFactor + { + get => minValueOfFactor; set + { + minValueOfFactor = value; + IsResultActual = false; + } + } + public RebarPrimitive RebarPrimitive + { + get => rebarPrimitive; set + { + rebarPrimitive = value; + IsResultActual = false; + } + } + public RebarCrackInputData InputData + { + get => inputData; set + { + inputData = value; + IsResultActual = false; + } + } + public IShiftTraceLogger? TraceLogger { get; set; } + public bool IsResultActual { get; private set; } = false; + + public double GetSofteningFactor() + { + if (IsResultActual == false) + { + GetNdms(); + softeningFactor = GetPsiSFactor(InputData.ForceTuple, InputData.CrackableNdmCollection); + IsResultActual = true; + } + return softeningFactor; + + } + + private void GetNdms() + { + var options = new TriangulationOptions() + { + CalcTerm = CalcTerms.ShortTerm, + LimiteState = LimitStates.SLS, + }; + concreteNdm = RebarPrimitive.GetConcreteNdm(options); + concreteNdm.StressScale = 1d; + rebarNdm = RebarPrimitive.GetRebarNdm(options); + } + + private double GetPsiSFactor(ForceTuple forceTuple, IEnumerable crackableNndms) + { + + var crackResult = calculateCrackTuples(forceTuple, crackableNndms); + if (crackResult.IsValid == false) + { + string errorString = LoggerStrings.CalculationError + crackResult.Description; + TraceLogger?.AddMessage($"Rebar name: {RebarPrimitive.Name}\n" + errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + + actualRebarResult = GetRebarStressResult(forceTuple); + rebarActualStrain = actualRebarResult.RebarStrain; + rebarActualStress = actualRebarResult.RebarStress; + TraceLogger?.AddMessage($"Actual strain of rebar EpsilonS = {rebarActualStrain}(dimensionless)"); + concreteStrainActual = concreteNdm.Prestrain; + //concreteStrainActual = stressLogic.GetTotalStrain(TupleConverter.ConvertToLoaderStrainMatrix(strainTupleActual), concreteNdm); + TraceLogger?.AddMessage($"Actual strain of concrete on the axis of rebar EpsilonC = {concreteStrainActual}(dimensionless)"); + if (crackResult.IsSectionCracked == false) + { + TraceLogger?.AddMessage($"Section is not cracked PsiS = {MinValueOfFactor}"); + return MinValueOfFactor; + } + if (crackResult.FactorOfCrackAppearance == 0d) + { + TraceLogger?.AddMessage($"Section is cracked in start force combination, PsiS = 1.0"); + return 1d; + } + crackRebarResult = GetRebarStressResult(crackResult.TupleOfCrackAppearance as ForceTuple); + + var stressInCracking = crackRebarResult.RebarStress; + TraceLogger?.AddMessage($"Stress in rebar immediately after cracking Sigma,scrc = {stressInCracking}(Pa)"); + TraceLogger?.AddMessage($"Actual stress in rebar Sigma,s = {rebarActualStress}(Pa)"); + double psiS = GetExponentialSofteningFactor(stressInCracking); + TraceLogger?.AddMessage($"PsiS = {psiS}"); + //return 0.94d; + return psiS; + } + + private double GetExponentialSofteningFactor(double stressInCracking) + { + var stressRatio = stressInCracking / rebarActualStress; + var logic = new ExpSofteningLogic() + { + ForceRatio = stressRatio, + PsiSMin = MinValueOfFactor, + PowerFactor = 1d, + BettaFactor = 0.8d, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + double psiS = logic.GetSofteningFactor(); + return psiS; + } + + private CrackForceResult calculateCrackTuples(ForceTuple forceTuple, IEnumerable ndms) + { + var sectionCrackedLogic = new SectionCrackedLogic() + { + NdmCollection = ndms, + CheckedNdmCollection = new List() { concreteNdm }, + //TraceLogger = TraceLogger?.GetSimilarTraceLogger(100) + }; + var crackedLogis = new CrackedLogic(sectionCrackedLogic) + { + StartTuple = new ForceTuple(), + EndTuple = forceTuple, + //TraceLogger = TraceLogger?.GetSimilarTraceLogger(100) + }; + var calculator = new CrackForceCalculator(crackedLogis) + { + NdmCollection = ndms, + EndTuple = forceTuple, + Accuracy = new Accuracy() + { + IterationAccuracy = 0.01d, + MaxIterationCount = 1000 + }, + //TraceLogger = TraceLogger?.GetSimilarTraceLogger(150) + }; + calculator.Run(); + return calculator.Result as CrackForceResult; + } + + private RebarStressResult GetRebarStressResult(ForceTuple forceTuple) + { + var calculator = new RebarStressCalculator() + { + ForceTuple = forceTuple, + NdmCollection = InputData.CrackedNdmCollection, + RebarPrimitive = RebarPrimitive + }; + calculator.Run(); + var result = calculator.Result as RebarStressResult; + if (result.IsValid == false) + { + string errorString = LoggerStrings.CalculationError + result.Description; + TraceLogger?.AddMessage($"Rebar name: {RebarPrimitive.Name}\n" + errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + return result; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/StabSoftetingLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/StabSoftetingLogic.cs new file mode 100644 index 0000000..f4178a7 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/SofteningLogics/StabSoftetingLogic.cs @@ -0,0 +1,24 @@ +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class StabSoftetingLogic : ICrackSofteningLogic + { + private double stabSofteningValue; + public IShiftTraceLogger? TraceLogger { get; set; } + public StabSoftetingLogic(double stabSofteningValue) + { + this.stabSofteningValue = stabSofteningValue; + } + public double GetSofteningFactor() + { + TraceLogger?.AddMessage($"Constant value of softening factor PsiS = {stabSofteningValue}"); + return stabSofteningValue; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/StressStateFactorLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/StressStateFactorLogic.cs new file mode 100644 index 0000000..2e1b915 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/StressStateFactorLogic.cs @@ -0,0 +1,30 @@ +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class StressStateFactorLogic : IStressStateFactorLogic + { + public ForceTuple ForceTuple { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public double GetStressStateFactor() + { + if (ForceTuple.Nz > 0d) + { + TraceLogger.AddMessage($"Cross-section is tensioned since Nz = {ForceTuple.Nz}(N)"); + return 1.2d; + } + else + { + TraceLogger.AddMessage($"Cross-section is bent or compressed since Nz = {ForceTuple.Nz}(N)"); + return 1d; + } + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TensileAreaLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Cracking/TensileAreaLogicSP63.cs deleted file mode 100644 index 845aa73..0000000 --- a/StructureHelperLogics/NdmCalculations/Cracking/TensileAreaLogicSP63.cs +++ /dev/null @@ -1,45 +0,0 @@ -using LoaderCalculator.Data.Materials; -using LoaderCalculator.Data.Matrix; -using LoaderCalculator.Data.Ndms; -using LoaderCalculator.Logics; -using StructureHelperCommon.Models.Forces; -using StructureHelperCommon.Services.Forces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.NdmCalculations.Cracking -{ - public class TensileAreaLogicSP63 : ITensileAreaLogic - { - const double maxConcreteFactor = 0.5d; - const double minConcreteFactor = 0.1d; - const double minRebarFactor = 3d; - private static IStressLogic stressLogic => new StressLogic(); - public IEnumerable NdmCollection { get; set; } - public IStrainMatrix StrainMatrix { get; set; } - - public double GetTensileArea() - { - var rebarCollection = NdmCollection - .Where(x => x is RebarNdm); - var rebarArea = rebarCollection. - Sum(x => x.Area * x.StressScale); - var concreteCollection = NdmCollection - .Where(x => x.Material is ConcreteMaterial); - var concreteArea = concreteCollection - .Sum(x => x.Area * x.StressScale); - var concreteTensileArea = concreteCollection - .Where(x => stressLogic.GetTotalStrainWithPresrain(StrainMatrix, x) > 0d) - .Sum(x => x.Area * x.StressScale); - - concreteTensileArea = Math.Max(concreteTensileArea, rebarArea * minRebarFactor); - concreteTensileArea = Math.Max(concreteTensileArea, concreteArea * minConcreteFactor); - concreteTensileArea = Math.Min(concreteTensileArea, concreteArea * maxConcreteFactor); - - return concreteTensileArea; - } - } -} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TensileConcreteAreaLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Cracking/TensileConcreteAreaLogicSP63.cs new file mode 100644 index 0000000..72996f3 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/TensileConcreteAreaLogicSP63.cs @@ -0,0 +1,62 @@ +using LoaderCalculator.Data.Materials; +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Services.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class TensileConcreteAreaLogicSP63 : ITensileConcreteAreaLogic + { + const double maxConcreteFactor = 0.5d; + const double minConcreteFactor = 0.1d; + const double minRebarFactor = 9d; + private static IStressLogic stressLogic => new StressLogic(); + public IEnumerable NdmCollection { get; set; } + public IStrainMatrix StrainMatrix { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public double GetTensileArea() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + + var rebarCollection = NdmCollection + .Where(x => x is RebarNdm & stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); + var rebarArea = rebarCollection. + Sum(x => x.Area * x.StressScale); + TraceLogger?.AddMessage($"Summary rebar area As = {rebarArea}"); + var concreteCollection = NdmCollection + .Where(x => x.Material is ConcreteMaterial); + var concreteArea = concreteCollection + .Sum(x => x.Area * x.StressScale); + TraceLogger?.AddMessage($"Concrete area Ac = {concreteArea}"); + var concreteTensileArea = concreteCollection + .Where(x => stressLogic.GetTotalStrain(StrainMatrix, x) > 0d) + .Sum(x => x.Area * x.StressScale); + TraceLogger?.AddMessage($"Concrete tensile area Ac,t = {concreteTensileArea}"); + + double areaByRebar = rebarArea * minRebarFactor; + TraceLogger?.AddMessage($"Concrete area is considered not less than {minRebarFactor} of area of rebars"); + TraceLogger?.AddMessage($"Minimum concrete effective area from area of rebar Ac,eff = {rebarArea} * {minRebarFactor} = {areaByRebar}"); + concreteTensileArea = Math.Max(concreteTensileArea, areaByRebar); + double areaByMinConcreteFactor = concreteArea * minConcreteFactor; + TraceLogger?.AddMessage($"Concrete area is considered not less than {minConcreteFactor} of area of concrete"); + TraceLogger?.AddMessage($"Minimum concrete effective area Ac,eff = {concreteArea} * {minConcreteFactor} = {areaByMinConcreteFactor}"); + concreteTensileArea = Math.Max(concreteTensileArea, areaByMinConcreteFactor); + double areaByMaxConcreteFactor = concreteArea * maxConcreteFactor; + TraceLogger?.AddMessage($"Concrete area is considered not greater than {maxConcreteFactor} of area of concrete"); + TraceLogger?.AddMessage($"Maximum concrete effective area Ac,eff = {concreteArea} * {maxConcreteFactor} = {areaByMaxConcreteFactor}"); + concreteTensileArea = Math.Min(concreteTensileArea, areaByMaxConcreteFactor); + TraceLogger?.AddMessage($"Concrete effective area Ac,eff = {concreteTensileArea}"); + return concreteTensileArea; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaByStrainLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaByStrainLogic.cs new file mode 100644 index 0000000..8303141 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaByStrainLogic.cs @@ -0,0 +1,64 @@ +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models; +using StructureHelperLogics.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class TensionRebarAreaByStrainLogic : ITensionRebarAreaLogic + { + IStressLogic stressLogic; + public IStrainMatrix StrainMatrix { get; set; } + public IEnumerable Rebars { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public TensionRebarAreaByStrainLogic(IStressLogic stressLogic) + { + this.stressLogic = stressLogic; + } + public TensionRebarAreaByStrainLogic() : this(new StressLogic()) + { + + } + public double GetTensionRebarArea() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage("Method of obtaining of summary area of rebars in tension based on areas which are proportional by maximum strain"); + var rebars = Rebars + .Where(x => stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); + if (!rebars.Any()) + { + string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + var maxStrain = rebars + .Select(x => stressLogic.GetSectionStrain(StrainMatrix, x)) + .Max(); + TraceLogger?.AddMessage($"Maximum strain maxStrain = {maxStrain}"); + if (TraceLogger is not null) + { + TraceService.TraceNdmCollection(TraceLogger, rebars); + } + double sumArea = 0d; + foreach (var rebar in rebars) + { + double area = rebar.Area * rebar.StressScale; + double strain = stressLogic.GetSectionStrain(StrainMatrix, rebar); + TraceLogger?.AddMessage($"Rebar area = {area}(m^2)"); + TraceLogger?.AddMessage($"Rebar strain = {strain}"); + var reducedArea = area * strain / maxStrain; + TraceLogger?.AddMessage($"Reduced rebar area = area * strain / maxStrain = {area} * {strain} / {maxStrain} = {reducedArea}(m^2)"); + sumArea += reducedArea; + } + return sumArea; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaSimpleSumLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaSimpleSumLogic.cs new file mode 100644 index 0000000..d446c3a --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaSimpleSumLogic.cs @@ -0,0 +1,53 @@ +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2024 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class TensionRebarAreaSimpleSumLogic : ITensionRebarAreaLogic + { + IStressLogic stressLogic; + public IStrainMatrix StrainMatrix { get; set; } + public IEnumerable Rebars { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public TensionRebarAreaSimpleSumLogic(IStressLogic stressLogic) + { + this.stressLogic = stressLogic; + } + public TensionRebarAreaSimpleSumLogic() : this(new StressLogic()) + { + + } + public double GetTensionRebarArea() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage("Method of obtaining of summary area of rebars in tension based on ordinary summarizing of areas"); + var rebars = Rebars + .Where(x => stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); + if (!rebars.Any()) + { + string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + if (TraceLogger is not null) + { + TraceService.TraceNdmCollection(TraceLogger, rebars); + } + var rebarArea = rebars.Sum(x => x.Area * x.StressScale); + return rebarArea; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackCalculator.cs new file mode 100644 index 0000000..c388607 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackCalculator.cs @@ -0,0 +1,250 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelper.Models.Materials; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Services.Forces; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.Services.NdmPrimitives; + +//Copyright (c) 2024 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class TupleCrackCalculator : ICalculator + { + private static readonly ILengthBetweenCracksLogic lengthLogic = new LengthBetweenCracksLogicSP63(); + private TupleCrackResult result; + private ICrackedSectionTriangulationLogic triangulationLogic; + private List? rebarPrimitives; + private IEnumerable crackableNdms; + private IEnumerable crackedNdms; + private IEnumerable elasticNdms; + private CrackForceResult crackForceResult; + private StrainTuple longDefaultStrainTuple; + private StrainTuple shortDefaultStrainTuple; + private double longLength; + private double shortLength; + private object locker = new(); + + public string Name { get; set; } + public TupleCrackInputData InputData { get; set; } + public IResult Result => result; + + public IShiftTraceLogger? TraceLogger { get; set; } + + public void Run() + { + PrepareNewResult(); + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + + try + { + TraceLogger?.AddMessage($"Calculation of crack width by force combination"); + ProcessCalculations(); + TraceLogger?.AddMessage(LoggerStrings.CalculationHasDone); + + } + catch (Exception ex) + { + result.IsValid = false; + result.Description += ex; + TraceLogger?.AddMessage(LoggerStrings.CalculationError + ex, TraceLogStatuses.Error); + } + + } + + private void PrepareNewResult() + { + result = new() + { + IsValid = true, + Description = string.Empty, + InputData = InputData + }; + } + + private void ProcessCalculations() + { + CheckInputData(); + Triangulate(); + + longDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms); + shortDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms); + var longElasticStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, elasticNdms); + var shortElasticStrainTuple = CalcStrainMatrix(InputData.ShortTermTuple as ForceTuple, elasticNdms); + if (result.IsValid == false) { return; } + if (InputData.UserCrackInputData.SetLengthBetweenCracks == true) + { + longLength = InputData.UserCrackInputData.LengthBetweenCracks; + shortLength = InputData.UserCrackInputData.LengthBetweenCracks; + TraceLogger?.AddMessage($"User value of length between cracks Lcrc = {longLength}"); + } + else + { + longLength = GetLengthBetweenCracks(longElasticStrainTuple); + shortLength = GetLengthBetweenCracks(shortElasticStrainTuple); + } + //CalcCrackForce(); + //for (int j = 0; j < 100000; j++) + //{ + result.RebarResults.Clear(); + int rebarCount = rebarPrimitives.Count; + Task[] tasks = new Task[rebarCount]; + for (int i = 0; i < rebarCount; i++) + { + var rebar = rebarPrimitives[i]; + tasks[i] = new Task(() => ProcessRebar(rebar)); + tasks[i].Start(); + } + Task.WaitAll(tasks); + for (int i = 0; i < rebarCount; i++) + { + result.RebarResults.Add(tasks[i].Result); + } + //} + + if (result.RebarResults.Any(x => x.IsValid == false)) + { + result.IsValid = false; + return; + } + result.LongTermResult = new() + { + CrackWidth = result.RebarResults.Max(x => x.LongTermResult.CrackWidth), + UltimateCrackWidth = InputData.UserCrackInputData.UltimateLongCrackWidth + }; + result.ShortTermResult = new() + { + CrackWidth = result.RebarResults.Max(x => x.ShortTermResult.CrackWidth), + UltimateCrackWidth = InputData.UserCrackInputData.UltimateShortCrackWidth + }; + } + + private RebarCrackResult ProcessRebar(RebarPrimitive rebar) + { + RebarCrackCalculatorInputData rebarCalculatorData = GetRebarCalculatorInputData(rebar); + var calculator = new RebarCrackCalculator + { + InputData = rebarCalculatorData, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + calculator.Run(); + var rebarResult = calculator.Result as RebarCrackResult; + return rebarResult; + } + + private RebarCrackCalculatorInputData GetRebarCalculatorInputData(RebarPrimitive rebar) + { + IEnumerable crackableNdmsLoc = null; + IEnumerable crackedNdmsLoc = null; + RebarPrimitive rebarCopy = null; + lock (locker) + { + rebarCopy = rebar.Clone() as RebarPrimitive; + rebarCopy.HeadMaterial = rebarCopy.HeadMaterial.Clone() as IHeadMaterial; + var triangulationLogicLoc = new CrackedSectionTriangulationLogic(InputData.Primitives); + crackableNdmsLoc = triangulationLogicLoc.GetNdmCollection(); + crackedNdmsLoc = triangulationLogicLoc.GetCrackedNdmCollection(); + } + + var longRebarData = new RebarCrackInputData() + { + CrackableNdmCollection = crackableNdmsLoc, + CrackedNdmCollection = crackedNdmsLoc, + ForceTuple = InputData.LongTermTuple.Clone() as ForceTuple, + Length = longLength + }; + var shortRebarData = new RebarCrackInputData() + { + CrackableNdmCollection = crackableNdms, + CrackedNdmCollection = crackedNdms, + ForceTuple = InputData.ShortTermTuple.Clone() as ForceTuple, + Length = shortLength + }; + var rebarCalculatorData = new RebarCrackCalculatorInputData() + { + RebarPrimitive = rebarCopy, + LongRebarData = longRebarData, + ShortRebarData = shortRebarData, + UserCrackInputData = InputData.UserCrackInputData + }; + return rebarCalculatorData; + } + + private StrainTuple CalcStrainMatrix(ForceTuple forceTuple, IEnumerable ndms) + { + IForceTupleInputData inputData = new ForceTupleInputData() + { + NdmCollection = ndms, + Tuple = forceTuple + }; + IForceTupleCalculator calculator = new ForceTupleCalculator() + { + InputData = inputData, + //TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + calculator.Run(); + var forceResult = calculator.Result as IForcesTupleResult; + if (forceResult.IsValid == false) + { + result.IsValid = false; + result.Description += forceResult.Description; + TraceLogger?.AddMessage("Bearing capacity of cross-section is not enough for action", TraceLogStatuses.Error); + return null; + } + var strain = TupleConverter.ConvertToStrainTuple(forceResult.LoaderResults.StrainMatrix); + return strain; + } + + private double GetLengthBetweenCracks(StrainTuple strainTuple) + { + var logic = new LengthBetweenCracksLogicSP63() + { + NdmCollection = elasticNdms, + TraceLogger = TraceLogger + }; + logic.StrainMatrix = TupleConverter.ConvertToLoaderStrainMatrix(strainTuple); + return logic.GetLength(); + } + + private void Triangulate() + { + triangulationLogic = new CrackedSectionTriangulationLogic(InputData.Primitives) + { + //TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + rebarPrimitives = triangulationLogic.GetRebarPrimitives(); + crackableNdms = triangulationLogic.GetNdmCollection(); + crackedNdms = triangulationLogic.GetCrackedNdmCollection(); + elasticNdms = triangulationLogic.GetElasticNdmCollection(); + } + + private void CalcCrackForce() + { + var calculator = new CrackForceCalculator(); + calculator.EndTuple = InputData.LongTermTuple; + calculator.NdmCollection = crackableNdms; + calculator.Run(); + crackForceResult = calculator.Result as CrackForceResult; + } + + private void CheckInputData() + { + if (InputData.Primitives is null || InputData.Primitives.Count == 0) + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": input data doesn't have any primitives"); + } + } + + public object Clone() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackInputData.cs new file mode 100644 index 0000000..69aa841 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackInputData.cs @@ -0,0 +1,39 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2024 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Input data for calculation of crack for specific force tuple + /// + public class TupleCrackInputData : IInputData, IHasPrimitives + { + /// + public bool IsValid { get; set; } + public string TupleName { get; set; } = string.Empty; + /// + /// Force tuple for long term calculations + /// + public IForceTuple? LongTermTuple { get; set; } + /// + /// Force tuple for short term calculations + /// + public IForceTuple? ShortTermTuple { get; set; } + /// + public List? Primitives { get; set;} + /// + /// Settings ajusted by user + /// + public UserCrackInputData UserCrackInputData { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackResult.cs new file mode 100644 index 0000000..6e3ca8b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackResult.cs @@ -0,0 +1,34 @@ +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2024 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Result of crack calculation for specific force tuple + /// + public class TupleCrackResult : IResult + { + /// + public bool IsValid { get; set; } + /// + public string Description { get; set; } + public TupleCrackInputData InputData { get; set; } + public bool IsCracked { get; set; } + public List RebarResults { get; private set; } + public CrackWidthRebarTupleResult LongTermResult { get; set; } + public CrackWidthRebarTupleResult ShortTermResult { get; set; } + + public TupleCrackResult() + { + RebarResults = new (); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/UserCrackInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/UserCrackInputData.cs new file mode 100644 index 0000000..7816977 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/UserCrackInputData.cs @@ -0,0 +1,40 @@ +using StructureHelperCommon.Models.Calculators; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Settings for crack calculations assigned by user + /// + public class UserCrackInputData : IInputData + { + /// + /// Flag of assigning of user value of softening factor + /// + public bool SetSofteningFactor {get;set;} + /// + /// User value of softening factor, dimensionless + /// + public double SofteningFactor {get;set;} + /// + /// Flag of assigning of user value of length between cracks + /// + public bool SetLengthBetweenCracks {get;set;} + /// + /// Length between cracks, m + /// + public double LengthBetweenCracks {get;set;} + /// + /// Ultimate long-term crack width, m + /// + public double UltimateLongCrackWidth { get; set; } + /// + /// Ultimate short-term crack width, m + /// + public double UltimateShortCrackWidth { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/UserCrackInputDataUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Cracking/UserCrackInputDataUpdateStrategy.cs new file mode 100644 index 0000000..910a6e8 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/UserCrackInputDataUpdateStrategy.cs @@ -0,0 +1,24 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + internal class UserCrackInputDataUpdateStrategy : IUpdateStrategy + { + public void Update(UserCrackInputData targetObject, UserCrackInputData sourceObject) + { + if (ReferenceEquals(targetObject, sourceObject)) { return; } + CheckObject.CompareTypes(targetObject, sourceObject); + + targetObject.SetSofteningFactor = sourceObject.SetSofteningFactor; + targetObject.SofteningFactor = sourceObject.SofteningFactor; + targetObject.SetLengthBetweenCracks = sourceObject.SetLengthBetweenCracks; + targetObject.LengthBetweenCracks = sourceObject.LengthBetweenCracks; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Primitives/CirclePrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/CirclePrimitive.cs index a7794e7..2275ee7 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/CirclePrimitive.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/CirclePrimitive.cs @@ -74,14 +74,43 @@ namespace StructureHelperLogics.NdmCalculations.Primitives return true; } - List> INdmPrimitive.GetValuePoints() + List INdmPrimitive.GetValuePoints() { - var points = new List>(); - NamedValue newPoint; - newPoint = new NamedValue() + var points = new List(); + INamedAreaPoint newPoint; + newPoint = new NamedAreaPoint { Name = "Center", - Value = Center.Clone() as Point2D + Point = Center.Clone() as Point2D, + Area = 0d + }; + points.Add(newPoint); + newPoint = new NamedAreaPoint + { + Name = "Left", + Point = new Point2D() { X = Center.X - Diameter / 2d, Y = Center.Y}, + Area = 0d + }; + points.Add(newPoint); + newPoint = new NamedAreaPoint + { + Name = "Top", + Point = new Point2D() { X = Center.X, Y = Center.Y + Diameter / 2d }, + Area = 0d + }; + points.Add(newPoint); + newPoint = new NamedAreaPoint + { + Name = "Right", + Point = new Point2D() { X = Center.X + Diameter / 2d, Y = Center.Y }, + Area = 0d + }; + points.Add(newPoint); + newPoint = new NamedAreaPoint + { + Name = "Bottom", + Point = new Point2D() { X = Center.X, Y = Center.Y - Diameter / 2d }, + Area = 0d }; points.Add(newPoint); return points; diff --git a/StructureHelperLogics/NdmCalculations/Primitives/IHasPrimitives.cs b/StructureHelperLogics/NdmCalculations/Primitives/IHasPrimitives.cs index 522f5fe..c88cd7c 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/IHasPrimitives.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/IHasPrimitives.cs @@ -4,6 +4,9 @@ namespace StructureHelperLogics.NdmCalculations.Primitives { public interface IHasPrimitives { + /// + /// Collection of NdmPrimitives + /// List Primitives { get; } } } diff --git a/StructureHelperLogics/NdmCalculations/Primitives/INamedAreaPoint.cs b/StructureHelperLogics/NdmCalculations/Primitives/INamedAreaPoint.cs new file mode 100644 index 0000000..c6bc330 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Primitives/INamedAreaPoint.cs @@ -0,0 +1,11 @@ +using StructureHelperCommon.Models.Shapes; + +namespace StructureHelperLogics.NdmCalculations.Primitives +{ + public interface INamedAreaPoint + { + double Area { get; set; } + string Name { get; set; } + Point2D Point { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Primitives/INdmPrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/INdmPrimitive.cs index 28d5b1e..e3621b3 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/INdmPrimitive.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/INdmPrimitive.cs @@ -14,21 +14,45 @@ using StructureHelperCommon.Models.Parameters; namespace StructureHelperLogics.NdmCalculations.Primitives { + /// + /// Geometrical primitive which generates ndm elemtntary part + /// public interface INdmPrimitive : ISaveable, ICloneable { + /// + /// Name of primitive + /// string? Name { get; set; } + /// + /// Base point of primitive + /// IPoint2D Center { get; } + /// + /// Host cross-section for primitive + /// ICrossSection? CrossSection { get; set; } + /// + /// Material of primitive + /// IHeadMaterial? HeadMaterial { get; set; } /// /// Flag of triangulation /// bool Triangulate { get; set; } + /// + /// Prestrain assigned from user + /// StrainTuple UsersPrestrain { get; } + /// + /// Prestrain assigned from calculations + /// StrainTuple AutoPrestrain { get; } + /// + /// Visual settings + /// IVisualProperty VisualProperty {get; } IEnumerable GetNdms(ITriangulationOptions triangulationOptions); - List> GetValuePoints(); + List GetValuePoints(); } } diff --git a/StructureHelperLogics/NdmCalculations/Primitives/IVisualProperty.cs b/StructureHelperLogics/NdmCalculations/Primitives/IVisualProperty.cs index c93eda5..b0727f1 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/IVisualProperty.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/IVisualProperty.cs @@ -9,10 +9,22 @@ namespace StructureHelperLogics.NdmCalculations.Primitives { public interface IVisualProperty { + /// + /// Flag of visibility + /// bool IsVisible { get; set; } Color Color { get; set; } + /// + /// Flag of assigning of color from material or from primitive's settings + /// bool SetMaterialColor { get; set; } + /// + /// Index by z-coordinate + /// int ZIndex { get; set; } + /// + /// Opacity of filling + /// double Opacity { get; set; } } } diff --git a/StructureHelperLogics/NdmCalculations/Primitives/NamedAreaPoint.cs b/StructureHelperLogics/NdmCalculations/Primitives/NamedAreaPoint.cs new file mode 100644 index 0000000..1f4b2f5 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Primitives/NamedAreaPoint.cs @@ -0,0 +1,17 @@ +using StructureHelperCommon.Models.Shapes; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Primitives +{ + public class NamedAreaPoint : INamedAreaPoint + { + public string Name { get; set; } + public Point2D Point { get; set; } + public double Area { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Primitives/PointPrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/PointPrimitive.cs index 270d202..5540e02 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/PointPrimitive.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/PointPrimitive.cs @@ -56,14 +56,14 @@ namespace StructureHelperLogics.Models.Primitives return logic.GetNdmCollection(); } - public List> GetValuePoints() + public List GetValuePoints() { - var points = new List>(); - NamedValue newPoint; - newPoint = new NamedValue() + var points = new List(); + var newPoint = new NamedAreaPoint() { Name = "Center", - Value = Center.Clone() as Point2D + Point = Center.Clone() as Point2D, + Area = Area }; points.Add(newPoint); return points; diff --git a/StructureHelperLogics/NdmCalculations/Primitives/RebarPrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/RebarPrimitive.cs index b3bfff9..b0e40a1 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/RebarPrimitive.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/RebarPrimitive.cs @@ -68,23 +68,45 @@ namespace StructureHelperLogics.NdmCalculations.Primitives } public IEnumerable GetNdms(ITriangulationOptions triangulationOptions) + { + List ndms = new() + { + GetConcreteNdm(triangulationOptions), + GetRebarNdm(triangulationOptions) + }; + return ndms; + } + + public RebarNdm GetRebarNdm(ITriangulationOptions triangulationOptions) { var options = new RebarTriangulationLogicOptions(this) { triangulationOptions = triangulationOptions }; var logic = new RebarTriangulationLogic(options); - return logic.GetNdmCollection(); + var rebar = logic.GetRebarNdm(); + return rebar; } - public List> GetValuePoints() + public Ndm GetConcreteNdm(ITriangulationOptions triangulationOptions) { - var points = new List>(); - NamedValue newPoint; - newPoint = new NamedValue() + var options = new RebarTriangulationLogicOptions(this) + { + triangulationOptions = triangulationOptions + }; + var logic = new RebarTriangulationLogic(options); + var concrete = logic.GetConcreteNdm(); + return concrete; + } + + public List GetValuePoints() + { + var points = new List(); + var newPoint = new NamedAreaPoint { Name = "Center", - Value = Center.Clone() as Point2D + Point = Center.Clone() as Point2D, + Area = Area }; points.Add(newPoint); return points; diff --git a/StructureHelperLogics/NdmCalculations/Primitives/RectanglePrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/RectanglePrimitive.cs index ca0f1dd..6007b60 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/RectanglePrimitive.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/RectanglePrimitive.cs @@ -82,20 +82,38 @@ namespace StructureHelperLogics.NdmCalculations.Primitives return true; } - public List> GetValuePoints() + public List GetValuePoints() { - var points = new List>(); - NamedValue newPoint; - newPoint = new NamedValue() + var points = new List(); + INamedAreaPoint newPoint; + newPoint = new NamedAreaPoint() { Name = "Center", - Value = Center.Clone() as Point2D + Point = Center.Clone() as Point2D }; points.Add(newPoint); - newPoint = new NamedValue() + newPoint = new NamedAreaPoint() { Name = "LeftTop", - Value = new Point2D() { X = Center.X - Width / 2d, Y = Center.Y + Height / 2d} + Point = new Point2D() { X = Center.X - Width / 2d, Y = Center.Y + Height / 2d} + }; + points.Add(newPoint); + newPoint = new NamedAreaPoint() + { + Name = "RightTop", + Point = new Point2D() { X = Center.X + Width / 2d, Y = Center.Y + Height / 2d } + }; + points.Add(newPoint); + newPoint = new NamedAreaPoint() + { + Name = "LeftBottom", + Point = new Point2D() { X = Center.X - Width / 2d, Y = Center.Y - Height / 2d } + }; + points.Add(newPoint); + newPoint = new NamedAreaPoint() + { + Name = "RightBottom", + Point = new Point2D() { X = Center.X + Width / 2d, Y = Center.Y - Height / 2d } }; points.Add(newPoint); return points; diff --git a/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogic.cs b/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogic.cs index b63607c..53e4380 100644 --- a/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogic.cs @@ -3,8 +3,10 @@ using LoaderCalculator.Data.Matrix; using LoaderCalculator.Data.Ndms; using LoaderCalculator.Data.Ndms.Transformations; using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Services.Forces; +using StructureHelperLogics.Models.Primitives; using System; using System.Collections.Generic; using System.Linq; @@ -23,14 +25,20 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations } public IEnumerable GetNdmCollection() { - var concreteNdm = new Ndm + List ndmCollection = new(); + if (options.HostPrimitive is not null) { - CenterX = options.Center.X, - CenterY = options.Center.Y, - Area = options.Area, - Material = options.HostMaterial.GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm), - StressScale = -1d - }; + var concreteNdm = GetConcreteNdm(); + ndmCollection.Add(concreteNdm); + } + + var rebarNdm = GetRebarNdm(); + ndmCollection.Add(rebarNdm); + return ndmCollection; + } + + public RebarNdm GetRebarNdm() + { var rebarNdm = new RebarNdm { CenterX = options.Center.X, @@ -38,9 +46,32 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations Area = options.Area, Material = options.HeadMaterial.GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm) }; - List ndmCollection = new() { concreteNdm, rebarNdm}; - NdmTransform.SetPrestrain(ndmCollection, TupleConverter.ConvertToLoaderStrainMatrix(options.Prestrain)); - return ndmCollection; + ; + NdmTransform.SetPrestrain(rebarNdm, TupleConverter.ConvertToLoaderStrainMatrix(options.Prestrain)); + return rebarNdm; + } + + public Ndm GetConcreteNdm() + { + var hostPrimitive = options.HostPrimitive; + var material = hostPrimitive + .HeadMaterial + .GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm); + + var prestrain = ForceTupleService.SumTuples(hostPrimitive.UsersPrestrain, + hostPrimitive.AutoPrestrain) + as StrainTuple; + + var concreteNdm = new Ndm + { + CenterX = options.Center.X, + CenterY = options.Center.Y, + Area = options.Area, + Material = material, + StressScale = -1d + }; + NdmTransform.SetPrestrain(concreteNdm, TupleConverter.ConvertToLoaderStrainMatrix(prestrain)); + return concreteNdm; } public void ValidateOptions(ITriangulationLogicOptions options) diff --git a/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogicOptions.cs b/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogicOptions.cs index e3d13d6..685b7b0 100644 --- a/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogicOptions.cs +++ b/StructureHelperLogics/NdmCalculations/Triangulations/RebarTriangulationLogicOptions.cs @@ -22,7 +22,8 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations public double Area { get; } public StrainTuple Prestrain { get; set; } public IHeadMaterial HeadMaterial { get; set; } - public IHeadMaterial HostMaterial { get; set; } + public INdmPrimitive HostPrimitive { get; set; } + /// public RebarTriangulationLogicOptions(RebarPrimitive primitive) @@ -30,7 +31,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations Center = primitive.Center.Clone() as Point2D; Area = primitive.Area; HeadMaterial = primitive.HeadMaterial; - HostMaterial = primitive.HostPrimitive.HeadMaterial; + HostPrimitive = primitive.HostPrimitive; Prestrain = ForceTupleService.SumTuples(primitive.UsersPrestrain, primitive.AutoPrestrain) as StrainTuple; } } diff --git a/StructureHelperLogics/Services/NdmCalculations/CalculationService.cs b/StructureHelperLogics/Services/NdmCalculations/CalculationService.cs index 481de12..2d75e1e 100644 --- a/StructureHelperLogics/Services/NdmCalculations/CalculationService.cs +++ b/StructureHelperLogics/Services/NdmCalculations/CalculationService.cs @@ -21,11 +21,18 @@ namespace StructureHelperLogics.Services.NdmCalculations public class CalculationService { private ICalculationProperty calculationProperty; + private ITriangulatePrimitiveLogic triangulateLogic; public IStrainMatrix GetPrimitiveStrainMatrix(INdmPrimitive[] ndmPrimitives, double mx, double my, double nz) { var ndmCollection = new List(); - ndmCollection.AddRange(NdmPrimitivesService.GetNdms(ndmPrimitives, calculationProperty.LimitState, calculationProperty.CalcTerm)); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = ndmPrimitives, + LimitState = calculationProperty.LimitState, + CalcTerm = calculationProperty.CalcTerm + }; + ndmCollection.AddRange(triangulateLogic.GetNdms()); var loaderData = new LoaderOptions { Preconditions = new Preconditions diff --git a/StructureHelperLogics/Services/NdmPrimitives/CheckPrimitivesForMeshingLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/CheckPrimitivesForMeshingLogic.cs new file mode 100644 index 0000000..b1901da --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/CheckPrimitivesForMeshingLogic.cs @@ -0,0 +1,47 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public class CheckPrimitivesForMeshingLogic : ICheckPrimitivesForMeshingLogic + { + public IEnumerable Primitives { get; set; } + + public IShiftTraceLogger? TraceLogger { get; set; } + + public bool Check() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + if (!Primitives.Any()) + { + string errorMessage = string.Intern(ErrorStrings.DataIsInCorrect + $": Count of primitive must be greater than zero"); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + if (!Primitives.Any(x => x.Triangulate == true)) + { + string errorMessage = string.Intern(ErrorStrings.DataIsInCorrect + $": There are not primitives to triangulate"); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + foreach (var item in Primitives) + { + if (item.Triangulate == true & + item.HeadMaterial is null) + { + string errorMessage = string.Intern(ErrorStrings.DataIsInCorrect + $": Primitive: {item.Name} can't be triangulated since material is null"); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + } + return true; + } + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/ICheckPrimitivesForMeshingLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/ICheckPrimitivesForMeshingLogic.cs new file mode 100644 index 0000000..4a2bb3f --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/ICheckPrimitivesForMeshingLogic.cs @@ -0,0 +1,16 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public interface ICheckPrimitivesForMeshingLogic : ILogic + { + IEnumerable Primitives { get; set; } + bool Check(); + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/IMeshHasDivisionLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/IMeshHasDivisionLogic.cs new file mode 100644 index 0000000..e8094a7 --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/IMeshHasDivisionLogic.cs @@ -0,0 +1,18 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public interface IMeshHasDivisionLogic : ILogic + { + List NdmCollection { get; set; } + IHasDivisionSize Primitive { get; set; } + void MeshHasDivision(); + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/IMeshPrimitiveLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/IMeshPrimitiveLogic.cs new file mode 100644 index 0000000..47e61cd --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/IMeshPrimitiveLogic.cs @@ -0,0 +1,19 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.NdmCalculations.Triangulations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public interface IMeshPrimitiveLogic : ILogic + { + INdmPrimitive Primitive { get; set; } + ITriangulationOptions TriangulationOptions { get; set; } + List MeshPrimitive(); + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/ITriangulatePrimitiveLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/ITriangulatePrimitiveLogic.cs new file mode 100644 index 0000000..acc8bf8 --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/ITriangulatePrimitiveLogic.cs @@ -0,0 +1,15 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperLogics.NdmCalculations.Primitives; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public interface ITriangulatePrimitiveLogic : ILogic + { + IEnumerable Primitives { get; set; } + LimitStates LimitState { get; set; } + CalcTerms CalcTerm { get; set; } + List GetNdms(); + } +} \ No newline at end of file diff --git a/StructureHelperLogics/Services/NdmPrimitives/MeshCrackedConcreteLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/MeshCrackedConcreteLogic.cs new file mode 100644 index 0000000..8a54a4e --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/MeshCrackedConcreteLogic.cs @@ -0,0 +1,116 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelper.Models.Materials; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.Models.Materials; +using StructureHelperLogics.Models.Primitives; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.NdmCalculations.Triangulations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + internal class MeshCrackedConcreteLogic : IMeshPrimitiveLogic + { + private IMeshPrimitiveLogic regularMeshLogic; + public List NdmCollection { get; set; } + public INdmPrimitive Primitive { get; set; } + public ITriangulationOptions TriangulationOptions { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + List IMeshPrimitiveLogic.MeshPrimitive() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + CheckPrimitive(); + List ndmCollection = new(); + if (Primitive.HeadMaterial.HelperMaterial is ICrackedMaterial) + { + ProcessICracked(ndmCollection); + } + else if (Primitive is RebarPrimitive rebar) + { + ProcessRebar(ndmCollection, rebar); + } + else + { + ProcessNonCracked(ndmCollection); + } + return ndmCollection; + } + + private void ProcessNonCracked(List ndmCollection) + { + TraceLogger?.AddMessage($"Primitive {Primitive.Name} is non-crackable primitive", TraceLogStatuses.Service); + List ndms = GetNdms(Primitive); + ndmCollection.AddRange(ndms); + } + + private void ProcessRebar(List ndmCollection, RebarPrimitive rebar) + { + TraceLogger?.AddMessage($"Primitive {Primitive.Name} is rebar primitive", TraceLogStatuses.Service); + var newPrimititve = rebar.Clone() as RebarPrimitive; + var newHostPrimitive = rebar.HostPrimitive.Clone() as INdmPrimitive; + SetNewMaterial(newHostPrimitive); + newPrimititve.HostPrimitive = newHostPrimitive; + List ndms = GetNdms(newPrimititve); + ndmCollection.AddRange(ndms); + } + + private void ProcessICracked(List ndmCollection) + { + TraceLogger?.AddMessage($"Primitive {Primitive.Name} is crackable primitive", TraceLogStatuses.Service); + var newPrimititve = Primitive.Clone() as INdmPrimitive; + SetNewMaterial(newPrimititve); + List ndms = GetNdms(newPrimititve); + ndmCollection.AddRange(ndms); + } + + private void SetNewMaterial(INdmPrimitive? newPrimititve) + { + TraceLogger?.AddMessage($"Process material {newPrimititve.HeadMaterial.Name} has started"); + var newHeadMaterial = newPrimititve.HeadMaterial.Clone() as IHeadMaterial; + var newMaterial = newHeadMaterial.HelperMaterial.Clone() as ICrackedMaterial; + TraceLogger?.AddMessage($"Set work in tension zone for material {newPrimititve.HeadMaterial.Name}"); + newMaterial.TensionForSLS = false; + newHeadMaterial.HelperMaterial = newMaterial as IHelperMaterial; + newPrimititve.HeadMaterial = newHeadMaterial; + } + + private List GetNdms(INdmPrimitive primitive) + { + TraceLogger?.AddMessage($"Triangulation primitive has started"); + regularMeshLogic = new MeshPrimitiveLogic() + { + Primitive = primitive, + TriangulationOptions = TriangulationOptions, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + List ndms = regularMeshLogic.MeshPrimitive(); + return ndms; + } + + private void CheckPrimitive() + { + if (TriangulationOptions.LimiteState is not LimitStates.SLS) + { + string errorMessage = string.Intern(ErrorStrings.DataIsInCorrect + $": Limit state for cracking must correspondent limit state of serviceability"); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + if (TriangulationOptions.CalcTerm is not CalcTerms.ShortTerm) + { + string errorMessage = string.Intern(ErrorStrings.DataIsInCorrect + $": Calc term for cracked concrete must correspondent short term"); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + TraceLogger?.AddMessage($"Primitive check is ok"); + } + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/MeshElasticLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/MeshElasticLogic.cs new file mode 100644 index 0000000..694c4bc --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/MeshElasticLogic.cs @@ -0,0 +1,72 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.Models.Primitives; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.NdmCalculations.Triangulations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + internal class MeshElasticLogic : IMeshPrimitiveLogic + { + private IMeshPrimitiveLogic regularMeshLogic; + public INdmPrimitive Primitive { get; set; } + public ITriangulationOptions TriangulationOptions { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public List MeshPrimitive() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + CheckInputData(); + List ndms = new(); + regularMeshLogic = new MeshPrimitiveLogic() + { + Primitive = Primitive, + TriangulationOptions = TriangulationOptions, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + ndms.AddRange(regularMeshLogic.MeshPrimitive()); + foreach (var ndm in ndms) + { + var material = ndm.Material; + var materialFunc = material.Diagram; + var newMaterialFunc = (IEnumerable parameters, double strain) => strain * material.InitModulus; + var existingPrestrain = ndm.Prestrain; + var newPrestrain = materialFunc(null, existingPrestrain) / material.InitModulus; + ndm.Material.Diagram = newMaterialFunc; + ndm.Prestrain = newPrestrain; + } + return ndms; + } + + private void CheckInputData() + { + if (Primitive is null) + { + string errorMessage = string.Intern(ErrorStrings.ParameterIsNull); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + if (TriangulationOptions.LimiteState is not LimitStates.SLS) + { + string errorMessage = string.Intern(ErrorStrings.DataIsInCorrect + $": Limit state for cracking must correspondent limit state of serviceability"); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + if (TriangulationOptions.CalcTerm is not CalcTerms.ShortTerm) + { + string errorMessage = string.Intern(ErrorStrings.DataIsInCorrect + $": Calc term for cracked concrete must correspondent short term"); + TraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + throw new StructureHelperException(errorMessage); + } + TraceLogger?.AddMessage($"Primitive check is ok"); + } + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/MeshHasDivisionLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/MeshHasDivisionLogic.cs new file mode 100644 index 0000000..c2d9bf0 --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/MeshHasDivisionLogic.cs @@ -0,0 +1,41 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Shapes; +using StructureHelperLogics.Models.Primitives; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public class MeshHasDivisionLogic : IMeshHasDivisionLogic + { + public List NdmCollection { get; set; } + public IHasDivisionSize Primitive { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public void MeshHasDivision() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + if (Primitive is IHasDivisionSize hasDivision) + { + if (hasDivision.ClearUnderlying == true) + { + TraceLogger?.AddMessage("Removing of background part has started", TraceLogStatuses.Service); + NdmCollection + .RemoveAll(x => + hasDivision + .IsPointInside(new Point2D() + { + X = x.CenterX, + Y = x.CenterY + }) == true); + } + } + } + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/MeshPrimitiveLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/MeshPrimitiveLogic.cs new file mode 100644 index 0000000..7790dc0 --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/MeshPrimitiveLogic.cs @@ -0,0 +1,34 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.Models.Materials; +using StructureHelperLogics.Models.Primitives; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.NdmCalculations.Triangulations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public class MeshPrimitiveLogic : IMeshPrimitiveLogic + { + public INdmPrimitive Primitive { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public ITriangulationOptions TriangulationOptions { get; set; } + + public List MeshPrimitive() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + List ndmCollection = new(); + var itemNdms = Primitive.GetNdms(TriangulationOptions); + ndmCollection.AddRange(itemNdms); + TraceLogger?.AddMessage($"Triangulation of primitive {Primitive.Name} has finished, {itemNdms.Count()} part(s) were obtained", TraceLogStatuses.Service); + return ndmCollection; + } + } +} diff --git a/StructureHelperLogics/Services/NdmPrimitives/NdmPrimitivesService.cs b/StructureHelperLogics/Services/NdmPrimitives/NdmPrimitivesService.cs deleted file mode 100644 index 709bdee..0000000 --- a/StructureHelperLogics/Services/NdmPrimitives/NdmPrimitivesService.cs +++ /dev/null @@ -1,56 +0,0 @@ -using LoaderCalculator.Data.Ndms; -using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Infrastructures.Exceptions; -using StructureHelperCommon.Models.Shapes; -using StructureHelperLogics.NdmCalculations.Primitives; -using StructureHelperLogics.NdmCalculations.Triangulations; - -namespace StructureHelperLogics.Services.NdmPrimitives -{ - public static class NdmPrimitivesService - { - public static List GetNdms(IEnumerable primitives, LimitStates limitState, CalcTerms calcTerm) - { - var orderedNdmPrimitives = primitives.OrderBy(x => x.VisualProperty.ZIndex); - var ndms = new List(); - var triangulationOptions = new TriangulationOptions() { LimiteState = limitState, CalcTerm = calcTerm }; - foreach (var item in orderedNdmPrimitives) - { - if (item is IHasDivisionSize) - { - var hasDivision = item as IHasDivisionSize; - if (hasDivision.ClearUnderlying == true) - { - ndms.RemoveAll(x => hasDivision.IsPointInside(new Point2D() { X = x.CenterX, Y = x.CenterY }) == true); - } - } - if (item.Triangulate == true) - { - ndms.AddRange(item.GetNdms(triangulationOptions)); - } - } - return ndms; - } - - public static bool CheckPrimitives(IEnumerable primitives) - { - if (!primitives.Any()) - { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": Count of primitive must be greater than zero"); - } - if (!primitives.Any(x => x.Triangulate == true)) - { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": There are not primitives to triangulate"); - } - foreach (var item in primitives) - { - if (item.Triangulate == true & - item.HeadMaterial is null) - { - throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": Primitive: {item.Name} can't be triangulated since material is null"); - } - } - return true; - } - } -} diff --git a/StructureHelperLogics/Services/NdmPrimitives/TextParametersLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/TextParametersLogic.cs index b4fbd24..f18e28e 100644 --- a/StructureHelperLogics/Services/NdmPrimitives/TextParametersLogic.cs +++ b/StructureHelperLogics/Services/NdmPrimitives/TextParametersLogic.cs @@ -18,6 +18,9 @@ namespace StructureHelperLogics.Services.NdmPrimitives { const string prefixInitial = "Initial"; const string prefixActual = "Actual"; + IConvertUnitLogic operationLogic = new ConvertUnitLogic(); + IGetUnitLogic unitLogic = new GetUnitLogic(); + static string firstAxisName => ProgramSetting.GeometryNames.FstAxisName; static string secondAxisName => ProgramSetting.GeometryNames.SndAxisName; static IEnumerable units = UnitsFactory.GetUnitCollection(); @@ -42,7 +45,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives const string name = "Summary Area"; const string shortName = "A"; var parameters = new List>(); - var unitArea = CommonOperation.GetUnit(UnitTypes.Area, "mm2"); + var unitArea = unitLogic.GetUnit(UnitTypes.Area, "mm2"); var unitName = $"{unitArea.Name}"; var unitMultiPlayer = unitArea.Multiplyer; var firstParameter = new ValueParameter() @@ -50,7 +53,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{name}", ShortName = $"{shortName}", - MeasurementUnit = unitName, + Text = unitName, Description = $"{name} of cross-section without reduction" }; try @@ -71,8 +74,8 @@ namespace StructureHelperLogics.Services.NdmPrimitives const string name = "Bending stiffness"; const string shortName = "EI"; var parameters = new List>(); - var unitArea = CommonOperation.GetUnit(UnitTypes.Area, "mm2"); - var unitStress = CommonOperation.GetUnit(UnitTypes.Stress, "MPa"); + var unitArea = unitLogic.GetUnit(UnitTypes.Area, "mm2"); + var unitStress = unitLogic.GetUnit(UnitTypes.Stress, "MPa"); var unitName = $"{unitStress.Name} * {unitArea.Name} * {unitArea.Name}"; var unitMultiPlayer = unitArea.Multiplyer * unitArea.Multiplyer * unitStress.Multiplyer; var firstParameter = new ValueParameter() @@ -80,7 +83,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefix} {name} {firstAxisName.ToUpper()}", ShortName = $"{shortName}{firstAxisName}", - MeasurementUnit = unitName, + Text = unitName, Description = $"{prefix} {name} of cross-section arbitrary {firstAxisName}-axis multiplied by {prefix} modulus" }; var secondParameter = new ValueParameter() @@ -88,7 +91,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefix} {name} {secondAxisName}", ShortName = $"{shortName}{secondAxisName}", - MeasurementUnit = unitName, + Text = unitName, Description = $"{prefix} {name} of cross-section arbitrary {secondAxisName}-axis multiplied by {prefix} modulus" }; try @@ -120,7 +123,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefixActual}/{prefixInitial} {name} {firstAxisName.ToUpper()} ratio", ShortName = $"{shortName}{firstAxisName}-ratio", - MeasurementUnit = "-", + Text = "-", Description = $"{prefixActual}/{prefixInitial} {name} of cross-section arbitrary {firstAxisName}-axis ratio" }; var secondParameter = new ValueParameter() @@ -128,7 +131,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefixActual}/{prefixInitial} {name} {secondAxisName} ratio", ShortName = $"{shortName}{secondAxisName}-ratio", - MeasurementUnit = "-", + Text = "-", Description = $"{prefixActual}/{prefixInitial} {name} of cross-section arbitrary {secondAxisName}-axis ratio" }; try @@ -155,8 +158,8 @@ namespace StructureHelperLogics.Services.NdmPrimitives const string name = "Longitudinal stiffness"; const string shortName = "EA"; var parameters = new List>(); - var unitArea = CommonOperation.GetUnit(UnitTypes.Area, "mm2"); - var unitStress = CommonOperation.GetUnit(UnitTypes.Stress, "MPa"); + var unitArea = unitLogic.GetUnit(UnitTypes.Area, "mm2"); + var unitStress = unitLogic.GetUnit(UnitTypes.Stress, "MPa"); var unitName = $"{unitStress.Name} * {unitArea.Name}" ; var unitMultiPlayer = unitArea.Multiplyer * unitStress.Multiplyer; var firstParameter = new ValueParameter() @@ -164,7 +167,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefix} {name}", ShortName = $"{shortName}", - MeasurementUnit = unitName, + Text = unitName, Description = $"{prefix} {name} of cross-section multiplied by {prefix} modulus" }; try @@ -190,7 +193,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefixActual}/{prefixInitial} {name} ratio", ShortName = $"{shortName}-ratio", - MeasurementUnit = "-", + Text = "-", Description = $"{prefixActual}/{prefixInitial} {name}-ratio of cross-section" }; try @@ -216,7 +219,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives { var parameters = new List>(); var unitType = UnitTypes.Length; - var unit = CommonOperation.GetUnit(unitType, "mm"); + var unit = unitLogic.GetUnit(unitType, "mm"); var unitName = unit.Name; var unitMultiPlayer = unit.Multiplyer; var firstParameter = new ValueParameter() @@ -224,7 +227,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefix} Center{firstAxisName.ToUpper()}", ShortName = $"{firstAxisName.ToUpper()}c", - MeasurementUnit = unitName, + Text = unitName, Description = $"{prefix} Displacement of center of gravity of cross-section along {firstAxisName}-axis" }; var secondParameter = new ValueParameter() @@ -232,7 +235,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives IsValid = true, Name = $"{prefix} Center{secondAxisName.ToUpper()}", ShortName = $"{secondAxisName.ToUpper()}c", - MeasurementUnit = unitName, + Text = unitName, Description = $"{prefix} Displacement of center of gravity of cross-section along {secondAxisName}-axis" }; try diff --git a/StructureHelperLogics/Services/NdmPrimitives/TriangulatePrimitiveLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/TriangulatePrimitiveLogic.cs new file mode 100644 index 0000000..4b24777 --- /dev/null +++ b/StructureHelperLogics/Services/NdmPrimitives/TriangulatePrimitiveLogic.cs @@ -0,0 +1,113 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Materials; +using StructureHelperCommon.Models.Shapes; +using StructureHelperLogics.Models.Materials; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.NdmCalculations.Triangulations; + +namespace StructureHelperLogics.Services.NdmPrimitives +{ + public class TriangulatePrimitiveLogic : ITriangulatePrimitiveLogic + { + private IMeshHasDivisionLogic divisionLogic; + private IMeshPrimitiveLogic meshLogic; + private List ndmCollection; + private ICheckPrimitivesForMeshingLogic checkLogic; + + public IEnumerable Primitives { get; set; } + public LimitStates LimitState { get; set; } + public CalcTerms CalcTerm { get; set; } + + public IShiftTraceLogger? TraceLogger { get; set; } + + public TriangulatePrimitiveLogic(IMeshPrimitiveLogic meshPrimitiveLogic) + { + meshLogic = meshPrimitiveLogic; + } + + public TriangulatePrimitiveLogic() : this (new MeshPrimitiveLogic()) { } + + public List GetNdms() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + CheckPrimitives(); + ndmCollection = new List(); + SetLogics(); + TraceInitialSettings(); + TriangulatePrimitives(); + return ndmCollection; + } + + private void TriangulatePrimitives() + { + var orderedNdmPrimitives = Primitives.OrderBy(x => x.VisualProperty.ZIndex); + foreach (var primitive in orderedNdmPrimitives) + { + TriangulatePrimitive(primitive); + } + if (TraceLogger is not null) + { + TraceService.TraceNdmCollection(TraceLogger, ndmCollection); + } + TraceLogger?.AddMessage($"Triangulation of primitives has finished, {ndmCollection.Count} part(s) were obtained", TraceLogStatuses.Service); + } + + private void TraceInitialSettings() + { + TraceLogger?.AddMessage($"Total count of primitives n = {Primitives.Count()}", TraceLogStatuses.Service); + TraceLogger?.AddMessage($"Limit state is {LimitState}", TraceLogStatuses.Service); + TraceLogger?.AddMessage($"Calc term is {CalcTerm}", TraceLogStatuses.Service); + } + + private void SetLogics() + { + divisionLogic = new MeshHasDivisionLogic() + { + NdmCollection = ndmCollection, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + var triangulationOptions = new TriangulationOptions() + { + LimiteState = LimitState, + CalcTerm = CalcTerm + }; + meshLogic.TriangulationOptions = triangulationOptions; + meshLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + } + + private void TriangulatePrimitive(INdmPrimitive primitive) + { + TraceLogger?.AddMessage($"Triangulation of primitive {primitive.Name} has started", TraceLogStatuses.Service); + if (primitive is IHasDivisionSize hasDivision) + { + divisionLogic.Primitive = hasDivision; + divisionLogic.MeshHasDivision(); + } + if (primitive.Triangulate == true) + { + meshLogic.Primitive = primitive; + var ndms = meshLogic.MeshPrimitive(); + ndmCollection.AddRange(ndms); + } + else + { + TraceLogger?.AddMessage($"Triangulation of primitive was skiped cause its settings", TraceLogStatuses.Service); + } + } + + private bool CheckPrimitives() + { + checkLogic = new CheckPrimitivesForMeshingLogic() + { + Primitives = Primitives, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + checkLogic.Check(); + return true; + } + } +} diff --git a/StructureHelperTests/FunctionalTests/Ndms/Calculators/CrackCalculatorTests/CrackCalculatorTest.cs b/StructureHelperTests/FunctionalTests/Ndms/Calculators/CrackCalculatorTests/CrackCalculatorTest.cs index 41ba585..393cde9 100644 --- a/StructureHelperTests/FunctionalTests/Ndms/Calculators/CrackCalculatorTests/CrackCalculatorTest.cs +++ b/StructureHelperTests/FunctionalTests/Ndms/Calculators/CrackCalculatorTests/CrackCalculatorTest.cs @@ -18,6 +18,8 @@ namespace StructureHelperTests.FunctionalTests.Ndms.Calculators.CrackCalculatorT { internal class CrackCalculatorTest { + private ITriangulatePrimitiveLogic triangulateLogic; + [TestCase(0.4d, 0.6d, 0.012d, 0.025d, 2, 2, 0.81d)] public void Run_ShouldPass(double width, double height, double topDiametr, double bottomDiametr, int widthCount, int heightCount, double expectedFactor) { @@ -25,7 +27,13 @@ namespace StructureHelperTests.FunctionalTests.Ndms.Calculators.CrackCalculatorT var template = new RectangleBeamTemplate(width, height) { TopDiameter = topDiametr, BottomDiameter = bottomDiametr, WidthCount = widthCount, HeightCount = heightCount }; var newSection = new SectionTemplate(new RectGeometryLogic(template)).GetCrossSection(); var ndmPrimitives = newSection.SectionRepository.Primitives; - var ndms = NdmPrimitivesService.GetNdms(ndmPrimitives, LimitStates.SLS, CalcTerms.ShortTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = ndmPrimitives, + LimitState = LimitStates.SLS, + CalcTerm = CalcTerms.ShortTerm + }; + var ndms = triangulateLogic.GetNdms(); var calculator = new CrackForceCalculator(); calculator.EndTuple = new ForceTuple() { Mx = -50e3d, My = -50e3d, Nz = 0d }; calculator.NdmCollection = ndms; diff --git a/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs b/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs index 24f06db..98eb362 100644 --- a/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs +++ b/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs @@ -15,7 +15,13 @@ namespace StructureHelperTests.FunctionalTests.Ndms.Calculators.ForceCalculatorT public void Run_ShouldPass(double width, double height, double topDiametr, double bottomDiametr, int widthCount, int heightCount, bool isBuckling, double expectedKx, double expectedKy, double expectedEpsZ) { //Arrange - var template = new RectangleBeamTemplate(width, height) { TopDiameter = topDiametr, BottomDiameter = bottomDiametr, WidthCount = widthCount, HeightCount = heightCount}; + var template = new RectangleBeamTemplate(width, height) + { + TopDiameter = topDiametr, + BottomDiameter = bottomDiametr, + WidthCount = widthCount, + HeightCount = heightCount + }; var newSection = new SectionTemplate(new RectGeometryLogic(template)).GetCrossSection(); var calculator = newSection.SectionRepository.CalculatorsList[0] as IForceCalculator; calculator.CompressedMember.Buckling = isBuckling; diff --git a/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityAxisTest.cs b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityAxisTest.cs new file mode 100644 index 0000000..1691ca2 --- /dev/null +++ b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityAxisTest.cs @@ -0,0 +1,39 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Models.Sections.Logics; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperTests.FunctionalTests.RCs.Eccentricitis +{ + public class RcEccentricityAxisLogicTests + { + [TestCase(12d, 0.2d, 0.02d)] + [TestCase(3d, 0.9d, 0.03d)] + [TestCase(2, 0.2d, 0.01d)] + public void GetValue_ShouldCalculateCorrectly(double length, double size, double expectedEccentricity) + { + // Arrange + var loggerMock = new Mock(); + + var rcEccentricityAxisLogic = new RcEccentricityAxisLogic + { + Length = length, + Size = size, + TraceLogger = loggerMock.Object, + }; + + // Act + var result = rcEccentricityAxisLogic.GetValue(); + + // Assert + //loggerMock.Verify(logger => logger.AddMessage(It.IsAny(), It.IsAny()), Times.Exactly(7)); // Adjust based on your actual calls + Assert.AreEqual(expectedEccentricity, result, 0.0001); // Adjust based on your expected result + // Add more assertions based on your expected behavior + } + } +} diff --git a/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityTest.cs b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityTest.cs new file mode 100644 index 0000000..673a002 --- /dev/null +++ b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityTest.cs @@ -0,0 +1,43 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Models.Sections.Logics; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperTests.FunctionalTests.RCs.Eccentricitis +{ + public class RcAccEccentricityLogicTests + { + [Test] + public void GetValue_ShouldCalculateCorrectly() + { + // Arrange + var eccentricityAxisLogicMock = new Mock(); + eccentricityAxisLogicMock.Setup(el => el.GetValue()).Returns(3.0); // Adjust based on your expected result + + var loggerMock = new Mock(); + + var rcAccEccentricityLogic = new RcAccEccentricityLogic(eccentricityAxisLogicMock.Object) + { + Length = 100.0, + SizeX = 5.0, + SizeY = 10.0, + TraceLogger = loggerMock.Object, + }; + + // Act + var result = rcAccEccentricityLogic.GetValue(); + + // Assert + eccentricityAxisLogicMock.Verify(el => el.GetValue(), Times.Exactly(2)); + //loggerMock.Verify(logger => logger.AddMessage(It.IsAny(), It.IsAny()), Times.Exactly(3)); // Adjust based on your actual calls + Assert.AreEqual(3.0, result.ex, 0.001); // Adjust based on your expected result + Assert.AreEqual(3.0, result.ey, 0.001); // Adjust based on your expected result + // Add more assertions based on your expected behavior + } + } +} diff --git a/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcEccentricityLogicTest.cs b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcEccentricityLogicTest.cs new file mode 100644 index 0000000..bef8dcd --- /dev/null +++ b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcEccentricityLogicTest.cs @@ -0,0 +1,58 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Sections.Logics; +using StructureHelperCommon.Models.Sections; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperTests.FunctionalTests.RCs.Eccentricitis +{ + public class RcEccentricityLogicTests + { + [TestCase(30, 1.0, 2.0, -60, -30)] + [TestCase(30, 2.0, 1.0, -30, -60)] + public void GetValue_ShouldCalculateCorrectly(double nz, double ex, double ey, double expectedMx, double expectedMy) + { + // Arrange + var inputForceTuple = new ForceTuple + { + Mx = 10, + My = 20, + Nz = nz, + Qx = 40.0, + Qy = 50.0, + Mz = 60.0, + }; + + var eccentricityLogicMock = new Mock(); + eccentricityLogicMock.Setup(el => el.GetValue()).Returns((ex, ey)); + + var loggerMock = new Mock(); + + var rcEccentricityLogic = new RcEccentricityLogic(eccentricityLogicMock.Object) + { + Length = 100.0, + SizeX = 5.0, + SizeY = 10.0, + InputForceTuple = inputForceTuple, + TraceLogger = loggerMock.Object, + }; + + // Act + var result = rcEccentricityLogic.GetValue(); + + // Assert + eccentricityLogicMock.Verify(el => el.GetValue(), Times.Once); + //loggerMock.Verify(logger => logger.AddMessage(It.IsAny(), It.IsAny()), Times.Exactly(6)); // Adjust based on your actual calls + //loggerMock.Verify(logger => logger.AddEntry(It.IsAny()), Times.Once); // Adjust based on your actual calls + Assert.AreEqual(expectedMx, result.Mx, 0.001); // Adjust based on your expected result + Assert.AreEqual(expectedMy, result.My, 0.001); // Adjust based on your expected result + // Add more assertions based on your expected behavior + } + } +} diff --git a/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs b/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs index 9f5078d..86b8db4 100644 --- a/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs +++ b/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs @@ -7,8 +7,8 @@ namespace StructureHelperTests.UnitTests.MaterialTests { public class MaterialStrengthTest { - [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.ShortTerm, 347826086.95652175d, 347826086.95652175d)] - [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.SLS, CalcTerms.ShortTerm, 400000000d, 400000000d)] + [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.ShortTerm, 339130434.78260875d, 339130434.78260875d)] + [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.SLS, CalcTerms.ShortTerm, 390000000d, 390000000d)] [TestCase(HeadmaterialType.Reinforecement500, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.ShortTerm, 400000000.0d, 434782608.69565225d)] [TestCase(HeadmaterialType.Reinforecement500, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.LongTerm, 434782608.69565225d, 434782608.69565225d)] [TestCase(HeadmaterialType.Reinforecement500, CodeTypes.SP63_2018, LimitStates.SLS, CalcTerms.ShortTerm, 5e8d, 5e8d)] diff --git a/StructureHelperTests/UnitTests/Ndms/Cracks/CrackWidthLogicTest.cs b/StructureHelperTests/UnitTests/Ndms/Cracks/CrackWidthLogicSP63Test.cs similarity index 96% rename from StructureHelperTests/UnitTests/Ndms/Cracks/CrackWidthLogicTest.cs rename to StructureHelperTests/UnitTests/Ndms/Cracks/CrackWidthLogicSP63Test.cs index 8aaec8c..4a52d15 100644 --- a/StructureHelperTests/UnitTests/Ndms/Cracks/CrackWidthLogicTest.cs +++ b/StructureHelperTests/UnitTests/Ndms/Cracks/CrackWidthLogicSP63Test.cs @@ -8,7 +8,7 @@ using StructureHelperLogics.NdmCalculations.Cracking; namespace StructureHelperTests.UnitTests.Ndms.Cracks { - public class CrackWidthLogicTest + public class CrackWidthLogicSP63Test { [TestCase(1.4d, 0.001d, 0d, 0.3d, 0.00020999999999999998d)] [TestCase(1.4d, 0.001d, 0.001d, 0.3d, 0d)] diff --git a/StructureHelperTests/UnitTests/Ndms/Cracks/EquivalentDiameterLogicTest.cs b/StructureHelperTests/UnitTests/Ndms/Cracks/EquivalentDiameterLogicTest.cs new file mode 100644 index 0000000..f710f8b --- /dev/null +++ b/StructureHelperTests/UnitTests/Ndms/Cracks/EquivalentDiameterLogicTest.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using LoaderCalculator.Data.Ndms; +using NUnit.Framework; +using StructureHelperLogics.NdmCalculations.Cracking; + +namespace StructureHelperTests.UnitTests.Ndms.Cracks +{ + public class EquivalentDiameterLogicTest + { + [TestCase(0.025d, 2, 0.025d, 2, 0.025d)] + [TestCase(0.032d, 2, 0.025d, 1, 0.029842055910607741d)] + [TestCase(0.032d, 1, 0.025d, 2, 0.027524820186583671d)] + public void Run_ShouldPass(double fstDiameter, int fstCount, double sndDiameter, int sndCount, double expectedDiameter) + { + //Arrange + List rebar = new(); + for (int i = 0; i < fstCount; i++) + { + rebar.Add(new RebarNdm() { Area = 0.785d * fstDiameter * fstDiameter }); + } + for (int i = 0; i < sndCount; i++) + { + rebar.Add(new RebarNdm() { Area = 0.785d * sndDiameter * sndDiameter }); + } + var logic = new EquivalentDiameterLogic() { Rebars = rebar }; + //Act + var eqDiametr = logic.GetAverageDiameter(); + //Assert + Assert.AreEqual(expectedDiameter, eqDiametr, 0.0001d); + } + } +} diff --git a/StructureHelperTests/UnitTests/Ndms/Cracks/TensionREbarAreaSumLogicTest.cs b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionREbarAreaSumLogicTest.cs new file mode 100644 index 0000000..8b41179 --- /dev/null +++ b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionREbarAreaSumLogicTest.cs @@ -0,0 +1,87 @@ +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperLogics.NdmCalculations.Cracking; +namespace StructureHelperTests.UnitTests.Ndms.Cracks +{ + public class TensionRebarAreaSimpleSumLogicTests + { + [Test] + public void GetTensionRebarArea_ShouldReturnCorrectSumArea_WhenRebarsInTension() + { + // Arrange + var mockStressLogic = new Mock(); + var mockStrainMatrix = new Mock(); + var mockTraceLogger = new Mock(); + + var rebars = new List + { + new RebarNdm { Area = 1.0, StressScale = 1.0 }, + new RebarNdm { Area = 2.0, StressScale = 1.0 }, + new RebarNdm { Area = 3.0, StressScale = 1.0 } + }; + + // Setup the mock to return positive strains + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 1.0))) + .Returns(0.5); + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 2.0))) + .Returns(1.0); + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 3.0))) + .Returns(1.5); + + var logic = new TensionRebarAreaSimpleSumLogic(mockStressLogic.Object) + { + StrainMatrix = mockStrainMatrix.Object, + Rebars = rebars, + TraceLogger = mockTraceLogger.Object + }; + + // Act + var result = logic.GetTensionRebarArea(); + + // Assert + // Expected result calculation: + // rebarArea = 1.0 * 1.0 + 2.0 * 1.0 + 3.0 * 1.0 = 6.0 + Assert.AreEqual(6.0, result); + + } + + [Test] + public void GetTensionRebarArea_ShouldThrowException_WhenNoRebarsInTension() + { + // Arrange + var mockStressLogic = new Mock(); + var mockStrainMatrix = new Mock(); + var mockTraceLogger = new Mock(); + + var rebars = new List + { + new RebarNdm { Area = 1.0, StressScale = 1.0 } + }; + + // Setup the mock to return non-positive strain + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.IsAny())) + .Returns(0.0); + + var logic = new TensionRebarAreaSimpleSumLogic(mockStressLogic.Object) + { + StrainMatrix = mockStrainMatrix.Object, + Rebars = rebars, + TraceLogger = mockTraceLogger.Object + }; + + // Act & Assert + var ex = Assert.Throws(() => logic.GetTensionRebarArea()); + StringAssert.Contains("Collection of rebars does not contain any tensile rebars", ex.Message); + } + } +} + + + + + diff --git a/StructureHelperTests/UnitTests/Ndms/Cracks/TensionRebarAreaByStrainLogicTest.cs b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionRebarAreaByStrainLogicTest.cs new file mode 100644 index 0000000..ea12e1d --- /dev/null +++ b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionRebarAreaByStrainLogicTest.cs @@ -0,0 +1,91 @@ +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperLogics.NdmCalculations.Cracking; +using System.Collections.Generic; +using System.Linq; + +namespace StructureHelperTests.UnitTests.Ndms.Cracks +{ + public class TensionRebarAreaByStrainLogicTests + { + [Test] + public void GetTensionRebarArea_ShouldReturnCorrectSumArea_WhenRebarsInTension() + { + // Arrange + var mockStressLogic = new Mock(); + var mockStrainMatrix = new Mock(); + var mockTraceLogger = new Mock(); + + var rebars = new List + { + new RebarNdm { Area = 1.0, StressScale = 1.0 }, + new RebarNdm { Area = 2.0, StressScale = 1.0 }, + new RebarNdm { Area = 3.0, StressScale = 1.0 } + }; + + // Setup the mock to return positive strains + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 1.0))) + .Returns(0.5); + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 2.0))) + .Returns(1.0); + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 3.0))) + .Returns(1.5); + + var logic = new TensionRebarAreaByStrainLogic(mockStressLogic.Object) + { + StrainMatrix = mockStrainMatrix.Object, + Rebars = rebars, + TraceLogger = mockTraceLogger.Object + }; + + // Act + var result = logic.GetTensionRebarArea(); + + // Assert + // Expected result calculation: + // maxStrain = 1.5 + // reducedArea for rebar 1 = 1.0 * 0.5 / 1.5 = 0.333... + // reducedArea for rebar 2 = 2.0 * 1.0 / 1.5 = 1.333... + // reducedArea for rebar 3 = 3.0 * 1.5 / 1.5 = 3.0 + // sumArea = 0.333... + 1.333... + 3.0 = 4.666... + Assert.AreEqual(4.666666666666667, result, 9); + } + [Test] + public void GetTensionRebarArea_ShouldThrowException_WhenNoRebarsInTension() + { + // Arrange + var mockStressLogic = new Mock(); + var mockStrainMatrix = new Mock(); + var mockTraceLogger = new Mock(); + + var rebars = new List + { + new RebarNdm { Area = 1.0, StressScale = 1.0 } + }; + + // Setup the mock to return non-positive strain + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.IsAny())) + .Returns(0.0); + + var logic = new TensionRebarAreaByStrainLogic(mockStressLogic.Object) + { + StrainMatrix = mockStrainMatrix.Object, + Rebars = rebars, + TraceLogger = mockTraceLogger.Object + }; + + // Act & Assert + var ex = Assert.Throws(() => logic.GetTensionRebarArea()); + StringAssert.Contains("Collection of rebars does not contain any tensile rebars", ex.Message); + + } + } +} + + + diff --git a/StructureHelperTests/UnitTests/Ndms/Triangulations/RectangleTriangulationTest.cs b/StructureHelperTests/UnitTests/Ndms/Triangulations/RectangleTriangulationTest.cs index e9e5ff4..fd12e6c 100644 --- a/StructureHelperTests/UnitTests/Ndms/Triangulations/RectangleTriangulationTest.cs +++ b/StructureHelperTests/UnitTests/Ndms/Triangulations/RectangleTriangulationTest.cs @@ -17,6 +17,8 @@ namespace StructureHelperTests.UnitTests.Ndms.Triangulations public class RectangleTriangulationTest { private Mock materialMock; + private ITriangulatePrimitiveLogic triangulateLogic; + [SetUp] public void Setup() { @@ -75,7 +77,13 @@ namespace StructureHelperTests.UnitTests.Ndms.Triangulations opening.VisualProperty.ZIndex = 1; var primitives = new List() { mainBlock, opening }; //Act - var ndms = NdmPrimitivesService.GetNdms(primitives, LimitStates.ULS, CalcTerms.ShortTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = primitives, + LimitState = LimitStates.ULS, + CalcTerm = CalcTerms.ShortTerm + }; + var ndms = triangulateLogic.GetNdms(); //Assert var area = ndms.Sum(x => x.Area); var moments = GeometryOperations.GetReducedMomentsOfInertia(ndms); @@ -106,7 +114,13 @@ namespace StructureHelperTests.UnitTests.Ndms.Triangulations opening.VisualProperty.ZIndex = 1; var primitives = new List() { mainBlock, opening }; //Act - var ndms = NdmPrimitivesService.GetNdms(primitives, LimitStates.ULS, CalcTerms.ShortTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = primitives, + LimitState = LimitStates.ULS, + CalcTerm = CalcTerms.ShortTerm + }; + var ndms = triangulateLogic.GetNdms(); //Assert var area = ndms.Sum(x => x.Area); var moments = GeometryOperations.GetReducedMomentsOfInertia(ndms); @@ -138,7 +152,13 @@ namespace StructureHelperTests.UnitTests.Ndms.Triangulations opening.VisualProperty.ZIndex = 1; var primitives = new List() { mainBlock, opening }; //Act - var ndms = NdmPrimitivesService.GetNdms(primitives, LimitStates.ULS, CalcTerms.ShortTerm); + triangulateLogic = new TriangulatePrimitiveLogic() + { + Primitives = primitives, + LimitState = LimitStates.ULS, + CalcTerm = CalcTerms.ShortTerm + }; + var ndms = triangulateLogic.GetNdms(); //Assert var area = ndms.Sum(x => x.Area); var moments = GeometryOperations.GetReducedMomentsOfInertia(ndms); diff --git a/StructureHelperTests/UnitTests/ParamTests/ProcessDoublePairTest.cs b/StructureHelperTests/UnitTests/ParamTests/ProcessDoublePairTest.cs new file mode 100644 index 0000000..8ce7ab0 --- /dev/null +++ b/StructureHelperTests/UnitTests/ParamTests/ProcessDoublePairTest.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using StructureHelperCommon.Models.Parameters; + +namespace StructureHelperTests.UnitTests.ParamTests +{ + public class ProcessDoublePairTest + { + [TestCase("100mm", DigitPlace.Start, "mm", 100d)] //Without backspace + [TestCase("100 mm", DigitPlace.Start, "mm", 100d)] //With backspace + [TestCase("Fixed3", DigitPlace.Any, "fixed", 3d)] + public void Run_ShouldPass(string inputString, DigitPlace digitPlace, string expectedText, double expectedValue) + { + //Arrange + var logic = new ProcessDoublePairLogic() { DigitPlace = digitPlace}; + //Act + var result = logic.GetValuePairByString(inputString); + //Assert + Assert.AreEqual(expectedText, result.Text); + Assert.AreEqual(expectedValue, result.Value, 0.001d); + } + } +} diff --git a/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs b/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs index c64a078..858a9c0 100644 --- a/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs +++ b/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs @@ -15,7 +15,7 @@ namespace StructureHelperTests.ViewModelTests var labels = new List(); for (int i = 0; i < columnCount; i++) { - labels[i] = $"Column{i}"; + labels.Add($"Column{i}"); } var array = new ArrayParameter(rowCount, columnCount, labels); for (int i = 0; i < columnCount; i++)