pyroll-core 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyroll/core/__init__.py +38 -0
- pyroll/core/config.py +155 -0
- pyroll/core/disk_elements/__init__.py +2 -0
- pyroll/core/disk_elements/disk_element_unit.py +73 -0
- pyroll/core/disk_elements/hookimpls.py +26 -0
- pyroll/core/grooves/__init__.py +10 -0
- pyroll/core/grooves/base.py +59 -0
- pyroll/core/grooves/boxes/__init__.py +3 -0
- pyroll/core/grooves/boxes/box.py +57 -0
- pyroll/core/grooves/boxes/constricted_box.py +63 -0
- pyroll/core/grooves/boxes/upset_box.py +18 -0
- pyroll/core/grooves/diamonds/__init__.py +3 -0
- pyroll/core/grooves/diamonds/diamond.py +60 -0
- pyroll/core/grooves/diamonds/gothic.py +41 -0
- pyroll/core/grooves/diamonds/square.py +48 -0
- pyroll/core/grooves/flat.py +31 -0
- pyroll/core/grooves/generic_elongation.py +258 -0
- pyroll/core/grooves/generic_elongation_solvers.py +422 -0
- pyroll/core/grooves/hexagonal.py +57 -0
- pyroll/core/grooves/ovals/__init__.py +8 -0
- pyroll/core/grooves/ovals/circular_oval.py +43 -0
- pyroll/core/grooves/ovals/constricted_circular_oval.py +53 -0
- pyroll/core/grooves/ovals/constricted_swedish_oval.py +61 -0
- pyroll/core/grooves/ovals/flat_oval.py +56 -0
- pyroll/core/grooves/ovals/oval_3radii.py +47 -0
- pyroll/core/grooves/ovals/oval_3radii_flanked.py +65 -0
- pyroll/core/grooves/ovals/swedish_oval.py +57 -0
- pyroll/core/grooves/ovals/upset_oval.py +47 -0
- pyroll/core/grooves/rounds/__init__.py +2 -0
- pyroll/core/grooves/rounds/false_round.py +65 -0
- pyroll/core/grooves/rounds/round.py +44 -0
- pyroll/core/grooves/spline.py +92 -0
- pyroll/core/hooks.py +420 -0
- pyroll/core/log.py +7 -0
- pyroll/core/profile/__init__.py +3 -0
- pyroll/core/profile/hookimpls.py +58 -0
- pyroll/core/profile/profile.py +380 -0
- pyroll/core/repr.py +49 -0
- pyroll/core/roll/__init__.py +3 -0
- pyroll/core/roll/hookimpls.py +65 -0
- pyroll/core/roll/roll.py +145 -0
- pyroll/core/roll_pass/__init__.py +8 -0
- pyroll/core/roll_pass/deformation_unit.py +61 -0
- pyroll/core/roll_pass/hookimpls/__init__.py +5 -0
- pyroll/core/roll_pass/hookimpls/deformation_unit.py +78 -0
- pyroll/core/roll_pass/hookimpls/disk_element.py +16 -0
- pyroll/core/roll_pass/hookimpls/profile.py +94 -0
- pyroll/core/roll_pass/hookimpls/roll.py +43 -0
- pyroll/core/roll_pass/hookimpls/roll_pass.py +107 -0
- pyroll/core/roll_pass/roll_pass.py +168 -0
- pyroll/core/roll_pass/three_roll_pass.py +84 -0
- pyroll/core/rotator/__init__.py +3 -0
- pyroll/core/rotator/hookimpls.py +71 -0
- pyroll/core/rotator/rotator.py +65 -0
- pyroll/core/sequence/__init__.py +3 -0
- pyroll/core/sequence/hookimpls.py +18 -0
- pyroll/core/sequence/sequence.py +68 -0
- pyroll/core/shapes.py +104 -0
- pyroll/core/transport/__init__.py +3 -0
- pyroll/core/transport/hookimpls.py +17 -0
- pyroll/core/transport/transport.py +57 -0
- pyroll/core/unit/__init__.py +3 -0
- pyroll/core/unit/hookimpls.py +67 -0
- pyroll/core/unit/unit.py +271 -0
- pyroll_core-2.0.0.dist-info/METADATA +109 -0
- pyroll_core-2.0.0.dist-info/RECORD +68 -0
- pyroll_core-2.0.0.dist-info/WHEEL +4 -0
- pyroll_core-2.0.0.dist-info/licenses/LICENSE +11 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from .generic_elongation import GenericElongationGroove
|
|
6
|
+
from .generic_elongation_solvers import solve_box_like
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HexagonalGroove(GenericElongationGroove):
|
|
10
|
+
"""Represents a hexagonal-shaped groove."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
r2: float,
|
|
16
|
+
depth: float,
|
|
17
|
+
ground_width: Optional[float] = None,
|
|
18
|
+
even_ground_width: Optional[float] = None,
|
|
19
|
+
usable_width: Optional[float] = None,
|
|
20
|
+
flank_angle: Optional[float] = None,
|
|
21
|
+
pad_angle: float = 0,
|
|
22
|
+
**kwargs
|
|
23
|
+
):
|
|
24
|
+
"""
|
|
25
|
+
Exactly two of ``ground_width``, ``even_ground_width``, ``usable_width`` and ``flank_angle`` must be given,
|
|
26
|
+
but not ``ground_width`` and ``even_ground_width`` at the same time.
|
|
27
|
+
Widths are always measured at the intersection of the extrapolated ground, face and flanks.
|
|
28
|
+
All angles are measured in ° (degree).
|
|
29
|
+
|
|
30
|
+
:param r1: radius 1 (face/flank)
|
|
31
|
+
:param r2: radius 2 (flank/ground)
|
|
32
|
+
:param depth: maximum depth
|
|
33
|
+
:param ground_width: width of the groove ground
|
|
34
|
+
:param even_ground_width: width of the even ground line
|
|
35
|
+
:param usable_width: usable width of the groove
|
|
36
|
+
:param flank_angle: inclination angle of the flanks
|
|
37
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
38
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
39
|
+
:raises ValueError: if not exactly two of ground_width, usable_width and flank_angle are given
|
|
40
|
+
"""
|
|
41
|
+
if flank_angle is not None:
|
|
42
|
+
flank_angle = np.deg2rad(flank_angle)
|
|
43
|
+
|
|
44
|
+
sol = solve_box_like(
|
|
45
|
+
r2=r2, r4=0, depth=depth, ground_width=ground_width, usable_width=usable_width, flank_angle=flank_angle,
|
|
46
|
+
indent=0, even_ground_width=even_ground_width
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
super().__init__(
|
|
50
|
+
r1=r1, r2=r2, pad_angle=np.deg2rad(pad_angle),
|
|
51
|
+
**sol,
|
|
52
|
+
**kwargs
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def classifiers(self):
|
|
57
|
+
return {"hexagonal"} | super().classifiers
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from .circular_oval import CircularOvalGroove
|
|
2
|
+
from .flat_oval import FlatOvalGroove
|
|
3
|
+
from .swedish_oval import SwedishOvalGroove
|
|
4
|
+
from .constricted_swedish_oval import ConstrictedSwedishOvalGroove
|
|
5
|
+
from .oval_3radii import Oval3RadiiGroove
|
|
6
|
+
from .oval_3radii_flanked import Oval3RadiiFlankedGroove
|
|
7
|
+
from .upset_oval import UpsetOvalGroove
|
|
8
|
+
from .constricted_circular_oval import ConstrictedCircularOvalGroove
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ..generic_elongation import GenericElongationGroove
|
|
6
|
+
from ..generic_elongation_solvers import solve_r124
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CircularOvalGroove(GenericElongationGroove):
|
|
10
|
+
"""Represents an oval-shaped groove with one main radius."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
r2: Optional[float] = None,
|
|
16
|
+
depth: Optional[float] = None,
|
|
17
|
+
usable_width: Optional[float] = None,
|
|
18
|
+
pad_angle: float = 0,
|
|
19
|
+
**kwargs
|
|
20
|
+
):
|
|
21
|
+
"""
|
|
22
|
+
Give exactly two of ``r2``, ``depth`` or ``usable_width``.
|
|
23
|
+
|
|
24
|
+
:param r1: radius 1 (face/flank)
|
|
25
|
+
:param r2: radius 2 (flank/ground)
|
|
26
|
+
:param depth: maximum depth
|
|
27
|
+
:param usable_width: usable width
|
|
28
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
29
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
30
|
+
"""
|
|
31
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
32
|
+
|
|
33
|
+
sol = solve_r124(r1=r1, r2=r2, depth=depth, width=usable_width, pad_angle=pad_angle)
|
|
34
|
+
|
|
35
|
+
super().__init__(
|
|
36
|
+
r2=sol["r2"], depth=sol["depth"], usable_width=sol["width"], flank_angle=sol["alpha"],
|
|
37
|
+
r1=r1, pad_angle=pad_angle,
|
|
38
|
+
**kwargs
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def classifiers(self):
|
|
43
|
+
return {"oval", "circular_oval"} | super().classifiers
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ..generic_elongation import GenericElongationGroove
|
|
6
|
+
from ..generic_elongation_solvers import solve_r1234
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ConstrictedCircularOvalGroove(GenericElongationGroove):
|
|
10
|
+
"""Represents an oval-shaped groove with one main radius."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
r2: float,
|
|
16
|
+
r3: float,
|
|
17
|
+
r4: float,
|
|
18
|
+
depth: float,
|
|
19
|
+
usable_width: float,
|
|
20
|
+
indent: float,
|
|
21
|
+
even_ground_width: float = 0,
|
|
22
|
+
pad_angle: float = 0,
|
|
23
|
+
**kwargs
|
|
24
|
+
):
|
|
25
|
+
"""
|
|
26
|
+
Widths are always measured at the intersection of the extrapolated ground, face and flanks.
|
|
27
|
+
|
|
28
|
+
:param r1: radius 1 (face/flank)
|
|
29
|
+
:param r2: radius 2 (flank/ground)
|
|
30
|
+
:param r3: radius 3 (ground)
|
|
31
|
+
:param r4: radius 4 (indent)
|
|
32
|
+
:param depth: maximum depth
|
|
33
|
+
:param usable_width: usable width of the groove
|
|
34
|
+
:param even_ground_width: width of the even ground line
|
|
35
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
36
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
40
|
+
|
|
41
|
+
sol = solve_r1234(r1, r2, r3, r4, depth, usable_width - even_ground_width, indent, pad_angle)
|
|
42
|
+
|
|
43
|
+
super().__init__(
|
|
44
|
+
usable_width=usable_width, depth=depth, indent=indent,
|
|
45
|
+
even_ground_width=even_ground_width,
|
|
46
|
+
r1=r1, r2=r2, r3=r3, r4=r4,
|
|
47
|
+
flank_angle=sol["flank_angle"], alpha3=sol["alpha3"], alpha4=sol["alpha4"], pad_angle=pad_angle,
|
|
48
|
+
**kwargs
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def classifiers(self):
|
|
53
|
+
return {"oval", "circular_oval", "constricted"} | super().classifiers
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ..generic_elongation import GenericElongationGroove
|
|
6
|
+
from ..generic_elongation_solvers import solve_box_like
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ConstrictedSwedishOvalGroove(GenericElongationGroove):
|
|
10
|
+
"""Represents a hexagonal-shaped groove with an indented ground that is used like an oval groove (swedish oval)."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
r2: float,
|
|
16
|
+
r4: float,
|
|
17
|
+
depth: float,
|
|
18
|
+
indent: float,
|
|
19
|
+
ground_width: Optional[float] = None,
|
|
20
|
+
even_ground_width: Optional[float] = None,
|
|
21
|
+
usable_width: Optional[float] = None,
|
|
22
|
+
flank_angle: Optional[float] = None,
|
|
23
|
+
pad_angle: float = 0,
|
|
24
|
+
**kwargs
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Exactly two of ``ground_width``, ``even_ground_width``, ``usable_width`` and ``flank_angle`` must be given,
|
|
28
|
+
but not ``ground_width`` and ``even_ground_width`` at the same time.
|
|
29
|
+
Widths are always measured at the intersection of the extrapolated ground, face and flanks.
|
|
30
|
+
All angles are measured in ° (degree).
|
|
31
|
+
|
|
32
|
+
:param r1: radius 1 (face/flank)
|
|
33
|
+
:param r2: radius 2 (flank)
|
|
34
|
+
:param r4: radius 4 (indent)
|
|
35
|
+
:param depth: maximum depth
|
|
36
|
+
:param indent: depth of the indent
|
|
37
|
+
:param ground_width: width of the groove ground
|
|
38
|
+
:param even_ground_width: width of the even ground line
|
|
39
|
+
:param usable_width: usable width of the groove
|
|
40
|
+
:param flank_angle: inclination angle of the flanks
|
|
41
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
42
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
43
|
+
:raises ValueError: if not exactly two of ground_width, usable_width and flank_angle are given
|
|
44
|
+
"""
|
|
45
|
+
if flank_angle is not None:
|
|
46
|
+
flank_angle = np.deg2rad(flank_angle)
|
|
47
|
+
|
|
48
|
+
sol = solve_box_like(
|
|
49
|
+
r2=r2, r4=r4, depth=depth, ground_width=ground_width, usable_width=usable_width, flank_angle=flank_angle,
|
|
50
|
+
indent=indent, even_ground_width=even_ground_width
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
super().__init__(
|
|
54
|
+
r1=r1, r2=r2, r4=r4, pad_angle=np.deg2rad(pad_angle), indent=indent,
|
|
55
|
+
**sol,
|
|
56
|
+
**kwargs
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def classifiers(self):
|
|
61
|
+
return {"oval", "swedish_oval", "constricted_swedish_oval"} | super().classifiers
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ..generic_elongation import GenericElongationGroove
|
|
6
|
+
from ..generic_elongation_solvers import solve_r124
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FlatOvalGroove(GenericElongationGroove):
|
|
10
|
+
"""Represent an oval-shaped groove with a flat ground."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
r2: float,
|
|
16
|
+
depth: float,
|
|
17
|
+
usable_width: Optional[float] = None,
|
|
18
|
+
even_ground_width: Optional[float] = None,
|
|
19
|
+
pad_angle: float = 0,
|
|
20
|
+
**kwargs
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
Give exactly one of ``usable_width`` and ``even_ground_width``.
|
|
24
|
+
|
|
25
|
+
:param r1: radius 1 (face/flank)
|
|
26
|
+
:param r2: radius 2 (flank/ground)
|
|
27
|
+
:param depth: maximum depth
|
|
28
|
+
:param usable_width: usable width
|
|
29
|
+
:param even_ground_width: width of the straight ground line
|
|
30
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
31
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
32
|
+
"""
|
|
33
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
34
|
+
|
|
35
|
+
sol = solve_r124(r1=r1, r2=r2, depth=depth, width=None, pad_angle=pad_angle)
|
|
36
|
+
|
|
37
|
+
if usable_width is None and even_ground_width is not None:
|
|
38
|
+
super().__init__(
|
|
39
|
+
r2=sol["r2"], depth=sol["depth"], usable_width=even_ground_width + sol["width"],
|
|
40
|
+
flank_angle=sol["alpha"], even_ground_width=even_ground_width,
|
|
41
|
+
r1=r1, pad_angle=pad_angle,
|
|
42
|
+
**kwargs
|
|
43
|
+
)
|
|
44
|
+
elif even_ground_width is None and usable_width is not None:
|
|
45
|
+
super().__init__(
|
|
46
|
+
r2=sol["r2"], depth=sol["depth"], usable_width=usable_width, flank_angle=sol["alpha"],
|
|
47
|
+
even_ground_width=usable_width - sol["width"],
|
|
48
|
+
r1=r1, pad_angle=pad_angle,
|
|
49
|
+
**kwargs
|
|
50
|
+
)
|
|
51
|
+
else:
|
|
52
|
+
raise TypeError("Give exactly one of usable_width and even_ground_width.")
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def classifiers(self):
|
|
56
|
+
return {"oval", "flat_oval"} | super().classifiers
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
import numpy as np
|
|
3
|
+
from scipy.optimize import minimize, Bounds
|
|
4
|
+
from numpy import sin, cos, tan, pi, array
|
|
5
|
+
from ..generic_elongation import GenericElongationGroove
|
|
6
|
+
from ..generic_elongation_solvers import solve_r123
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Oval3RadiiGroove(GenericElongationGroove):
|
|
10
|
+
"""Represents an oval-shaped groove with 3 main radii."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
r2: float,
|
|
16
|
+
r3: float,
|
|
17
|
+
depth: float,
|
|
18
|
+
usable_width: float,
|
|
19
|
+
pad_angle: float = 0,
|
|
20
|
+
**kwargs
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
Widths are always measured at the intersection of the extrapolated ground, face and flanks.
|
|
24
|
+
|
|
25
|
+
:param r1: radius 1 (face/flank)
|
|
26
|
+
:param r2: radius 2 (flank/ground)
|
|
27
|
+
:param r3: radius 3 (ground)
|
|
28
|
+
:param depth: maximum depth
|
|
29
|
+
:param usable_width: usable width of the groove
|
|
30
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
31
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
35
|
+
|
|
36
|
+
sol = solve_r123(r1, r2, r3, depth, usable_width, pad_angle)
|
|
37
|
+
|
|
38
|
+
super().__init__(
|
|
39
|
+
usable_width=usable_width, depth=depth,
|
|
40
|
+
r1=r1, r2=r2, r3=r3,
|
|
41
|
+
flank_angle=sol["flank_angle"], alpha3=sol["alpha3"], pad_angle=pad_angle,
|
|
42
|
+
**kwargs
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def classifiers(self):
|
|
47
|
+
return {"oval", "oval_3_radii"} | super().classifiers
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy.optimize import brentq
|
|
5
|
+
from numpy import sin, cos, tan, pi
|
|
6
|
+
|
|
7
|
+
from ..generic_elongation import GenericElongationGroove
|
|
8
|
+
from ..generic_elongation_solvers import solve_r123
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Oval3RadiiFlankedGroove(GenericElongationGroove):
|
|
12
|
+
"""Represents an oval-shaped groove with 3 main radii and a dedicated flank."""
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
r1: float,
|
|
17
|
+
r2: float,
|
|
18
|
+
r3: float,
|
|
19
|
+
depth: float,
|
|
20
|
+
usable_width: float,
|
|
21
|
+
flank_angle: Optional[float] = None,
|
|
22
|
+
flank_width: Optional[float] = None,
|
|
23
|
+
flank_height: Optional[float] = None,
|
|
24
|
+
flank_length: Optional[float] = None,
|
|
25
|
+
pad_angle: float = 0,
|
|
26
|
+
**kwargs
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
Widths are always measured at the intersection of the extrapolated ground, face and flanks.
|
|
30
|
+
All angles are measured in ° (degree).
|
|
31
|
+
|
|
32
|
+
:param r1: radius 1 (face/flank)
|
|
33
|
+
:param r2: radius 2 (flank/ground)
|
|
34
|
+
:param r3: radius 3 (ground)
|
|
35
|
+
:param depth: maximum depth
|
|
36
|
+
:param usable_width: usable width of the groove
|
|
37
|
+
|
|
38
|
+
:param flank_angle: inclination angle of the flanks
|
|
39
|
+
:param flank_width: horizontal extent of the flanks
|
|
40
|
+
:param flank_height: vertical extent of the flanks
|
|
41
|
+
:param flank_length: length of the flanks
|
|
42
|
+
|
|
43
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
44
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
if flank_angle is not None:
|
|
48
|
+
flank_angle = np.deg2rad(flank_angle)
|
|
49
|
+
|
|
50
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
51
|
+
|
|
52
|
+
sol = solve_r123(
|
|
53
|
+
r1, r2, r3, depth, usable_width, pad_angle, flank_angle, flank_width, flank_height, flank_length
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
super().__init__(
|
|
57
|
+
usable_width=usable_width, depth=depth,
|
|
58
|
+
r1=r1, r2=r2, r3=r3,
|
|
59
|
+
flank_angle=sol["flank_angle"], alpha3=sol["alpha3"], pad_angle=pad_angle,
|
|
60
|
+
**kwargs
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def classifiers(self):
|
|
65
|
+
return {"oval", "oval_3_radii", "oval_3_radii_flanked"} | super().classifiers
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ..generic_elongation import GenericElongationGroove
|
|
6
|
+
from ..generic_elongation_solvers import solve_box_like
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SwedishOvalGroove(GenericElongationGroove):
|
|
10
|
+
"""Represents a hexagonal-shaped groove that is used like an oval groove (swedish oval)."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
r2: float,
|
|
16
|
+
depth: float,
|
|
17
|
+
ground_width: Optional[float] = None,
|
|
18
|
+
even_ground_width: Optional[float] = None,
|
|
19
|
+
usable_width: Optional[float] = None,
|
|
20
|
+
flank_angle: Optional[float] = None,
|
|
21
|
+
pad_angle: float = 0,
|
|
22
|
+
**kwargs
|
|
23
|
+
):
|
|
24
|
+
"""
|
|
25
|
+
Exactly two of ``ground_width``, ``even_ground_width``, ``usable_width`` and ``flank_angle`` must be given,
|
|
26
|
+
but not ``ground_width`` and ``even_ground_width`` at the same time.
|
|
27
|
+
Widths are always measured at the intersection of the extrapolated ground, face and flanks.
|
|
28
|
+
All angles are measured in ° (degree).
|
|
29
|
+
|
|
30
|
+
:param r1: radius 1 (face/flank)
|
|
31
|
+
:param r2: radius 2 (flank/ground)
|
|
32
|
+
:param depth: maximum depth
|
|
33
|
+
:param ground_width: width of the groove ground
|
|
34
|
+
:param even_ground_width: width of the even ground line
|
|
35
|
+
:param usable_width: usable width of the groove
|
|
36
|
+
:param flank_angle: inclination angle of the flanks
|
|
37
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
38
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
39
|
+
:raises ValueError: if not exactly two of ground_width, usable_width and flank_angle are given
|
|
40
|
+
"""
|
|
41
|
+
if flank_angle is not None:
|
|
42
|
+
flank_angle = np.deg2rad(flank_angle)
|
|
43
|
+
|
|
44
|
+
sol = solve_box_like(
|
|
45
|
+
r2=r2, r4=0, depth=depth, ground_width=ground_width, usable_width=usable_width, flank_angle=flank_angle,
|
|
46
|
+
indent=0, even_ground_width=even_ground_width
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
super().__init__(
|
|
50
|
+
r1=r1, r2=r2, pad_angle=np.deg2rad(pad_angle),
|
|
51
|
+
**sol,
|
|
52
|
+
**kwargs
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def classifiers(self):
|
|
57
|
+
return {"oval", "swedish_oval"} | super().classifiers
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from ..generic_elongation import GenericElongationGroove
|
|
3
|
+
from ..generic_elongation_solvers import solve_r123
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class UpsetOvalGroove(GenericElongationGroove):
|
|
7
|
+
"""Represents an upright oval-shaped groove."""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
r1: float,
|
|
12
|
+
r2: float,
|
|
13
|
+
r3: float,
|
|
14
|
+
depth: float,
|
|
15
|
+
usable_width: float,
|
|
16
|
+
pad_angle: float = 0,
|
|
17
|
+
**kwargs
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
Widths are always measured at the intersection of the extrapolated ground, face and flanks.
|
|
21
|
+
|
|
22
|
+
:param r1: radius 1 (face/flank)
|
|
23
|
+
:param r2: radius 2 (flank/ground)
|
|
24
|
+
:param r3: radius 3 (ground)
|
|
25
|
+
:param depth: maximum depth
|
|
26
|
+
:param usable_width: usable width of the groove
|
|
27
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
28
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
32
|
+
|
|
33
|
+
sol = solve_r123(r1, r2, r3, depth, usable_width, pad_angle)
|
|
34
|
+
|
|
35
|
+
if sol["flank_angle"] > np.pi / 2:
|
|
36
|
+
raise ValueError("under the given conditions the flank angle is > 90°")
|
|
37
|
+
|
|
38
|
+
super().__init__(
|
|
39
|
+
usable_width=usable_width, depth=depth,
|
|
40
|
+
r1=r1, r2=r2, r3=r3,
|
|
41
|
+
flank_angle=sol["flank_angle"], alpha3=sol["alpha3"], pad_angle=pad_angle,
|
|
42
|
+
**kwargs
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def classifiers(self):
|
|
47
|
+
return {"oval", "upset"} | super().classifiers
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ..generic_elongation import GenericElongationGroove
|
|
6
|
+
from ..generic_elongation_solvers import solve_r124
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FalseRoundGroove(GenericElongationGroove):
|
|
10
|
+
"""Represents a round-shaped groove with a dedicated flank (false round)."""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
r1: float,
|
|
15
|
+
|
|
16
|
+
r2: Optional[float] = None,
|
|
17
|
+
depth: Optional[float] = None,
|
|
18
|
+
usable_width: Optional[float] = None,
|
|
19
|
+
|
|
20
|
+
flank_angle: Optional[float] = None,
|
|
21
|
+
flank_width: Optional[float] = None,
|
|
22
|
+
flank_height: Optional[float] = None,
|
|
23
|
+
flank_length: Optional[float] = None,
|
|
24
|
+
|
|
25
|
+
pad_angle: float = 0,
|
|
26
|
+
**kwargs
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
All angles are measured in ° (degree).
|
|
30
|
+
Give exactly two of ``r2``, ``depth`` or ``usable_width``.
|
|
31
|
+
Give exactly one of ``flank_angle``, ``flank_width``, ``flank_height`` or ``flank_length``.
|
|
32
|
+
|
|
33
|
+
:param r1: radius 1 (face/flank)
|
|
34
|
+
:param r2: radius 2 (flank/ground)
|
|
35
|
+
:param depth: maximum depth
|
|
36
|
+
:param usable_width: usable width
|
|
37
|
+
|
|
38
|
+
:param flank_angle: inclination angle of the flanks
|
|
39
|
+
:param flank_width: horizontal extent of the flanks
|
|
40
|
+
:param flank_height: vertical extent of the flanks
|
|
41
|
+
:param flank_length: length of the flanks
|
|
42
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
43
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
44
|
+
"""
|
|
45
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
46
|
+
|
|
47
|
+
if flank_angle is not None:
|
|
48
|
+
flank_angle = np.deg2rad(flank_angle)
|
|
49
|
+
|
|
50
|
+
sol = solve_r124(
|
|
51
|
+
r1=r1,
|
|
52
|
+
r2=r2, depth=depth, width=usable_width,
|
|
53
|
+
pad_angle=pad_angle,
|
|
54
|
+
flank_angle=flank_angle, flank_width=flank_width, flank_height=flank_height, flank_length=flank_length
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
super().__init__(
|
|
58
|
+
r2=sol["r2"], depth=sol["depth"], usable_width=sol["width"], flank_angle=sol["alpha"],
|
|
59
|
+
r1=r1, pad_angle=pad_angle,
|
|
60
|
+
**kwargs
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def classifiers(self):
|
|
65
|
+
return {"round", "false_round"} | super().classifiers
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy.optimize import root_scalar, minimize_scalar
|
|
5
|
+
|
|
6
|
+
from ..generic_elongation import GenericElongationGroove
|
|
7
|
+
from ..generic_elongation_solvers import solve_r124
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RoundGroove(GenericElongationGroove):
|
|
11
|
+
"""Represents a round-shaped groove."""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
r1: float,
|
|
16
|
+
r2: Optional[float] = None,
|
|
17
|
+
depth: Optional[float] = None,
|
|
18
|
+
usable_width: Optional[float] = None,
|
|
19
|
+
pad_angle: float = 0,
|
|
20
|
+
**kwargs
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
Give exactly two of ``r2``, ``depth`` or ``usable_width``.
|
|
24
|
+
|
|
25
|
+
:param r1: radius 1 (face/flank)
|
|
26
|
+
:param r2: radius 2 (flank/ground)
|
|
27
|
+
:param depth: maximum depth
|
|
28
|
+
:param usable_width: usable width
|
|
29
|
+
:param pad_angle: angle between z-axis and the roll face padding
|
|
30
|
+
:param kwargs: more keyword arguments passed to the GenericElongationGroove constructor
|
|
31
|
+
"""
|
|
32
|
+
pad_angle = np.deg2rad(pad_angle)
|
|
33
|
+
|
|
34
|
+
sol = solve_r124(r1=r1, r2=r2, depth=depth, width=usable_width, pad_angle=pad_angle)
|
|
35
|
+
|
|
36
|
+
super().__init__(
|
|
37
|
+
r2=sol["r2"], depth=sol["depth"], usable_width=sol["width"], flank_angle=sol["alpha"],
|
|
38
|
+
r1=r1, pad_angle=pad_angle,
|
|
39
|
+
**kwargs
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def classifiers(self):
|
|
44
|
+
return {"round",} | super().classifiers
|