Skip to content

Commit

Permalink
GSAGH-499: add validation on modal parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
SandeepArup committed Feb 3, 2025
1 parent 59f05a3 commit c18777e
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 17 deletions.
2 changes: 1 addition & 1 deletion DocsGeneration/Setup/GrasshopperFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public GrasshopperFixture() {

InitializeCore();

Utility.SetupUnitsDuringLoad();
OasysGH.Units.Utility.SetupUnitsDuringLoad();
}

public void AddPluginToGh() {
Expand Down
65 changes: 64 additions & 1 deletion GsaGH/Components/4_Analysis/CreateModalDynamicParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

using System.Linq;
using Grasshopper.Kernel.Parameters;
using Rhino.PlugIns;
using Grasshopper;
using GsaGH.Helpers;

namespace GsaGH.Components {
/// <summary>
Expand Down Expand Up @@ -114,11 +117,71 @@ protected override void SolveInternal(IGH_DataAccess da) {

double? dampingStiffness = taskParameter.ModalDamping.StiffnessProportion;
da.GetData(index, ref dampingStiffness);
taskParameter.ModalDamping = new ModalDamping(dampingStiffness);

taskParameter.ModalDamping = new ModalDamping(dampingStiffness);
if (!ValidateMassParticipation(taskParameter)) {
return;
}
da.SetData(0, new GsaModalDynamicGoo(taskParameter));
}


private bool ValidateMassParticipation(GsaModalDynamic parameter) {
bool validationStatus = true;
switch (parameter.Method()) {
case ModeCalculationMethod.NumberOfMode: {
var method = parameter.ModeCalculationStrategy as ModeCalculationStrategyByNumberOfModes;
if (method.NumberOfModes < 1) {
this.AddRuntimeError("Number of mode should be greater than 1");
validationStatus = false;
}
}
break;
case ModeCalculationMethod.FrquencyRange: {
var method = parameter.ModeCalculationStrategy as ModeCalculationStrategyByFrequency;
double higherFrequency = method.HigherFrequency ?? double.MaxValue;
if (method.LowerFrequency.HasValue && (!GsaGH.Helpers.Utility.IsInRange
(method.LowerFrequency.Value, 0, higherFrequency) || GsaGH.Helpers.Utility.IsApproxEqual(method.LowerFrequency.Value, higherFrequency))) {
this.AddRuntimeError("Lower frquency should be positive value and less than higher frquency");
validationStatus = false;
}
double lowerFrequency = method.LowerFrequency ?? 0;
if (method.HigherFrequency.HasValue && (!GsaGH.Helpers.Utility.IsInRange
(method.HigherFrequency.Value, lowerFrequency, method.HigherFrequency.Value) || GsaGH.Helpers.Utility.IsApproxEqual(method.HigherFrequency.Value, lowerFrequency))) {
this.AddRuntimeError("Upper frquency should be positive value and greater than lower frquency");
validationStatus = false;
}

}
break;
case ModeCalculationMethod.TargetMassRatio: {
var method = parameter.ModeCalculationStrategy as ModeCalculationStrategyByMassParticipation;
if (!GsaGH.Helpers.Utility.IsInRange(method.TargetMassInXDirection, 0, 100) || !GsaGH.Helpers.Utility.IsInRange(method.TargetMassInYDirection, 0, 100) || !GsaGH.Helpers.Utility.IsInRange(method.TargetMassInZDirection, 0, 100)) {
this.AddRuntimeError("Target Mass participation ratio should be within the range of [0:100]");
validationStatus = false;

Check warning on line 161 in GsaGH/Components/4_Analysis/CreateModalDynamicParameter.cs

View check run for this annotation

Codecov / codecov/patch

GsaGH/Components/4_Analysis/CreateModalDynamicParameter.cs#L160-L161

Added lines #L160 - L161 were not covered by tests
}
}
break;
}

double? dampingStiffness = parameter.ModalDamping.StiffnessProportion;
if (dampingStiffness.HasValue && !GsaGH.Helpers.Utility.IsInRange(dampingStiffness.Value, 0, 1)) {
this.AddRuntimeError("Damping stiffness should be within the range [0:1]");
validationStatus = false;
}

if (parameter.AdditionalMassDerivedFromLoads.ScaleFactor < 0) {
this.AddRuntimeError("Load scale factor should have positive value");
validationStatus = false;
}

if (parameter.MassOption.ScaleFactor < 0) {
this.AddRuntimeError("Mass scale factor should have positive value");
validationStatus = false;
}
return validationStatus;
}

public override void SetSelected(int i, int j) {
_selectedItems[i] = _dropDownItems[i][j];

Expand Down
16 changes: 16 additions & 0 deletions GsaGH/Helpers/Utility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

using System;

namespace GsaGH.Helpers {
public static class Utility {
public static bool IsInRange(double value, double min, double max) {
float epsilon = 10e-12f;
return value <= max + epsilon && value >= min - epsilon;
}

public static bool IsApproxEqual(double value1, double value2) {
float epsilon = 10e-12f;
return Math.Abs(value1 - value2) < epsilon;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;

using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;

using GsaAPI;
Expand Down Expand Up @@ -29,8 +30,23 @@ public CreateModalDynamicParameterByNumberOfModesTests(ModalMassOption massOptio
private void PrepareComponent(ModalMassOption massOption, Direction direction) {
_component = ComponentMother(massOption, direction);
var _modalDynamicAnalysisGoo = (GsaModalDynamicGoo)ComponentTestHelper.GetOutput(_component);
_modalDynamicAnalysis = _modalDynamicAnalysisGoo.Value;
_modeCalculationStrategy = _modalDynamicAnalysis.ModeCalculationStrategy as ModeCalculationStrategyByNumberOfModes;
if (_modalDynamicAnalysisGoo != null) {
_modalDynamicAnalysis = _modalDynamicAnalysisGoo.Value;
_modeCalculationStrategy = _modalDynamicAnalysis.ModeCalculationStrategy as ModeCalculationStrategyByNumberOfModes;
}
}

private void SetNumberOfMode(double value) {
ComponentTestHelper.SetInput(_component, value, 0);
}

private void SetStiffness(double value) {
ComponentTestHelper.SetInput(_component, value, 4);
}

private void SetScaleFactor(double loadScaleFactor, double massScalefactor) {
ComponentTestHelper.SetInput(_component, loadScaleFactor, 2);
ComponentTestHelper.SetInput(_component, massScalefactor, 3);
}

public static GH_OasysComponent ComponentMother(ModalMassOption massOption, Direction direction) {
Expand All @@ -42,7 +58,7 @@ public static GH_OasysComponent ComponentMother(ModalMassOption massOption, Dire
ComponentTestHelper.SetInput(comp, "L1", index++);
ComponentTestHelper.SetInput(comp, 1.1, index++);
ComponentTestHelper.SetInput(comp, 1.2, index++);
ComponentTestHelper.SetInput(comp, 1.3, index);
ComponentTestHelper.SetInput(comp, 1, index);

switch (massOption) {
case ModalMassOption.LumpMassAtNode:
Expand Down Expand Up @@ -79,6 +95,27 @@ public void ComponentShouldReturnCorrectNumberOfMode() {
Assert.Equal(5, _modeCalculationStrategy.NumberOfModes);
}

[Fact]
public void ComponentShouldReportErrorWhenNumberOfModeIsNegativeValue() {
SetNumberOfMode(-1);
ComponentTestHelper.ComputeOutput(_component);
Assert.Single(_component.RuntimeMessages(GH_RuntimeMessageLevel.Error));
}

[Fact]
public void ComponentShouldReportErrorWhenStiffnessIsNotInRange() {
SetStiffness(2);
ComponentTestHelper.ComputeOutput(_component);
Assert.Single(_component.RuntimeMessages(GH_RuntimeMessageLevel.Error));
}

[Fact]
public void ComponentShouldReportErrorWhenScaleFactorsAreNegative() {
SetScaleFactor(-1,-2);
ComponentTestHelper.ComputeOutput(_component);
Assert.Equal(2,_component.RuntimeMessages(GH_RuntimeMessageLevel.Error).Count);
}

[Fact]
public void ComponentShouldReturnCorrectCaseDefinition() {
Assert.Equal("L1", _modalDynamicAnalysis.AdditionalMassDerivedFromLoads.CaseDefinition);
Expand All @@ -96,7 +133,7 @@ public void ComponentShouldReturnCorrectMassScaleFactor() {

[Fact]
public void ComponentShouldReturnCorrectStiffnessProportion() {
Assert.Equal(1.3, _modalDynamicAnalysis.ModalDamping.StiffnessProportion);
Assert.Equal(1, _modalDynamicAnalysis.ModalDamping.StiffnessProportion);
}

[Fact]
Expand Down Expand Up @@ -156,11 +193,18 @@ public CreateModalDynamicParameterByFrquencyRangeTest(ModalMassOption massOption
private void PrepareComponent(ModalMassOption massOption, Direction direction) {
_component = ComponentMother(massOption, direction);
var _modalDynamicAnalysisGoo = (GsaModalDynamicGoo)ComponentTestHelper.GetOutput(_component);
_modalDynamicAnalysis = _modalDynamicAnalysisGoo.Value;
_modeCalculationStrategy = _modalDynamicAnalysis.ModeCalculationStrategy as ModeCalculationStrategyByFrequency;
if (_modalDynamicAnalysisGoo != null) {
_modalDynamicAnalysis = _modalDynamicAnalysisGoo.Value;
_modeCalculationStrategy = _modalDynamicAnalysis.ModeCalculationStrategy as ModeCalculationStrategyByFrequency;
}
}

public static GH_OasysComponent ComponentMother(ModalMassOption massOption= ModalMassOption.LumpMassAtNode, Direction direction= Direction.Y) {
private void SetFrequency(double lower, double upper) {
ComponentTestHelper.SetInput(_component, lower, 0);
ComponentTestHelper.SetInput(_component, upper, 1);
}

public static GH_OasysComponent ComponentMother(ModalMassOption massOption = ModalMassOption.LumpMassAtNode, Direction direction = Direction.Y) {
var comp = new CreateModalDynamicParameter();
comp.CreateAttributes();
comp.SetSelected(0, 1);
Expand All @@ -171,7 +215,7 @@ public static GH_OasysComponent ComponentMother(ModalMassOption massOption= Moda
ComponentTestHelper.SetInput(comp, "L1", index++);
ComponentTestHelper.SetInput(comp, 1.1, index++);
ComponentTestHelper.SetInput(comp, 1.2, index++);
ComponentTestHelper.SetInput(comp, 1.3, index);
ComponentTestHelper.SetInput(comp, 1, index);

switch (massOption) {
case ModalMassOption.LumpMassAtNode:
Expand Down Expand Up @@ -213,6 +257,13 @@ public void ComponentShouldReturnCorrectUpperFrequency() {
Assert.Equal(10, _modeCalculationStrategy.HigherFrequency);
}

[Fact]
public void ComponentShouldReportErrorFrequenciesAreNotCorrect() {
SetFrequency(6, 5);
ComponentTestHelper.ComputeOutput(_component);
Assert.Equal(2, _component.RuntimeMessages(GH_RuntimeMessageLevel.Error).Count);
}

[Fact]
public void ComponentShouldReturnCorrectLowerFrequency() {
Assert.Equal(5, _modeCalculationStrategy.LowerFrequency);
Expand All @@ -235,7 +286,7 @@ public void ComponentShouldReturnCorrectMassScaleFactor() {

[Fact]
public void ComponentShouldReturnCorrectStiffnessProportion() {
Assert.Equal(1.3, _modalDynamicAnalysis.ModalDamping.StiffnessProportion);
Assert.Equal(1, _modalDynamicAnalysis.ModalDamping.StiffnessProportion);
}

[Fact]
Expand Down Expand Up @@ -295,8 +346,10 @@ public CreateModalDynamicParameterByTargetMassParticipationTest(ModalMassOption
private void PrepareComponent(ModalMassOption massOption, Direction direction) {
_component = ComponentMother(massOption, direction);
var _modalDynamicAnalysisGoo = (GsaModalDynamicGoo)ComponentTestHelper.GetOutput(_component);
_modalDynamicAnalysis = _modalDynamicAnalysisGoo.Value;
_modeCalculationStrategy = _modalDynamicAnalysis.ModeCalculationStrategy as ModeCalculationStrategyByMassParticipation;
if (_modalDynamicAnalysisGoo != null) {
_modalDynamicAnalysis = _modalDynamicAnalysisGoo.Value;
_modeCalculationStrategy = _modalDynamicAnalysis.ModeCalculationStrategy as ModeCalculationStrategyByMassParticipation;
}
}

public static GH_OasysComponent ComponentMother(ModalMassOption massOption, Direction direction) {
Expand All @@ -312,7 +365,7 @@ public static GH_OasysComponent ComponentMother(ModalMassOption massOption, Dire
ComponentTestHelper.SetInput(comp, "L1", index++);
ComponentTestHelper.SetInput(comp, 1.1, index++);
ComponentTestHelper.SetInput(comp, 1.2, index++);
ComponentTestHelper.SetInput(comp, 1.3, index);
ComponentTestHelper.SetInput(comp, 1, index);

switch (massOption) {
case ModalMassOption.LumpMassAtNode:
Expand Down Expand Up @@ -386,7 +439,7 @@ public void ComponentShouldReturnCorrectMassScaleFactor() {

[Fact]
public void ComponentShouldReturnCorrectStiffnessProportion() {
Assert.Equal(1.3, _modalDynamicAnalysis.ModalDamping.StiffnessProportion);
Assert.Equal(1, _modalDynamicAnalysis.ModalDamping.StiffnessProportion);
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion GsaGHTests/GrasshopperFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public GrasshopperFixture() {

InitializeCore();

Utility.SetupUnitsDuringLoad();
OasysGH.Units.Utility.SetupUnitsDuringLoad();
}

public void AddPluginToGh() {
Expand Down
2 changes: 1 addition & 1 deletion IntegrationTests/GrasshopperFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public GrasshopperFixture() {
InitializeCore();

// setup headless units
Utility.SetupUnitsDuringLoad();
OasysGH.Units.Utility.SetupUnitsDuringLoad();
}

// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
Expand Down

0 comments on commit c18777e

Please sign in to comment.