From 2fdc4f7ce5eabfc0254602b955f005ca4196c474 Mon Sep 17 00:00:00 2001 From: connor-sp Date: Tue, 2 Dec 2025 10:31:26 -0800 Subject: [PATCH 1/3] feat: implemented ability to control reaction direction reversing tests: added tests --- src/loadbearing_wall/linear_reactions.py | 9 +++++--- src/loadbearing_wall/wall_model.py | 1 + tests/test_wall_model.py | 28 ++++++++++++++---------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/loadbearing_wall/linear_reactions.py b/src/loadbearing_wall/linear_reactions.py index 7dadd67..59aa5fe 100644 --- a/src/loadbearing_wall/linear_reactions.py +++ b/src/loadbearing_wall/linear_reactions.py @@ -63,6 +63,7 @@ class LinearReactionString: magnitude_end_key: str location_start_key: str location_end_key: str + reverse_reaction_direction: bool = True @classmethod def from_projected_loads( @@ -72,11 +73,13 @@ def from_projected_loads( magnitude_end_key: str, location_start_key: str, location_end_key: str, + reverse_reaction_direction: bool = True ): w0 = magnitude_start_key w1 = magnitude_end_key x0 = location_start_key x1 = location_end_key + reverse_direction = -1 if reverse_reaction_direction else 1 linear_reaction_components = {} for load_dir, load_cases in projected_loads.items(): linear_reaction_components.setdefault(load_dir, {}) @@ -84,8 +87,8 @@ def from_projected_loads( linear_reaction_components[load_dir].setdefault(load_case, []) for applied_load in applied_loads: linear_reaction = LinearReaction( - applied_load[w0], - applied_load.get(w1), + applied_load[w0] * reverse_direction, + applied_load.get(w1) * reverse_direction, applied_load[x0], applied_load.get(x1), ) @@ -93,7 +96,7 @@ def from_projected_loads( linear_reaction_components[load_dir][load_case].append( linear_reaction ) - return cls(linear_reaction_components, w0, w1, x0, x1) + return cls(linear_reaction_components, w0, w1, x0, x1, reverse_reaction_direction) def extract_reaction_string(self, xa: float, xb: float, case: str, dir: str): """ diff --git a/src/loadbearing_wall/wall_model.py b/src/loadbearing_wall/wall_model.py index 55be149..baf590e 100644 --- a/src/loadbearing_wall/wall_model.py +++ b/src/loadbearing_wall/wall_model.py @@ -253,6 +253,7 @@ def get_reactions( self.magnitude_end_key, self.location_start_key, self.location_end_key, + self.reverse_reaction_force_direction ) return lrs.consolidate_reactions( flatten=flattened, dir_key=direction_key, case_key=case_key diff --git a/tests/test_wall_model.py b/tests/test_wall_model.py index 1d77827..fff64f3 100644 --- a/tests/test_wall_model.py +++ b/tests/test_wall_model.py @@ -46,20 +46,24 @@ def test_wall_model_runs(WM0, WM1): def test_no_spread(WM0): + rxn = WM0.get_reactions(flattened=False) + assert rxn["Fz"]["D"] == [ + {"dir": "Fz", "case": "D", "w1": -1 * 10.0, "w2": -1 * 10.0, "x1": 1.00, "x2": 1.75}, + {"dir": "Fz", "case": "D", "w1": -1 * 210.0, "w2": -1 * 210.0, "x1": 1.750000000001, "x2": 2.249999999999}, + {"dir": "Fz", "case": "D", "w1": -1 * 10.0, "w2": -1 * 10.0, "x1": 2.250000000001, "x2": 3.0}, + ] + assert rxn["Fz"]["L"] == [ + {"dir": "Fz", "case": "L", "w1": -1 * 15.0, "w2": -1 * 15.0, "x1": 0.00, "x2": 1.75}, + {"dir": "Fz", "case": "L", "w1": -1 * 215.0, "w2": -1 * 215.0, "x1": 1.750000000001, "x2": 2.00}, + {"dir": "Fz", "case": "L", "w1": -1 * 200.0, "w2": -1 * 200.0, "x1": 2.00, "x2": 2.249999999999}, + ] + WM0.reverse_reaction_force_direction = False rxn = WM0.get_reactions(flattened=False) assert rxn["Fz"]["D"] == [ {"dir": "Fz", "case": "D", "w1": 10.0, "w2": 10.0, "x1": 1.00, "x2": 1.75}, {"dir": "Fz", "case": "D", "w1": 210.0, "w2": 210.0, "x1": 1.750000000001, "x2": 2.249999999999}, {"dir": "Fz", "case": "D", "w1": 10.0, "w2": 10.0, "x1": 2.250000000001, "x2": 3.0}, ] - assert rxn["Fz"]["L"] == [ - {"dir": "Fz", "case": "L", "w1": 15.0, "w2": 15.0, "x1": 0.00, "x2": 1.75}, - {"dir": "Fz", "case": "L", "w1": 215.0, "w2": 215.0, "x1": 1.750000000001, "x2": 2.00}, - {"dir": "Fz", "case": "L", "w1": 200.0, "w2": 200.0, "x1": 2.00, "x2": 2.249999999999}, - - # {"dir": "Fz", "case": "L", "w1": 100.0, "x1": 0.5}, - # {"dir": "Fz", "case": "L", "w1": 15.0, "w2": 15.0, "x1": 0.0, "x2": 2.0}, - ] def test_45_spread(WM1): @@ -68,8 +72,8 @@ def test_45_spread(WM1): { "dir": "Fz", "case": "D", - "w1": 30.0, - "w2": 30.0, + "w1": -1 * 30.0, + "w2": -1 * 30.0, "x1": 0.0, "x2": 4.0, }, @@ -79,8 +83,8 @@ def test_45_spread(WM1): { "dir": "Fz", "case": "L", - "w1": 32.5, - "w2": 32.5, + "w1": -1 * 32.5, + "w2": -1 * 32.5, "x1": 0.0, "x2": 4.0, }, From 741fb8c9914d070b341f88e2a7832c039b817e6a Mon Sep 17 00:00:00 2001 From: connor-sp Date: Tue, 2 Dec 2025 10:32:01 -0800 Subject: [PATCH 2/3] chroe: bump version --- src/loadbearing_wall/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loadbearing_wall/__init__.py b/src/loadbearing_wall/__init__.py index 0741559..5a83791 100644 --- a/src/loadbearing_wall/__init__.py +++ b/src/loadbearing_wall/__init__.py @@ -5,7 +5,7 @@ The wall model is parameterizable and can represent any material """ -__version__ = "0.3.1" +__version__ = "0.4.0" from loadbearing_wall.wall_model import LinearWallModel from loadbearing_wall import * From b1ef5a7508acf8c8d794385890a4ea8adc7bc392 Mon Sep 17 00:00:00 2001 From: connor-sp Date: Tue, 2 Dec 2025 10:32:36 -0800 Subject: [PATCH 3/3] blakciy --- src/loadbearing_wall/linear_reactions.py | 6 ++++-- src/loadbearing_wall/wall_model.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/loadbearing_wall/linear_reactions.py b/src/loadbearing_wall/linear_reactions.py index 59aa5fe..2f89c90 100644 --- a/src/loadbearing_wall/linear_reactions.py +++ b/src/loadbearing_wall/linear_reactions.py @@ -73,7 +73,7 @@ def from_projected_loads( magnitude_end_key: str, location_start_key: str, location_end_key: str, - reverse_reaction_direction: bool = True + reverse_reaction_direction: bool = True, ): w0 = magnitude_start_key w1 = magnitude_end_key @@ -96,7 +96,9 @@ def from_projected_loads( linear_reaction_components[load_dir][load_case].append( linear_reaction ) - return cls(linear_reaction_components, w0, w1, x0, x1, reverse_reaction_direction) + return cls( + linear_reaction_components, w0, w1, x0, x1, reverse_reaction_direction + ) def extract_reaction_string(self, xa: float, xb: float, case: str, dir: str): """ diff --git a/src/loadbearing_wall/wall_model.py b/src/loadbearing_wall/wall_model.py index baf590e..a7ed536 100644 --- a/src/loadbearing_wall/wall_model.py +++ b/src/loadbearing_wall/wall_model.py @@ -253,7 +253,7 @@ def get_reactions( self.magnitude_end_key, self.location_start_key, self.location_end_key, - self.reverse_reaction_force_direction + self.reverse_reaction_force_direction, ) return lrs.consolidate_reactions( flatten=flattened, dir_key=direction_key, case_key=case_key