diff --git a/pyroll/core/__init__.py b/pyroll/core/__init__.py index 1d88720..5384dda 100644 --- a/pyroll/core/__init__.py +++ b/pyroll/core/__init__.py @@ -125,7 +125,6 @@ Unit.OutProfile.strain, Unit.OutProfile.length, Unit.OutProfile.t, - Unit.OutProfile.position, BaseRollPass.strain_rate, BaseRollPass.OutProfile.filling_ratio, BaseRollPass.OutProfile.cross_section_filling_ratio, diff --git a/pyroll/core/roll/roll.py b/pyroll/core/roll/roll.py index f94dea6..123fae2 100644 --- a/pyroll/core/roll/roll.py +++ b/pyroll/core/roll/roll.py @@ -4,6 +4,7 @@ from scipy.interpolate import interpn from shapely.geometry import LineString +from .. import FlatGroove from ..grooves import GrooveBase from ..hooks import HookHost, Hook @@ -131,17 +132,26 @@ class Roll(HookHost): thermal_stress_field = Hook[List[np.ndarray[float]]]() """Thermal stress field inside the roll body.""" - def __init__(self, groove: GrooveBase, **kwargs): + def __init__(self, groove: GrooveBase = None, barrel_width: float = None, **kwargs): """ :param groove: the groove object defining the shape of the roll's surface + :param barrel_width: the barrel width of the roll's surface :param kwargs: additional hook values as keyword arguments to set explicitly """ self.__dict__.update(kwargs) super().__init__() - self.groove = groove - """The groove object defining the shape of the roll's surface.""" + if groove is not None and barrel_width is not None: + raise ValueError("Only one of 'groove' or 'barrel_width' can be provided") + + if groove is not None and barrel_width is None: + self.groove = groove + """The groove object defining the shape of the roll's surface.""" + + if groove is None and barrel_width is not None: + self.groove = FlatGroove(usable_width=barrel_width) + """The groove object defining the shape of the roll's surface.""" self._contour_line = None @@ -159,7 +169,7 @@ def contour_line(self) -> LineString: return self._contour_line def surface_interpolation( - self, x: Union[float, np.ndarray], z: Union[float, np.ndarray] + self, x: Union[float, np.ndarray], z: Union[float, np.ndarray] ) -> Union[float, np.ndarray]: """ Calculate the linear interpolation of the roll surface at the given points. diff --git a/tests/cooling_pipe/test_cooling_pipe_values.py b/tests/cooling_pipe/test_cooling_pipe_values.py index 9f4243c..27ec394 100644 --- a/tests/cooling_pipe/test_cooling_pipe_values.py +++ b/tests/cooling_pipe/test_cooling_pipe_values.py @@ -20,7 +20,7 @@ def test_cooling_pipe_area(): def test_cooling_pipe_coolant_velocity(): - ip = Profile.round(radius=0.5) + ip = Profile.round(radius=0.5, position=0) seq = PassSequence([CoolingPipe(label="Cooling Pipe", inner_radius=1, coolant_volume_flux=1, velocity=1, length=1)]) @@ -30,7 +30,7 @@ def test_cooling_pipe_coolant_velocity(): def test_cooling_pipe_coolant_flow_cross_section(): - ip = Profile.round(radius=0.5) + ip = Profile.round(radius=0.5, position=0) seq = PassSequence([CoolingPipe(label="Cooling Pipe", inner_radius=1, coolant_volume_flux=1, velocity=1, length=1)]) seq.solve(ip) diff --git a/tests/pass_sequence/test_by_position.py b/tests/pass_sequence/test_by_position.py index 07fb7b3..df4b93e 100644 --- a/tests/pass_sequence/test_by_position.py +++ b/tests/pass_sequence/test_by_position.py @@ -3,7 +3,17 @@ from pathlib import Path -from pyroll.core import Profile, Roll, RollPass, Transport, RoundGroove, CircularOvalGroove, PassSequence +from pyroll.core import ( + Profile, + Roll, + RollPass, + Transport, + RoundGroove, + CircularOvalGroove, + PassSequence, + root_hooks, + Unit, +) def flow_stress(self: RollPass.Profile): @@ -14,6 +24,8 @@ def flow_stress(self: RollPass.Profile): def test_by_position(tmp_path: Path, caplog): caplog.set_level(logging.DEBUG, logger="pyroll") + root_hooks.append(Unit.OutProfile.position) + with RollPass.Profile.flow_stress(flow_stress): in_profile = Profile.round( diameter=30e-3, temperature=1200 + 273.15, material=["C45", "steel"], length=1, position=0 @@ -67,8 +79,8 @@ def test_by_position(tmp_path: Path, caplog): with pytest.raises(ValueError) as exc_info: sequence.find_value_by_position_or_time(position=1.15, hook_name="test") - assert str(exc_info.value) == ("No hook with name test found.") + assert str(exc_info.value) == "No hook with name test found." with pytest.raises(ValueError) as exc_info: sequence.find_value_by_position_or_time(position=10, hook_name="temperature") - assert str(exc_info.value) == ("Coordinate index 10 out of sequence range.") + assert str(exc_info.value) == "Coordinate index 10 out of sequence range." diff --git a/tests/roll_pass/test_roll_pass_default_flat.py b/tests/roll_pass/test_roll_pass_default_flat.py new file mode 100644 index 0000000..67b609a --- /dev/null +++ b/tests/roll_pass/test_roll_pass_default_flat.py @@ -0,0 +1,34 @@ +import logging +from pathlib import Path +from pyroll.core import Profile, Roll, RollPass, FlatGroove + +roll_barrel_width = 350e-3 + + +# noinspection DuplicatedCode +def test_cartesian_positions(tmp_path: Path, caplog): + caplog.set_level(logging.DEBUG, logger="pyroll") + + in_profile = Profile.box( + height=15e-3, width=150e-3, temperature=1200 + 273.15, material=["C45", "steel"], length=1, flow_stress=100e6 + ) + + rp = RollPass( + label="Test-Flat", + roll=Roll( + barrel_width=roll_barrel_width, + nominal_radius=160e-3, + rotational_frequency=1, + neutral_point=-20e-3, + ), + gap=2e-3, + ) + + try: + rp.solve(in_profile) + finally: + print("\nLog:") + print(caplog.text) + + assert isinstance(rp.roll.groove, FlatGroove) + assert rp.roll.groove.usable_width == roll_barrel_width diff --git a/tests/test_copy.py b/tests/test_copy.py index d01f748..b9f9bf8 100644 --- a/tests/test_copy.py +++ b/tests/test_copy.py @@ -71,6 +71,7 @@ def test_solve_copied(): material=["C45", "steel"], flow_stress=100e6, length=1, + position=0, ) local_sequence = PassSequence( diff --git a/tests/test_solve.py b/tests/test_solve.py index d318c6b..1f1c84c 100644 --- a/tests/test_solve.py +++ b/tests/test_solve.py @@ -16,10 +16,7 @@ def test_solve(tmp_path: Path, caplog): with RollPass.Profile.flow_stress(flow_stress): in_profile = Profile.round( - diameter=30e-3, - temperature=1200 + 273.15, - material=["C45", "steel"], - length=1, + diameter=30e-3, temperature=1200 + 273.15, material=["C45", "steel"], length=1, position=0 ) sequence = PassSequence( diff --git a/tests/test_solve3.py b/tests/test_solve3.py index 25b10a2..b2531f2 100644 --- a/tests/test_solve3.py +++ b/tests/test_solve3.py @@ -16,6 +16,7 @@ def test_solve3(tmp_path: Path, caplog): material=["C45", "steel"], flow_stress=100e6, length=1, + position=0, ) sequence = PassSequence( diff --git a/tests/test_solve_disks.py b/tests/test_solve_disks.py index 26fe2f4..704748e 100644 --- a/tests/test_solve_disks.py +++ b/tests/test_solve_disks.py @@ -18,6 +18,7 @@ def test_solve_disks(tmp_path: Path, caplog, monkeypatch): material=["C45", "steel"], flow_stress=100e6, length=1, + position=0, ) sequence = PassSequence( diff --git a/tests/test_solve_round_constricted_box_spreading.py b/tests/test_solve_round_constricted_box_spreading.py index 4e9090b..a841e7a 100644 --- a/tests/test_solve_round_constricted_box_spreading.py +++ b/tests/test_solve_round_constricted_box_spreading.py @@ -18,7 +18,7 @@ def width(self: RollPass.OutProfile, cycle): if cycle: return None - return self.roll_pass.in_profile.width * self.roll_pass.draught ** -0.5 + return self.roll_pass.in_profile.width * self.roll_pass.draught**-0.5 def test_solve_round_constricted_box(tmp_path: Path, caplog): @@ -36,6 +36,7 @@ def test_solve_round_constricted_box(tmp_path: Path, caplog): flow_stress=100e6, density=7.5e3, specific_heat_capcity=690, + position=0, ) sequence = PassSequence( @@ -54,12 +55,11 @@ def test_solve_round_constricted_box(tmp_path: Path, caplog): ), nominal_radius=160e-3, rotational_frequency=1, - neutral_point=-20e-3 + neutral_point=-20e-3, ), gap=4e-3, disk_element_count=15, ), - ] ) diff --git a/tests/test_solve_round_flat_spreading.py b/tests/test_solve_round_flat_spreading.py index a1f9bbd..b49b514 100644 --- a/tests/test_solve_round_flat_spreading.py +++ b/tests/test_solve_round_flat_spreading.py @@ -18,7 +18,7 @@ def width(self: RollPass.OutProfile, cycle): if cycle: return None - return self.roll_pass.in_profile.width * self.roll_pass.draught ** -0.5 + return self.roll_pass.in_profile.width * self.roll_pass.draught**-0.5 def test_solve_round_flat(tmp_path: Path, caplog): @@ -36,6 +36,7 @@ def test_solve_round_flat(tmp_path: Path, caplog): flow_stress=100e6, density=7.5e3, specific_heat_capcity=690, + position=0, ) sequence = PassSequence( @@ -48,12 +49,11 @@ def test_solve_round_flat(tmp_path: Path, caplog): ), nominal_radius=160e-3, rotational_frequency=1, - neutral_point=-20e-3 + neutral_point=-20e-3, ), gap=10e-3, disk_element_count=15, ), - ] ) diff --git a/tests/test_solve_round_oval_round_spreading.py b/tests/test_solve_round_oval_round_spreading.py index d052fe2..204b3c6 100644 --- a/tests/test_solve_round_oval_round_spreading.py +++ b/tests/test_solve_round_oval_round_spreading.py @@ -21,7 +21,7 @@ def width(self: RollPass.OutProfile, cycle): if cycle: return None - return self.roll_pass.in_profile.width * self.roll_pass.draught ** -0.5 + return self.roll_pass.in_profile.width * self.roll_pass.draught**-0.5 def test_solve(tmp_path: Path, caplog): @@ -38,6 +38,7 @@ def test_solve(tmp_path: Path, caplog): material=["C45", "steel"], length=1, flow_stress=100e6, + position=0, ) sequence = PassSequence( diff --git a/tests/test_solve_square_oval_spreading.py b/tests/test_solve_square_oval_spreading.py index 8c9c1f8..a1fa8e1 100644 --- a/tests/test_solve_square_oval_spreading.py +++ b/tests/test_solve_square_oval_spreading.py @@ -19,7 +19,7 @@ def width(self: RollPass.OutProfile, cycle): if cycle: return None - return self.roll_pass.in_profile.width * self.roll_pass.draught ** -0.5 + return self.roll_pass.in_profile.width * self.roll_pass.draught**-0.5 def test_solve(tmp_path: Path, caplog): @@ -37,6 +37,7 @@ def test_solve(tmp_path: Path, caplog): flow_stress=100e6, density=7.5e3, specific_heat_capcity=690, + position=0, ) sequence = PassSequence( @@ -44,19 +45,14 @@ def test_solve(tmp_path: Path, caplog): RollPass( label="Oval", roll=Roll( - groove=CircularOvalGroove( - depth=8e-3, - r1=6e-3, - r2=40e-3 - ), + groove=CircularOvalGroove(depth=8e-3, r1=6e-3, r2=40e-3), nominal_radius=160e-3, rotational_frequency=1, - neutral_point=-20e-3 + neutral_point=-20e-3, ), gap=2e-3, disk_element_count=15, ), - ] ) @@ -82,4 +78,4 @@ def test_solve(tmp_path: Path, caplog): except ImportError: pass - assert not np.isclose(sequence[0].out_profile.filling_ratio, 1) \ No newline at end of file + assert not np.isclose(sequence[0].out_profile.filling_ratio, 1) diff --git a/tests/test_square_bulging.py b/tests/test_square_bulging.py index 2989970..a445530 100644 --- a/tests/test_square_bulging.py +++ b/tests/test_square_bulging.py @@ -3,22 +3,10 @@ from shapely import LineString import numpy as np -from pyroll.core import ( - Profile, - Roll, - RollPass, - SquareGroove, - CircularOvalGroove, - PassSequence, Rotator -) +from pyroll.core import Profile, Roll, RollPass, SquareGroove, CircularOvalGroove, PassSequence in_profile = Profile.from_groove( - groove=SquareGroove( - usable_width=21.54e-3, - tip_depth=10.6e-3, - r1=5e-3, - r2=3e-3 - ), + groove=SquareGroove(usable_width=21.54e-3, tip_depth=10.6e-3, r1=5e-3, r2=3e-3), filling=0.98, gap=3e-3, temperature=1200 + 273.15, @@ -27,6 +15,7 @@ flow_stress=100e6, density=7.5e3, specific_heat_capcity=690, + position=0, ) @@ -38,25 +27,21 @@ def test_solve(tmp_path: Path, caplog): RollPass( label="Oval", roll=Roll( - groove=CircularOvalGroove( - depth=4.43e-3, - r1=6e-3, - r2=25.5e-3 - ), + groove=CircularOvalGroove(depth=4.43e-3, r1=6e-3, r2=25.5e-3), nominal_radius=320, ), velocity=1, gap=2e-3, ) - ] ) - sequence.solve(in_profile) - horizontal_line_at_zero = LineString([(-sequence[0].in_profile.width / 2, 0), (sequence[0].in_profile.width / 2, 0)]) + horizontal_line_at_zero = LineString( + [(-sequence[0].in_profile.width / 2, 0), (sequence[0].in_profile.width / 2, 0)] + ) intersection_at_y0 = sequence[0].in_profile.cross_section.intersection(horizontal_line_at_zero) assert np.isclose(sequence.out_profile.width, sequence.out_profile.cross_section.width) - assert np.isclose(intersection_at_y0.length, 17.247e-3, atol=1e-3) \ No newline at end of file + assert np.isclose(intersection_at_y0.length, 17.247e-3, atol=1e-3)