pyroll-core 3.0.2.post2__tar.gz → 3.0.3__tar.gz

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.
Files changed (80) hide show
  1. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/PKG-INFO +1 -1
  2. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/__init__.py +3 -1
  3. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/profile/profile.py +24 -24
  4. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/sequence/sequence.py +80 -27
  5. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/.gitignore +0 -0
  6. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/LICENSE +0 -0
  7. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/README.md +0 -0
  8. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/hatch.toml +0 -0
  9. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyproject.toml +0 -0
  10. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/config.py +0 -0
  11. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/disk_elements/__init__.py +0 -0
  12. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/disk_elements/disk_element_unit.py +0 -0
  13. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/disk_elements/hookimpls.py +0 -0
  14. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/__init__.py +0 -0
  15. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/base.py +0 -0
  16. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/boxes/__init__.py +0 -0
  17. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/boxes/box.py +0 -0
  18. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/boxes/constricted_box.py +0 -0
  19. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/boxes/upset_box.py +0 -0
  20. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/diamonds/__init__.py +0 -0
  21. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/diamonds/diamond.py +0 -0
  22. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/diamonds/gothic.py +0 -0
  23. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/diamonds/square.py +0 -0
  24. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/equivalent_ripped_groove.py +0 -0
  25. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/flat.py +0 -0
  26. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/generic_elongation.py +0 -0
  27. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/generic_elongation_solvers.py +0 -0
  28. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/hexagonal.py +0 -0
  29. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/__init__.py +0 -0
  30. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/circular_oval.py +0 -0
  31. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/constricted_circular_oval.py +0 -0
  32. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/constricted_swedish_oval.py +0 -0
  33. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/flat_oval.py +0 -0
  34. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/oval_3radii.py +0 -0
  35. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/oval_3radii_flanked.py +0 -0
  36. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/swedish_oval.py +0 -0
  37. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/ovals/upset_oval.py +0 -0
  38. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/rounds/__init__.py +0 -0
  39. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/rounds/false_round.py +0 -0
  40. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/rounds/round.py +0 -0
  41. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/grooves/spline.py +0 -0
  42. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/hooks.py +0 -0
  43. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/log.py +0 -0
  44. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/profile/__init__.py +0 -0
  45. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/profile/hookimpls.py +0 -0
  46. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/repr.py +0 -0
  47. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll/__init__.py +0 -0
  48. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll/hookimpls.py +0 -0
  49. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll/roll.py +0 -0
  50. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/__init__.py +0 -0
  51. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/base.py +0 -0
  52. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/deformation_unit.py +0 -0
  53. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/__init__.py +0 -0
  54. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/base_roll_pass.py +0 -0
  55. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/deformation_unit.py +0 -0
  56. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/disk_element.py +0 -0
  57. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/helpers.py +0 -0
  58. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/profile.py +0 -0
  59. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/roll.py +0 -0
  60. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/symmetric_roll_pass.py +0 -0
  61. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/three_roll_pass.py +0 -0
  62. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/hookimpls/two_roll_pass.py +0 -0
  63. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/symmetric_roll_pass.py +0 -0
  64. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/three_roll_pass.py +0 -0
  65. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/roll_pass/two_roll_pass.py +0 -0
  66. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/rotator/__init__.py +0 -0
  67. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/rotator/hookimpls.py +0 -0
  68. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/rotator/rotator.py +0 -0
  69. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/sequence/__init__.py +0 -0
  70. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/sequence/hookimpls.py +0 -0
  71. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/shapes.py +0 -0
  72. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/transport/__init__.py +0 -0
  73. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/transport/cooling_pipe.py +0 -0
  74. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/transport/hookimpls/__init__.py +0 -0
  75. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/transport/hookimpls/cooling_pipe.py +0 -0
  76. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/transport/hookimpls/transport.py +0 -0
  77. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/transport/transport.py +0 -0
  78. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/unit/__init__.py +0 -0
  79. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/unit/hookimpls.py +0 -0
  80. {pyroll_core-3.0.2.post2 → pyroll_core-3.0.3}/pyroll/core/unit/unit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyroll-core
3
- Version: 3.0.2.post2
3
+ Version: 3.0.3
4
4
  Summary: PyRoll rolling simulation framework - core library.
5
5
  Project-URL: Homepage, https://pyroll-project.github.io
6
6
  Project-URL: Repository, https://github.com/pyroll-project/pyroll-core
@@ -44,7 +44,7 @@ from .hooks import Hook, HookHost, HookFunction, root_hooks
44
44
  from .disk_elements import DiskElementUnit
45
45
  from .config import Config, config, PlottingBackend, ConfigValue, ConfigMeta
46
46
 
47
- VERSION = "3.0.2.post2"
47
+ VERSION = "3.0.3"
48
48
 
49
49
  __all__ = [
50
50
  # grooves
@@ -132,5 +132,7 @@ root_hooks.extend(
132
132
  PassSequence.log_elongation,
133
133
  BaseRollPass.OutProfile.technologically_orientated_cross_section,
134
134
  BaseRollPass.technologically_orientated_contour_lines,
135
+ # BaseRollPass.back_tension,
136
+ # BaseRollPass.front_tension
135
137
  ]
136
138
  )
@@ -191,13 +191,13 @@ class Profile(HookHost):
191
191
 
192
192
  @classmethod
193
193
  def from_groove(
194
- cls,
195
- groove: GrooveBase,
196
- width: Optional[float] = None,
197
- filling: Optional[float] = None,
198
- height: Optional[float] = None,
199
- gap: Optional[float] = None,
200
- **kwargs,
194
+ cls,
195
+ groove: GrooveBase,
196
+ width: Optional[float] = None,
197
+ filling: Optional[float] = None,
198
+ height: Optional[float] = None,
199
+ gap: Optional[float] = None,
200
+ **kwargs,
201
201
  ) -> "Profile":
202
202
  """
203
203
  Create a profile instance based on a given groove.
@@ -242,8 +242,8 @@ class Profile(HookHost):
242
242
  poly = Polygon(np.concatenate([upper_contour_line.coords, lower_contour_line.coords]))
243
243
 
244
244
  if (
245
- # one percent tolerance to bypass discretization issues
246
- -width / 2 < poly.bounds[0] * 1.01 or width / 2 > poly.bounds[2] * 1.01
245
+ # one percent tolerance to bypass discretization issues
246
+ -width / 2 < poly.bounds[0] * 1.01 or width / 2 > poly.bounds[2] * 1.01
247
247
  ):
248
248
  raise ValueError(
249
249
  "Profile's width can not be larger than its contour lines." "May be caused by critical overfilling."
@@ -294,7 +294,7 @@ class Profile(HookHost):
294
294
 
295
295
  @classmethod
296
296
  def square(
297
- cls, side: Optional[float] = None, diagonal: Optional[float] = None, corner_radius: float = 0, **kwargs
297
+ cls, side: Optional[float] = None, diagonal: Optional[float] = None, corner_radius: float = 0, **kwargs
298
298
  ) -> "SquareProfile":
299
299
  """
300
300
  Creates a square shaped profile (a real square with rounded corners, without imperfections of square grooves).
@@ -347,12 +347,12 @@ class Profile(HookHost):
347
347
 
348
348
  @classmethod
349
349
  def hexagon(
350
- cls,
351
- side: Optional[float] = None,
352
- height: Optional[float] = None,
353
- diagonal: Optional[float] = None,
354
- corner_radius: float = 0,
355
- **kwargs,
350
+ cls,
351
+ side: Optional[float] = None,
352
+ height: Optional[float] = None,
353
+ diagonal: Optional[float] = None,
354
+ corner_radius: float = 0,
355
+ **kwargs,
356
356
  ) -> "HexagonProfile":
357
357
  """
358
358
  Creates a hexagonal shaped profile (a real hexagonal shape with rounded corners,
@@ -567,7 +567,7 @@ class DiamondProfile(Profile):
567
567
 
568
568
  class SquareProfile(Profile):
569
569
  def __init__(
570
- self, side: Optional[float] = None, diagonal: Optional[float] = None, corner_radius: float = 0, **kwargs
570
+ self, side: Optional[float] = None, diagonal: Optional[float] = None, corner_radius: float = 0, **kwargs
571
571
  ):
572
572
  """
573
573
  Creates a square shaped profile (a real square with rounded corners, without imperfections of square grooves).
@@ -626,12 +626,12 @@ class SquareProfile(Profile):
626
626
 
627
627
  class HexagonProfile(Profile):
628
628
  def __init__(
629
- self,
630
- side: Optional[float] = None,
631
- height: Optional[float] = None,
632
- diagonal: Optional[float] = None,
633
- corner_radius: float = 0,
634
- **kwargs,
629
+ self,
630
+ side: Optional[float] = None,
631
+ height: Optional[float] = None,
632
+ diagonal: Optional[float] = None,
633
+ corner_radius: float = 0,
634
+ **kwargs,
635
635
  ):
636
636
  """
637
637
  Creates a hexagonal shaped profile (a real hexagonal shape with rounded corners,
@@ -680,7 +680,7 @@ class HexagonProfile(Profile):
680
680
  * (side, side)
681
681
  )
682
682
  polygon = Polygon(line)
683
- polygon = polygon.buffer(corner_radius)
683
+ polygon = polygon.buffer(-corner_radius).buffer(2 * corner_radius).buffer(-corner_radius)
684
684
 
685
685
  super().__init__(cross_section=refine_cross_section(polygon), classifiers={"hexagon"}, **kwargs)
686
686
 
@@ -1,3 +1,5 @@
1
+ import copy
2
+
1
3
  import numpy as np
2
4
 
3
5
  from collections.abc import Sequence
@@ -144,6 +146,8 @@ class PassSequence(Unit, Sequence[Unit]):
144
146
  :param final_cross_section_area: area of the final cross-section
145
147
  """
146
148
 
149
+ copied_sequence = copy.deepcopy(self)
150
+
147
151
  def calculate_velocities_array(velocities: np.ndarray[float], cross_sections_areas: np.ndarray[float]):
148
152
  for i in range(len(cross_sections_areas) - 2, -1, -1):
149
153
  velocities[i] = velocities[i + 1] * cross_sections_areas[i + 1] / cross_sections_areas[i]
@@ -152,30 +156,32 @@ class PassSequence(Unit, Sequence[Unit]):
152
156
  for roll_pass, velocity in zip(roll_passes, velocities):
153
157
  roll_pass.velocity = velocity
154
158
 
155
- usable_cross_section_areas = np.asarray([roll_pass.usable_cross_section.area for roll_pass in self.roll_passes])
156
- initial_velocities = np.zeros_like(usable_cross_section_areas, dtype=float)
159
+ usable_cross_section_areas = np.asarray([roll_pass.usable_cross_section.area for roll_pass in copied_sequence.roll_passes])
160
+ initial_roll_pass_velocities = np.zeros_like(usable_cross_section_areas, dtype=float)
157
161
 
158
- initial_velocities[-1] = final_speed
162
+ initial_roll_pass_velocities[-1] = final_speed
159
163
  usable_cross_section_areas[-1] = final_cross_section_area
160
164
 
161
- calculate_velocities_array(velocities=initial_velocities, cross_sections_areas=usable_cross_section_areas)
162
- set_velocities_to_roll_passes(roll_passes=self.roll_passes, velocities=initial_velocities)
165
+ calculate_velocities_array(velocities=initial_roll_pass_velocities, cross_sections_areas=usable_cross_section_areas)
166
+ set_velocities_to_roll_passes(roll_passes=copied_sequence.roll_passes, velocities=initial_roll_pass_velocities)
163
167
 
164
- self.solve(in_profile)
168
+ copied_sequence.solve(in_profile)
165
169
 
166
170
  for i in range(self.max_iteration_count):
167
- prior_velocities = np.asarray([roll_pass.velocity for roll_pass in self.roll_passes])
168
- current_velocities = prior_velocities.copy()
169
- profile_areas = [roll_pass.out_profile.cross_section.area for roll_pass in self.roll_passes]
171
+ prior_roll_pass_velocities = np.asarray([roll_pass.velocity for roll_pass in copied_sequence.roll_passes])
172
+ current_roll_pass_velocities = prior_roll_pass_velocities.copy()
173
+ profile_areas = [roll_pass.out_profile.cross_section.area for roll_pass in copied_sequence.roll_passes]
170
174
 
171
- calculate_velocities_array(velocities=current_velocities, cross_sections_areas=profile_areas)
172
- set_velocities_to_roll_passes(roll_passes=self.roll_passes, velocities=current_velocities)
175
+ calculate_velocities_array(velocities=current_roll_pass_velocities, cross_sections_areas=profile_areas)
176
+ set_velocities_to_roll_passes(roll_passes=copied_sequence.roll_passes, velocities=current_roll_pass_velocities)
173
177
 
174
- self.solve(in_profile)
178
+ copied_sequence.solve(in_profile)
175
179
 
176
- difference = np.abs(prior_velocities - current_velocities)
180
+ difference = np.abs(prior_roll_pass_velocities - current_roll_pass_velocities)
177
181
 
178
182
  if np.all(difference < 0.01):
183
+ set_velocities_to_roll_passes(roll_passes=self.roll_passes, velocities=current_roll_pass_velocities)
184
+ self.solve(in_profile)
179
185
  break
180
186
 
181
187
  def solve_velocities_forward(self, in_profile: Profile, initial_speed: float):
@@ -187,6 +193,8 @@ class PassSequence(Unit, Sequence[Unit]):
187
193
  :param final_cross_section_area: area of the final cross-section
188
194
  """
189
195
 
196
+ copied_sequence = copy.deepcopy(self)
197
+
190
198
  def calculate_velocities_array(velocities: np.ndarray[float], cross_sections_areas: np.ndarray[float]):
191
199
  for i in range(1, len(usable_cross_section_areas)):
192
200
  velocities[i] = velocities[i - 1] * cross_sections_areas[i - 1] / cross_sections_areas[i]
@@ -195,28 +203,73 @@ class PassSequence(Unit, Sequence[Unit]):
195
203
  for roll_pass, velocity in zip(roll_passes, velocities):
196
204
  roll_pass.velocity = velocity
197
205
 
198
- usable_cross_section_areas = np.asarray([roll_pass.usable_cross_section.area for roll_pass in self.roll_passes])
199
- initial_velocities = np.zeros_like(usable_cross_section_areas, dtype=float)
206
+ usable_cross_section_areas = np.asarray([roll_pass.usable_cross_section.area for roll_pass in copied_sequence.roll_passes])
207
+ initial_roll_pass_velocities = np.zeros_like(usable_cross_section_areas, dtype=float)
200
208
 
201
- initial_velocities[0] = initial_speed * in_profile.cross_section.area / self.roll_passes[
202
- 0].usable_cross_section.area
209
+ initial_roll_pass_velocities[0] = initial_speed * in_profile.cross_section.area / copied_sequence.roll_passes[0].usable_cross_section.area
203
210
 
204
- calculate_velocities_array(velocities=initial_velocities, cross_sections_areas=usable_cross_section_areas)
205
- set_velocities_to_roll_passes(roll_passes=self.roll_passes, velocities=initial_velocities)
211
+ calculate_velocities_array(velocities=initial_roll_pass_velocities, cross_sections_areas=usable_cross_section_areas)
212
+ set_velocities_to_roll_passes(roll_passes=copied_sequence.roll_passes, velocities=initial_roll_pass_velocities)
206
213
 
207
- self.solve(in_profile)
214
+ copied_sequence.solve(in_profile)
208
215
 
209
216
  for i in range(self.max_iteration_count):
210
- prior_velocities = np.asarray([roll_pass.velocity for roll_pass in self.roll_passes])
211
- current_velocities = prior_velocities.copy()
212
- profile_areas = [roll_pass.out_profile.cross_section.area for roll_pass in self.roll_passes]
217
+ prior_velocities = np.asarray([roll_pass.velocity for roll_pass in copied_sequence.roll_passes])
218
+ profile_areas = [roll_pass.out_profile.cross_section.area for roll_pass in copied_sequence.roll_passes]
219
+ roll_pass_velocities = np.zeros_like(usable_cross_section_areas, dtype=float)
220
+ roll_pass_velocities[0] = initial_speed * in_profile.cross_section.area / profile_areas[0]
213
221
 
214
- calculate_velocities_array(velocities=current_velocities, cross_sections_areas=profile_areas)
215
- set_velocities_to_roll_passes(roll_passes=self.roll_passes, velocities=current_velocities)
222
+ calculate_velocities_array(velocities=roll_pass_velocities, cross_sections_areas=profile_areas)
223
+ set_velocities_to_roll_passes(roll_passes=copied_sequence.roll_passes, velocities=roll_pass_velocities)
216
224
 
217
- self.solve(in_profile)
225
+ copied_sequence.solve(in_profile)
218
226
 
219
- difference = np.abs(prior_velocities - current_velocities)
227
+ difference = np.abs(prior_velocities - roll_pass_velocities)
220
228
 
221
229
  if np.all(difference < 0.01):
230
+ set_velocities_to_roll_passes(roll_passes=self.roll_passes, velocities=roll_pass_velocities)
231
+ self.solve(in_profile)
222
232
  break
233
+
234
+ def solve_interstand_tensions_with_given_velocity_ratios(self, in_profile: Profile,
235
+ velocity_ratios: np.ndarray[float], final_speed: float):
236
+ """
237
+ Solve method, that calculates the resulting tensions for given reductions.
238
+ Further, it sets the velocities according to these reductions and the finishing speed.
239
+
240
+ :param in_profile: incoming profile
241
+ :param velocity_ratios: velocity_ratio per stand.
242
+ :param final_speed: speed of the last stand
243
+ """
244
+
245
+ roll_pass_velocities = [final_speed]
246
+ for ratio in reversed(velocity_ratios):
247
+ previous_roll_pass_velocity = roll_pass_velocities[0] / ratio
248
+ roll_pass_velocities.insert(0, previous_roll_pass_velocity)
249
+
250
+ roll_pass_velocities = np.array(roll_pass_velocities)
251
+ for i, roll_pass in enumerate(self.roll_passes):
252
+ roll_pass.velocity = roll_pass_velocities[i]
253
+
254
+ copied_sequence = copy.deepcopy(self)
255
+ copied_sequence.solve(in_profile)
256
+
257
+ tensions = np.zeros(len(copied_sequence.roll_passes) * 2)
258
+ engineering_strains = (roll_pass_velocities[1:] - roll_pass_velocities[:-1]) / roll_pass_velocities[:-1]
259
+
260
+ for index in range(1, len(self.roll_passes)):
261
+ engineering_strain = engineering_strains[index - 1]
262
+
263
+ tensions[2 * index - 1] = copied_sequence.roll_passes[
264
+ index - 1].in_profile.elastic_modulus * engineering_strain
265
+ tensions[2 * index] -= copied_sequence.roll_passes[
266
+ index - 1].out_profile.elastic_modulus * engineering_strain
267
+
268
+ tensions[0] = 0
269
+ tensions[-1] = 0
270
+
271
+ for index, roll_pass in enumerate(copied_sequence.roll_passes):
272
+ roll_pass.back_tension = tensions[2 * index]
273
+ roll_pass.front_tension = tensions[2 * index + 1]
274
+
275
+ self.solve(in_profile=in_profile)
File without changes
File without changes